@font-face{font-family:"Newsreader";src:url("/assets/fonts/newsreader-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Newsreader";src:url("/assets/fonts/newsreader-500.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;}
@font-face{font-family:"Inter";src:url("/assets/fonts/inter-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Inter";src:url("/assets/fonts/inter-500.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;}

:root{
  --paper:#EFE9DE; --paper-2:#F7F2EA; --paper-3:#FBF8F2; --mist:#E1E7E4;
  --ink:#2A211B; --ink-soft:#6E6153; --ink-faint:#9C8F80;
  --clay:#BE5F30; --clay-deep:#9E4A1E; --blush:#EB9E86;
  --line:#DCD2C4; --line-soft:#E6DED2;
  --phase-m:#E6C3BB; --phase-f:#CDDABF; --phase-o:#F0D6A4; --phase-l:#D6CCE2; --on-phase:#3B2A22;
  --cap-fur:#C1622F; --cap-furd:#9E4A1E; --cap-snout:#E39B6B; --cap-ear:#A85F3C;
  --cap-nose:#5A3320; --cap-eye:#3B2416; --cap-blush:#F2A088; --cap-yuzu:#F59E0B; --cap-leaf:#10B981;
  --shadow:0 1px 2px rgba(60,40,25,.04), 0 12px 32px rgba(60,40,25,.06);
  --serif:"Newsreader","Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
  --sans:"Inter",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --ease:cubic-bezier(.22,.61,.36,1); --col:1060px;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --paper:#1C1714; --paper-2:#241E18; --paper-3:#2A2219; --mist:#232622;
  --ink:#F1E9DF; --ink-soft:#B6A99B; --ink-faint:#897D6F;
  --clay:#E07848; --clay-deep:#EFA07A; --blush:#E88A6E;
  --line:#38312A; --line-soft:#2C2620;
  --phase-m:#5E3F3A; --phase-f:#45523C; --phase-o:#5F4E30; --phase-l:#463F55; --on-phase:#F1E4DC;
  --cap-fur:#E07848; --cap-furd:#B25A32; --cap-snout:#C07A4E; --cap-ear:#8A4526;
  --cap-nose:#2A1710; --cap-eye:#1C110A; --cap-blush:#E88A6E; --cap-yuzu:#FBBF24; --cap-leaf:#34D399;
  --shadow:0 1px 2px rgba(0,0,0,.2), 0 14px 36px rgba(0,0,0,.28);
}}
:root[data-theme="dark"]{
  --paper:#1C1714; --paper-2:#241E18; --paper-3:#2A2219; --mist:#232622;
  --ink:#F1E9DF; --ink-soft:#B6A99B; --ink-faint:#897D6F;
  --clay:#E07848; --clay-deep:#EFA07A; --blush:#E88A6E;
  --line:#38312A; --line-soft:#2C2620;
  --phase-m:#5E3F3A; --phase-f:#45523C; --phase-o:#5F4E30; --phase-l:#463F55; --on-phase:#F1E4DC;
  --cap-fur:#E07848; --cap-furd:#B25A32; --cap-snout:#C07A4E; --cap-ear:#8A4526;
  --cap-nose:#2A1710; --cap-eye:#1C110A; --cap-blush:#E88A6E; --cap-yuzu:#FBBF24; --cap-leaf:#34D399;
  --shadow:0 1px 2px rgba(0,0,0,.2), 0 14px 36px rgba(0,0,0,.28);
}
*{box-sizing:border-box;}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth;}}
body{margin:0; background:var(--paper); color:var(--ink); font-family:var(--sans); font-size:17px; line-height:1.65;
  -webkit-font-smoothing:antialiased; position:relative; overflow-x:hidden;}
body::after{content:""; position:fixed; inset:0; pointer-events:none; z-index:80; opacity:.045;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");}
.wrap{max-width:var(--col); margin:0 auto; padding:0 28px;}
h1,h2,h3{font-family:var(--serif); font-weight:500; color:var(--ink); text-wrap:balance; margin:0;}
h2{font-size:clamp(28px,4.6vw,44px); line-height:1.06; letter-spacing:-.014em;}
h3{font-size:20px; line-height:1.2;}
p{margin:0;}
.eye{font-family:var(--sans); font-size:12.5px; letter-spacing:.2em; text-transform:uppercase; color:var(--clay-deep); font-weight:500; margin:0 0 16px;}
.lead{color:var(--ink-soft); font-size:19px; max-width:56ch;}
.body{color:var(--ink-soft); max-width:52ch;}
section{padding:clamp(64px,9vw,112px) 0;}
.num{font-variant-numeric:tabular-nums;}
a{color:var(--clay-deep);}

header{position:sticky; top:0; z-index:60; backdrop-filter:saturate(120%) blur(8px); transition:background .3s var(--ease), border-color .3s var(--ease); border-bottom:1px solid transparent;}
header.stuck{background:color-mix(in srgb, var(--paper) 82%, transparent); border-bottom:1px solid var(--line);}
.navrow{display:flex; align-items:center; justify-content:space-between; padding:16px 28px;}
.mark{font-family:var(--serif); font-size:23px; letter-spacing:.01em;}
.mark b{color:var(--clay); font-weight:500;}
.navcta{font-family:var(--sans); font-size:14.5px; color:var(--ink); text-decoration:none; border:1px solid var(--line); border-radius:30px; padding:8px 18px; transition:border-color .25s, background .25s;}
/* :hover moved to the (hover:hover) block at the end — it sticks after a tap on iOS */

.cta{display:inline-flex; align-items:center; gap:9px; font-family:var(--sans); font-size:16px; color:var(--cta-fg);
  background:var(--cta); border:0; border-radius:40px; padding:14px 28px; cursor:pointer;
  transition:background .25s var(--ease), transform .25s var(--ease); text-decoration:none;}
.cta:focus-visible{outline:2px solid var(--clay-deep); outline-offset:3px;}
.ghost{margin-left:20px; font-size:15px; color:var(--ink-soft); text-decoration:none; border-bottom:1px solid var(--line);}
.micro{font-size:13px; color:var(--ink-faint); margin-top:12px;}

.band{background:var(--paper-2); border-top:1px solid var(--line-soft); border-bottom:1px solid var(--line-soft);}
.center{max-width:60ch; margin:0 auto; text-align:center;}
.reframe{background:linear-gradient(180deg, transparent, color-mix(in srgb,var(--phase-l) 26%, transparent) 40%, color-mix(in srgb,var(--phase-o) 22%, transparent)); }

.trust .icons{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:28px;}
.ic{background:var(--paper-3);border:1px solid var(--line);border-radius:16px;padding:20px 16px;text-align:center;box-shadow:var(--shadow);}
.ic svg{width:26px;height:26px;color:var(--clay);margin-bottom:10px;}
.ic .t{font-size:14px;color:var(--ink);}

.form{max-width:460px;}
.fieldrow{display:flex;gap:8px;margin-top:14px;}
.fieldrow input{flex:1;font-family:var(--sans);font-size:15px;color:var(--ink);background:var(--paper-3);border:1px solid var(--line);border-radius:30px;padding:13px 18px;}
.fieldrow input:focus{outline:2px solid var(--clay);outline-offset:1px;border-color:transparent;}
.formmsg{font-size:13.5px;margin-top:10px;min-height:1.2em;}
.formmsg.err{color:#B4472C;}
.success{display:none;}
.success.show{display:block;animation:fade .6s var(--ease);}
@keyframes fade{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0 4px;}
.selchip{border:1px solid var(--line);border-radius:24px;padding:7px 14px;font-size:13.5px;color:var(--ink-soft);background:var(--paper-3);cursor:pointer;transition:.2s;font-family:var(--sans);}
.selchip[aria-pressed="true"]{background:var(--clay);color:#fff;border-color:transparent;}
.q{font-size:14.5px;color:var(--ink);margin:14px 0 2px;}

footer{border-top:1px solid var(--line);padding:34px 0 60px;}
.footrow{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;color:var(--ink-faint);font-size:13.5px;}
.footrow .mark{font-size:20px;}
.footlinks{display:flex;gap:18px;}
.footlinks a{color:var(--ink-soft);text-decoration:none;}

@media (prefers-reduced-motion:no-preference){
  .js .reveal{opacity:0;transform:translateY(18px);transition:opacity .8s var(--ease), transform .8s var(--ease);}
  .js .reveal.in{opacity:1;transform:none;}
}
@media (max-width:820px){
  .trust .icons{grid-template-columns:1fr 1fr;}
}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);}

/* ═══════════════════════════════════════════════════════════════════════════
   APP SHOWCASE — scroll-driven product tour with a faithful in-browser phone.
   The .device carries its OWN token set matching the real app (constants/theme.ts),
   so the screen inside reads as the actual product, distinct from the page.
   ═══════════════════════════════════════════════════════════════════════════ */
.device{
  --a-bg:#F5F4F0; --a-surf:#FFFFFF; --a-surf2:#EDECEA;
  --a-ink:#1D1D1F; --a-ink2:#4E4E52; --a-ink3:#6A6A6E; --a-line:#E8E6E0;
  --a-acc:#C1622F; --a-acc-soft:#FAEEE8; --a-acc-dk:#9E4A1E;
  --a-warm:#F59E0B; --a-warm-soft:#FEF3C7; --a-cool:#10B981; --a-cool-soft:#D1FAE5;
  --a-rose:#F43F5E; --a-rose-soft:#FFE4E6; --a-water:#38BDF8; --a-water-soft:#E0F2FE;
  --a-lut:#8B5CF6; --a-lut-soft:#F1ECFB; --a-lut-ink:#6D28D9;
  --a-ringA:#FBD9A0; --a-ringB:#E8915A; --a-ringC:#C1622F;
  --bezel:#2B241D; --bezel-edge:#0d0b09;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .device{
  --a-bg:#14110D; --a-surf:#211C15; --a-surf2:#2B251C;
  --a-ink:#F5F1EC; --a-ink2:#ABA399; --a-ink3:#968D80; --a-line:#28231C;
  --a-acc:#E07848; --a-acc-soft:#2D1608; --a-acc-dk:#C1622F;
  --a-warm:#FBBF24; --a-warm-soft:#2D2310; --a-cool:#34D399; --a-cool-soft:#0D2E22;
  --a-rose:#FB7185; --a-rose-soft:#2D1018; --a-water:#7DD3FC; --a-water-soft:#0C2A38;
  --a-lut:#A78BFA; --a-lut-soft:#1E1630; --a-lut-ink:#A78BFA;
  --bezel:#231d17; --bezel-edge:#000;
}}
:root[data-theme="dark"] .device{
  --a-bg:#14110D; --a-surf:#211C15; --a-surf2:#2B251C;
  --a-ink:#F5F1EC; --a-ink2:#ABA399; --a-ink3:#968D80; --a-line:#28231C;
  --a-acc:#E07848; --a-acc-soft:#2D1608; --a-acc-dk:#C1622F;
  --a-warm:#FBBF24; --a-warm-soft:#2D2310; --a-cool:#34D399; --a-cool-soft:#0D2E22;
  --a-rose:#FB7185; --a-rose-soft:#2D1018; --a-water:#7DD3FC; --a-water-soft:#0C2A38;
  --a-lut:#A78BFA; --a-lut-soft:#1E1630; --a-lut-ink:#A78BFA;
  --bezel:#231d17; --bezel-edge:#000;
}

/* ── CINEMA: one sticky phone, three acts (peek → beauty → dock) ───────────
   .cin-stage and .cin-rail share one grid cell: the rail is tall and defines
   the scroll range, the stage sticks inside it. The phone's transform is owned
   entirely by app.js (see "cinema"); CSS only sets the docked resting state so
   no-JS and reduced-motion visitors get a sane static layout.               */
.cinema{position:relative;display:grid;grid-template-columns:1fr;align-items:start;padding:0;}
/* app.js reads 100svh off this, never off window.innerHeight (which the iOS URL bar
   moves) and never off .cin-stage (which goes height:auto on the static route).
   position:absolute keeps it out of grid/flex flow — it must never be a grid item. */
.svh-probe{position:absolute;top:0;left:0;width:0;height:100svh;visibility:hidden;pointer-events:none;}
.cin-stage{grid-area:1/1;position:sticky;top:0;height:100svh;display:flex;align-items:center;justify-content:center;
  perspective:1500px;perspective-origin:50% 44%;pointer-events:none;z-index:1;}
.cin-stage .device{pointer-events:auto;transform-style:preserve-3d;}
.js .cin-stage .device{will-change:transform;}

/* ambient warm halo behind the phone — inherits the approved phase-breathing glow.
   Heavily blurred and edge-free: it must read as light in the room, never a disc. */
.cin-halo{position:absolute;width:min(560px,72vw);aspect-ratio:1;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle at 50% 46%, color-mix(in srgb,var(--clay) 20%,transparent), transparent 68%);
  filter:blur(56px);}

.cin-rail{grid-area:1/1;position:relative;z-index:2;width:100%;max-width:var(--col);margin:0 auto;padding:0 28px;pointer-events:none;}
.cin-rail > *{pointer-events:auto;}

/* Act I — the fold. The stack is height-aware, not just width-aware: on a short
   laptop the type has to give way so the phone still has room to peek into. */
.cin-intro{min-height:100svh;display:flex;flex-direction:column;align-items:center;text-align:center;
  padding-top:clamp(88px,12vh,130px);}
.cin-intro h1{font-size:clamp(40px,min(8.4vw,10.5vh),106px);line-height:.93;letter-spacing:-.038em;}
.cin-intro .sub{margin:clamp(18px,2.2vh,26px) auto 0;font-size:clamp(16.5px,min(1.35vw,2.2vh),20.5px);
  color:var(--ink-soft);max-width:58ch;}
.cin-intro .heroform{margin:clamp(22px,3vh,34px) auto 0;}
.cin-intro .micro{margin-top:13px;}

/* Act II — the beauty shot: deliberately empty, the phone owns the viewport */
.cin-beauty{min-height:86svh;pointer-events:none;}

/* Reduced motion (class set by app.js): no acts. The phone is simply docked in a
   two-column layout and never moves; only the screen swap remains. */
.cinema.cin-static{grid-template-columns:1fr minmax(340px,44%);gap:clamp(24px,3.5vw,52px);
  max-width:var(--col);margin:0 auto;padding:0 28px;}
.cinema.cin-static .cin-stage{grid-area:1/2;perspective:none;}
.cinema.cin-static .cin-stage .device{transform:scale(.82);}
.cinema.cin-static .cin-rail{grid-area:1/1;padding:0;max-width:none;}
.cinema.cin-static .cin-intro{min-height:auto;text-align:left;align-items:flex-start;padding-top:12vh;padding-bottom:8vh;}
.cinema.cin-static .cin-intro .sub,.cinema.cin-static .cin-intro .heroform{margin-left:0;}
.cinema.cin-static .cin-beauty{display:none;}
.cinema.cin-static .cin-halo{display:none;}
/* ≤900px static route. The old version put .cin-stage and .cin-rail in the SAME
   grid cell (1/1) with one column — i.e. it drew the headline, the email field and
   the CTA directly on top of a stationary phone. Reduced-motion users got the worst
   page on the site. It is a real flex column now: hero → phone → captions.
   app.js owns .cin-static (reduced motion OR a short/landscape viewport). */
@media (max-width:900px){
  .cinema.cin-static{display:flex;flex-direction:column;gap:0;max-width:var(--col);margin:0 auto;padding:0 20px;}
  .cinema.cin-static .cin-rail{display:contents;}          /* role-less div → safe to un-box */
  .cinema.cin-static .cin-intro{order:1;min-height:auto;text-align:center;align-items:center;padding:8svh 0 4svh;}
  .cinema.cin-static .cin-stage{order:2;position:static;height:auto;padding:0 0 32px;perspective:none;}
  /* The device's layout box is a fixed 322px. Inside this column (100vw − 40px of
     padding) that overflows on any viewport under ~362px, so it needs a width-driven
     scale, not transform:none. Reduced-motion still gets a still phone — a static
     scale is not motion. */
  .cinema.cin-static .cin-stage .device{transform:scale(.86);transform-origin:top center;
    margin:0 auto;transform-style:flat;}
  .cinema.cin-static .cin-beauty{display:none;}
  .cinema.cin-static .cin-halo{display:none;}
  .cinema.cin-static .sc-steps{order:3;display:block;grid-template-rows:none;}
  .cinema.cin-static .sc-step{position:static;grid-area:auto;height:auto;min-height:0;
    justify-content:flex-start;align-items:flex-start;text-align:left;padding:0 0 48px;
    opacity:1;transform:none;}
  .cinema.cin-static .sc-step .eye,.cinema.cin-static .sc-step .body{display:block;}

  /* no-JS: same shape, same reasoning (without it the phone freezes over the hero) */
  html:not(.js) .cinema{display:flex;flex-direction:column;padding:0 20px;}
  html:not(.js) .cin-rail{display:contents;}
  html:not(.js) .cin-intro{order:1;min-height:auto;padding:8svh 0 4svh;}
  html:not(.js) .cin-stage{order:2;position:static;height:auto;perspective:none;}
  html:not(.js) .cin-beauty{display:none;}
  html:not(.js) .sc-steps{order:3;}
}

/* Act III — captions drive the screens; phone is docked right */
.sc-step{min-height:88svh;display:flex;flex-direction:column;justify-content:center;max-width:36ch;}
.sc-step:last-child{min-height:76svh;}
.sc-step .k{width:26px;height:26px;border-radius:9px;display:flex;align-items:center;justify-content:center;font-size:13px;background:var(--paper-2);border:1px solid var(--line);color:var(--clay);margin-bottom:18px;}
.sc-step h3{font-family:var(--serif);font-weight:500;font-size:clamp(26px,3.4vw,38px);line-height:1.06;letter-spacing:-.018em;}
.sc-step .body{margin-top:16px;font-size:17px;}
.sc-step .tag{display:inline-block;margin-top:16px;font-size:13px;color:var(--ink-faint);font-style:italic;}
.js .sc-step{opacity:.3;transition:opacity .55s var(--ease);}
.js .sc-step.on{opacity:1;}
@media (prefers-reduced-motion:reduce){.js .sc-step{transition:none;}}

/* ── The device ───────────────────────────────────────────────────────────── */
.device{position:relative;width:322px;padding:11px;border-radius:52px;
  background:linear-gradient(155deg,#3a322a,var(--bezel) 42%,var(--bezel-edge));
  box-shadow:0 2px 4px rgba(0,0,0,.35), 0 30px 60px -14px rgba(40,25,12,.5), inset 0 0 0 1px rgba(255,255,255,.06);}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .device{box-shadow:0 2px 4px rgba(0,0,0,.5), 0 34px 64px -14px rgba(0,0,0,.6), inset 0 0 0 1px rgba(255,255,255,.05);}}
.ph-screen{position:relative;width:300px;height:626px;border-radius:42px;overflow:hidden;background:var(--a-bg);color:var(--a-ink);
  font-family:var(--sans);-webkit-font-smoothing:antialiased;}
.ph-screen svg{flex:none;}  /* inline SVGs must not collapse to 0 width inside flex rows */
.ph-island{position:absolute;top:9px;left:50%;transform:translateX(-50%);width:88px;height:26px;border-radius:16px;background:#0b0a08;z-index:40;}
.ph-status{position:absolute;top:0;left:0;right:0;height:46px;display:flex;align-items:center;justify-content:space-between;padding:16px 22px 0;font-size:13px;font-weight:600;color:var(--a-ink);z-index:30;pointer-events:none;}
.ph-status .st-r{display:flex;align-items:center;gap:5px;}
.ph-status svg{display:block;}

/* screens stack; only the active one shows */
.ph-body{position:absolute;inset:0;}
.appscreen{position:absolute;inset:0;padding:52px 16px 78px;overflow:hidden;
  display:flex;flex-direction:column;opacity:0;transform:translateY(10px) scale(.985);pointer-events:none;}
@media (prefers-reduced-motion:no-preference){.appscreen{transition:opacity .6s var(--ease), transform .6s var(--ease);}}
.appscreen[data-active]{opacity:1;transform:none;pointer-events:auto;}
html:not(.js) .appscreen{position:relative;opacity:1;transform:none;}      /* no-JS: show stacked */
html:not(.js) .appscreen[data-screen="score"]{}
.appscreen::-webkit-scrollbar{display:none;}

/* Fade the cropped bottom into the app bg so it reads like a live scroll — the
   real app's screens are ScrollViews, so content continuing past the fold is
   truthful, but a hard cut looks like a rendering bug. Only on the screens that
   actually overflow (score/nutrition/fitness); cycle fits, and chat's input bar
   already terminates it. Was opacity:0 with the gradient inverted, so it had
   never rendered once. */
.appscreen::after{content:"";position:absolute;left:0;right:0;bottom:70px;height:40px;
  background:linear-gradient(transparent,var(--a-bg));opacity:0;pointer-events:none;z-index:20;}
.appscreen[data-screen="score"]::after,
.appscreen[data-screen="nutrition"]::after,
.appscreen[data-screen="fitness"]::after{opacity:1;}

/* ── Shared in-app primitives ─────────────────────────────────────────────── */
.a-h{font-size:23px;font-weight:700;letter-spacing:-.4px;color:var(--a-ink);line-height:1;}
.a-sub{font-size:12px;color:var(--a-ink2);margin-top:3px;}
.a-card{background:var(--a-surf);border:1px solid var(--a-line);border-radius:18px;box-shadow:0 2px 14px rgba(60,40,25,.05);}
.a-eye{font-size:9.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--a-ink3);}
.a-row{display:flex;align-items:center;}
.a-ava{width:34px;height:34px;border-radius:50%;background:var(--a-acc);color:#fff;font-size:13px;font-weight:600;display:flex;align-items:center;justify-content:center;flex:none;}
.a-tophdr{display:flex;align-items:flex-end;justify-content:space-between;}
.a-pillbtn{display:flex;align-items:center;justify-content:center;gap:7px;background:var(--a-acc);color:#fff;font-size:13.5px;font-weight:600;border-radius:14px;padding:12px;border:0;width:100%;}

/* Bottom tab bar (real app: Home · Nutrition · Cycle · Fitness · Assistant) */
.ph-tabs{position:absolute;left:0;right:0;bottom:0;height:70px;padding:9px 8px 12px;display:grid;grid-template-columns:repeat(5,1fr);
  background:color-mix(in srgb,var(--a-bg) 92%,transparent);backdrop-filter:blur(12px);border-top:1px solid var(--a-line);z-index:35;}
.ph-tab{display:flex;flex-direction:column;align-items:center;gap:3px;background:none;border:0;cursor:pointer;color:var(--a-ink3);padding:0;}
.ph-tab svg{width:22px;height:22px;}
.ph-tab .tl{font-size:9.5px;font-weight:500;}
.ph-tab[aria-selected="true"]{color:var(--a-acc);}

/* ── SCORE screen ─────────────────────────────────────────────────────────── */
.sc-greet{font-size:13px;color:var(--a-ink2);}
.sc-name{font-size:26px;font-weight:700;letter-spacing:-.4px;color:var(--a-ink);line-height:1;margin-top:2px;}
.sc-idrow{display:flex;align-items:center;gap:9px;justify-content:center;margin:10px 0 2px;}
.sc-idrow .em{font-size:22px;}
.sc-idrow .t{font-size:14px;font-weight:700;color:var(--a-ink);}
.sc-idrow .s{font-size:10.5px;color:var(--a-ink3);margin-top:1px;}
/* Mirrors heroRingArea in the app (app/(tabs)/index.tsx:1020): a fixed square that
   NEVER shrinks — the app's ScrollView absorbs overflow instead. flex:none is
   load-bearing here: every child is position:absolute so this box's min-content
   height is 0, which made it the only shrinkable item in the column. It silently
   ate all 82px of overflow, rendered 136px instead of 218px, and dragged the
   corner pillars 23px onto the ring. (RN defaults flexShrink to 0; CSS defaults
   it to 1 — that's how the mock drifted from the app.)
   Width follows the app's ring×1.55 ratio, widened to ~92% of the content box to
   match how heroRingArea fills its parent. That is what buys the corner labels
   their clearance. */
.sc-ringwrap{position:relative;flex:none;width:260px;height:218px;margin:6px auto 0;
  display:flex;align-items:center;justify-content:center;}
.sc-halo{position:absolute;width:150px;height:150px;border-radius:50%;box-shadow:0 0 24px 3px var(--a-lut);opacity:.22;}
.sc-dial{position:absolute;width:158px;height:158px;border-radius:50%;
  background:radial-gradient(circle at 50% 42%, rgba(240,168,117,.30), rgba(240,168,117,.08) 58%, transparent 72%);}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .sc-dial{background:radial-gradient(circle at 50% 42%, rgba(224,120,72,.26), rgba(224,120,72,.07) 58%, transparent 72%);}}
:root[data-theme="dark"] .sc-dial{background:radial-gradient(circle at 50% 42%, rgba(224,120,72,.26), rgba(224,120,72,.07) 58%, transparent 72%);}
.sc-ring{position:absolute;width:150px;height:150px;}
.sc-ring svg{width:100%;height:100%;transform:rotate(-90deg);}
.sc-ring .trk{fill:none;stroke:var(--a-acc);opacity:.16;stroke-width:11;}
.sc-ring .arc{fill:none;stroke:url(#phGrad);stroke-width:11;stroke-linecap:round;}
.sc-orb{position:absolute;width:118px;height:118px;border-radius:50%;display:flex;flex-direction:column;align-items:center;justify-content:center;
  background:radial-gradient(circle at 50% 40%, #FFF6EE, #F4D8C1 70%, #EAC2A4);box-shadow:inset 0 0 22px rgba(193,98,47,.14);}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .sc-orb{background:radial-gradient(circle at 50% 40%, #2A1E16, #1F1610 70%, #17110C);}}
:root[data-theme="dark"] .sc-orb{background:radial-gradient(circle at 50% 40%, #2A1E16, #1F1610 70%, #17110C);}
.sc-orb .lab{font-size:7px;font-weight:700;letter-spacing:.14em;color:var(--a-acc-dk);}
.sc-orb .num{font-size:42px;font-weight:800;line-height:.98;
  background:linear-gradient(180deg,#EE9A5C,#C1622F 55%,#8A3D1A);-webkit-background-clip:text;background-clip:text;color:transparent;}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .sc-orb .num{background:linear-gradient(180deg,#FBD9A0,#E8915A 55%,#C1622F);-webkit-background-clip:text;background-clip:text;color:transparent;}}
:root[data-theme="dark"] .sc-orb .num{background:linear-gradient(180deg,#FBD9A0,#E8915A 55%,#C1622F);-webkit-background-clip:text;background-clip:text;color:transparent;}
/* Corner pillars — mirrors cornerStat/cornerTL..BR (app/(tabs)/index.tsx:1038).
   NO fixed width: the app sizes these to their content, and the mock's invented
   60px box is what made "Nourished" (62px) spill. Labels align OUTWARD from the
   ring (flex-start on the left corners, flex-end on the right) exactly as the app
   does — centring them pulled every label back toward the ring. */
.sc-pillar{position:absolute;display:flex;flex-direction:column;gap:2px;}
/* 11.5/8.5/10 ≈ the app's 16/11/13 scaled by the mock's ring ratio (150/210 = .714).
   The mock had inflated these to 12.5/9/11, which is what pushed the longest word
   ("Nourished") back into the ring — with outward alignment, a wider label reaches
   further inward, so type size here IS clearance. */
.sc-pillar .w{font-size:11.5px;font-weight:600;color:var(--a-ink);white-space:nowrap;letter-spacing:-.1px;}
.sc-pillar .r{display:flex;align-items:center;gap:3px;}
.sc-pillar .r svg{width:10px;height:10px;}
.sc-pillar .r .pl{font-size:8.5px;color:var(--a-ink3);white-space:nowrap;}
.sc-pillar.tl,.sc-pillar.bl{align-items:flex-start;}
.sc-pillar.tr,.sc-pillar.br{align-items:flex-end;}
.sc-pillar.tl{top:11px;left:4px;} .sc-pillar.tr{top:11px;right:4px;}
.sc-pillar.bl{bottom:11px;left:4px;} .sc-pillar.br{bottom:11px;right:4px;}
.sc-bandrow{display:flex;align-items:center;justify-content:center;gap:9px;margin-top:10px;}
.sc-band{background:var(--a-acc-soft);color:var(--a-acc);font-size:12px;font-weight:700;padding:4px 12px;border-radius:999px;}
.sc-mom{font-size:12px;font-weight:700;color:var(--a-acc);}
.sc-hist{font-size:11px;color:var(--a-ink3);}
.sc-why{text-align:center;font-size:12px;color:var(--a-ink2);margin:8px auto 0;max-width:30ch;line-height:1.45;}
.sc-msg{margin-top:12px;padding:13px 14px;}
.sc-msg .hd{display:flex;align-items:center;gap:8px;}
.sc-msg .ic{width:26px;height:26px;border-radius:8px;background:var(--a-rose-soft);display:flex;align-items:center;justify-content:center;}
.sc-msg .ic svg{width:15px;height:15px;color:var(--a-rose);margin:0;}
.sc-msg .ti{font-size:13.5px;font-weight:600;}
.sc-msg .bd{font-size:12.5px;color:var(--a-ink2);line-height:1.5;margin-top:8px;}

/* ── CYCLE screen ─────────────────────────────────────────────────────────── */
.cy-hero{margin-top:12px;padding:16px;border-radius:20px;background:var(--a-lut-soft);}
.cy-hero .top{display:flex;align-items:flex-start;justify-content:space-between;}
.cy-hero .eye{color:var(--a-lut-ink);}
.cy-hero .ph{font-size:26px;font-weight:700;color:var(--a-lut-ink);line-height:1;margin-top:5px;}
.cy-hero .dy{font-size:12px;color:var(--a-ink2);margin-top:4px;}
.cy-hero .orb{width:48px;height:48px;border-radius:50%;background:var(--a-surf);display:flex;align-items:center;justify-content:center;flex:none;}
.cy-hero .orb svg{width:24px;height:24px;color:var(--a-lut-ink);}
.cy-tl{position:relative;height:11px;border-radius:6px;display:flex;gap:2px;margin-top:16px;}
.cy-tl>span{border-radius:6px;height:100%;}
.cy-tl .here{position:absolute;top:50%;width:16px;height:16px;border-radius:50%;background:var(--a-surf);border:3px solid var(--a-lut);transform:translate(-50%,-50%);box-shadow:0 1px 4px rgba(0,0,0,.15);}
.cy-tlft{display:flex;align-items:center;justify-content:space-between;margin-top:9px;font-size:11px;color:var(--a-ink2);}
.cy-tlft .d{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--a-lut);margin-right:5px;vertical-align:middle;}
.cy-tlft b{color:var(--a-lut-ink);} .cy-tlft .nx b{color:var(--a-rose);}
.cy-stats{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-top:14px;}
.cy-stat{background:var(--a-surf);border:1px solid var(--a-line);border-radius:14px;padding:11px 12px;}
.cy-stat .k{font-size:9px;font-weight:700;letter-spacing:.1em;color:var(--a-ink3);}
.cy-stat .v{font-size:16px;font-weight:700;color:var(--a-ink);margin-top:4px;}
.cy-stat .s{font-size:11px;margin-top:2px;}
.cy-acts{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-top:12px;}
.cy-act{display:flex;align-items:center;justify-content:center;gap:7px;padding:12px;border-radius:14px;font-size:12.5px;font-weight:600;}
.cy-act svg{width:15px;height:15px;}

/* ── NUTRITION screen ─────────────────────────────────────────────────────── */
.nu-sum{margin-top:12px;padding:16px;border-radius:20px;}
.nu-sum .top{display:flex;align-items:center;justify-content:space-between;}
.nu-sum .swap{width:22px;height:22px;border-radius:50%;background:var(--a-surf2);display:flex;align-items:center;justify-content:center;}
.nu-sum .swap svg{width:12px;height:12px;color:var(--a-ink3);}
.nu-mid{display:flex;align-items:center;justify-content:space-between;margin-top:8px;}
.nu-kcal{font-size:38px;font-weight:800;color:var(--a-ink);line-height:1;}
.nu-kcal small{display:block;font-size:12px;font-weight:500;color:var(--a-ink2);margin-top:5px;}
.nu-donut{position:relative;width:66px;height:66px;flex:none;text-align:center;}
.nu-donut svg{width:66px;height:66px;transform:rotate(-90deg);}
.nu-donut .cap{font-size:10px;color:var(--a-ink2);margin-top:3px;}
.nu-pbar{height:8px;border-radius:4px;background:var(--a-surf2);margin-top:14px;overflow:hidden;}
.nu-pbar>i{display:block;height:100%;border-radius:4px;background:var(--a-warm);}
.nu-note{font-size:11.5px;font-weight:500;color:var(--a-warm);margin-top:8px;}
.nu-add{margin-top:14px;}
.nu-tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:9px;}
.nu-t{background:var(--a-acc-soft);border-radius:12px;padding:10px 4px;text-align:center;color:var(--a-acc);}
.nu-t svg{width:16px;height:16px;} .nu-t .l{font-size:10px;font-weight:600;margin-top:3px;}
.nu-meals{margin-top:16px;}
.nu-mh{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;}
.nu-mh .t{font-size:15px;font-weight:600;} .nu-mh .n{font-size:11px;color:var(--a-ink3);}
.nu-meal{background:var(--a-surf);border:1px solid var(--a-line);border-radius:14px;padding:11px 12px;margin-bottom:9px;}
.nu-meal .mh{display:flex;align-items:center;gap:8px;}
.nu-meal .mi{width:26px;height:26px;border-radius:8px;background:var(--a-warm-soft);display:flex;align-items:center;justify-content:center;}
.nu-meal .mi svg{width:14px;height:14px;color:var(--a-warm);}
.nu-meal .mn{font-size:13px;font-weight:600;flex:1;} .nu-meal .mk{font-size:12px;color:var(--a-ink3);}
.nu-food{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--a-ink2);margin-top:8px;}
.nu-food .fe{font-size:15px;} .nu-food .fn{flex:1;} .nu-food .fk{color:var(--a-ink3);}

/* ── FITNESS screen ───────────────────────────────────────────────────────── */
.fi-desc{display:flex;align-items:center;justify-content:center;gap:6px;font-size:12px;color:var(--a-ink2);margin-top:9px;}
.fi-desc svg{width:14px;height:14px;color:var(--a-acc);}
.fi-act{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-top:14px;}
.fi-c{background:var(--a-surf);border:1px solid var(--a-line);border-radius:16px;padding:12px;text-align:center;box-shadow:0 2px 12px rgba(60,40,25,.04);}
.fi-c .eye{display:flex;align-items:center;justify-content:space-between;}
.fi-c .eye svg{width:12px;height:12px;color:var(--a-ink3);}
.fi-ring{position:relative;width:84px;height:84px;margin:8px auto 6px;}
.fi-ring svg{width:100%;height:100%;transform:rotate(-90deg);}
.fi-ring .t{fill:none;stroke:var(--a-surf2);stroke-width:9;}
.fi-ring .a{fill:none;stroke:var(--a-acc);stroke-width:9;stroke-linecap:round;}
.fi-ring .c{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;}
.fi-ring .c b{font-size:17px;font-weight:800;color:var(--a-ink);} .fi-ring .c s{font-size:9px;color:var(--a-ink3);text-decoration:none;}
.fi-foot{font-size:10.5px;color:var(--a-ink2);}
.fi-steps .big{font-size:26px;font-weight:800;color:var(--a-ink);margin:6px 0 1px;}
.fi-spark{display:flex;align-items:flex-end;justify-content:center;gap:3px;height:38px;margin-top:8px;}
.fi-spark i{width:8px;border-radius:3px;background:var(--a-cool-soft);}
.fi-spark i:last-child{background:var(--a-cool);}
.fi-sync{margin-top:14px;padding:14px;border-radius:16px;background:var(--a-lut-soft);}
.fi-sync .sh{display:flex;align-items:center;gap:7px;}
.fi-sync .sh svg{width:14px;height:14px;color:var(--a-lut-ink);}
.fi-sync .sh .e{font-size:10px;font-weight:700;letter-spacing:.08em;color:var(--a-lut-ink);flex:1;}
.fi-sync .pill{background:var(--a-surf);color:var(--a-lut-ink);font-size:8.5px;font-weight:700;letter-spacing:.05em;padding:4px 8px;border-radius:999px;}
.fi-sync .cp{font-size:12.5px;color:var(--a-ink);margin-top:10px;line-height:1.4;}
.fi-prac{display:flex;align-items:center;gap:9px;background:var(--a-surf);border-radius:12px;padding:9px 11px;margin-top:8px;}
.fi-prac svg{width:15px;height:15px;color:var(--a-lut-ink);}
.fi-prac .n{font-size:12.5px;font-weight:600;flex:1;color:var(--a-ink);} .fi-prac .m{font-size:11px;color:var(--a-ink3);}

/* ── CHAT screen ──────────────────────────────────────────────────────────── */
.appscreen[data-screen="chat"]{padding-bottom:70px;}
.ch-hdr{display:flex;align-items:center;gap:10px;padding-bottom:12px;border-bottom:1px solid var(--a-line);}
.ch-ava{position:relative;width:40px;height:40px;border-radius:50%;background:var(--a-acc-soft);padding:4px;flex:none;box-shadow:0 2px 8px rgba(60,40,25,.08);}
.ch-ava .dot{position:absolute;bottom:0;right:0;width:10px;height:10px;border-radius:50%;background:var(--a-cool);border:2px solid var(--a-surf);}
.ch-hdr .nm{font-size:15px;font-weight:600;color:var(--a-ink);}
.ch-hdr .st{font-size:11px;color:var(--a-cool);margin-top:1px;}
.ch-conv{flex:1;display:flex;flex-direction:column;gap:9px;padding:14px 2px 6px;overflow:hidden;}
.ch-day{text-align:center;font-size:10px;color:var(--a-ink3);position:relative;margin-bottom:2px;}
.ch-b{max-width:86%;font-size:12.5px;line-height:1.45;padding:11px 13px;}
.ch-b.ai{background:var(--a-surf);border:1px solid var(--a-line);color:var(--a-ink);border-radius:16px 16px 16px 5px;align-self:flex-start;box-shadow:0 2px 10px rgba(60,40,25,.05);}
.ch-b.me{background:var(--a-acc);color:#fff;border-radius:16px 16px 5px 16px;align-self:flex-end;}
.ch-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px;}
.ch-chip{background:var(--a-acc-soft);color:var(--a-acc);font-size:11px;font-weight:600;padding:7px 11px;border-radius:999px;}
.ch-in{display:flex;align-items:center;gap:8px;margin-top:10px;background:var(--a-surf);border:1px solid var(--a-line);border-radius:16px;padding:9px 10px 9px 14px;}
.ch-in .ph{flex:1;font-size:12px;color:var(--a-ink3);}
.ch-in .snd{width:30px;height:30px;border-radius:50%;background:var(--a-acc);display:flex;align-items:center;justify-content:center;flex:none;}
.ch-in .snd svg{width:15px;height:15px;color:#fff;}

/* ═══════════════════════════════════════════════════════════════════════════
   DIRECTION MOVES (2026-07-14) — phase-glow ring, phase system, anti-shame
   contrast, day scenario, trust testimonial. Borrowed from the reference board.
   ═══════════════════════════════════════════════════════════════════════════ */
:root{
  --pm:#E0567A; --pm-soft:#F7E1E4; --pm-ink:#B23052;
  --pf:#3E9E7A; --pf-soft:#DEEADF; --pf-ink:#2C7256;
  --po:#D68A2E; --po-soft:#F3E6CB; --po-ink:#9C6417;
  --pl:#8B5CF6; --pl-soft:#EBE6F6; --pl-ink:#6D3FCB;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --pm:#F17795; --pm-soft:#331820; --pm-ink:#F79DB2;
  --pf:#4FBE93; --pf-soft:#152A22; --pf-ink:#6FD3AC;
  --po:#E6A54B; --po-soft:#2E2410; --po-ink:#F0BE74;
  --pl:#A78BFA; --pl-soft:#211838; --pl-ink:#C0AAFB;
}}
:root[data-theme="dark"]{
  --pm:#F17795; --pm-soft:#331820; --pm-ink:#F79DB2;
  --pf:#4FBE93; --pf-soft:#152A22; --pf-ink:#6FD3AC;
  --po:#E6A54B; --po-soft:#2E2410; --po-ink:#F0BE74;
  --pl:#A78BFA; --pl-soft:#211838; --pl-ink:#C0AAFB;
}

/* Move 1 · the phase-breathing glow. Was the hero ring's aura; now it haloes the
   phone itself, so the "whole rhythm" idea reads behind the actual product. */
@media (prefers-reduced-motion:no-preference){
  .cin-halo{animation:phaseGlow 24s ease-in-out infinite;}
  @keyframes phaseGlow{
    0%,100%{box-shadow:0 0 90px 10px color-mix(in srgb,var(--pm) 18%,transparent);}
    25%{box-shadow:0 0 90px 10px color-mix(in srgb,var(--pf) 18%,transparent);}
    50%{box-shadow:0 0 90px 10px color-mix(in srgb,var(--po) 18%,transparent);}
    75%{box-shadow:0 0 90px 10px color-mix(in srgb,var(--pl) 18%,transparent);}
  }
}

/* Move 2 · phase system — four named, coloured phases */
.phasesys{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:34px;}
.phasesys .p{border-radius:16px;padding:16px 15px;border:1px solid transparent;}
.phasesys .p .t{display:flex;align-items:center;gap:8px;}
.phasesys .p .t .d{width:10px;height:10px;border-radius:50%;flex:none;}
.phasesys .p .nm{font-family:var(--serif);font-size:17px;color:inherit;}
.phasesys .p .ds{font-size:13px;margin-top:6px;opacity:.9;}
.phasesys .pm{background:var(--pm-soft);color:var(--pm-ink);} .phasesys .pm .d{background:var(--pm);}
.phasesys .pf{background:var(--pf-soft);color:var(--pf-ink);} .phasesys .pf .d{background:var(--pf);}
.phasesys .po{background:var(--po-soft);color:var(--po-ink);} .phasesys .po .d{background:var(--po);}
.phasesys .pl{background:var(--pl-soft);color:var(--pl-ink);} .phasesys .pl .d{background:var(--pl);}
@media (max-width:640px){.phasesys{grid-template-columns:1fr 1fr;}}

/* Move 4 · anti-shame contrast */
.contrast{display:grid;grid-template-columns:1fr 1fr;gap:16px;max-width:720px;margin:30px auto 0;}
.contrast .col{border-radius:18px;padding:22px 24px;}
.contrast .dont{background:var(--paper-3);border:1px solid var(--line);}
.contrast .do{background:var(--clay);color:#fff;}
.contrast .ct{font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;font-weight:700;margin-bottom:14px;}
.contrast .dont .ct{color:var(--ink-faint);}
.contrast .do .ct{color:rgba(255,255,255,.8);}
.contrast ul{margin:0;padding:0;list-style:none;}
.contrast li{display:flex;gap:10px;align-items:flex-start;font-size:15px;line-height:1.4;padding:8px 0;}
.contrast li .mk{flex:none;font-weight:700;}
.contrast .dont li{color:var(--ink-faint);} .contrast .dont .mk{color:var(--pm);}
.contrast .dont s{text-decoration-color:color-mix(in srgb,var(--pm) 60%,transparent);}
.contrast .do li{color:#fff;} .contrast .do .mk{color:#fff;}
@media (max-width:600px){.contrast{grid-template-columns:1fr;}}

/* ── Responsive: the phone can't dock sideways on a phone, so the composition
   splits vertically — phone pinned in the upper field, caption PINNED in a band
   beneath it. This is a different layout, not the desktop one stacked.

   The old version let the captions scroll through the pinned phone and painted an
   opaque scrim over the product to hide the collision. That is gone. The phone's
   scale is now SOLVED from the caption's measured height (app.js → solveMobile),
   so `capTop − devBottom = GAP` is an identity and nothing ever needs hiding.

   ⚠ LOAD-BEARING: .cinema, .cin-rail and .sc-steps must stay free of
   transform / filter / contain. Any of those becomes the sticky containing block
   for .sc-step and the whole invariant dies silently. (Verification: G9.)     */
@media (max-width:900px){
  .cin-stage{perspective:none;}                       /* the tilt is desktop-only now */
  .cin-stage .device{transform-style:flat;pointer-events:none;}  /* no grey tap flash, no mis-tap fling */
  .cin-halo{width:min(560px,86vw);animation:none;}    /* 104vw read as a full-bleed wash; the keyframes repaint a blurred layer forever */
  .cin-rail{padding:0;}
  .cin-intro{padding:clamp(40px,7svh,72px) 20px 0;pointer-events:none;}
  .cin-intro > *{pointer-events:auto;}                /* don't let the empty hero column swallow taps aimed at the phone */
  .cin-intro h1{font-size:clamp(40px,11.5vw,60px);letter-spacing:-.03em;}
  .cin-intro .sub{font-size:16.5px;max-width:34ch;}
  .cin-tight .cin-intro .sub{display:none;}           /* class owned by app.js — a max-height MQ resolves against the LARGE viewport on iOS and would never fire */
  .cin-intro .formmsg{min-height:0;}
  .cin-beauty{min-height:78svh;}
  .cin-cue{display:none;}                             /* ships with zero CSS rules → an unstyled 17px paragraph over the phone */

  /* ── THE PLATE ──────────────────────────────────────────────────────────────
     All five captions share one grid cell and each is a sticky 100svh plate, so
     the caption's y is NOT a function of scrollY — same as the phone's. Two things
     that both hold still cannot cross. They cross-fade positionally instead.
     The `.js` prefix ties specificity with `.js .sc-step` (:204) and wins on order. */
  .js .sc-steps{display:grid;grid-template-columns:1fr;grid-template-rows:calc(5 * 80svh);}
  .js .sc-step{grid-area:1/1;align-self:start;position:sticky;top:0;
    height:100svh;min-height:0;max-width:none;
    display:flex;flex-direction:column;justify-content:flex-end;align-items:center;text-align:center;
    padding:0 20px var(--cap-padbot,18px);
    pointer-events:none;opacity:0;transition:none;}
  /* NO will-change: five 100svh composited layers ≈ 20MB. Opacity promotes as needed. */
  .sc-step::before{content:none;}                     /* ◀ THE SCRIM IS DELETED */
  .sc-step .k,.sc-step .tag{display:none;}
  .sc-step .eye{font-size:11px;letter-spacing:.18em;margin-bottom:6px;}
  .sc-step h3{font-size:clamp(23px,6.2vw,30px);line-height:1.08;}
  .sc-step .body{font-size:14px;line-height:1.45;margin-top:8px;max-width:48ch;margin-left:auto;margin-right:auto;}
  /* shed rungs — app.js drops copy rather than shrinking the phone below legibility */
  .cap-shed-body .sc-step .body{display:none;}
  .cap-shed-eye .sc-step .eye{display:none;}

  /* The bar is already 92% opaque; blurring a flat --a-bg returns --a-bg, but the
     backdrop-filter forces the whole .device subtree through an offscreen surface
     on every scroll frame. */
  .ph-tabs{backdrop-filter:none;background:var(--a-bg);}
  /* grain the eye cannot resolve at 3×, for a permanent full-viewport layer */
  body::after{display:none;}

  /* The phone swaps screens alone: the outgoing one is gone at 240ms, the incoming
     starts at 300ms. Per-element timing, so no velocity can ever show two at once. */
  .appscreen{transform:none;}
}
@media (max-width:900px) and (prefers-reduced-motion:no-preference){
  .appscreen{transform:none;transition:opacity .24s cubic-bezier(.4,0,1,1);}
  .appscreen[data-active]{transform:none;transition:opacity .32s .30s cubic-bezier(.2,.8,.2,1);}
}



/* ── Audit fixes (2026-07-14): contrast, focus, hero form, reduced-motion ── */
:root{--ink-faint:#6E6153; --cta:#9E4A1E; --cta-fg:#fff;}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--ink-faint:#A99C8D; --cta:#E07848; --cta-fg:#1C1714;}}
:root[data-theme="dark"]{--ink-faint:#A99C8D; --cta:#E07848; --cta-fg:#1C1714;}
.heroform{margin-top:26px;max-width:460px;}
.heroin{margin-top:26px;font-family:var(--serif);font-size:21px;line-height:1.35;color:var(--ink);}
.sr-only:focus{position:fixed;top:12px;left:12px;width:auto;height:auto;clip:auto;padding:10px 16px;background:var(--cta);color:#fff;border-radius:8px;z-index:200;}
.ph-tab:focus-visible,.selchip:focus-visible,.navcta:focus-visible,.footlinks a:focus-visible,.micro a:focus-visible{outline:2px solid var(--clay-deep);outline-offset:2px;border-radius:6px;}
@media (prefers-reduced-motion:reduce){.js .sc-step{opacity:1 !important;}}
@media (max-width:480px){.fieldrow{flex-direction:column;} .fieldrow input,.fieldrow .cta{width:100%;} .heroform .cta{justify-content:center;}}


/* ═══════════════════════════════════════════════════════════════════════════
   UPGRADE 2026-07-15 — more air, bigger display type, and the download moment.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Sections breathe: the old clamp(64,9vw,112) read cramped next to the type. */
section{padding:clamp(88px,12vw,172px) 0;}
h2{font-size:clamp(30px,5vw,56px);line-height:1.02;letter-spacing:-.022em;}
.lead{font-size:clamp(17px,1.5vw,20px);line-height:1.6;}
.band .lead,.reframe .lead{max-width:62ch;}
.phasenote{margin-top:16px;font-size:14.5px;color:var(--ink-faint);font-style:italic;max-width:62ch;}
.trust .icons{margin-top:clamp(28px,4vw,44px);}

/* ── The download moment ─────────────────────────────────────────────────── */
.join{background:var(--paper-2);border-top:1px solid var(--line-soft);}
.joincol{max-width:660px;text-align:center;}
.joincol .eye{color:var(--clay-deep);}
.joinlead{margin:20px auto 0;}
.joincol .form{margin:clamp(26px,3.4vw,38px) auto 0;}
.joincol .formmsg{text-align:center;}
.joincol .micro{text-align:center;}

/* Availability: deliberately inert. No href, no button — it must never read as
   something you can tap to install today. */
.stores{display:flex;flex-direction:column;align-items:center;gap:12px;margin-top:clamp(28px,3.6vw,40px);}
.store{display:inline-flex;align-items:center;gap:11px;padding:11px 20px;border-radius:14px;
  border:1px solid var(--line);background:var(--paper-3);color:var(--ink-faint);cursor:default;}
.store svg{width:22px;height:22px;flex:none;opacity:.75;}
.store .st{display:flex;flex-direction:column;line-height:1.15;text-align:left;}
.store .st b{font-size:14px;font-weight:600;color:var(--ink-soft);}
.store .st i{font-size:11.5px;font-style:normal;letter-spacing:.04em;}
.storenote{font-size:12.5px;color:var(--ink-faint);}

/* success state inherits the centred column */
.success .chips{justify-content:center;}
.success .q{text-align:center;}

/* ── Cited research: quiet and precise. Credibility, not a billboard. ────── */
.cite{max-width:720px;margin:clamp(30px,4vw,46px) auto 0;padding:24px 26px;border-radius:16px;
  background:var(--paper-3);border:1px solid var(--line-soft);
  font-size:15px;line-height:1.6;color:var(--ink-soft);text-align:left;}
.cite .k{display:block;font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  font-weight:700;color:var(--ink-faint);margin-bottom:10px;}
.cite a{display:inline-block;margin-top:10px;font-size:13px;color:var(--ink-faint);text-decoration:none;
  border-bottom:1px solid var(--line);}
.cite a:focus-visible{outline:2px solid var(--clay-deep);outline-offset:3px;border-radius:3px;}


/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE POLISH 2026-07-15 — everything below ≤900px only; desktop is untouched.
   ═══════════════════════════════════════════════════════════════════════════ */

/* iOS zooms the LAYOUT viewport on focus of any input under 16px and never zooms
   back out. The hero form is the first thing most visitors tap, and after that
   every svh, every rect and the whole cinema solve resolve against a 1.067×
   viewport. 16px is the only value Safari accepts (maximum-scale would "fix" it
   by breaking pinch-zoom — a WCAG 1.4.4 failure). */
@media (max-width:900px){ .fieldrow input{font-size:16px;letter-spacing:-.005em;} }

@media (max-width:900px){
  /* The sticky bar cost 74px of a 667px fold and then sat across the docked
     phone's Dynamic Island and status bar for the whole tour — the fastest way to
     stop a pixel-accurate mockup reading as a real phone. The hero form is in the
     fold and #join closes the page, so nothing is lost by letting it scroll away. */
  header{position:static;backdrop-filter:none;}
  header.stuck{background:none;border-bottom-color:transparent;}

  /* touch targets → 44px, without changing how any of them look */
  .navcta{min-height:44px;display:inline-flex;align-items:center;padding:0 18px;}
  .selchip{min-height:44px;padding:0 16px;display:inline-flex;align-items:center;}
  .chips{gap:12px;}
  .footlinks a{display:inline-flex;align-items:center;min-height:44px;padding:0 10px;}
  .footrow{flex-direction:column;align-items:center;text-align:center;gap:20px;}
  .footlinks{gap:8px;}

  /* The badge is deliberately inert, but on touch there is no cursor:default to
     say so — it's just a button that does nothing when you tap it. Make it read
     as the status line it actually is. */
  .store{background:none;border:0;padding:0;pointer-events:none;-webkit-user-select:none;user-select:none;}

  /* .wrap's 28px + .cite's 26px double-padded the measure down to ~36ch. Let it
     full-bleed: ~44ch, and an inset band suits the literary voice better than a card. */
  .cite{margin-inline:-28px;border-radius:0;padding:22px 24px;}
  /* inline-block drew a full-width rule under a 2-line citation */
  .cite a{display:inline;border-bottom:0;text-decoration:underline;
    text-decoration-color:var(--line);text-underline-offset:3px;box-decoration-break:clone;}

  .contrast .col{padding:18px 16px;}
  .contrast li{text-wrap:pretty;}
  /* centred body copy stops reading as premium under ~45ch; at 30ch it's a wall.
     The eyebrow and h2 stay centred — they're short and balanced. */
  .band .lead,.trust .lead,.joinlead{text-align:left;margin-left:0;margin-right:0;}
  .lead{text-wrap:pretty;}
}
/* 322 × .86 = 277, which still overflows a 320px viewport's 280px column */
@media (max-width:380px){
  .cinema.cin-static .cin-stage .device{transform:scale(.78);}
}
/* a 2×2 of ragged 2-line labels; one calm list reads better and costs less height */
@media (max-width:400px){
  .trust .icons{grid-template-columns:1fr;gap:10px;}
  .ic{display:flex;align-items:center;gap:14px;text-align:left;padding:14px 16px;}
  .ic svg{margin-bottom:0;}
}

/* iOS paints a grey rectangle on every tap — including inside the phone mockup.
   Suppress it, then give the things that ARE tappable real feedback back. */
html{-webkit-tap-highlight-color:transparent;}
.cta:active{transform:scale(.985);}
.selchip:active{background:var(--paper-2);}

/* :hover sticks after a tap on iOS — the nav pill stays lit for the rest of the
   session. Fence the four hover rules to real pointers; desktop is hover:hover
   and pointer:fine, so it resolves exactly as before. */
@media (hover:hover) and (pointer:fine){
  .navcta:hover{border-color:var(--clay); background:var(--paper-2);}
  .cta:hover{filter:brightness(1.06); transform:translateY(-1px);}
  .footlinks a:hover{color:var(--clay);}
  .cite a:hover{color:var(--clay);border-bottom-color:var(--clay);}
}

/* ═══════════════════════════════════════════════════════════════════════════
   FINAL POLISH — 2026-07-23, the pre-advertising pass.
   Appended last on purpose: every rule below overrides something above it.
   NOTHING here adds transform / filter / contain to .cinema, .cin-rail or
   .sc-steps — any of those silently becomes .sc-step's sticky containing block
   and kills the whole tour.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · Light mode shipped with --ink-faint === --ink-soft (both #6E6153 after the
       override at :586), so the three-level ink hierarchy collapsed to two and
       every .micro read as body copy. Darken soft and leave faint alone: 6.5:1
       and 4.9:1 on --paper, so both still clear AA comfortably. */
:root{--ink-soft:#5A4E42;}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--ink-soft:#B6A99B;}}
:root[data-theme="dark"]{--ink-soft:#B6A99B;}

/* 2 · `<section class="wrap">` (the trust block) — .wrap is (0,1,0) and beat
       `section` at (0,0,1), so its `padding:0 28px` shorthand zeroed the block
       padding. It was the one section on the page with no breathing room at all
       and it collided with both neighbours. */
section.wrap{padding-top:clamp(72px,7.6vw,110px);padding-bottom:clamp(72px,7.6vw,110px);}

/* 3 · Section rhythm. 12vw pinned at the 172px ceiling on any viewport ≥1434px,
       so every boundary between two sections was 344px of dead space while the
       rhythm INSIDE a section was ~34px — a 10:1 mismatch that reads as
       disconnection rather than air. 220px outer / 56px inner is a clean 4:1,
       and it takes ~1,100px off the page. */
section{padding:clamp(72px,7.6vw,110px) 0;}
.contrast{margin:clamp(36px,4vw,56px) auto 0;}
.cite{margin:clamp(36px,4vw,56px) auto 0;}
footer{padding:clamp(44px,4.4vw,64px) 0 clamp(52px,5.2vw,76px);}

/* 4 · The "Scroll" cue had exactly ONE rule and it lived inside the ≤900px block,
       so above 900px it rendered as a raw 17px paragraph floating in the left
       margin of the beauty shot — on the page's single biggest beat. Kept in
       normal flow in the left rail lane (the one lane the phone never enters)
       and styled as a deliberate editorial micro-label. */
@media (min-width:901px){
  .cin-cue{display:flex;align-items:center;gap:12px;margin:0;
    padding-top:clamp(20px,4vh,44px);
    font-family:var(--sans);font-size:11px;letter-spacing:.24em;
    text-transform:uppercase;color:var(--ink-faint);}
  .cin-cue .ln{display:block;width:34px;height:1px;flex:none;
    background:linear-gradient(90deg,var(--line),transparent);}
}

/* 5 · Light-mode surfaces. --paper-3 (#FBF8F2) sits 1.06:1 against --paper
       (#EFE9DE), so the research card, the "Most apps" card, the email field and
       the store badge all dissolved into the page. The fill can't carry the
       separation at this warmth — the hairline has to. */
@media (prefers-color-scheme:light){
  :root:not([data-theme="dark"]){--line:#D3C7B6;}
  :root:not([data-theme="dark"]) .cite,
  :root:not([data-theme="dark"]) .contrast .dont{box-shadow:0 1px 2px rgba(42,33,27,.04);}
}
:root[data-theme="light"]{--line:#D3C7B6;}

/* 6 · .contrast .do was white on --clay: 3.0:1 in dark, below AA on the card that
       carries the brand's entire promise. --cta/--cta-fg is the pair already
       tuned for AA in both themes, so reuse it instead of inventing a third. */
.contrast .do{background:var(--cta);color:var(--cta-fg);}
.contrast .do .ct{color:color-mix(in srgb,var(--cta-fg) 78%,transparent);}

/* 7 · .formmsg.err was a hardcoded #B4472C — 3.3:1 on the dark paper, on the one
       message a user absolutely has to be able to read. */
:root{--err:#A33C1C;}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--err:#F0937A;}}
:root[data-theme="dark"]{--err:#F0937A;}
.formmsg.err{color:var(--err);}

/* 8 · The header pill is the page's only persistent conversion path and its
       border was a 1.1:1 hairline on light — effectively invisible. */
.navcta{border-color:color-mix(in srgb,var(--ink) 30%,transparent);}

/* 9 · The ambient halo is a warm glow on dark but a grey-brown smudge on light:
       a mid-tone clay wash blurred over warm paper goes muddy. Blush at lower
       strength keeps the "light in the room" read. */
@media (prefers-color-scheme:light){
  :root:not([data-theme="dark"]) .cin-halo{
    background:radial-gradient(circle at 50% 46%, color-mix(in srgb,var(--blush) 24%,transparent), transparent 70%);
    opacity:.72;}
}

/* 10 · The .reframe gradient never returned to transparent, so it hard-cut at the
        section's bottom edge instead of dissolving into the next one. */
.reframe{background:linear-gradient(180deg, transparent,
  color-mix(in srgb,var(--phase-l) 26%, transparent) 38%,
  color-mix(in srgb,var(--phase-o) 20%, transparent) 72%, transparent);}

/* 11 · MOBILE — the hero email field + CTA rendered 224px wide on a 390px phone
        (the join form is 334px). .fieldrow's children get width:100%, but the
        width they fill is .heroform's shrink-to-fit box, which collapses to the
        input's size=20 intrinsic width. The single most important element on the
        page for paid traffic was rendering at 63% of its column. Height is
        unchanged, so introTail / peekTop and the phone's peek are untouched. */
@media (max-width:900px){
  .cin-intro .heroform{width:100%;max-width:min(420px,100%);margin-left:auto;margin-right:auto;}
}

/* 12 · MOBILE — the header is deliberately static ≤900px (it used to bisect the
        phone's Dynamic Island and ate 74px of the fold), but nothing replaced it,
        leaving ~7,000px — eight viewports — between the hero form and #join with
        nothing to tap. This pill is a direct child of <body>, NOT inside .cinema,
        so it can never become a containing block for anything in the tour. It
        only appears after the cinema and hides again once #join is on screen. */
.mcta{display:none;}
@media (max-width:900px){
  .mcta{display:inline-flex;align-items:center;justify-content:center;
    position:fixed;left:50%;bottom:calc(14px + env(safe-area-inset-bottom));
    z-index:70;min-height:48px;padding:0 26px;border-radius:30px;
    font-family:var(--sans);font-size:15px;font-weight:600;text-decoration:none;
    background:var(--cta);color:var(--cta-fg);
    box-shadow:0 6px 22px rgba(0,0,0,.18);
    transform:translate(-50%,140%);transition:transform .3s var(--ease),opacity .3s var(--ease);
    opacity:0;pointer-events:none;}
  .mcta.on{transform:translate(-50%,0);opacity:1;pointer-events:auto;}
}
@media (prefers-reduced-motion:reduce){.mcta{transition:none;}}

/* 13 · The cinema's grid column was `1fr`, whose automatic minimum is the
        min-content of its widest item — the phone, which is a hard 322px wide.
        At a 320px viewport that forced the whole grid 2px past the fold and the
        page scrolled sideways. minmax(0,1fr) lets the column shrink; the phone is
        transformed, not laid out, so nothing about the tour moves. (Layout only —
        no transform/filter/contain, so .sc-step's sticky container is untouched.) */
.cinema{grid-template-columns:minmax(0,1fr);}

/* 14 · Tap targets. The privacy links in the two form footnotes were 16px tall —
        under even the WCAG 2.5.8 minimum of 24px, on the one page that is about to
        take mobile ad traffic — and the header pill was 42px. Padding-block rather
        than a font bump so the line's look is unchanged. */
.micro a{display:inline-block;padding-block:6px;}
.navcta{display:inline-flex;align-items:center;min-height:44px;}
/*      The footer links are standalone targets (not inline in a sentence, so the
        WCAG 2.5.8 text exception doesn't cover them) and were 22px tall.
        inline-FLEX, not inline-block: the ≤600px block above sets min-height:44px
        and leans on align-items to centre the label, and this rule is appended
        last, so inline-block would win and un-centre them. */
.footlinks a{display:inline-flex;align-items:center;padding-block:6px;}

/* 15 · Adding TikTok made the footer a FOUR-link row — 307px of links inside a
        264px column at 320px wide — so the page scrolled sideways again. Same
        class of bug as the phone's 322px min-content, but reintroduced by CONTENT
        rather than layout: .footrow already wraps, .footlinks never did. */
.footlinks{flex-wrap:wrap;justify-content:center;}
