/* masa — shared MOCK / DEVICE frame (s5 #10, Jul 17 2026, Juan: "make the audience + threads
   mockups match the hero phone-mock look"). The subpages don't load azul.css, so the hero frame's
   look is mirrored here and linked on audience/threads (EN+ES). Content-driven height, not the
   hero's fixed 393×852. Identity copied from azul.css .frame: 40px radius, page ground, uniform
   hairline, a CONTAINED glow, the dough-dot header, a home indicator.
   ⚑ RESKIN DEBT (runbook): this duplicates the hero frame values from azul.css. When the hero
   frame is lifted into shared CSS, collapse these two into one component. */

/* font-family:var(--f-ui) — the mock UI renders in the OS system font (SF Pro on iPhone), so the
   device reads as real iOS (s5d, Juan). The media glow moved OFF the frame (the frame isn't the
   media); the frame keeps only its elevation shadow. */
.device{position:relative;max-width:390px;margin:22px auto 0;border-radius:40px;
  background:var(--g);border:1px solid var(--line);
  box-shadow:var(--lift);font-family:var(--f-ui);
  overflow:hidden;isolation:isolate;display:flex;flex-direction:column;
  -webkit-text-size-adjust:100%;}
/* the mock's own card titles were Cal Sans; iOS UI is all SF, so force the system font here too */
.device .nl-from,.device .dt{font-family:var(--f-ui);}
/* ⚑ DISPERSED INTERFACE GLOW (s5o) — the flask dispersed light, same as the hero's .frame-amb (see the
   full note in azul.css). Soft multi-radial wash inside the device; iOS-cheap radial-gradients, no blur
   filter. The subpage devices are static (IO fade-in only), so it's motivated. Clipped by overflow:hidden. */
.dev-amb{position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(75% 42% at 72% 18%, rgba(255,140,66,.12), transparent 62%),
    radial-gradient(64% 44% at 24% 30%, rgba(146,220,229,.10), transparent 64%),
    radial-gradient(58% 38% at 56% 82%, rgba(231,150,180,.05), transparent 66%);}
.device>:not(.dev-amb){position:relative;z-index:1;}
/* header: the dough dot (the mascot, same as the hero's f-top) + label + a quiet status word */
.dev-top{display:flex;align-items:center;gap:8px;padding:22px 18px 6px;font-size:13px;color:var(--ink);}
.dev-top .dot{width:30px;height:30px;border-radius:var(--r-dough);background:var(--dough);flex:none;
  display:flex;align-items:center;justify-content:center;gap:4px;}
.dev-top .dot i{width:4px;height:4px;border-radius:50%;background:var(--dough-eye);display:block;}
.dev-top b{font-weight:500;font-size:14px;}
.dev-top .st{margin-left:auto;font-size:11.5px;color:var(--soft);}
/* body: the beats stack, bottom-weighted like a real thread */
.dev-body{padding:6px 16px 2px;display:flex;flex-direction:column;gap:9px;}
.dev-lbl{font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--soft);
  font-family:var(--f-body);font-weight:600;margin:2px 2px 0;}
/* the photo a client sends — mirrors the hero's .shot-img (rounded, hairline) */
/* motivated glow on the mock photo — follows the image (s5h, Juan) */
.dev-shot{width:184px;border-radius:16px;overflow:hidden;border:1px solid var(--line);align-self:flex-end;
  box-shadow:0 8px 26px -10px rgba(255,140,66,.26);}
/* height:auto lets aspect-ratio square the image — without it the width/height HTML attrs pin a
   definite height and aspect-ratio is ignored (the image renders tall). */
.dev-shot img{width:100%;height:auto;aspect-ratio:1;object-fit:cover;display:block;}
.dev-ind{width:120px;height:5px;border-radius:3px;background:color-mix(in srgb,var(--ink) 26%,transparent);
  margin:12px auto 12px;flex:none;}

/* ⚑ LIVE-TEXTING MOCK v2 (s5p) — RESTORED from the flask-exact study (Juan: "the old one-shot had
   better animation"). Replaces s5o's JS typing-dots with a PURE-CSS staggered cascade keyed on
   `.phone-wrap.in` (the s5n scroll-reveal already adds it): each beat rises + scales in like an iMessage
   bubble arriving, one at a time (~0.75s apart), on Apple-like eases — opacity on --ease-out, the
   transform on --ease-spring (a gentle overshoot pop). masa's avatar blinks + nods once as each of its
   replies lands (a reaction, not a loop; transform-only = compositor, can't jank). All beats hold their
   final layout the whole time (no display:none, no push-up), so it's rock-solid + no marquee = no
   scroll flicker. The base delay lets the frame reveal first, then the conversation types in.
   reduced-motion → all visible; fail-open via `.phone-wrap.in` (the reveal script guarantees it). */
@media (prefers-reduced-motion:no-preference){
  html.js .frame .thread>*{opacity:0;transform:translateY(12px) scale(.97);}
  html.js .phone-wrap.in .frame .thread>*{opacity:1;transform:none;
    transition:opacity .5s var(--ease-out),transform .55s var(--ease-spring);transition-delay:.3s;}
  html.js .phone-wrap.in .frame .thread>*:nth-child(2){transition-delay:1.05s;}
  html.js .phone-wrap.in .frame .thread>*:nth-child(3){transition-delay:1.8s;}
  html.js .phone-wrap.in .frame .thread>*:nth-child(4){transition-delay:2.55s;}
  html.js .phone-wrap.in .frame .thread>*:nth-child(5){transition-delay:3.3s;}
  html.js .phone-wrap.in .frame .thread>*:nth-child(6){transition-delay:4.05s;}
  /* masa reacts as its reply lands: eyes blink (scaleY squash), head gives a 1px nod. 340ms, once. */
  html.js .phone-wrap.in .frame .thread .ava{animation:avaNod .34s var(--ease-out) 1.3s 1 both;}
  html.js .phone-wrap.in .frame .thread .ava i{animation:avaBlink .34s var(--ease-out) 1.3s 1 both;}
  html.js .phone-wrap.in .frame .thread .fr:nth-of-type(4) .ava,
  html.js .phone-wrap.in .frame .thread .fr:nth-of-type(4) .ava i{animation-delay:2.85s;}
}
@keyframes avaBlink{0%,100%{transform:scaleY(1)}45%,55%{transform:scaleY(.12)}}
@keyframes avaNod{0%,100%{transform:translateY(0)}50%{transform:translateY(1px)}}

/* the beat arrows between sections shrink inside the device (they were page-sized) */
.device .io-arrow{font-size:16px;margin:6px 0;max-width:none;}
/* ⚑ the beat labels are MASA's narration of the demo, NOT iOS UI (Juan s5e — "make sure they don't
   register as part of the mock/our platform"). A short mango tick marks them as an annotation layer;
   the real app never renders "you send / you say ok" — the tick makes that unmistakable. */
.device .io-k{margin-top:2px;position:relative;padding-left:16px;}
.device .io-k::before{content:"";position:absolute;left:0;top:.55em;width:10px;height:2px;
  border-radius:1px;background:var(--chip);}
.device .drop,.device .nl{max-width:none;}
/* threads: the bubbles sit directly on the device ground (no panel wrapper), like the hero */
.device .thread{background:transparent;padding:0;}
/* the link-card thumbnail (threads) — bleeds to the card's top edges, matches the product's linkCard */
.dlink-img{display:block;border-radius:9px 9px 0 0;overflow:hidden;margin:-9px -11px 9px;
  box-shadow:0 8px 24px -12px rgba(255,140,66,.24);}
.dlink-img img{width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;display:block;}
/* the AI-labeling note in the caption (honesty rule) — quiet, never competes with the caption */
.ai-note{color:var(--soft);opacity:.7;font-size:.9em;}

/* ⚑ MOTION (s5, Juan: "add fluid motion like flask" — and he views on iPhone). The homepage's
   .reveal uses animation-timeline:view(), which SAFARI DOESN'T SUPPORT — so it never animates on
   Juan's phone. For motion he actually sees, the device fades+lifts in via IntersectionObserver
   (the small script in each subpage adds .in), which works on iOS. iOS-cheap (transform/opacity
   only). FAIL-OPEN: the hidden start state is gated on html.js, so no-JS keeps the device visible;
   reduced-motion shows it immediately (the script adds .in up front). */
@media (prefers-reduced-motion:no-preference){
  /* ⚑ s5m — device reveal now blur-into-focus, matching the homepage's Linear-style .reveal
     (one blur, iOS-cheap). */
  html.js .device{opacity:0;transform:translateY(22px) scale(.986);filter:blur(7px);
    transition:opacity .7s var(--ease-out),transform .7s var(--ease-out),filter .7s var(--ease-out);}
  html.js .device.in{opacity:1;transform:none;filter:none;}
}

/* ⚑ LIVE VOICE-NOTE WAVEFORM (s5m, flask-style) — the waveform bars breathe a subtle equalizer
   bounce so the voice notes read alive, not frozen. scaleY pulses each bar around its OWN set
   height (so the wave shape is preserved); staggered by nth-child for the travelling-wave look.
   Cheap (compositor-only transform), reduced-motion gated. Covers the hero mock's .fvn and the
   knot / audience .vn. Shared here in mock.css (loaded on every page that has a voice note). */
@media (prefers-reduced-motion:no-preference){
  .fvn .wave i,.vn .wave i{transform-origin:50% 50%;animation:vn-eq 1.3s ease-in-out infinite;}
  .fvn .wave i:nth-child(3n),.vn .wave i:nth-child(3n){animation-delay:-.45s;}
  .fvn .wave i:nth-child(3n+1),.vn .wave i:nth-child(3n+1){animation-delay:-.9s;}
  @keyframes vn-eq{0%,100%{transform:scaleY(.55)}50%{transform:scaleY(1)}}
}

/* ⚑ HEADER NAV (s5t) — flask-style: inline links on desktop, a hamburger drawer on mobile. Shared here
   (every page loads mock.css), so the header.njk partial gets nav site-wide. The per-page `.bar` rules
   (padding, the 2-state glass) are untouched; this only adds the nav + toggle + drawer. */
.bar .brand{text-decoration:none;}
.navmenu{display:flex;align-items:center;gap:18px;}
.nav{display:flex;align-items:center;gap:16px;}
.nav a{font-size:13px;color:var(--soft);text-decoration:none;white-space:nowrap;transition:color .15s var(--ease-out);}
.nav a:hover{color:var(--ink);}
.navtoggle{display:none;}
@media(max-width:767px){
  /* mobile: the row collapses to brand + ☰; everything else moves into the drawer */
  .bar{position:relative;}
  .navtoggle{display:flex;flex-direction:column;justify-content:center;gap:5px;
    width:40px;height:40px;padding:9px;background:none;border:0;cursor:pointer;-webkit-tap-highlight-color:transparent;}
  .navtoggle span{display:block;height:2px;width:22px;background:var(--ink);border-radius:2px;
    transition:transform .22s var(--ease-out),opacity .18s var(--ease-out);}
  .bar.open .navtoggle span:nth-child(1){transform:translateY(7px) rotate(45deg);}
  .bar.open .navtoggle span:nth-child(2){opacity:0;}
  .bar.open .navtoggle span:nth-child(3){transform:translateY(-7px) rotate(-45deg);}
  .navmenu{position:absolute;top:calc(100% + 6px);right:0;flex-direction:column;align-items:flex-end;gap:16px;
    background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);padding:18px 22px;
    box-shadow:var(--lift-sm);min-width:172px;z-index:40;
    opacity:0;visibility:hidden;transform:translateY(-6px);
    transition:opacity .2s var(--ease-out),transform .2s var(--ease-out),visibility 0s .2s;}
  .bar.open .navmenu{opacity:1;visibility:visible;transform:none;
    transition:opacity .2s var(--ease-out),transform .2s var(--ease-out),visibility 0s 0s;}
  .nav{flex-direction:column;align-items:flex-end;gap:14px;}
  .nav a{font-size:15px;color:var(--ink);}
}
