/* Rocoto · WhatsApp drawn as WhatsApp (iOS, light theme, Spanish).
   A fixed 390 x 844 document. Every glyph and every shape here is drawn for this kit.
   Owner: the WhatsApp builder. Used by ../demos/*.html. */

/* The face. Apple's own is asked for first and Inter is served to everyone else — which is most
   readers, since the shop is on Android. Nothing from the system sits between the two: `system-ui`,
   `BlinkMacSystemFont`, `Helvetica Neue`, `Segoe UI`, `Roboto` and `Arial` all resolve to a local
   face on Android, Linux and Windows, and Inter would never be reached. `block`, because a WhatsApp
   screen drawn in DejaVu for 100 ms is a wrong screenshot. Inter is OFL; the licence sits beside it.
   The file is a SUBSET of Inter 4.001 Regular — Latin, Latin-1, Latin Extended-A and the punctuation
   these screens set — cut with pyftsubset, keeping kern, liga, calt, ccmp, mark, mkmk, locl, tnum and
   zero. Emoji come from the reader's own system face, the way they do in WhatsApp. 140 KB became 26 KB.
   Cut it again with:
     python3 -m fontTools.subset inter-full.woff2 --output-file=inter.woff2 --flavor=woff2
       --layout-features='kern,liga,calt,ccmp,mark,mkmk,locl,tnum,zero' --name-IDs='*' --notdef-outline
       --unicodes='U+0020-007E,U+00A0-00FF,U+0100-017F,U+2010-2027,U+2030-2033,U+2039-203A,U+2044,U+20AC,U+2122,U+2190-2193' */
@font-face{
  font-family:'Inter';
  src:url('../wa/fonts/inter.woff2') format('woff2');
  font-weight:100 900; font-style:normal; font-display:block;
}

/* == springs (generated) ==
   Motion 13.4.0 spring solver, sampled to CSS linear().
   Regenerate with: node peru/wa/vendor/gen-springs.mjs */
:root{
  --wa-sp-sheet: linear(0, 0.0112, 0.0406, 0.0827, 0.1334, 0.1892, 0.2476, 0.3068, 0.3652, 0.4218, 0.4758, 0.5268, 0.5746, 0.6188, 0.6596, 0.6969, 0.7308, 0.7616, 0.7894, 0.8144, 0.8367, 0.8567, 0.8745, 0.8903, 0.9042, 0.9166, 0.9275, 0.937, 0.9454, 0.9528, 0.9592, 0.9648, 0.9697, 0.974, 0.9776, 0.9808, 0.9836, 0.986, 0.988, 0.9898, 0.9913, 0.9926, 0.9938, 0.9947, 0.9955, 0.9962, 0.9968, 0.9973, 0.9978, 0.9981, 0.9985, 0.9987, 0.9989, 0.9991, 0.9993, 0.9994, 1, 1, 1, 1);
  --wa-sp-sheet-t: 600ms;   /* spring 240/30/1 */
  /* THE IN-CHAT BROWSER TRAVELS SLOWER THAN A BANNER (SPEC 17b). Peter: «the animations of the
     link webpage that opens up is a bit fast» — so the browser's rise, its loading line and its
     page changes are a third longer, and the banner, the share card and the composer keep the
     600 above. `SHEET_MS` in wa.js carries this same number. */
  --wa-sp-sheet-slow-t: 800ms;
  --wa-pg-fade: .35s;
  --wa-pg-rise-t: 600ms;
  --wa-sp-banner: linear(0, 0.0124, 0.0452, 0.0924, 0.1494, 0.2123, 0.2782, 0.3448, 0.4102, 0.4734, 0.5332, 0.5892, 0.641, 0.6884, 0.7313, 0.7699, 0.8043, 0.8347, 0.8615, 0.8849, 0.9052, 0.9226, 0.9376, 0.9503, 0.961, 0.9699, 0.9774, 0.9835, 0.9885, 0.9925, 0.9957, 0.9981, 1.0001, 1.0015, 1.0025, 1.0033, 1.0037, 1.004, 1, 1);
  --wa-sp-banner-t: 400ms;   /* spring 260/28/1 */
  --wa-sp-card: linear(0, 0.0141, 0.0505, 0.1022, 0.1633, 0.2298, 0.2982, 0.3663, 0.4323, 0.495, 0.5537, 0.6079, 0.6575, 0.7024, 0.7427, 0.7786, 0.8104, 0.8384, 0.8628, 0.8842, 0.9026, 0.9185, 0.9322, 0.9438, 0.9537, 0.9621, 0.9691, 0.975, 0.9799, 0.984, 0.9874, 0.9902, 0.9924, 0.9942, 0.9957, 0.9969, 0.9978, 0.9986, 0.9991, 0.9995, 0.9999, 1.0001, 1.0003, 1, 1);
  --wa-sp-card-t: 450ms;   /* spring 300/32/1 */
}
/* == end springs == */

:root{
  --wa-w: 390px;
  --wa-h: 844px;

  /* The wallpaper is WhatsApp's own default light chat wallpaper, the file itself
     (`wallpaper.webp`, 760 x 1396 = 2x for a 380-390 pt screen). Its paper measures #E5DDD5 and
     its doodle is that paper darkened by 16 levels, so every colour that sits ON it was judged
     again beside a real iOS light-theme capture: incoming #FFFFFF, outgoing #D9FDD3, the date and
     system chips a translucent white-grey, the encryption notice #FFEFD1. */
  --wa-wall:      #E5DDD5;
  --wa-bar:       #F6F5F3;
  --wa-in:        #FFFFFF;
  --wa-out:       #D9FDD3;
  --wa-ink:       #111B21;
  --wa-meta:      #667781;
  --wa-tint:      #00A884;
  --wa-send:      #25D366;
  --wa-tick:      #8696A0;
  --wa-tick-blue: #53BDEB;
  --wa-link:      #027EB5;   /* a URL inside message TEXT */
  /* A template button row is GREEN, and --wa-link above is a different thing: the blue is for a
     URL inside message TEXT. The capture to check it against is Meta's own, in the WhatsApp
     Business Platform docs for message templates: the «See Dates» CTA-URL button under a template
     bubble, drawn with the boxed external-link glyph and green ink. Sampled at full resolution on
     the stems of that word, the ink runs #326F45..#42805B — hue 143 deg, the green family this
     token belongs to. */
  --wa-action:    #51A868;
  --wa-line:      rgba(11,20,26,.13);
  --wa-hair:      rgba(11,20,26,.09);
  --wa-shadow:    0 1px .5px rgba(11,20,26,.13);
  --wa-e2e-bg:    #FFEFD1;
  --wa-chip-bg:   rgba(255,255,255,.88);

  /* Ours everywhere, and Apple's own where it exists — see the note under this block. */
  --wa-font: "SF Pro Text", "SF Pro Display", "Inter", sans-serif;

  --wa-status-h: 59px;
  --wa-head-h: 48px;

  --wa-ease-ios: cubic-bezier(.32,.72,0,1);
  --wa-ease-out: cubic-bezier(.22,1,.36,1);
}

/* `-apple-system` is NOT an Apple-only name: Chromium answers it with the system UI face on every
   platform, so on Android it paints Roboto and on this Linux box it painted DejaVu — measured, 16 px:
   the stack led by it came out 334.37 px wide, exactly DejaVu, where Inter is 321.00. It is therefore
   served only to the engine that means SF by it. `"SF Pro Text"` and `"SF Pro Display"` are safe to
   name anywhere: nothing else answers to them, and they fall through to Inter. */
@supports (-webkit-touch-callout: none){
  :root{ --wa-font: -apple-system, "SF Pro Text", "SF Pro Display", "Inter", sans-serif; }
}

*,*::before,*::after{ box-sizing:border-box; }

html,body{
  width:var(--wa-w); height:var(--wa-h);
  margin:0; padding:0; overflow:hidden;
  background:var(--wa-wall);
  font-family:var(--wa-font);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

.wa{
  position:relative;
  width:var(--wa-w); height:var(--wa-h);
  display:flex; flex-direction:column;
  overflow:hidden;
  background:var(--wa-wall);
  color:var(--wa-ink);
  font-size:16px; line-height:1.31;
  user-select:none;
  isolation:isolate;
}
.wa.is-fading .wa-app,.wa.is-fading .wa-banner,.wa.is-fading .wa-lock{ opacity:0; transition:opacity .19s ease-in; }
.wa img{ display:block; }

/* ---------------------------------------------------------------- status */

.wa-status{
  position:relative; z-index:12;
  flex:0 0 var(--wa-status-h); height:var(--wa-status-h);
  /* iOS paints the status bar in the navigation bar's own colour, never in the wallpaper's */
  background:var(--wa-bar);
  color:var(--wa-ink);
}
.wa-clock{
  position:absolute; left:0; top:0; width:133px; height:100%;
  display:flex; align-items:center; justify-content:center; padding-top:1px;
  font-size:17px; font-weight:600; letter-spacing:-.38px;
  font-variant-numeric:tabular-nums;
}
.wa-sysicons{
  position:absolute; right:34px; top:0; height:100%;
  display:flex; align-items:center; gap:6px; padding-top:1px;
}
/* Apple's own: 125 x 36.67, 11.33 from the top, and the time centred on its band. */
.wa-island{
  position:absolute; left:50%; top:11.33px; width:125px; height:36.67px;
  margin-left:-62.5px; border-radius:20px; background:#000; z-index:50;
}
.wa-no-island .wa-island{ display:none; }
.wa.list-up .wa-status{ background:#fff; }

/* ---------------------------------------------------------------- header */

.wa-head{
  position:relative; z-index:11;
  flex:0 0 var(--wa-head-h); height:var(--wa-head-h);
  display:flex; align-items:center;
  padding:0 16px 0 8px;
  background:var(--wa-bar);
  box-shadow:0 .5px 0 var(--wa-line);
}
.wa-back{ display:flex; align-items:center; gap:4px; color:var(--wa-ink); flex:0 0 auto; padding-right:3px; }
.wa-back svg{ width:13px; height:24px; display:block; }
.wa-unread{ font-size:15px; letter-spacing:-.1px; }
.wa-av{
  flex:0 0 auto; width:36px; height:36px; border-radius:50%;
  margin-left:3px; overflow:hidden; background:#CFD5D9; position:relative; display:block;
}
.wa-av img,.wa-av svg{ width:100%; height:100%; display:block; }
.wa-idty{ flex:1 1 auto; min-width:0; margin-left:9px; padding-right:8px; display:block; }
.wa-name{
  font-size:17px; font-weight:600; letter-spacing:-.43px; line-height:1.14;
  display:flex; align-items:center; gap:4px; min-width:0;
}
.wa-name .nm{ min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.wa-name .wa-verif{ flex:0 0 auto; width:15px; height:15px; display:block; }
.wa-pres{
  display:block; font-size:12.5px; line-height:1.25; color:var(--wa-meta); letter-spacing:-.04px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; margin-top:1px; height:16px;
}
.wa-acts{ flex:0 0 auto; display:flex; align-items:center; gap:20px; color:var(--wa-ink); }
.wa-acts svg{ display:block; }

/* --------------------------------------------------------- app / chat box */

.wa-app{ position:relative; flex:1 1 auto; min-height:0; }
.wa-chat{
  position:absolute; inset:0; display:flex; flex-direction:column;
  transition:transform var(--wa-sp-sheet-t) var(--wa-sp-sheet);
}
.wa-chat.pushed{ transform:translateX(100%); }

.wa-body{
  position:relative; flex:1 1 auto; min-height:0;
  display:flex; flex-direction:column; justify-content:flex-end;
  overflow:hidden;
  /* WhatsApp's own wallpaper at the app's apparent scale: the file is 2x for a 380-390 pt wide
     screen, so it is painted at the full width of the screen and repeats down. One tile is taller
     than the thread's window, so the repeat is only insurance. */
  background-color:var(--wa-wall);
  background-image:url("../wa/wallpaper.webp");
  background-repeat:repeat; background-size:100% auto; background-position:top center;
}
.wa-feed{ position:relative; z-index:1; padding:12px 0 8px; contain:layout paint; }

/* a row opens by growing to its own height, with its ink there from the first frame */
.wa-row{ display:block; position:relative; }
/* THE COLUMN OPENS. THE INK IS ALREADY THERE. The opening is the reference's, measured on its
   live demos at 16 ms: an ease-out cubic over ~420 ms (57 % at 100 ms, 89 % at 200, 98 % at 300).
   It is the only thing that moves. A bubble is opaque from its first frame, the way WhatsApp
   paints one — opacity would carry the BUBBLE and not just its words, and the wallpaper's doodles
   read straight through the green of every message the shop sends. */
.wa-grow{ height:0; overflow:hidden; transition:height .39s cubic-bezier(.33,1,.68,1); }
.wa-row.on .wa-grow{ height:var(--h,auto); }
.wa-fade{ display:flex; padding:2px 17px 0; }
/* THE INDICATOR HANDS ITS PLACE STRAIGHT TO THE MESSAGE. WhatsApp swaps the three dots for the
   bubble in one move, so the dots go in one frame — and their box eases shut on the same curve
   the message opens on, which keeps the sum of the two heights continuous: the thread standing
   above the swap holds still while the bubble takes the dots' place. */
.wa-row.typing:not(.on) .wa-fade{ opacity:0; }
.wa-row.out .wa-fade{ justify-content:flex-end; }
.wa-row.mid .wa-fade{ justify-content:center; }
.wa-row.first .wa-fade{ padding-top:8px; }
.wa.is-measuring .wa-grow{ height:auto !important; }

/* ---------------------------------------------------------------- bubble */

.wa-b{
  position:relative; max-width:78%;
  border-radius:7.5px;
  box-shadow:var(--wa-shadow);
  background:var(--wa-in);
  padding:7px 9px 7px 10px;
}
.wa-row.out .wa-b{ background:var(--wa-out); }
/* THE TAIL, read off real screenshots rather than off anyone's drawing of WhatsApp. Two things
   are true there:
   (a) the beak hangs off the BOTTOM outer corner — bottom-right on an outgoing bubble,
       bottom-left on an incoming one;
   (b) it belongs to the LAST message of a run, not the first: where three outgoing bubbles land
       together, only the lowest carries a beak and the two above it have every corner rounded.
   (b) is the only arrangement that reads, too — a beak on the bottom of the FIRST bubble points
   straight at the bubble underneath it.
   The captures, so this can be checked instead of believed: WABetaInfo's iOS 26 chat-bubbles
   shot (an iPhone, WhatsApp light theme, three outgoing messages at 17:14 — beak on the third
   only, bottom-right), and wikiHow's «Reply to a Specific Message on WhatsApp» step 6 (an
   outgoing «Hey» and an incoming «What's up?», each with the beak at its bottom outer corner).
   Which bubble is last changes as the thread grows, so `.tail` is written per frame by the player. */
.wa-row.tail .wa-b::after{
  content:""; position:absolute; bottom:0; width:8px; height:12px;
  background:inherit; filter:drop-shadow(0 1px .4px rgba(11,20,26,.11));
}
.wa-row.in.tail .wa-b{ border-bottom-left-radius:0; }
.wa-row.in.tail .wa-b::after{
  left:-8px;
  clip-path:path("M8 0 L8 3.2 C7.8 5.5 6.9 7.5 5.6 8.9 C4.2 10.4 2.4 11.4 .4 11.8 L.4 12 L8 12 Z");
}
.wa-row.out.tail .wa-b{ border-bottom-right-radius:0; }
.wa-row.out.tail .wa-b::after{
  right:-8px;
  clip-path:path("M0 0 L0 3.2 C.2 5.5 1.1 7.5 2.4 8.9 C3.8 10.4 5.6 11.4 7.6 11.8 L7.6 12 L0 12 Z");
}

.wa-txt{
  font-size:16px; line-height:21px; letter-spacing:-.32px;
  color:var(--wa-ink); word-wrap:break-word; overflow-wrap:break-word;
}
.wa-txt::after{ content:""; display:block; clear:both; }

/* the time and the ticks are floated, so the text wraps around them */
.wa-meta{
  float:right; display:inline-flex; align-items:center; gap:3px;
  margin:9px 0 -2px 10px;
  font-size:11px; line-height:11px; letter-spacing:.07px; color:var(--wa-meta);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}
.wa-meta.below{ float:none; position:absolute; right:9px; bottom:6px; margin:0; }
.wa-tick{ display:block; width:16px; height:11px; color:var(--wa-tick); }
.wa-tick svg{ display:block; width:100%; height:100%; }
.wa-tick.blue{ color:var(--wa-tick-blue); }
.wa-tick.clock{ width:11px; height:11px; }

/* ----------------------------------------------------------- system rows */

.wa-chip{
  display:inline-flex; align-items:center; gap:5px; max-width:88%;
  background:var(--wa-chip-bg); color:#54656F;
  border-radius:7.5px; padding:5px 12px 6px;
  font-size:12.5px; line-height:16px; letter-spacing:-.02px; text-align:center;
  box-shadow:var(--wa-shadow);
}
.wa-chip.date{ font-weight:500; color:#5A6B74; padding:4px 12px 5px; text-transform:none; }
.wa-chip.e2e{
  display:block; max-width:100%; background:var(--wa-e2e-bg); color:#5C5432;
  padding:8px 14px 9px; text-align:center; line-height:19px;
}
.wa-chip.e2e svg{ width:9px; height:12px; display:inline-block; vertical-align:-1px; margin-right:4px; opacity:.8; }
.wa-chip .wa-rocoto{ flex:0 0 auto; width:15px; height:15px; border-radius:50%; }

/* ------------------------------------------------------------ voice note */

.wa-b.voice{ padding:7px 10px; }
/* The avatar sits on the side away from the tail — right on an incoming note, left on your own —
   and the mic is a bare green glyph tucked into its lower inner corner, not a badged disc. */
.wa-voice{ display:flex; align-items:center; gap:9px; width:222px; }
.wa-row.in .wa-voice{ flex-direction:row-reverse; }
.wa-vav{ position:relative; flex:0 0 auto; width:44px; height:44px; }
.wa-vav .wa-av{ width:44px; height:44px; margin:0; }
.wa-mic{
  position:absolute; right:-3px; bottom:-1px; width:13px; height:17px;
  display:flex; align-items:center; justify-content:center;
  color:var(--wa-send); transition:color .35s ease;
}
.wa-row.in .wa-mic{ right:auto; left:-4px; }
.wa-voice.heard .wa-mic{ color:#53BDEB; }
.wa-mic svg{ width:100%; height:100%; }
.wa-vmain{ flex:1 1 auto; min-width:0; }
.wa-vtop{ display:flex; align-items:center; }
.wa-play{ flex:0 0 auto; width:19px; height:22px; color:#54656F; margin-right:9px; }
.wa-play svg{ width:100%; height:100%; display:block; }
.wa-wave{ flex:1 1 auto; display:flex; align-items:center; justify-content:space-between; gap:2.2px; height:22px; position:relative; padding-left:7px; }
.wa-bar{ flex:0 0 2.6px; width:2.6px; border-radius:2px; background:#C6CFD4; }
.wa-bar.done{ background:#8D989E; }
/* The head travels ON the bars and parks on the last one: the player writes --p, and the two
   ends of the run are inset by the head's own width so it never leaves the waveform. Centred on
   the progress instead, it finished 6.5 px outside the bars, against the avatar and its mic, and
   read as a green blob glued to the circle. */
.wa-head-dot{
  position:absolute; top:50%; width:13px; height:13px; margin-top:-6.5px;
  left:calc(7px + var(--p,0) * (100% - 20px));
  border-radius:50%; background:var(--wa-send);
}
.wa-vbot{
  display:flex; align-items:center; justify-content:space-between;
  margin-top:3px; font-size:11px; color:var(--wa-meta); font-variant-numeric:tabular-nums;
}
.wa-vdur{ letter-spacing:.1px; }
.wa-b.voice .wa-meta{ float:none; margin:0; }

/* ----------------------------------------------------------------- photo */

.wa-b.media{ padding:2px; }
.wa-photo{
  position:relative; width:230px; height:288px; border-radius:6px; overflow:hidden;
  background:linear-gradient(160deg,#DED6CA,#CDC3B4);
}
.wa-photo img{ width:100%; height:100%; object-fit:cover; }
/* the clock reads white over the picture itself, on the faintest scrim — never in a pill */
.wa-photo::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:56px; pointer-events:none;
  background:linear-gradient(180deg,rgba(11,20,26,0),rgba(11,20,26,.30));
}
.wa-photo.is-missing img{ display:none; }
.wa-photo .wa-ph-mark{ display:none; position:absolute; inset:0; align-items:center; justify-content:center; color:#A79C8C; }
.wa-photo.is-missing .wa-ph-mark{ display:flex; }
.wa-b.media .wa-meta{
  float:none; position:absolute; right:10px; bottom:8px; margin:0; color:#fff; z-index:1;
  text-shadow:0 1px 3px rgba(11,20,26,.45);
}
.wa-b.media .wa-tick{ color:#fff; }
.wa-b.media .wa-tick.blue{ color:var(--wa-tick-blue); }

/* ------------------------------------------------ Rocoto's confirmation card

   THE MESSAGE THAT SAYS THE SUPPLIER WAS PAID (SPEC 17b). It is an image message — the shop
   sends it, the supplier receives it, and it is the same object on both phones — but it is
   DRAWN, not decoded, so it holds at every width the page scales a handset to. Rocoto's own
   surface: paper #FAF7F3 on ink #1A1413, the face mark, and the figure with its unit on the
   number's own line, exactly as the product sets one. Judged at the size row two draws the
   phone — about 270 px of handset, so 164 px of card. */
.wa-card{
  display:block; width:246px; border-radius:6px; overflow:hidden;
  background:#FAF7F3; color:#1A1413; padding:14px 14px 13px;
  box-shadow:inset 0 0 0 1px rgba(26,20,19,.07);
}
.wa-card .wc-h{ display:flex; align-items:center; gap:7px; }
.wa-card .wc-h img{ width:17px; height:17px; display:block; }
.wa-card .wc-h span{ font-size:12.5px; font-weight:600; letter-spacing:-.1px; line-height:17px; }
.wa-card .wc-l{ display:block; margin-top:11px; font-size:12.5px; line-height:16px; color:#7A6F63; letter-spacing:-.1px; }
.wa-card .wc-f{ display:block; margin-top:2px; }
.wa-card .wc-w{ display:block; margin-top:4px; font-size:17px; font-weight:600; line-height:22px; letter-spacing:-.3px; }
/* the tick belongs to the open-graph frame below, where the preview has to say «sent» on its own */
.wa-card .wc-ok{ display:none; }
.wa-card .rp-fig .cur{ font-size:15px; line-height:18px; color:#7A6F63; }
.wa-card .rp-fig .val{ font-size:29px; line-height:34px; letter-spacing:-.6px; }
/* the clock sits in the card's own bottom-right corner, so the reference stops short of it */
.wa-card .wc-r{ display:block; margin-top:8px; padding-right:50px; font-size:11px; line-height:15px;
  color:#8A8078; letter-spacing:-.05px; font-variant-numeric:tabular-nums;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.wa-b.media.card{ padding:2px; }
.wa-b.media.card .wa-meta{ right:14px; bottom:13px; color:var(--wa-meta); text-shadow:none; }
.wa-b.media.card .wa-tick{ color:var(--wa-meta); }
.wa-b.media.card .wa-tick.blue{ color:var(--wa-tick-blue); }

/* ------------------------------------------------------------- the shutter

   A white beat over the whole screen, at the root of the phone, because the app that takes the
   photograph is Rocoto's own and its camera is a page of it. */
.wa-flash{ position:absolute; inset:0; background:#fff; opacity:0; pointer-events:none; z-index:60; }

/* --------------------------------------------- CTA-URL rows in the bubble */

.wa-b.has-cta{ padding:0; }
.wa-b.has-cta .wa-txtwrap{ padding:8px 10px 6px 11px; }
.wa-cta-b{
  display:flex; align-items:center; justify-content:center; gap:8px;
  height:45px; color:var(--wa-action); font-size:16px; letter-spacing:-.32px;
  border-top:.5px solid var(--wa-hair);
  transition:background .15s ease;
}
.wa-cta-b:last-child{ border-bottom-left-radius:inherit; border-bottom-right-radius:inherit; }
.wa-cta-b svg{ flex:0 0 auto; width:17px; height:17px; }
.wa-cta-b.pressed{ background:rgba(11,20,26,.07); }

/* --------------------------------------------------------- link preview */

.wa-prev{
  display:block; background:rgba(11,20,26,.05); border-radius:6px; overflow:hidden;
  margin:-2px -3px 5px; width:268px; max-width:100%;
}
.wa-prev .im{ display:block; height:112px; background:#DDD6CA; }
/* the page's own picture fills the slot; a DRAWN preview (`.og` below) brings its own marks,
   and this rule stops short of them */
.wa-prev .im > img{ width:100%; height:100%; object-fit:cover; }
.wa-prev .bd{ display:block; padding:8px 10px 9px; }
.wa-prev .t{ display:block; font-size:14px; font-weight:500; line-height:18px; letter-spacing:-.1px; }
.wa-prev .d{ display:block; font-size:13px; line-height:17px; color:var(--wa-meta); margin-top:2px; }
.wa-prev .u{ display:block; font-size:12.5px; color:var(--wa-meta); margin-top:3px; }
/* A URL inside a message is the app's own link blue, underlined, the way WhatsApp draws one. */
.wa-txt.lk, .wa-txt .lk{ color:var(--wa-link); text-decoration:underline; text-underline-offset:2px;
  text-decoration-thickness:from-font; }

/* ─── THE CONFIRMATION AS AN OPEN-GRAPH IMAGE (SPEC 17c) ─────────────────────────────────────
   Peter: «would actually be a link with the social graph image preview being that confirmation
   tick that the funds were sent. a nifty way to use previews as real data». So the picture slot
   of the preview holds Rocoto's own drawing in a 1200 x 630 frame — the tick, «Funds sent», the
   amount, then the supplier's name — and the title and the host stand under it as they do under
   any preview. Judged at the size a row draws it: 268 px of card inside a 390 px screen is 185 px
   where the page draws the handset at 270. */
.wa-prev .im.og{ height:auto; aspect-ratio:1200/630; background:#FAF7F3; }
.wa-card.wide{
  width:100%; height:100%; border-radius:0; box-shadow:none; padding:14px 16px;
  display:grid; grid-template-columns:minmax(0,1fr); align-content:start;
}
/* THE TICK BELONGS TO WHAT IS DONE. A confirmation that funds were sent wears it; a link that
   asks a customer to pay states the order and the figure, and the column it would stand in is
   simply not there. */
.wa-card.wide.tick{ grid-template-columns:56px minmax(0,1fr); column-gap:12px; padding:12px 14px; }
.wa-card.wide .wc-h{ grid-column:1 / -1; grid-row:1; }
.wa-card.wide.tick .wc-ok{ display:block; grid-column:1; grid-row:2 / 5; align-self:center; width:56px; height:56px; margin-top:10px; }
.wa-card.wide .wc-ok svg{ display:block; width:100%; height:100%; }
.wa-card.wide .wc-l{ grid-row:2; margin-top:12px; font-size:13.5px; font-weight:600;
  line-height:20px; color:#1A1413; letter-spacing:-.1px; }
.wa-card.wide .wc-f{ grid-row:3; margin-top:1px; }
.wa-card.wide .wc-w{ grid-row:4; margin-top:0; font-size:15px; font-weight:500;
  line-height:20px; letter-spacing:-.2px; color:#5C534B; }
.wa-card.wide.tick .wc-l, .wa-card.wide.tick .wc-f, .wa-card.wide.tick .wc-w{ grid-column:2; }
.wa-card.wide .rp-fig .cur{ font-size:16px; line-height:20px; }
.wa-card.wide .rp-fig .val{ font-size:32px; line-height:38px; letter-spacing:-.7px; }
.wa-card.wide .wc-r{ display:none; }
.wa-card.wide.tick .wc-l{ font-size:16px; line-height:22px; font-weight:500; margin-top:10px; }
.wa-card.wide.tick .wc-w{ font-size:13px; line-height:18px; font-weight:400; }
.wa-card.wide.tick .rp-fig .val{ line-height:36px; }


/* ─── SENT FOR THE SHOP ──────────────────────────────────────────────────────────────────────
   Rocoto answers a customer on the selling phone, so the outgoing message wears the kit's own
   Rocoto mark and its name, and nothing else about the bubble changes. */
.wa-by{ display:flex; align-items:center; gap:5px; padding:1px 0 5px;
  font-size:12px; font-weight:600; line-height:15px; letter-spacing:-.1px; color:var(--wa-meta); }
.wa-by .wa-rocoto{ flex:0 0 auto; width:13px; height:13px; border-radius:50%; }

/* ------------------------------------------------------------- QR / card */

.wa-b.qr{ padding:4px 4px 6px; }
.wa-qrcard{ width:224px; }
.wa-qrbox{
  width:100%; aspect-ratio:1/1; background:#fff; border-radius:5px;
  display:flex; align-items:center; justify-content:center; padding:12px;
  box-shadow:inset 0 0 0 .5px var(--wa-hair);
}
.wa-qrbox svg{ width:100%; height:100%; }
.wa-qrfoot{ display:flex; align-items:baseline; justify-content:space-between; padding:6px 6px 0; }
.wa-qrcap{ font-size:13px; color:var(--wa-meta); }
.wa-b.qr .wa-meta{ float:none; margin:0; }

/* ----------------------------------------------------------- typing dots */

.wa-typing{ display:flex; align-items:center; gap:3.8px; height:11px; }
.wa-typing i{ width:7px; height:7px; border-radius:50%; background:#8FA0A8; display:block; }
.wa-b.typing{ padding:8px 10px; }
/* the dots run while the indicator is ON the screen, and on no other frame */
.wa-row.on .wa-typing i:nth-child(1){ animation:wa-tp 1.6s infinite ease-in-out; }
.wa-row.on .wa-typing i:nth-child(2){ animation:wa-tp 1.6s .085s infinite ease-in-out; }
.wa-row.on .wa-typing i:nth-child(3){ animation:wa-tp 1.6s .17s infinite ease-in-out; }
@keyframes wa-tp{
  0%{ transform:translateY(0); opacity:.42 }
  5.5%{ transform:translateY(-2.4px); opacity:.9 }
  15%{ transform:translateY(.8px); opacity:.78 }
  22%{ transform:translateY(-.9px); opacity:.62 }
  31%,100%{ transform:translateY(0); opacity:.42 }
}

/* -------------------------------------------------------------- composer */

.wa-foot{
  position:relative; z-index:11; flex:0 0 auto;
  background:var(--wa-bar);
  box-shadow:0 -.5px 0 var(--wa-line);
}
.wa-comp{ display:flex; align-items:flex-end; gap:9px; padding:7px 11px 7px; }
.wa-plus{ flex:0 0 auto; width:25px; height:25px; color:#54656F; margin-bottom:4px; }
.wa-field{
  flex:1 1 auto; min-width:0; min-height:34px;
  background:#fff; border-radius:17px; box-shadow:inset 0 0 0 .5px var(--wa-hair);
  display:flex; align-items:flex-end; gap:8px; padding:6px 9px 6px 13px;
}
.wa-ftext{
  flex:1 1 auto; min-width:0; font-size:16.5px; line-height:21px; letter-spacing:-.38px;
  color:var(--wa-ink); padding:.5px 0 .5px; word-wrap:break-word; white-space:pre-wrap;
  max-height:105px; overflow:hidden;
}
.wa-ftext.ph{ color:#8696A0; }
.wa-caret{
  display:inline-block; width:2px; height:19px; background:#25D366; vertical-align:-4px;
  margin-left:1px; border-radius:1px;
}
.wa-sticker{ flex:0 0 auto; width:22px; height:22px; color:#54656F; }
.wa-cam{ flex:0 0 auto; width:25px; height:25px; color:#54656F; margin-bottom:4px; }
.wa-slot{ position:relative; flex:0 0 auto; width:33px; height:33px; margin-bottom:.5px; }
.wa-round{
  position:absolute; inset:0; width:33px; height:33px; border-radius:50%; background:var(--wa-send);
  color:#fff; display:flex; align-items:center; justify-content:center;
  transition:transform .19s var(--wa-sp-card), opacity .13s linear;
}
.wa-round svg{ width:19px; height:19px; }
.wa-sendb{ opacity:0; transform:scale(.55) rotate(-24deg); }
.wa-cam{
  transition:width .2s var(--wa-ease-ios), opacity .12s linear, margin .2s var(--wa-ease-ios),
             transform .2s var(--wa-ease-ios);
  overflow:hidden;
}
.wa.has-text .wa-sendb{ opacity:1; transform:none; }
.wa.has-text .wa-mic-b{ opacity:0; transform:scale(.55) rotate(20deg); }
.wa.has-text .wa-cam{ width:0; opacity:0; margin-right:-9px; transform:scale(.6); }
/* iOS draws it 139 x 5 with its bottom edge 8 px off the screen */
.wa-home{ height:34px; display:flex; align-items:flex-end; justify-content:center; padding-bottom:8px; }
.wa-home i{ display:block; width:139px; height:5px; border-radius:3px; background:#0B141A; opacity:.9; }

.wa-rec{ display:none; align-items:center; gap:12px; padding:7px 16px; height:48px; }
.wa.is-rec .wa-rec{ display:flex; }
.wa.is-rec .wa-comp{ display:none; }
.wa-rec .dot{ flex:0 0 auto; width:22px; height:22px; color:#FF3B30; animation:wa-blink 1.1s infinite ease-in-out; }
.wa-rec .dot svg{ width:100%; height:100%; display:block; }
@keyframes wa-blink{ 0%,100%{opacity:1} 50%{opacity:.25} }
.wa-rec .tm{ font-size:17px; color:var(--wa-ink); font-variant-numeric:tabular-nums; min-width:44px; }
.wa-rec .sl{ flex:1 1 auto; text-align:center; font-size:15px; color:#8696A0;
  transition:opacity .22s ease-out, transform .22s ease-out; }
.wa.is-locked .wa-rec .sl{ opacity:0; transform:translateX(-14px); position:absolute; }
.wa-rec .lw{ flex:1 1 auto; height:22px; overflow:hidden; position:relative; display:none; }
.wa.is-locked .wa-rec .lw{ display:block; }
.wa-rec .lwi{ position:absolute; left:100%; top:0; height:22px; display:flex; align-items:center; gap:2.6px; }
.wa-rec .lwi i{ display:block; width:2.8px; border-radius:2px; background:#8696A0; }
.wa-rec .tr{ flex:0 0 auto; width:22px; height:22px; color:#54656F; }

/* ------------------------------------------------------- in-chat browser */

/* iOS paints ONE status bar, for the phone, and a presented sheet travels UNDER it: the clock
   never moves and is never drawn twice. So the sheet begins below the status bar and carries no
   bar of its own. The join is invisible because the status bar and this sheet's toolbar are the
   same colour (--wa-bar / #F6F5F3), exactly as a presented sheet reads on the phone. */
.wa-sheet{
  position:absolute; top:var(--wa-status-h); left:0; right:0; bottom:0; z-index:40;
  display:flex; flex-direction:column; background:#fff;
  overflow:hidden;
  transform:translateY(104%);
  transition:transform var(--wa-sp-sheet-slow-t) var(--wa-sp-sheet);
  box-shadow:0 -14px 44px rgba(11,20,26,.22);
  will-change:transform;
}
.wa-sheet.up{ transform:translateY(0); }
.wa-sheet-top{ flex:0 0 auto; background:#F6F5F3; box-shadow:0 .5px 0 var(--wa-line); position:relative; }
.wa-sheet-bar{ height:52px; display:flex; align-items:center; justify-content:space-between; padding:0 16px; position:relative; }
.wa-sheet-done{ flex:0 0 auto; font-size:16.5px; color:var(--wa-ink); letter-spacing:-.38px; }
.wa-sheet-mid{ position:absolute; left:84px; right:84px; top:50%; transform:translateY(-50%); text-align:center; }
.wa-sheet-t{ display:block; font-size:15.5px; font-weight:600; letter-spacing:-.28px; line-height:1.2;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.wa-sheet-h{ display:flex; align-items:center; justify-content:center; gap:5px;
  font-size:12.5px; color:#8A8F94; line-height:1.25; margin-top:1px; }
.wa-sheet-h svg{ width:9px; height:11px; opacity:.85; }
.wa-sheet-rl{ flex:0 0 auto; width:20px; height:20px; color:var(--wa-ink); }
.wa-prog{ position:absolute; left:0; bottom:0; height:2.5px; width:0; background:#0A84FF; opacity:0; }
.wa-sheet-doc{ flex:1 1 auto; min-height:0; overflow:hidden; position:relative; background:#fff; }

/* ------------------------------------------- the pages inside the browser */

.wa-pg{
  position:absolute; inset:0; padding:22px 20px 24px; display:flex; flex-direction:column;
  opacity:0; transform:translateY(10px); pointer-events:none;
  transition:opacity var(--wa-pg-fade) ease-out, transform var(--wa-pg-rise-t) var(--wa-sp-card);
  color:#1A1413; background:#fff; overflow:hidden;
}
.wa-pg.on{ opacity:1; transform:none; }
/* A PRESENTED SHEET CARRIES A PAINTED PAGE. While the sheet itself is travelling — up or down —
   its page has no transition at all: it is simply there, whole, from the first frame of the
   slide to the last, the way a card that slides into view is whole. The .26s cross-fade below
   belongs to a page CHANGE inside a sheet that is already parked. */
.wa-sheet.sliding .wa-pg{ transition:none; }
.wa-pg-brand{ display:flex; align-items:center; gap:8px; font-size:15px; font-weight:600; letter-spacing:-.2px; }
.wa-pg-brand img{ width:22px; height:22px; }
.wa-pg-brand span{ display:inline-block; }
.wa-pg h1{ font-size:25px; font-weight:600; letter-spacing:-.6px; margin:20px 0 4px; }
.wa-pg .sub{ font-size:15px; color:#6F665C; margin:0; }
.wa-pg .amount{ font-size:40px; font-weight:600; letter-spacing:-1.2px; margin:14px 0 0; }
.wa-pg .lines{ margin:18px 0 0; padding:14px 0 0; border-top:.5px solid #E7E0D7; }
.wa-pg .lines div{ display:flex; justify-content:space-between; gap:12px; font-size:14.5px; color:#3A332E; padding:5px 0; }
.wa-pg .lines div span:last-child{ color:#8A8078; }
.wa-pg .grow{ flex:1 1 auto; }
.wa-pg .btn{
  display:flex; align-items:center; justify-content:center; height:52px; border-radius:26px;
  background:#1A1413; color:#fff; font-size:16.5px; font-weight:500; letter-spacing:-.38px;
  transition:transform .15s ease, filter .15s ease, background .15s ease;
}
.wa-pg .btn.pressed{ transform:scale(.975); filter:brightness(1.35); }
.wa-pg .note{ font-size:12.5px; color:#8A8078; text-align:center; margin-top:12px; line-height:1.4; }
.wa-pg .eyebrow{ font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:#B5ABA0; margin-bottom:8px; }

/* ─── THE PAGE THE CUSTOMER OPENS FROM THE YAPE LINK (SPEC 17e) ──────────────────────────────
   `pay/link.tsx` on a phone: the shop, the order as OUR delivery note, the amount, and the two
   acts. `Open Yape` is asleep until the amount is in hand, because no published Yape address
   carries one and a customer typing it is where a wrong figure starts (the prototype's own
   research note). The two marks stand where the customer pays, each one its own app's tile. */
.wa-pg .btn svg{ flex:0 0 auto; width:19px; height:19px; margin-right:9px; }
.wa-pg .btn.sec{ background:#F3F1ED; color:#1A1413; margin-bottom:10px; }
.wa-pg .btn.off{ background:#EDEAE4; color:#B0A79C; }
/* the same document, standing in a page's own column rather than filling a screen */
.rp-doc.flat{ flex:0 0 auto; padding:0; overflow:visible; margin-top:18px; }
.pl-marks{ display:flex; align-items:center; gap:9px; margin-top:22px; }
.pl-mk{ flex:0 0 auto; width:38px; height:38px; border-radius:9px; overflow:hidden; display:block; }
/* each file is that app's square tile on a wide canvas: cover takes the tile and leaves the rest */
.pl-mk img{ width:38px; height:38px; object-fit:cover; display:block; }
.pl-with{ font-size:14px; color:#6F665C; letter-spacing:-.2px; }
.pl-amt{ margin-top:18px; }
.pl-amt .rp-fig .cur{ font-size:20px; line-height:26px; }
.pl-amt .rp-fig .val{ font-size:46px; line-height:54px; letter-spacing:-1.4px; }
.pl-num{ font-size:22px; font-weight:600; letter-spacing:-.5px; margin:8px 0 0;
  font-variant-numeric:tabular-nums; }
.pl-say{ margin-top:6px !important; }
/* Customer payment uses the same product type, button geometry and neutral surfaces. */
.wa-pg.payment{ font-family:"Inter",var(--wa-font); }
.wa-pg.payment h1{ font-size:20px; line-height:28px; font-weight:700; letter-spacing:-.2px; }
.wa-pg.payment .sub{ font-size:14px; line-height:20px; color:var(--rp-contentSecondary); }
.wa-pg.payment .btn{ border-radius:8px; font-size:16px; line-height:20px; letter-spacing:-.1px; }
.wa-pg.payment .btn.sec{ background:var(--rp-backgroundSecondary); }
.wa-pg.payment .btn.off{ background:var(--rp-backgroundSecondary); color:var(--rp-contentTertiary); }
.wa-pg.payment .note{ color:var(--rp-contentSecondary); font-size:14px; line-height:20px; }
.wa-pg.payment .pl-with{ color:var(--rp-contentSecondary); }
.wa-pg.payment .pl-amt .rp-fig .val{ font-size:44px; line-height:52px; letter-spacing:-1px; }
.wa-pg.payment .pl-num{ font-size:20px; line-height:28px; font-weight:500; }


.wa-banks{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin-top:18px; }
.wa-bank{
  height:64px; border-radius:12px; background:#fff; box-shadow:inset 0 0 0 1px #E7E0D7;
  display:flex; align-items:center; justify-content:center; padding:10px 9px; position:relative;
  overflow:hidden; transition:transform .15s ease, box-shadow .2s ease, background .15s ease;
}
.wa-bank img{ max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain; }
.wa-bank .fb{ display:none; font-size:12px; font-weight:600; color:#3A332E; text-align:center; line-height:1.15; letter-spacing:-.2px; }
.wa-bank.is-missing img{ display:none; }
.wa-bank.is-missing .fb{ display:block; }
.wa-bank.sel{ box-shadow:inset 0 0 0 2px #1A1413; }
.wa-bank.dark{ background:#1A1413; box-shadow:inset 0 0 0 1px #1A1413; }
.wa-bank.other .fb{ display:block; color:#6F665C; font-weight:500; font-size:12.5px; line-height:1.25; max-width:70px; }
.wa-bank.dark .fb{ color:#fff; }
.wa-bank.pressed{ transform:scale(.96); }

/* the bank picker, as a list: the mark, the name, and where it takes you */
.wa-blist{ margin-top:16px; border-top:.5px solid #EFE9E1; }
.wa-brow{
  display:flex; align-items:center; gap:14px; height:64px;
  border-bottom:.5px solid #EFE9E1; position:relative;
  transition:background .15s ease;
}
.wa-brow.pressed{ background:#F7F4EF; }
.wa-brow .wa-bank{
  flex:0 0 auto; width:86px; height:48px; border-radius:10px; padding:5px 6px;
  box-shadow:inset 0 0 0 1px #E7E0D7;
}
.wa-brow .wa-bank .fb{ font-size:10.5px; }
.wa-brow .nm{ flex:1 1 auto; min-width:0; font-size:16px; letter-spacing:-.32px; color:#1A1413;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.wa-brow .ch{ flex:0 0 auto; width:9px; height:15px; color:#C9BFB4; }
.wa-brow .ok{ flex:0 0 auto; width:21px; height:21px; display:none; }
.wa-brow.sel .ok{ display:block; }
.wa-brow.sel .ch{ display:none; }
.wa-brow.sel .wa-bank{ box-shadow:inset 0 0 0 2px #1A1413; }

.wa-pg .center{ flex:1 1 auto; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; gap:16px; }
.wa-pg .spin{ width:44px; height:44px; }
.wa-pg.on .wa-spin{ animation:wa-rot .9s linear infinite; }
.wa-spin{ transform-origin:50% 50%; }
@keyframes wa-rot{ to{ transform:rotate(360deg) } }
.wa-pg .check{ width:66px; height:66px; }
.wa-pg .ok-t{ font-size:22px; font-weight:600; letter-spacing:-.5px; }
.wa-pg .ok-s{ font-size:15px; color:#6F665C; max-width:260px; line-height:1.42; }

.wa-pay-opt{
  display:flex; align-items:center; gap:14px; height:82px; border-radius:16px;
  box-shadow:inset 0 0 0 1px #E7E0D7; padding:0 18px; background:#fff; margin-top:12px;
  transition:transform .15s ease, background .15s ease;
}
.wa-pay-opt .ic{ flex:0 0 auto; width:46px; height:46px; border-radius:12px; display:flex; align-items:center;
  justify-content:center; overflow:hidden; background:#F4F0EA; }
.wa-pay-opt .ic img{ width:100%; height:100%; object-fit:contain; padding:5px; }
/* the wallet's own mark is a square inside a wide file: fill the tile with the square */
.wa-pay-opt .ic.wa-mark{ background:#fff; }
.wa-pay-opt .ic.wa-mark img{ object-fit:cover; padding:0; border-radius:12px; }
.wa-mark .fb{ display:none; font-size:11.5px; font-weight:700; color:#3A332E; letter-spacing:-.2px; }
.wa-mark.is-missing img{ display:none; }
.wa-mark.is-missing .fb{ display:block; }
.wa-pay-opt .tx{ flex:1 1 auto; }
.wa-pay-opt .t{ display:block; font-size:17.5px; font-weight:600; letter-spacing:-.35px; }
.wa-pay-opt .s{ display:block; font-size:13.5px; color:#6F665C; margin-top:2px; }
.wa-pay-opt .ch{ flex:0 0 auto; width:9px; height:15px; color:#C3B9AE; }
.wa-pay-opt.pressed{ background:#F7F4EF; transform:scale(.99); }
.wa-pay-opt{ transition:transform .15s ease, background .15s ease; }

/* --------------------------------------------------- notification banner */

/* It arrives opaque and leaves opaque: the 400 ms spring carries it in from beyond the top edge
   and takes it back the same way. A banner you can read the clock and the chat's name through is
   two texts fighting for the same 64 px. The travel is written off its own height and its own
   top, so the one that lands on the lock screen clears the edge as completely as the one in the
   chat does. */
.wa-banner{
  position:absolute; left:8px; right:8px; --top:56px; top:var(--top); z-index:60;
  min-height:64px; border-radius:26px; padding:13px 15px 13px 13px;
  display:flex; gap:12px; align-items:flex-start;
  background:rgba(252,252,254,.66);
  -webkit-backdrop-filter:blur(30px) saturate(190%);
  backdrop-filter:blur(30px) saturate(190%);
  box-shadow:0 6px 22px rgba(0,0,0,.18), inset 0 0 0 .5px rgba(255,255,255,.5);
  transform:translateY(calc(-100% - var(--top) - 10px)) scale(.96);
  transition:transform var(--wa-sp-banner-t) var(--wa-sp-banner);
}
.wa-banner.on{ transform:none; }
.wa-banner.lock{ --top:258px; }
.wa-banner .ic{ position:relative; flex:0 0 auto; width:38px; height:38px; border-radius:8.5px;
  display:flex; align-items:center; justify-content:center; }
.wa-banner .ic img,.wa-banner .ic svg{ width:100%; height:100%; border-radius:inherit; object-fit:cover; display:block; }
.wa-banner .ic.rocoto{ width:60px; height:60px; border-radius:13px; align-self:center; overflow:hidden; }
.wa-banner .ic.rocoto img{ width:46px; height:46px; border-radius:0; object-fit:contain; }
.wa-banner.round .ic{ border-radius:50%; }
.wa-banner .bdg{
  position:absolute; right:-3px; bottom:-3px; width:17px; height:17px; border-radius:50%;
  box-shadow:0 0 0 1.6px rgba(252,252,254,.92); overflow:hidden; display:block;
}
.wa-banner .bdg svg{ width:100%; height:100%; display:block; border-radius:50%; }
.wa-banner .bd{ flex:1 1 auto; min-width:0; }
.wa-banner .tp{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.wa-banner .t{ font-size:15px; font-weight:600; letter-spacing:-.24px; color:#111; }
.wa-banner .w{ font-size:13px; color:rgba(60,60,67,.72); flex:0 0 auto; }
.wa-banner .b{ font-size:15px; line-height:18px; color:#111; margin-top:2px; letter-spacing:-.24px; }

/* ------------------------------------------------------- the screen itself

   A phone that goes to sleep darkens, rests, and lights again on its lock screen. The veil IS the
   screen: its opacity is written by the player on every frame, so it scrubs with the clock, and it
   covers the whole handset, status bar and island included. */

.wa-veil{
  position:absolute; inset:0; z-index:90; background:#000; opacity:0; pointer-events:none;
}

/* --------------------------------------------------------- the lock screen */

/* THE LOCK SCREEN LIFTS; NOTHING DISSOLVES. The phone carries the app over the lock opaquely —
   it is already standing there, behind — and the lock screen travels off the top edge, the way it
   does when a notification is tapped. Blending two whole screens is a slideshow, and it put the
   lock's clock, its date and its torch and camera buttons straight through the thread and the
   composer for about 200 ms. */
.wa-lock{
  /* A LOCKED PHONE COVERS EVERYTHING. The lock stands over the browser sheet, the camera and
     Rocoto's own app — every surface but the banner that lands on it, the finger that presses
     it and the screen's own veil — so a phone that is asleep with an app open shows the lock,
     and the app is uncovered when the lock travels off the top edge. */
  position:absolute; inset:0; z-index:48; overflow:hidden; will-change:transform;
  contain:paint;
  color:#fff; display:flex; flex-direction:column;
  transform-origin:50% 42%;
  transition:transform .52s var(--wa-ease-ios);
}
.wa-lock.gone{ transform:translateY(-100%); pointer-events:none; }
.wa-lock .lk-wall{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.wa-lock .lk-scrim{
  position:absolute; inset:0;
  background:linear-gradient(180deg,rgba(10,14,20,.42) 0%,rgba(10,14,20,.12) 38%,rgba(10,14,20,.34) 100%);
}
.wa-lock-status{ position:relative; height:var(--wa-status-h); flex:0 0 auto; color:#fff; }
.wa-lock-status .wa-clock{ display:none; }
.wa-lock .lk-top{
  position:relative; flex:0 0 auto; display:flex; flex-direction:column; align-items:center;
  padding-top:6px;
  text-shadow:0 1px 14px rgba(0,0,0,.32);
}
.wa-lock .lk-pad{ width:13px; height:17px; opacity:.92; display:block; margin-bottom:9px; }
.wa-lock .lk-pad svg{ width:100%; height:100%; display:block; }
.wa-lock .lk-date{ font-size:20px; font-weight:600; letter-spacing:-.45px; }
.wa-lock .lk-time{
  font-size:88px; font-weight:400; letter-spacing:-2.6px; line-height:1.03; margin-top:-2px;
  font-variant-numeric:tabular-nums;
}
.wa-lock .lk-foot{
  position:absolute; left:0; right:0; bottom:44px;
  display:flex; align-items:center; justify-content:space-between; padding:0 42px;
}
.wa-lock .lk-b{
  width:50px; height:50px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:rgba(22,26,32,.38); box-shadow:inset 0 0 0 .5px rgba(255,255,255,.18);
}
.wa-lock .lk-b svg{ width:25px; height:25px; display:block; }
.wa-lock .wa-home{ position:absolute; left:0; right:0; bottom:0; }
.wa-lock .wa-home i{ background:#fff; opacity:.85; }

/* the chat stands behind the lock screen, whole and opaque, and is simply uncovered by it */
.wa-app{ transform-origin:50% 45%; }

/* -------------------------------------------------------------- touch dot */

.wa-dot{
  position:absolute; z-index:70; width:42px; height:42px; margin:-21px 0 0 -21px;
  border-radius:50%; background:rgba(11,20,26,.24);
  box-shadow:0 0 0 .5px rgba(11,20,26,.08);
  opacity:0; transform:scale(.5); pointer-events:none;
  transition:opacity .14s linear, transform .22s var(--wa-ease-out);
}
.wa-dot.on{ transform:scale(1); }

/* -------------------------------------------------------------- chat list */

.wa-list{
  position:absolute; inset:0; z-index:20; background:#fff; display:flex; flex-direction:column;
  transition:transform var(--wa-sp-sheet-t) var(--wa-sp-sheet), opacity .34s ease-out;
}
.wa-list.gone{ transform:translateX(-28%); opacity:0; }
.wa-list .lh{ padding:2px 16px 4px; }
.wa-list .lh .t{ font-size:33px; font-weight:700; letter-spacing:-.86px; }
.wa-list .srch{ margin:9px 16px 6px; height:36px; border-radius:10px; background:#EFEEEC;
  display:flex; align-items:center; gap:7px; padding:0 10px; color:#8696A0; font-size:16px; }
.wa-list .srch svg{ width:15px; height:15px; }
.wa-lrow{ display:flex; gap:12px; padding:9px 16px; align-items:center; }
.wa-lrow .wa-av{ width:49px; height:49px; margin:0; }
.wa-lrow .c{ flex:1 1 auto; min-width:0; }
.wa-lrow .r1{ display:flex; justify-content:space-between; align-items:baseline; gap:8px; }
.wa-lrow .nm{ font-size:17px; font-weight:600; letter-spacing:-.43px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.wa-lrow .tm{ font-size:12.5px; color:var(--wa-meta); flex:0 0 auto; }
.wa-lrow .r2{ display:flex; justify-content:space-between; align-items:center; gap:8px; margin-top:2px; }
.wa-lrow .pv{ font-size:15px; color:var(--wa-meta); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; letter-spacing:-.24px; }
.wa-lrow .bd{ flex:0 0 auto; min-width:21px; height:21px; border-radius:11px; background:#25D366; color:#fff;
  font-size:12.5px; font-weight:600; display:flex; align-items:center; justify-content:center; padding:0 6px; }
.wa-list .sep{ height:.5px; background:var(--wa-hair); margin-left:77px; }
.wa-lrows{ flex:1 1 auto; min-height:0; overflow:hidden; }
.wa-tabs{
  flex:0 0 auto; display:flex; align-items:flex-start; justify-content:space-around;
  height:50px; padding-top:7px; background:var(--wa-bar);
  box-shadow:0 -.5px 0 var(--wa-line);
}
.wa-tab{ display:flex; flex-direction:column; align-items:center; gap:2px; color:#8E8E93; width:74px; }
.wa-tab.on{ color:var(--wa-tint); }
.wa-tab svg{ width:25px; height:25px; display:block; }
.wa-tab .lb{ font-size:10px; letter-spacing:-.1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:74px; }
.wa-list .wa-home i{ background:#0B141A; }

/* ------------------------------------------------------------ motion off */

.wa.is-noanim, .wa.is-noanim *, .wa.is-noanim *::before, .wa.is-noanim *::after{
  transition:none !important; animation:none !important;
}
@media (prefers-reduced-motion: reduce){
  .wa, .wa *, .wa *::before, .wa *::after{ transition:none !important; animation:none !important; }
}

/* the QR on the charge page, inside the in-chat browser */
/* ------------------------------------------------- Yape's «Mi QR», drawn here
   Yape's own screen, in our markup: the purple field, the hairline chevron and the title, the
   white sentence, the white card that straddles the field's foot with the code and the shop's
   name, and the teal button. Proportions measured off Yape's own screen and set on the browser's
   page area (390 x 733). Every figure is Yape's own, measured on that screen and moved up by the
   111 px of browser chrome our page sits under: the sentence at 122, the card at 190 straddling
   the field's foot half above and half below, the field ending at 47 %, the button 48 high and 36
   clear of the foot. A page opened in a browser has no status bar of its own, so the title simply
   starts at the top. */
.wa-pg.yape{ padding:0; background:#fff; }
.yq{ position:absolute; inset:0; color:#fff; }
.yq-field{ position:absolute; left:0; right:0; top:0; height:47%; background:#742284; }
.yq-bar{ position:relative; height:46px; display:flex; align-items:center; justify-content:center; }
.yq-back{ position:absolute; left:15px; top:50%; width:11px; height:19px; margin-top:-9.5px; color:#fff; }
.yq-back svg{ width:100%; height:100%; display:block; }
.yq-t{ font-size:19px; font-weight:600; letter-spacing:-.3px; }
/* the sentence stands in the field's own air, clear of the card that straddles its foot */
.yq-say{
  position:absolute; left:32px; right:32px; top:122px; margin:0;
  text-align:center; font-size:15.5px; line-height:21px; letter-spacing:-.24px; color:#fff;
}
.yq-card{
  position:absolute; left:17px; right:17px; top:190px;
  background:#fff; border-radius:12px; box-shadow:0 8px 22px rgba(24,6,30,.18);
  padding:18px 20px 20px; text-align:center;
}
.yq-mark{ display:block; width:42px; height:42px; margin:0 auto; border-radius:11px; overflow:hidden; }
/* the file is the app's square tile on a wide canvas: cover takes the tile and leaves the rest */
.yq-mark img{ width:42px; height:42px; object-fit:cover; }
.yq-code{ display:block; width:178px; height:178px; margin:8px auto 4px; }
.yq-code svg{ display:block; width:100%; height:100%; }
.yq-name{ display:block; font-size:17.5px; font-weight:700; letter-spacing:-.3px; color:#742284; }
.yq-btn{
  position:absolute; left:17px; right:17px; bottom:36px; height:48px; border-radius:8px;
  background:#01C8AF; color:#fff; display:flex; align-items:center; justify-content:center;
  font-size:14px; font-weight:700; letter-spacing:.04em;
}

/* ------------------------------------------------------------ paused
   The parent can stop a demo at any instant. The clock stops in wa.js; this stops everything the
   browser is running on its own — the typing dots, the recording pulse, the spinner — so a paused
   phone is a still photograph. `play` starts them again from where they stood. */
.wa.is-paused,
.wa.is-paused *,
.wa.is-paused *::before,
.wa.is-paused *::after{ animation-play-state:paused !important; }

/* ═══ THE CAMERA, THE SHARE SHEET AND THE ROCOTO APP ════════════════════════════════════════
   Three surfaces that take the WHOLE screen the way an app does on iOS, and they are drawn here
   for one reason: on delivery the paper invoice is photographed with the phone's own camera and
   shared to Rocoto, which is an APP — so the story leaves WhatsApp and comes back to it.
   Every one of them is a state of the clock: `seek` toggles a class, CSS carries the motion, and
   a scrub backwards unwinds it in the same order. */

/* iOS paints ONE status bar and it takes the colour of what holds the screen: white on black
   while the camera is up, and the phone's own light bar again the moment an app takes over. */
.wa.cam-up .wa-status{ background:#000; color:#fff; }
/* AND THE APP YOU LEFT STANDS BACK. iOS parks it a little smaller and dimmer behind the one that
   opened; it is what makes the arrival read as an app opening rather than a page changing. The
   transition is carried by `.wa-switch`, which only a demo that HAS another app wears, so nothing
   else in the kit gains a transition it never had. */
.wa-switch .wa-app{ transition:transform .42s var(--wa-ease-ios), opacity .18s linear; }
.wa.behind .wa-app{ transform:scale(.935); opacity:.42; }

/* ---------------------------------------------------------------- the camera */

/* IT ARRIVES SLOWLY AND LEAVES FAST, and the two are written as two states rather than one
   duration: an app that fades out at the same rate it faded in leaves two whole screens at half
   strength for a quarter of a second, which is a slideshow and not an app switch. Leaving, it
   holds its ink for a beat, shrinks, and is gone before the screen behind it is back. */
.wa-camera{
  position:absolute; top:var(--wa-status-h); left:0; right:0; bottom:0; z-index:42;
  background:#000; color:#fff; display:flex; flex-direction:column; overflow:hidden;
  opacity:0; transform:scale(.94); pointer-events:none;
  transition:opacity .15s linear .1s, transform .34s var(--wa-ease-ios);
}
.wa-camera.up{ opacity:1; transform:none;
  transition:opacity .16s linear, transform .42s var(--wa-ease-ios); }
.ca-top{ flex:0 0 40px; display:flex; align-items:center; justify-content:space-between; padding:0 26px; }
.ca-top svg{ display:block; }
.ca-top .bolt{ width:15px; height:21px; color:#FFD60A; }
.ca-top .caret{ width:17px; height:9px; color:rgba(255,255,255,.9); }
.ca-top .live{ width:22px; height:22px; color:#FFD60A; }
/* the live frame: 390 x 520, which is the 3:4 a phone photographs in */
.ca-view{ position:relative; flex:0 0 520px; height:520px; overflow:hidden; background:#0C0C0C; }
.ca-view img{ width:100%; height:100%; object-fit:cover; }
/* the lens is still finding its focus the moment the app opens, and settles on the paper */
.ca-view img{ transform:scale(1.045); filter:blur(3.4px); transition:transform 1.5s var(--wa-ease-out), filter .8s ease-out; }
.wa-camera.up .ca-view img{ transform:none; filter:none; }
/* the focus square iOS puts on what it has locked on to, ticks and all, over the paper */
.ca-box{
  position:absolute; left:160px; top:236px; width:76px; height:76px;
  box-shadow:0 0 0 1.2px #FFD60A; opacity:0; transition:opacity .34s ease-out .5s;
}
.ca-box::before,.ca-box::after{ content:""; position:absolute; background:#FFD60A; }
.ca-box::before{ left:-6px; right:-6px; top:50%; height:1.2px; margin-top:-.6px;
  background:linear-gradient(90deg,#FFD60A 0 6px,transparent 6px calc(100% - 6px),#FFD60A calc(100% - 6px)); }
.ca-box::after{ top:-6px; bottom:-6px; left:50%; width:1.2px; margin-left:-.6px;
  background:linear-gradient(180deg,#FFD60A 0 6px,transparent 6px calc(100% - 6px),#FFD60A calc(100% - 6px)); }
.wa-camera.up .ca-box{ opacity:.95; }
.wa-camera.shot .ca-box{ opacity:0; transition:opacity .12s linear; }
.ca-zoom{ flex:0 0 56px; display:flex; align-items:center; justify-content:center; }
.ca-zoom .z{
  display:flex; align-items:center; justify-content:center; width:31px; height:31px; margin:0 5px;
  border-radius:50%; background:rgba(60,60,67,.62); font-size:11.5px; color:#fff; letter-spacing:-.1px;
}
.ca-zoom .z.on{ width:38px; height:38px; font-size:13px; font-weight:600; color:#FFD60A; background:rgba(40,40,45,.72); }
.ca-modes{ flex:0 0 30px; display:flex; align-items:center; justify-content:center; gap:26px; }
.ca-modes span{ font-size:11.5px; letter-spacing:1.1px; color:rgba(255,255,255,.62); }
.ca-modes span.on{ color:#FFD60A; }
.ca-bar{ flex:1 1 auto; display:flex; align-items:center; justify-content:space-between; padding:0 30px; }
.ca-well{
  width:56px; height:56px; border-radius:7px; overflow:hidden; background:#1C1C1E;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.18); position:relative;
}
.ca-well img{ width:100%; height:100%; object-fit:cover; opacity:0; transform:scale(1.25); }
.wa-camera.shot .ca-well img{ opacity:1; transform:none; transition:opacity .2s linear, transform .34s var(--wa-ease-out); }
.ca-shut{
  width:74px; height:74px; border-radius:50%; box-shadow:inset 0 0 0 3.4px #fff;
  display:flex; align-items:center; justify-content:center;
}
.ca-shut i{ display:block; width:62px; height:62px; border-radius:50%; background:#fff; transition:transform .12s ease-out; }
.ca-shut.pressed i{ transform:scale(.86); }
.ca-flip{
  width:44px; height:44px; border-radius:50%; background:rgba(60,60,67,.62);
  display:flex; align-items:center; justify-content:center; color:#fff;
}
.ca-flip svg{ width:23px; height:23px; display:block; }
.ca-flash{ position:absolute; inset:0; background:#fff; opacity:0; pointer-events:none; z-index:3; }

/* THE PICTURE, LOOKED AT. From the camera the well opens the shot full screen: the day and the
   hour it was taken at the top, and the toolbar every photo carries — share at the left edge, the
   bin at the right. */
.ca-review{
  position:absolute; inset:0; z-index:2; background:#000; display:flex; flex-direction:column;
  opacity:0; pointer-events:none; transition:opacity .22s linear;
}
.wa-camera.review .ca-review{ opacity:1; }
.ca-rtop{ flex:0 0 46px; display:flex; align-items:center; justify-content:center;
  font-size:12.5px; color:rgba(255,255,255,.86); letter-spacing:-.1px; }
.ca-rimg{ flex:1 1 auto; min-height:0; display:flex; align-items:center; }
.ca-rimg img{ width:100%; height:auto; max-height:100%; object-fit:contain; }
.ca-rbar{ flex:0 0 78px; display:flex; align-items:center; justify-content:space-between; padding:0 30px; color:#fff; }
.ca-rbar .g{ width:26px; height:28px; display:flex; align-items:center; justify-content:center; }
.ca-rbar svg{ width:100%; height:100%; display:block; }

/* ------------------------------------------------------------ the share sheet */

.wa-share{ position:absolute; inset:0; z-index:46; pointer-events:none; }
.sh-scrim{ position:absolute; inset:0; background:rgba(0,0,0,.36); opacity:0; transition:opacity .3s linear; }
.wa-share.up .sh-scrim{ opacity:1; }
.sh-card{
  position:absolute; left:0; right:0; bottom:0; height:470px;
  background:#F2F1F6; color:#000; border-radius:13px 13px 0 0;
  box-shadow:0 -10px 40px rgba(0,0,0,.28);
  /* it LEAVES on a short curve and ARRIVES on the sheet's own spring: the state it moves into
     carries the timing, so one element reads as two different gestures. */
  transform:translateY(102%); transition:transform .28s cubic-bezier(.4,0,1,1);
}
.wa-share.up .sh-card{ transform:none; transition:transform var(--wa-sp-sheet-t) var(--wa-sp-sheet); }
.sh-grab{ width:36px; height:5px; border-radius:3px; background:rgba(60,60,67,.3); margin:6px auto 0; }
.sh-item{ display:flex; align-items:center; gap:13px; padding:14px 16px 16px; }
.sh-item .th{ flex:0 0 auto; width:58px; height:74px; border-radius:6px; overflow:hidden; background:#DDD8D0; }
.sh-item .th img{ width:100%; height:100%; object-fit:cover; }
.sh-item .tx{ flex:1 1 auto; min-width:0; }
.sh-item .t{ display:block; font-size:16px; font-weight:600; letter-spacing:-.32px; }
.sh-item .s{ display:block; font-size:13.5px; color:rgba(60,60,67,.62); margin-top:2px; }
.sh-item .x{
  flex:0 0 auto; width:30px; height:30px; border-radius:50%; background:rgba(118,118,128,.14);
  display:flex; align-items:center; justify-content:center; color:rgba(60,60,67,.6);
}
.sh-item .x svg{ width:12px; height:12px; display:block; }
.sh-apps{ display:flex; gap:15px; padding:2px 16px 18px; }
.sh-app{ width:60px; display:flex; flex-direction:column; align-items:center; gap:7px; }
.sh-app .ic{
  width:60px; height:60px; border-radius:13.5px; display:flex; align-items:center; justify-content:center;
  overflow:hidden; box-shadow:0 1px 3px rgba(0,0,0,.16); transition:transform .14s ease;
}
.sh-app .ic svg{ width:34px; height:34px; display:block; }
.sh-app .lb{ font-size:11px; line-height:13px; color:#000; text-align:center; letter-spacing:-.1px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:66px; }
.sh-app.pressed .ic{ transform:scale(.92); }
/* Rocoto's own icon: the face mark on the company's paper, the way the app wears it */
.sh-app .ic.rocoto{ background:#FAF7F3; box-shadow:0 1px 3px rgba(0,0,0,.16), inset 0 0 0 .5px rgba(26,20,19,.12); }
.sh-app .ic.rocoto img{ width:40px; height:40px; display:block; }
.sh-acts{ background:#fff; border-radius:13px; margin:0 10px; overflow:hidden; }
.sh-act{ display:flex; align-items:center; justify-content:space-between; gap:14px;
  height:52px; padding:0 16px; font-size:16.5px; letter-spacing:-.38px; border-top:.5px solid rgba(60,60,67,.16); }
.sh-act:first-child{ border-top:0; }
.sh-act svg{ width:21px; height:21px; display:block; color:#000; }

/* --------------------------------------------------------------- the Rocoto app

   THE APP IS THE PRODUCT'S OWN SCREEN, LIFTED. Every value below is the prototype's
   (`app/src/prototypes/bodega-pay-later/`, live at demo.soyrocoto.com/bodega-pay-later/): Base
   Web's type ramp under the Rocoto theme — Inter, HeadingXSmall 20/28, LabelMedium 16/20,
   LabelSmall 14/16, LabelXSmall 12/16, HeadingSmall 24/32 for the figure — Base's own colours
   (contentSecondary #4B4B4B, contentTertiary #5E5E5E, borderOpaque and backgroundSecondary
   #F3F3F3), Base's 8 px button radius, the 52 px act the payment page sets, the document head
   `detail.tsx` draws on a phone (the name, then the day in the brand's own date face, then the
   provenance line), and the figure lockup from `rocoto/figure` — the unit on the number's own
   line, the fraction at 0.65 em with zero leading. */

.wa-rapp{
  position:absolute; top:var(--wa-status-h); left:0; right:0; bottom:0; z-index:44;
  background:#fff; color:#1A1413; overflow:hidden;
  font-family:"Inter",var(--wa-font);
  opacity:0; transform:scale(.88); pointer-events:none;
  /* leaving: opaque for a beat, then gone fast — see the camera above */
  transition:opacity .15s linear .1s, transform .34s var(--wa-ease-ios);
}
.wa-rapp.up{ opacity:1; transform:none;
  /* opacity is NOT in this list: the app is opaque from its first frame, so nothing behind it
     (the camera, still settling its own leave) is ever seen through it — a cross-dissolve is
     the one thing an app switch never is. Only the arrival's SCALE animates. */
  transition:transform .42s var(--wa-ease-ios); }
.rp{
  position:absolute; inset:0; display:flex; flex-direction:column; background:#fff;
  opacity:0; transition:opacity .24s ease-out;
}
.rp.on{ opacity:1; }
.rp-bar{ flex:0 0 48px; display:flex; align-items:center; gap:14px; padding:0 16px; }
.rp-bar .bk{ width:22px; height:22px; display:block; color:#1A1413; }
.rp-bar .w{ font-size:16px; font-weight:500; line-height:20px; letter-spacing:-.1px; }
.rp-doc{ flex:1 1 auto; min-height:0; padding:6px 16px 0; overflow:hidden; }
.rp-who{ font-size:20px; font-weight:700; line-height:28px; letter-spacing:-.2px; }
/* §138.12 — a document's date has its own voice, and the brand names the face */
.rp-when{ font-family:Georgia,"Times New Roman",serif; font-size:16px; font-weight:400; line-height:20px; margin-top:6px; }
.rp-meta{ font-size:12px; font-weight:500; line-height:16px; color:#5E5E5E; margin-top:7px; }
.rp-lines{ margin-top:14px; }
/* THE ROW IS THE PRODUCT'S OWN (SPEC 17b, «the rows at the prototype's 66 px pitch with each
   product's face, name, quantity and unit on one line»). Measured off the real capture at
   `peru/cap/pedido-movil.webp`: a 40 px painted face, the name in LabelMedium, the quantity in
   ink with its unit beside it in contentSecondary, the row's own menu at the right edge, and a
   66 px pitch that grows when a long name takes a second line. */
.rp-line{
  display:grid; grid-template-columns:40px minmax(0,1fr) auto auto 20px; align-items:center;
  column-gap:14px; min-height:66px; padding:8px 0; border-top:1px solid #F3F3F3;
}
.rp-line .f{ width:40px; height:40px; border-radius:6px; overflow:hidden; background:#F3F3F3; display:block; }
.rp-line .f img{ width:100%; height:100%; object-fit:contain; display:block; }
/* a product nobody has painted yet stands as the shelf it sits on does on the real screen: the
   seat, and nothing in it */
.rp-line .f.blank{ background:#F3F3F3; }
/* a line's name WRAPS, the way the document's own rows do (`overflowWrap: 'anywhere'`), rather
   than truncating: the shop has to be able to read what it is paying for */
.rp-line .n{ font-size:16px; font-weight:500; line-height:20px; min-width:0; overflow-wrap:anywhere; }
.rp-line .q{ font-size:16px; font-weight:500; line-height:20px; white-space:nowrap;
  font-variant-numeric:tabular-nums; }
.rp-line .u{ font-size:14px; line-height:20px; color:#4B4B4B; white-space:nowrap; }
.rp-line .m{ display:flex; align-items:center; justify-content:flex-end; gap:3px; }
.rp-line .m i{ width:3.5px; height:3.5px; border-radius:50%; background:#8E8E8E; display:block; }
.rp-line .a{ font-size:16px; font-weight:500; line-height:20px; min-width:76px; text-align:right;
  white-space:nowrap; font-variant-numeric:tabular-nums; }
.rp-total{ display:flex; align-items:baseline; justify-content:space-between; gap:16px;
  border-top:1px solid #F3F3F3; padding-top:14px; }
.rp-total .lb{ font-size:14px; font-weight:500; line-height:16px; color:#4B4B4B; }
.rp-fig{ display:inline-flex; align-items:baseline; gap:5px; white-space:nowrap;
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1; }
.rp-fig .cur{ font-size:14px; font-weight:500; line-height:16px; color:#4B4B4B; }
.rp-fig .val{ font-size:24px; font-weight:700; line-height:32px; letter-spacing:-.2px; }
.rp-fig .fr{ font-size:.65em; line-height:0; }
/* WHERE THE PURCHASE CAME FROM. The prototype puts the SOURCE under the document — the
   conversation the order was read out of (`source-thread.tsx`, `EmbeddedConversation`) — elevated
   off the page, on paper, inside the one faint red hairline this app draws: `RING(accent,
   borderOpaque, 42)` from `cedar/shell/embeds.tsx`, which is the accent at low strength and means
   «Rocoto's own act», never a status. Here the source is the photograph it read. */
.rp-src{
  margin-top:14px; border-radius:8px; overflow:hidden; background:#fff;
  box-shadow:0 0 0 1px color-mix(in srgb,#C01B2C 42%,#F3F3F3), 0 2px 10px rgba(26,20,19,.08);
}
@supports not (color: color-mix(in srgb, #000 42%, #fff)){
  .rp-src{ box-shadow:0 0 0 1px #DD989F, 0 2px 10px rgba(26,20,19,.08); }
}
.rp-src-h{ display:flex; align-items:center; gap:8px; height:34px; padding:0 12px;
  border-bottom:1px solid #F3F3F3; }
.rp-src-h img{ width:16px; height:16px; }
.rp-src-h span{ font-size:12px; font-weight:500; line-height:16px; }
.rp-src-b{ height:150px; overflow:hidden; background:#EFEAE4; }
.rp-src-b img{ width:100%; height:100%; object-fit:cover; object-position:center 36%; display:block; }

/* the strip the real screen carries between the document and its dock (`pedido-movil.webp`):
   a full-bleed band of Base's `backgroundSecondary` with the count at the document's own left
   margin, so the foot of the list is stated rather than left as white space */
.rp-count{ flex:0 0 auto; background:#F3F3F3; padding:14px 16px;
  font-size:14px; line-height:20px; color:#4B4B4B; }

/* bottom padding clears the home indicator (34px) plus the card's own 16px of air, so
   the act the demo is about — `Pay later` — never sits under the bar iOS draws there */
.rp-acts{ flex:0 0 auto; display:grid; gap:10px; padding:14px 16px 50px; }
/* the app's own home indicator, over whichever `.rp` page is on — not inside any one of
   them, so it never fades with a page cross-fade */
.wa-rapp > .wa-home{ position:absolute; left:0; right:0; bottom:0; }
.rp-btn{
  height:52px; border-radius:8px; display:flex; align-items:center; justify-content:center;
  font-size:16px; font-weight:500; line-height:20px; letter-spacing:-.1px;
  transition:transform .13s ease-out, filter .13s ease-out;
}
.rp-btn.pri{ background:#1A1413; color:#fff; }
.rp-btn.sec{ background:#F3F3F3; color:#1A1413; }
.rp-btn.pressed{ transform:scale(.985); filter:brightness(1.3); }
/* the settled seat, where the two acts stood: the payment page's own block — Base's
   backgroundSecondary, its 8 px corner, its 16 px of air — and an INK check, because colour is
   not a status system in this product */
.rp-done{ display:flex; align-items:flex-start; gap:12px; background:#F3F3F3; border-radius:8px; padding:16px; }
.rp-done .ok{ flex:0 0 auto; width:36px; height:36px; display:block; margin-top:1px; }
.rp-done .t{ display:block; font-size:16px; font-weight:500; line-height:20px; }
.rp-done .s{ display:block; font-size:14px; line-height:20px; color:#4B4B4B; margin-top:5px; }
/* Payment review uses WorkflowDialog/OverlayCard phone tokens at product 1e6f5f3e.
   One stationary invoice remains below the sheet throughout review and confirmation. */
.wa{
  --rp-backgroundPrimary:#fff;
  --rp-contentPrimary:#1A1413;
  --rp-contentSecondary:#4B4B4B;
  --rp-contentTertiary:#5E5E5E;
  --rp-backgroundSecondary:#F3F3F3;
}
.rp-drawer{
  background:transparent;
  transition:opacity .18s linear;
}
.rp-payment-scrim{ position:absolute; inset:0; background:rgba(0,0,0,.5); }
.rp-payment-sheet{
  position:absolute; inset:auto 0 0; height:600px; max-height:100%;
  display:flex; flex-direction:column; overflow:hidden;
  background:var(--rp-backgroundPrimary); color:var(--rp-contentPrimary);
  border-radius:16px 16px 0 0;
}
.rp-drawer.review .rp-payment-sheet{
  transform:translateY(100%); transition:transform .4s cubic-bezier(.2,.8,.4,1);
}
.rp-drawer.review.arrived .rp-payment-sheet{ transform:translateY(0); }
.rp-payment-head{
  flex:0 0 64px; display:flex; align-items:center; justify-content:space-between;
  padding:0 8px 0 16px; font-size:20px; line-height:28px; font-weight:700;
}
.rp-payment-close{ width:48px; height:48px; display:grid; place-items:center; }
.rp-payment-close svg{ width:20px; height:20px; }
.rp-payment-body{ flex:1; min-height:0; padding:0 16px; }
.rp-payment-party{ margin:0; font-size:16px; line-height:24px; }
.rp-payment-ref{ margin:4px 0 0; font-size:12px; line-height:20px; color:var(--rp-contentTertiary); }
.rp-payment-amount{ margin-top:16px; }
.rp-payment-amount .rp-fig{ gap:12px; }
.rp-payment-amount .rp-fig .cur{ font-size:18px; line-height:24px; color:var(--rp-contentSecondary); }
.rp-payment-amount .rp-fig .val{ font-size:44px; line-height:52px; letter-spacing:-1px; }
.rp-payment-offer{ margin:8px 0 16px; font-size:14px; line-height:20px; color:var(--rp-contentSecondary); }
.rp-payment-row{
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  padding:10px 0; font-size:14px; line-height:20px; border-top:1px solid var(--rp-backgroundSecondary);
}
.rp-payment-row .rp-fig{ gap:4px; }
.rp-payment-row .rp-fig .cur{ font-size:12px; line-height:20px; }
.rp-payment-row .rp-fig .val{ font-size:16px; line-height:20px; font-weight:500; letter-spacing:0; }
.rp-payment-row.repayment{ font-weight:500; }
.rp-payment-rate{ font-weight:500; font-variant-numeric:tabular-nums; }
.rp-payment-schedule{
  margin-top:12px; padding:12px 16px; background:var(--rp-backgroundSecondary); border-radius:8px;
  display:flex; flex-direction:column; gap:4px; font-size:14px; line-height:20px;
}
.rp-payment-date{ font-family:Georgia,"Times New Roman",serif; font-size:18px; line-height:24px; }
.rp-payment-method{ color:var(--rp-contentSecondary); font-size:12px; line-height:20px; }
.rp-payment-foot{ flex:0 0 auto; padding:14px 16px 50px; }
/* A stable, prominent result. The demo clock draws the check, so seeking stays exact. */
.rp-payment-progress,.rp-payment-receipt{
  flex:1; min-height:0; display:flex; flex-direction:column; align-items:center;
  padding:28px 24px 8px; text-align:center;
}
.rp-success-mark,.rp-progress-mark{ display:block; flex:0 0 auto; width:88px; height:88px; color:var(--rp-contentPrimary); }
.rp-success-mark{
  opacity:var(--rp-mark-progress,1);
  transform:scale(calc(.92 + var(--rp-mark-progress,1) * .08));
}
.rp-success-stroke{ stroke-dasharray:1; stroke-dashoffset:calc(1 - var(--rp-check-progress,1)); }
.rp-progress-mark{ display:grid; place-items:center; }
.rp-progress-mark svg{ width:64px; height:64px; }
.rp-payment-status{
  flex:0 0 auto; margin:16px 0 0; font-size:24px; line-height:32px;
  font-weight:500; letter-spacing:-.5px;
}
.rp-payment-receipt .rp-payment-amount,.rp-payment-progress .rp-payment-amount{ margin-top:12px; }
.rp-payment-receipt .rp-fig,.rp-payment-progress .rp-fig{ justify-content:center; gap:8px; }
.rp-payment-receipt .rp-fig .val,.rp-payment-progress .rp-fig .val{ font-size:56px; line-height:64px; letter-spacing:-1.5px; }
.rp-payment-receipt .rp-fig .cur,.rp-payment-progress .rp-fig .cur{ font-size:22px; line-height:28px; }
.rp-payment-receipt .rp-payment-party,.rp-payment-progress .rp-payment-party{
  margin-top:8px; max-width:100%; font-size:18px; line-height:24px;
}
.rp-payment-receipt .rp-payment-schedule{ align-self:stretch; flex:0 0 auto; margin-top:24px; }
.rp-payment-receipt .rp-payment-date{ font-family:inherit; font-size:20px; line-height:26px; font-weight:500; }
.rp-payment-context{ margin:20px 0 0; font-size:14px; line-height:20px; color:var(--rp-contentSecondary); }
.rp-payment-source{
  align-self:stretch; margin-top:32px; padding:18px 0;
  display:flex; align-items:center; justify-content:space-between;
  border-block:1px solid var(--rp-backgroundSecondary);
  font-size:16px; line-height:24px; color:var(--rp-contentSecondary);
}
.rp-payment-source strong{ font-weight:500; color:var(--rp-contentPrimary); }
.rp-settled > .wa-pg-brand{ padding:16px 24px; margin:0; }
.rp-settled .rp-payment-receipt{ justify-content:center; padding-bottom:32px; }
.rp-settled .rp-success-mark{ width:104px; height:104px; }
.rp-settled .rp-payment-party{ margin-top:4px; }
@media (prefers-reduced-motion:reduce){
  .rp-drawer,.rp-drawer .rp-payment-sheet{ transition:none; }
  .rp-progress-mark svg{ animation:none; }
  .rp-success-mark{ opacity:1; transform:none; }
  .rp-success-stroke{ stroke-dashoffset:0; }
}

.rp-wait{ flex:1 1 auto; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:16px; }
.rp-wait .sp{ width:38px; height:38px; display:block; }
.rp-wait .t{ font-size:16px; font-weight:500; line-height:20px; }
.rp-wait .s{ font-size:14px; line-height:20px; color:#4B4B4B; }
/* ------------------------------------------ the app's own camera (SPEC 17b)

   ON DELIVERY THE PHONE NEVER LEAVES ROCOTO. Peter: «that should literally auto turn into a
   "pay later" screen that they just tap and boom. not go to "sharing" to add to rocoto. would
   be in the real rocoto app.» So the camera is a PAGE of the app, wearing the app's own head:
   a plain viewfinder on the paper, and one shutter under it. No iOS chrome, no share sheet. */
.rc-view{ flex:1 1 auto; min-height:0; position:relative; overflow:hidden; background:#0C0C0C; margin:2px 0 0; }
.rc-view img{ width:100%; height:100%; object-fit:cover; display:block; }
/* the frame the invoice is held in: four corners, the app's ink, drawn on the picture */
.rc-guide{ position:absolute; inset:26px 22px; pointer-events:none; }
.rc-guide i{ position:absolute; width:26px; height:26px; border:2px solid rgba(255,255,255,.92); }
.rc-guide i:nth-child(1){ left:0; top:0; border-right:0; border-bottom:0; border-radius:4px 0 0 0; }
.rc-guide i:nth-child(2){ right:0; top:0; border-left:0; border-bottom:0; border-radius:0 4px 0 0; }
.rc-guide i:nth-child(3){ right:0; bottom:0; border-left:0; border-top:0; border-radius:0 0 4px 0; }
.rc-guide i:nth-child(4){ left:0; bottom:0; border-right:0; border-top:0; border-radius:0 0 0 4px; }
.rc-foot{ flex:0 0 150px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;
  padding-bottom:22px; background:#fff; }
.rc-say{ font-size:14px; line-height:20px; color:#4B4B4B; }
.rc-shut{ width:68px; height:68px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  box-shadow:inset 0 0 0 2px #1A1413; transition:transform .13s ease-out; }
.rc-shut i{ display:block; width:56px; height:56px; border-radius:50%; background:#1A1413;
  transition:transform .13s ease-out; }
.rc-shut.pressed i{ transform:scale(.86); }
.rc-read{ display:flex; align-items:center; gap:10px; }
.rc-read .sp{ width:22px; height:22px; display:block; color:#1A1413; }
.rc-read .t{ font-size:16px; font-weight:500; line-height:20px; }

/* the spinner runs on the page that is showing, and on no other frame */
.rp.on .wa-spin{ animation:wa-rot .9s linear infinite; }
