/* Vyro Health - site.css (v3 "The Quattro" relaunch)
   Spec: design/direction-v3.md (tokens B.3, type C.2, layout E, motion F) + design/master-decisions-v3.md.
   One text family (Schibsted Grotesk, variable 400-600), wordmark as inline SVG.
   Two acts: dark (.dark: nav, hero, trust, what's in it, on the night, final tile, sticky bar) and light (canvas).
   Radius system {999, 20, 12, 0}. One shadow (product). Ember is the only hue. Hyphen-only copy. */

/* ---------- Fonts ---------- */
@font-face {
  font-family: "Schibsted Grotesk";
  src: url("/fonts/schibsted-grotesk-latin.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Schibsted Grotesk";
  src: url("/fonts/schibsted-grotesk-italic-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/* ---------- Tokens (direction-v3 B.3) ---------- */
:root {
  /* Palette A "Midnight tungsten" (direction-v5 §1.1, master-decisions-v5 §10.11). Dark act = field, light act = canvas. */
  --field: #0B0F15;
  --field-2: #151B24;
  --field-3: #1E2630;
  --ink: #F4F1EA;
  --ink-muted: #AAB2BC;
  --accent: #E9531B;
  --accent-ink: #B93E10;
  --accent-light: #FFB48A;
  --canvas: #F6F4EF;
  --canvas-2: #ECE9E2;
  --paper: #FBFAF7;
  --light-ink: #0F1318;
  --light-muted: #4E5661;
  --skin-light: #F2C4A0;             /* grade target + pool colour ONLY, never text */
  --hairline-dark: #232B36;
  --hairline: #D9D5CC;
  --hairline-strong: #C4BFB5;
  --focus-light: #B93E10;
  --focus-dark: #FFB48A;
  --warn: #B3261E;
  --shadow-product: 0 24px 48px -16px rgba(11, 15, 21, 0.22);
  /* polish-v4 §0 pools re-tokenised (direction-v5 §3): warm centre = accent-light 10 percent, lift = ink 5 percent */
  --pool-warm: rgba(255, 180, 138, 0.10);
  --pool-lift: rgba(244, 241, 234, 0.05);
  --floor-shadow: rgba(15, 19, 24, 0.65);
  --field-0: rgba(11, 15, 21, 0);            /* transparent field: every pool ends here, never through a grey */
  --hair-w: 1px;                             /* hairlines: 1 px at 1x, 0.5 px at 2x+ (§5.2) */

  --font: "Schibsted Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* type scale v3 (direction-v3 C.2): literal three steps, px / px line-height.
     < 768 = phone, 768-1023 = tablet, >= 1024 = desktop. No clamp(). */
  --fs-product: 20px; --lh-product: 26px;
  --fs-h1: 38px;      --lh-h1: 40px;      --ls-h1: -0.03em;
  --fs-display: 72px; --lh-display: 72px; --ls-display: -0.04em;
  --fs-price: 80px;   --lh-price: 80px;   --ls-price: -0.04em;
  --fs-h2: 34px;      --lh-h2: 38px;      --ls-h2: -0.02em;
  --fs-h3: 22px;      --lh-h3: 28px;
  --fs-lead: 20px;    --lh-lead: 29px;    --ls-lead: 0;
  --fs-body: 18px;    --lh-body: 28px;
  --fs-small: 16px;   --lh-small: 24px;
  --fs-caption: 14px; --lh-caption: 22px; --ls-caption: 0.005em;
  --fs-label: 14px;   --lh-label: 20px;
  --fs-badge: 16px;   --lh-badge: 24px;
  --fs-ledger-label: 16px; --lh-ledger-label: 24px;
  --fs-stepnum: 32px; --lh-stepnum: 36px;
  --fs-active: 24px; --lh-active: 28px;   /* polish-v4 §3: active name, all widths */
  --fs-faq: 18px;     --lh-faq: 25px;
  --fs-menu: 26px;    --lh-menu: 32px;

  --container: 1200px;
  --container-wide: 1360px;
  --measure: 720px;
  /* Line-length caps for the 55-70 characters gate. Schibsted Grotesk 1ch = 0.61em, so the caps are set
     to the pixel widths the spec intends: body 47ch = 517 px at 18 px (max 69 characters per line);
     fine print 51ch = 437 px at 14 px (max 69). Measured in v2 with QA/tools/measure.mjs. */
  --measure-body: 47ch;
  --measure-fine: 51ch;
  --pad: 20px;
  --gutter: 16px;
  --section: 64px;
  --section-gap: 56px;
  --card-pad: 24px;
  --nav-h: 64px;
  --bar-h: 72px;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);          /* every entrance, reveal, open (motion-spec-v3 §1) */
  --ease-hover: ease;                               /* colour changes on hover only */
  --ease-move: cubic-bezier(0.77, 0, 0.175, 1);    /* on-screen re-position only: the FAQ glyph */
  --t-fast: 160ms;
  --t-press: 100ms;
  --t-med: 240ms;
  --t-bar: 280ms;
  --t-reveal: 440ms;
  --t-rule: 500ms;
  --t-settle: 600ms;

  /* theme variables: light act defaults; .dark flips them */
  --surface: var(--canvas);
  --text: var(--light-ink);
  --text-muted: var(--light-muted);
  --rule: var(--hairline);
  --rule-strong: var(--hairline-strong);
  --link: var(--accent-ink);
  --fn-color: var(--accent-ink);
  --focus: var(--focus-light);
  --numeral: var(--accent);
}
@media (min-width: 768px) {
  :root {
    --pad: 32px; --gutter: 24px; --section: 88px; --section-gap: 72px; --card-pad: 28px;
    --fs-product: 22px; --lh-product: 28px;
    --fs-h1: 46px; --lh-h1: 48px;
    --fs-display: 96px; --lh-display: 96px;
    --fs-price: 96px; --lh-price: 96px;
    --fs-h2: 40px; --lh-h2: 44px;
    --fs-lead: 21px; --lh-lead: 30px;
    --fs-h3: 24px; --lh-h3: 30px;
    --fs-stepnum: 38px; --lh-stepnum: 42px;
  }
}
@media (min-width: 1024px) {
  :root {
    --section: 120px; --section-gap: 96px; --nav-h: 72px; --card-pad: 32px;
    --fs-product: 24px; --lh-product: 30px;
    --fs-h1: 64px; --lh-h1: 64px; --ls-h1: -0.035em;   /* direction-v5 §5: 64/64, 3 lines max at 1440 (measured 3, see craft-notes-v5-r1 §2); 1024-1279 band below */
    --fs-display: 128px; --lh-display: 120px; --ls-display: -0.045em;
    --fs-price: 120px; --lh-price: 112px; --ls-price: -0.045em;
    --fs-h2: 52px; --lh-h2: 56px; --ls-h2: -0.025em;
    --fs-h3: 26px; --lh-h3: 32px;
    --fs-lead: 22px; --lh-lead: 32px; --ls-lead: -0.005em;
    --fs-label: 15px;
    --fs-badge: 17px;
    --fs-ledger-label: 18px; --lh-ledger-label: 28px;
    --fs-stepnum: 48px; --lh-stepnum: 52px;
    --fs-faq: 20px; --lh-faq: 27px;
  }
}
@media (min-width: 1024px) and (max-width: 1279px) {
  :root { --fs-h1: 52px; --lh-h1: 54px; --fs-display: 112px; --lh-display: 108px; --fs-price: 104px; --lh-price: 100px; }   /* 1024-1279 band: the 6-column copy slot holds 52 px at 3 lines (master-decisions §7.3 principle) */
}
@media (min-width: 1280px) {
  :root { --pad: 48px; }
}

/* dark act: same tokens, flipped roles */
.dark {
  --surface: var(--field);
  --text: var(--ink);
  --text-muted: var(--ink-muted);
  --rule: var(--hairline-dark);
  --rule-strong: var(--hairline-dark);
  --link: var(--accent-light);
  --fn-color: var(--accent-light);
  --focus: var(--focus-dark);
  --numeral: var(--accent-light);
  background: var(--field);
  color: var(--ink);
}
/* hairlines (§5.2): 1 px at 1x, 0.5 px on 2x+ screens */
@media (min-resolution: 2dppx) { :root { --hair-w: 0.5px; } }

/* ---------- Reset (minimal) ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: calc(var(--nav-h) + 16px);
  background: var(--canvas);
}
@media (max-width: 1023px) {
  html { scroll-padding-bottom: 96px; }   /* anchors never land behind the sticky CTA bar (72 px, 85 px when its price line wraps at 390) */
}
html:focus-within { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html:focus-within { scroll-behavior: auto; }
}
body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--light-ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-variant-numeric: lining-nums;
  font-optical-sizing: auto;
  overflow-x: clip;
}
h1, h2, h3, h4, p, ul, ol, dl, dd, figure, table { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg, picture { display: block; max-width: 100%; }
img { height: auto; }
a { color: var(--link); text-decoration-thickness: 2px; text-underline-offset: 4px; }
a:hover { text-decoration-thickness: 3px; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
strong, b { font-weight: 500; }
em, i { font-style: italic; font-weight: 400; }
sup { line-height: 0; }
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 6px;
}
::selection { background: var(--accent-light); color: var(--field); }
.dark ::selection { background: var(--accent-light); color: var(--field); }

/* ---------- Type roles ---------- */
.h1, .h2, .h3, .display { text-wrap: balance; overflow-wrap: anywhere; }
.h1 {
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  letter-spacing: var(--ls-h1);
  font-weight: 600;
  max-width: 14em;   /* the spec's 15ch in Schibsted (1ch = 0.61em) would be 9em; 14em holds "One dose, under the tongue." on one line at 1440 */
}
.h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  font-weight: 600;
  max-width: 24ch;
}
.h3 {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: -0.01em;
  font-weight: 500;
}
.lead {
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  letter-spacing: var(--ls-lead);
  font-weight: 400;
  max-width: 44ch;
}
p { max-width: var(--measure-body); }
.small { font-size: var(--fs-small); line-height: var(--lh-small); }
.caption {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--ls-caption);
  color: var(--text-muted);
  max-width: var(--measure-fine);
}
.product-line {
  font-size: var(--fs-product);
  line-height: var(--lh-product);
  font-weight: 500;
  color: var(--accent-light);
  max-width: none;
}
.display {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  font-weight: 600;
  font-variant-numeric: tabular-nums lining-nums;
  text-rendering: geometricPrecision;
  color: var(--numeral);
}
.muted { color: var(--text-muted); }

/* ---------- Layout primitives ---------- */
.container { width: 100%; max-width: calc(var(--container) + 2 * var(--pad)); margin-inline: auto; padding-inline: var(--pad); }
.container-wide { width: 100%; max-width: calc(var(--container-wide) + 2 * var(--pad)); margin-inline: auto; padding-inline: var(--pad); }
.measure { max-width: var(--measure); }
/* Section rhythm: light sections carry a single gap to their predecessor; act edges use the full padding. */
.section { padding-top: var(--section-gap); }
.section--act-start { padding-top: var(--section); border-top: var(--hair-w) solid var(--hairline); }
.section--last { padding-bottom: var(--section); }
.dark.section { padding-top: var(--section-gap); }
.dark.section--act-end { padding-bottom: var(--section); }
.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); }

/* ---------- Stage recipe (polish-v4 §0): an alpha cutout standing in CSS light on the section field ----------
   ::before = light pool (two radial gradients, both to transparent graphite by 62 percent of their radius),
   ::after = floor shadow (flat ellipse under the base). Per-stage geometry comes from custom properties set inline
   or per breakpoint. overflow: clip, not hidden: a stage is never a scroll container. Nothing here has a fill. */
.stage {
  position: relative;
  isolation: isolate;
  overflow: clip;
  margin: 0;
  --pool-x: 50%; --pool-y: 40%; --pool-w: 240px; --pool-h: 280px;
  --floor-x: 50%; --floor-y: 6px; --floor-w: 0px; --floor-h: 0px;
}
.stage::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* --pool-w / --pool-h are the pool's full width and height (the spec's numbers); the gradient takes radii, so half.
     Read as radii the 390 hero pool would leave the stage at the top and print a seam; read as sizes it ends >= 33 px inside. */
  background:
    radial-gradient(ellipse calc(var(--pool-w) / 2) calc(var(--pool-h) / 2) at var(--pool-x) var(--pool-y),
      var(--pool-warm) 0%, rgba(255, 180, 138, 0.05) 38%, var(--field-0) 62%),
    radial-gradient(ellipse calc(var(--pool-w) * 0.4) calc(var(--pool-h) * 0.4) at var(--pool-x) var(--pool-y),
      var(--pool-lift) 0%, var(--field-0) 60%);
}
.stage::after {
  content: "";
  position: absolute;
  z-index: 0;
  pointer-events: none;
  left: var(--floor-x);
  bottom: var(--floor-y);
  width: var(--floor-w);
  height: var(--floor-h);
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 50%, var(--floor-shadow) 0%, rgba(15, 19, 24, 0.25) 45%, var(--field-0) 72%);
}
.stage > img, .stage > picture { position: relative; z-index: 1; display: block; }

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 100;
  background: var(--ink);
  color: var(--field);
  padding: 12px 20px;
  border-radius: 999px;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 500;
  text-decoration: none;
}
.skip-link:focus { top: 12px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 0 28px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--light-ink);
  font-size: 18px;
  line-height: 1;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  /* a top light catch and a 1 px ground contact; no glow, no gradient (§5.5) */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 1px 0 rgba(0, 0, 0, 0.25);
  transition: background-color var(--t-fast) var(--ease-hover), color var(--t-fast) var(--ease-hover), transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease-hover);
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--accent-ink); color: var(--ink); }
}
.btn:active { background: var(--accent-ink); color: var(--ink); transform: translateY(1px); box-shadow: 0 0 0 rgba(0, 0, 0, 0); transition-duration: var(--t-press); }
.btn:focus-visible { outline-offset: 3px; border-radius: 999px; }
.btn--nav { min-height: 48px; padding: 0 20px; font-size: 16px; }
/* any button on graphite-2 carries the hairline-dark border (B.4 boundary rule) */
.compare .btn { border: var(--hair-w) solid var(--hairline-dark); }
.btn--disabled {
  background: var(--canvas-2);
  color: var(--light-muted);
  pointer-events: none;
}

.link-secondary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 48px;
  font-weight: 500;
  font-size: 18px;
  line-height: 1;
  color: var(--link);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.link-secondary { text-decoration-thickness: 2px; text-underline-offset: 5px; }
.link-secondary .icon { width: 18px; height: 18px; transition: transform var(--t-fast) var(--ease); }
.link-secondary:hover { text-decoration-thickness: 2px; }
@media (hover: hover) and (pointer: fine) {
  .link-secondary:hover .icon { transform: translateY(2px); }
}

/* inline text links: 48 px hit box without moving the line */
.text-link {
  font-weight: 500;
  display: inline-block;
  padding-block: 12px;
  margin-block: -12px;
}
/* prose links in the disclaimer, footer legal text and reading pages: 48 px hit box by vertical padding, no layout change */
.disclaimer p a, .footer__disclaimer p a, .faq__panel p a, .prose p a, .cta-note a {
  display: inline-block;
  padding-block: 14px;
  margin-block: -14px;
  position: relative;
  z-index: 1;
}

/* ---------- Footnotes ---------- */
sup.fn { font-size: max(0.7em, 14px); line-height: 0; vertical-align: baseline; position: relative; top: -0.45em; }
sup.fn a {
  display: inline-block;
  min-width: 48px;
  min-height: 48px;
  line-height: 48px;
  text-align: center;
  vertical-align: baseline;
  font-weight: 600;
  color: var(--fn-color);
  text-decoration: none;
  margin: -24px -19px;   /* 48 x 48 hit box centred on the marker; the margin box is 0 x 10 px so the line box does not grow */
  position: relative;
  z-index: 1;
}
sup.fn a:hover { text-decoration: underline; }
.footnotes {
  margin-top: 40px;
  padding-top: 16px;
  border-top: var(--hair-w) solid var(--rule);
  max-width: var(--measure-fine);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--text-muted);
}
.footnotes li { position: relative; padding-left: 20px; }
.footnotes li + li { margin-top: 8px; }
.footnotes .fn-num { position: absolute; left: 0; top: 0; font-weight: 600; color: var(--fn-color); transition: color 600ms var(--ease-hover); }
.footnotes li:target { color: var(--text); }
.footnotes li.is-hit .fn-num { color: var(--accent); transition: none; }   /* to ember instantly, back over 600 ms (F.14) */
.dark .footnotes li.is-hit .fn-num { color: var(--accent-light); }

/* ---------- Nav (direction-v5 §5.7): a translucent layer of the field, 82 percent + 14 px blur, film frames scroll under it ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(11, 15, 21, 0.82);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  height: var(--nav-h);
  color: var(--ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
@media (prefers-reduced-transparency: reduce) {
  .nav { background: var(--field); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
.nav::before {
  /* iOS 26 Safari paints the page under its top toolbar strip while the bar sticks below it (Master patch 25.09.):
     extend the bar's graphite upward so scrolled copy never shows above the bar. Off-canvas at scroll 0, no overflow. */
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 240px;
  background: var(--field);
  pointer-events: none;
}
.nav .btn--nav { box-shadow: none; }
.nav::after {
  /* hairline under the bar once the page has scrolled (sentinel + IntersectionObserver, no scroll listener) */
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 1px;
  background: var(--hairline-dark);
  opacity: 0;
  transition: opacity var(--t-fast) var(--ease-hover);
}
.nav.is-scrolled::after { opacity: 1; }
.nav-sentinel { position: absolute; top: 0; left: 0; width: 1px; height: 1px; pointer-events: none; }
main { position: relative; }
.nav__inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.nav__brand {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  color: var(--ink);
  text-decoration: none;
}
.nav__brand .wordmark { height: 30px; width: auto; }
.nav__links { display: none; }
.nav__cta { display: inline-flex; align-items: center; gap: 8px; }
.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  color: var(--ink);
}
.nav__toggle .icon { width: 24px; height: 24px; }
.nav__toggle .icon-x { display: none; }
.nav__toggle[aria-expanded="true"] .icon-list { display: none; }
.nav__toggle[aria-expanded="true"] .icon-x { display: block; }

/* Mobile menu panel: in the DOM, hidden by visibility so it is not tabbable when closed. */
.nav__panel {
  position: fixed;
  inset: var(--nav-h) 0 0 0;
  z-index: 49;
  background: var(--field);
  padding: 32px var(--pad) 40px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: auto;
  overscroll-behavior: contain;
  visibility: hidden;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity var(--t-fast) var(--ease),
              transform 0s linear var(--t-fast),
              visibility 0s linear var(--t-fast);
}
.nav__panel.is-open {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition: opacity 200ms var(--ease),
              transform 200ms var(--ease),
              visibility 0s;
}
.nav__panel ul { display: grid; gap: 8px; }
.nav__panel a:not(.btn) {
  display: flex;
  align-items: center;
  min-height: 56px;
  font-size: var(--fs-menu);
  line-height: var(--lh-menu);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  border-bottom: var(--hair-w) solid var(--hairline-dark);
}
.nav__panel .btn { align-self: flex-start; margin-top: 32px; }
html.menu-open, body.menu-open { overflow: hidden; }
body.menu-open .btn--nav { visibility: hidden; }

@media (min-width: 1024px) {
  .nav__links { display: flex; align-items: center; gap: 8px; margin-left: auto; margin-right: 24px; }
  .nav__links a {
    display: inline-flex;
    align-items: center;
    min-height: 48px;
    padding: 0 12px;
    font-size: 17px;
    line-height: 24px;
    font-weight: 500;
    color: var(--ink);
    text-decoration: none;
    position: relative;
  }
  .nav__links a::after {
    /* 2 px ember-light underline, opacity only (F.13); no sliding line */
    content: "";
    position: absolute;
    left: 12px; right: 12px; bottom: 8px;
    height: 2px;
    background: var(--accent-light);
    opacity: 0;
    transition: opacity var(--t-fast) var(--ease-hover);
  }
  .nav__links a:hover::after, .nav__links a[aria-current="page"]::after, .nav__links a.is-current::after { opacity: 1; }
  .nav__toggle, .nav__panel { display: none !important; }
}

/* ---------- Mobile sticky CTA bar (D.13) ---------- */
.ctabar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  min-height: var(--bar-h);
  padding: 8px var(--pad) calc(8px + env(safe-area-inset-bottom, 0px));
  background: rgba(11, 15, 21, 0.82);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  color: var(--ink);
  border-top: var(--hair-w) solid var(--hairline-dark);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  transform: translateY(100%);
  visibility: hidden;
  transition: transform 220ms var(--ease), visibility 0s linear 220ms;
}
.ctabar.is-visible { transform: none; visibility: visible; transition: transform var(--t-bar) var(--ease), visibility 0s; }
@supports (animation-timing-function: linear(0, 1)) {
  .ctabar.is-visible { transition-timing-function: linear(0, 0.186 8%, 0.466 17%, 0.682 25%, 0.821 33%, 0.903 42%, 0.949 50%, 0.973 58%, 0.986 67%, 0.993 75%, 0.997 83%, 0.998 92%, 1); }
}
body.menu-open .ctabar { transform: translateY(100%); visibility: hidden; }
/* master-decisions §7.2 (AUDIT r1 F3): no price in the bar; one 16/24 line in --ink (never muted) beside the button */
.ctabar__text { display: block; min-width: 0; font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 500; color: var(--ink); text-wrap: balance; }   /* one line from 462 px up (232 px of text + 174 px button + gaps); at 390 it balances to two 24 px lines and the bar stays 72 */
.ctabar .btn { flex: none; min-height: 56px; padding: 0 20px; }
@media (prefers-reduced-transparency: reduce) { .ctabar { background: var(--field); -webkit-backdrop-filter: none; backdrop-filter: none; } }
html:not(.js) .ctabar { display: none; }
@media (min-width: 1024px) { .ctabar { display: none; } }

/* ---------- Hero (1): "the hand and the vial", one autoplaying film at every width (master-decisions-v6 §11.20 < 768, §11.21 / brief-v10 row B >= 768) ----------
   < 1024 = FILM FOLD: product line -> H1 -> CTA row -> note -> full-bleed film stage (60 svh, 9:16 hand film < 768, 16:9 hand film from 768) -> lead.
   .hero__copy is display: contents below 1024, so its children and the stage share one column and `order` puts the lead under the stage
   while the DOM keeps the reading order (product line, H1, lead, CTAs, note). The stage is masked 48 px into the field at its top and bottom
   (non-viewport edges); left and right are viewport edges. Two posters (one <picture> per breakpoint, the other hidden): the visible <img> = LCP;
   the <video> is opacity 0 until motion.js sees `playing` (frame 0 = the poster, so the fade only covers decoder start).
   >= 1024 = the 16:9 frame IS the hero: absolute behind the whole section (cover), copy in columns 1-7 on the frame's field-dark left 55 percent,
   the hand + vial group stands in the frame's own light right of centre (--film-x picks the crop side), footnote at the section's bottom left. */
.hero { position: relative; isolation: isolate; overflow: clip; padding-top: 24px; padding-bottom: 48px; }
.hero__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }
.hero__copy { display: contents; }
.hero__copy > * + * { margin-top: 16px; }
.hero__copy .h1 { margin-top: 12px; }
.hero .lead { max-width: 42ch; color: var(--ink-muted); }
.hero__ctas { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; margin-top: 24px; }
.cta-note { font-size: var(--fs-caption); line-height: var(--lh-small); color: var(--text-muted); margin-top: 12px; max-width: var(--measure-fine); }   /* master-decisions-v3 §8.2: 14/24 microcopy under the hero and final-tile buttons; --text-muted = stone-muted on .dark, ink-muted on light */
.hero__copy .cta-note { margin-top: 12px; }
/* film fold order (< 1024) */
.hero__copy > .product-line { order: 1; }
.hero__copy > .h1 { order: 2; }
.hero__copy > .hero__ctas { order: 3; }
.hero__copy > .cta-note { order: 4; }
.hero__stage { order: 5; }
.hero__copy > .lead { order: 6; margin-top: 28px; }
.hero__stage {
  position: relative;
  margin: 20px calc(-1 * var(--pad)) 0;
  height: 60vh;
  min-height: 420px;
  max-height: 640px;
  overflow: clip;
  --film-x: 50%; --film-y: 50%;   /* object-position of poster + film; < 768 overrides --film-y (r9 block), >= 768 --film-x (below) */
  --vig-x: 50%; --vig-y: 40%;     /* centre of the settle's vignette (::after): over the hand + vial group */
  --settle-s: 1.04; --settle-o: 0.85; --vig-o: 0.35;   /* r10.1 settle amplitudes < 768 (motion-spec-v10 §1: one grammar, three amplitudes) */
  -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 48px, #000 calc(100% - 48px), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%);
  mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 48px, #000 calc(100% - 48px), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%);
}
@supports (height: 1svh) { .hero__stage { height: 60svh; } }
.hero__pic, .hero__poster, .hero__film { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.hero__pic--desk { display: none; }   /* the 16:9 poster lives from 768 up; hidden here (and its <picture> hands this width a 1 px data URI, so nothing is fetched) */
.hero__poster, .hero__film { object-fit: cover; object-position: var(--film-x) var(--film-y); }
.hero__poster { z-index: 0; }
.hero__film { z-index: 1; opacity: 0; }
.hero__stage.is-playing .hero__film { opacity: 1; transition: opacity 240ms var(--ease); }   /* frame 0 = the poster: the fade is invisible, it only covers decoder start */
html:not(.motion-on) .hero__film { display: none; }
html:not(.motion-on) .hero__stage.is-playing .hero__film { display: block; opacity: 1; }   /* reduced motion / save-data + a tap on the play button: the film plays over the poster */
/* the one control: 48 x 48, ember stroke on the field; hidden until play() is refused (iOS Low Power) or motion is reduced (motion.js). Below 768 at 72 percent of the
   stage's height so it never covers the vial or its label (upper 60 percent); from 768 at 76 / 76 percent = under the hand + vial group, right of centre, clear of the
   copy columns. Same recipe as .scene__play / .actives__play. */
.hero__play { position: absolute; z-index: 3; left: 50%; top: 72%; width: 48px; height: 48px; margin: -24px 0 0 -24px; padding: 0; border: 1.5px solid var(--accent); border-radius: 50%;
  background: rgba(11, 15, 21, 0.72); color: var(--ink); display: grid; place-items: center; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hero__play svg { display: block; width: 20px; height: 20px; margin-left: 2px; }
.hero__play:hover { background: rgba(11, 15, 21, 0.9); }
.hero__play:focus-visible { outline: 2px solid var(--focus-dark); outline-offset: 3px; }
/* §11.20.2.3 (< 768, r9) extended to every width (§11.21 / brief-v10 "the same animations on desktop"): the scroll-linked settle, CSS only (.sda.motion-on). Over the
   first 320 px of the document the stage sharpens into place, scale 1.04 -> 1 and opacity 0.85 -> 1, while a soft radial vignette (::after, centred on --vig-x --vig-y:
   the hand + vial group) lifts 0.35 -> 0; the film is already playing, nothing pins. The rule outranks the once-per-session time entrance
   (.js:not(.hero-seen) [data-motion="hero"] .hero__stage, 4 classes) by the html type selector, so the stage has ONE animation in scroll-timeline engines; engines
   without them (Firefox) keep the time entrance. Reduced motion never carries .motion-on. Whitelist: transform + opacity only. >= 1024 the stage is the whole
   section (absolute, inset 0): the 1.04 stays inside .hero { overflow: clip } and the vignette sits under the copy (stage z 0 < copy z 1). */
@keyframes hero-settle { from { transform: scale(var(--settle-s, 1.04)); opacity: var(--settle-o, 0.85); } to { transform: none; opacity: 1; } }   /* r10.1: amplitudes per width via --settle-s/--settle-o (motion-spec-v10 §1) */
@keyframes hero-vignette { from { opacity: var(--vig-o, 0.35); } to { opacity: 0; } }
@supports (animation-timeline: scroll()) {
  html.sda.motion-on [data-motion="hero"] .hero__stage { animation: hero-settle linear both; animation-timeline: scroll(root); animation-range: 0 320px; }
  .sda.motion-on .hero__stage::after { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
    background: radial-gradient(ellipse 72% 64% at var(--vig-x) var(--vig-y), rgba(11, 15, 21, 0) 0%, rgba(11, 15, 21, 0) 42%, rgba(11, 15, 21, 0.9) 100%);
    animation: hero-vignette linear both; animation-timeline: scroll(root); animation-range: 0 320px; }
}
.hero .footnotes { margin-top: 40px; }
@media (min-width: 768px) {
  .hero { padding-top: 56px; }
  .hero__copy > * + * { margin-top: 24px; }
  .hero__ctas { margin-top: 36px; }
  .hero__stage { --film-x: 100%; --film-y: 50%; --vig-x: 62%; --vig-y: 55%; --settle-s: 1.03; --settle-o: 0.88; --vig-o: 0.30; margin-top: 24px; }   /* 16:9 frame from 768 in the ~1.25 film-fold box (height-bound, ~30 percent of the width cropped): the crop comes off the empty left 55 percent of the plate (beats.json: hand + vial in cols 57-89), so the group lands at 39-85 percent of the 768 box; the vignette is centred on it (0.73 of the frame -> 62 percent) */
  .hero__pic--hand { display: none; }   /* the 9:16 poster lives below 768 (its <picture> hands this width the 1 px data URI) */
  .hero__pic--desk { display: block; }
  .hero__play { left: 56%; top: 76%; }   /* under the vial (frame cols 0.62-0.75 -> 56 percent of the 768 box), on the hand, clear of the label rows (16-40 percent of the frame) */
  .hero .footnotes { max-width: none; }                       /* AUDIT r1 F10: the footnote rule spans the full container (grid-column 1 / -1 equivalent; the block sits after the grid) */
  .hero .footnotes li { max-width: var(--measure-fine); }     /* the text keeps the fine-print measure */
}
@media (min-width: 1024px) {
  .hero { display: flex; flex-direction: column; min-height: min(calc(100svh - var(--nav-h)), 900px); padding-top: 80px; padding-bottom: 56px; }
  .hero > .container-wide { flex: 1; display: flex; flex-direction: column; }
  .hero__grid { flex: 1; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); align-items: center; }
  .hero__copy { display: block; position: relative; z-index: 1; grid-column: 1 / span 7; }
  .hero__copy > * { order: 0; }
  .hero__copy > * + * { margin-top: 28px; }
  .hero__copy > .lead { margin-top: 28px; }
  .hero__ctas { margin-top: 40px; }
  .hero .h1 > span { display: block; }   /* two sentences, two lines at 1440 (C.2 hero fit check) */
  .hero__stage {
    position: absolute; inset: 0; z-index: 0; order: 0;
    margin: 0; height: auto; min-height: 0; max-height: none;
    --film-x: 30%; --film-y: 50%; --vig-x: 74%; --vig-y: 55%; --settle-s: 1.025; --settle-o: 0.90; --vig-o: 0.30;   /* the section box (1440 x 835 = 1.72) is close to 16:9: 44 px of the 1484 px frame leave, 30 percent of them on the left (13 px), so the group (plate cols 57-89) sits at 58-91 percent of the stage, 15 px right of the copy's 7th column (822 px), and the hand's right edge stays in frame down to 1024 wide; the vignette centre = the group's centre (0.73 of the frame) */
  }
  .hero__play { left: 70%; top: 76%; }   /* under the vial (frame cols 0.62-0.75 -> 70 percent of the stage at 1440), on the hand, below the label rows */
  .hero .footnotes { position: relative; z-index: 1; margin-top: 40px; max-width: 58.333%; }   /* 48 would push the hero to 909 px at 1440 x 900; the cap is 900. r5.1: the block (and its hairline) stays inside the copy's 7 columns so the rule does not cross the bottle in the frame (AUDIT r1 F10 asked for the full span in the two-column r4 layout; with the frame behind the section the rule must stop before the object) */
}

/* ---------- Trust strip (2): safety line + five badges ----------
   master-decisions §7.1 (AUDIT r1 F2/F8): no horizontal scroller, no scroll-snap, nothing hidden behind a swipe.
   < 768: one-column list, five rows, icon left, rows >= 48 px. 768-1023: grid 3 + 2. >= 1024: five across, unchanged. */
.trust { padding-top: 0; padding-bottom: 64px; }
.trust__line { font-size: var(--fs-small); line-height: var(--lh-small); color: var(--ink-muted); max-width: 500px; margin-bottom: 24px; }   /* 560 px rendered 76 characters at 16 px; 500 px keeps it under 70 */
.trust__row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  padding-block: 12px;
}
.trust__row::before, .trust__row::after { content: ""; position: absolute; left: 0; right: 0; height: var(--hair-w); background: var(--hairline-dark); transform-origin: left; }
.trust__row::before { top: 0; }
.trust__row::after { bottom: 0; }
.trust__row li {
  min-width: 0;
  min-height: 48px;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: var(--fs-badge);
  line-height: var(--lh-badge);
  font-weight: 500;
  color: var(--ink);
}
.trust__row .icon { flex: none; width: 24px; height: 24px; color: var(--ink); }
.trust__row li[hidden] { display: none; }
@media (min-width: 768px) {
  .trust__row { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px var(--gutter); padding-block: 20px; }
  .trust__row li { align-items: flex-start; min-height: 0; }
}
@media (min-width: 1024px) {
  .trust { padding-bottom: 88px; }
  .trust__row { display: flex; gap: var(--gutter); justify-content: space-between; }
  .trust__row li { flex: 1 1 0; align-items: center; }
}

/* ---------- What's in it (3): the hand-held vial FILM beside the H2 + four actives as one numbered unit (polish-v4 §2-§3; r10: brief-v10 row C, master §11.21) ----------
   The stage keeps its place and size logic from r6 / r6.2 (§11.16.3): 390 = first in the column, 300 px tall, the 4:5 film box (240 x 300) centred in it; 768 = cols 8-12,
   420 tall, the box width-bound in the column (bottom-aligned with the head); >= 1024 = 600 tall, the box 480 x 600. Inside the box: the <video> (bottom), the poster
   <img> over it until the film is playing (240 ms fade), the play button (only when autoplay is refused or motion is reduced); every edge of the box dissolves into
   the field (--fade), the .stage pool glows behind the fade. The vial act (the 96-frame canvas scrub that stood beside the list) is gone; the list keeps its columns. */
.actives.section { position: relative; overflow: clip; padding-top: var(--section); }   /* the banner slot is retired; the section has its own top edge once more */
.actives__open { display: grid; grid-template-columns: minmax(0, 1fr); }
.actives__head { margin-top: 8px; }   /* 390: the H2 begins 8 px under the stage, on solid field (the film's bottom edge is dissolved, so no line exists between image and text) */
.actives__head .lead { margin-top: 20px; color: var(--ink-muted); }
.actives__stage {
  order: -1;
  --stage-h: 300px;
  height: var(--stage-h);
  width: auto;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  --pool-x: 50%; --pool-y: 50%; --pool-w: 300px; --pool-h: 360px;
  --floor-w: 0px; --floor-h: 0px;
}
/* the film box: 4:5, as tall as the stage unless the column is narrower (768), never wider than it; the same edge dissolve as the night film (all four edges: the box
   stands inside the section, none of its edges is a viewport edge). #000 in the masks is alpha, not a colour. */
.actives__film {
  position: relative;
  z-index: 1;
  isolation: isolate;
  width: min(100%, calc(var(--stage-h) * 0.8));
  aspect-ratio: 4 / 5;
  --fade: 48px;
  -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%), linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%);
  mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%), linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%);
  -webkit-mask-composite: source-in; mask-composite: intersect;
}
.actives__video, .actives__poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; }
.actives__video { z-index: 0; background: var(--field); }
.actives__poster { z-index: 1; opacity: 1; transition: opacity 240ms var(--ease); }
.actives__film.is-playing .actives__poster { opacity: 0; }   /* the poster stays in the DOM under the film (no-JS / reduced-motion image) */
html:not(.motion-on) .actives__poster { transition: none; }
.actives__play { position: absolute; z-index: 2; left: 50%; top: 50%; width: 48px; height: 48px; margin: -24px 0 0 -24px; padding: 0; border: 1.5px solid var(--accent); border-radius: 50%;
  background: rgba(11, 15, 21, 0.72); color: var(--ink); display: grid; place-items: center; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.actives__play svg { display: block; width: 20px; height: 20px; margin-left: 2px; }
.actives__play:hover { background: rgba(11, 15, 21, 0.9); }
.actives__play:focus-visible { outline: 2px solid var(--focus-dark); outline-offset: 3px; }
.actives__body { margin-top: 48px; }
.actives__list { display: grid; grid-template-columns: minmax(0, 1fr); }
.active {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  column-gap: 16px;
  row-gap: 6px;
  align-content: start;
  padding: 24px 0 28px;
  border-top: var(--hair-w) solid var(--hairline-dark);
}
.active--signal { border-top: 2px solid var(--accent); }   /* the fourth active is the different one; the rule says so, once */
.active__num {
  grid-row: 1 / span 4;
  font-size: var(--fs-stepnum);
  line-height: 1;
  padding-top: 2px;
  font-weight: 600;
  color: var(--accent-light);
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -0.02em;
}
.active__name { grid-column: 2; font-size: var(--fs-active); line-height: var(--lh-active); letter-spacing: -0.01em; font-weight: 600; color: var(--ink); }
.active__role { grid-column: 2; margin-top: 2px; font-size: var(--fs-label); line-height: var(--lh-label); font-weight: 500; color: var(--accent-light); max-width: none; }
.active__text { grid-column: 2; font-size: var(--fs-small); line-height: var(--lh-small); color: var(--ink-muted); max-width: 36ch; }
.active__text + .active__text { margin-top: 8px; }
/* the vial act (direction-v6 §5: the canvas scrub beside the list and its figure / layer rules) is RETIRED in r10 (brief-v10 row C): the film stage above carries the object */
.actives__dose { margin-top: 24px; font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--ink-muted); }
.actives .footnotes { margin-top: 48px; }
@media (min-width: 768px) {
  .actives__open { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); align-items: end; }
  .actives__head { grid-column: 1 / span 7; margin-top: 0; }
  .actives__stage {
    order: 0;
    grid-column: 8 / span 5;
    width: 100%;
    --stage-h: 420px;
    margin-right: 0;
    --pool-x: 50%; --pool-y: 58%; --pool-w: 340px; --pool-h: 420px;
  }
  .actives__film { --fade: 56px; }
  .actives__body { margin-top: 56px; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); align-items: start; }
  .actives__list { grid-column: 1 / span 8; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gutter); }
  .actives__dose { grid-column: 1 / span 8; }
  .actives .footnotes { grid-column: 1 / -1; }
}
@media (min-width: 1024px) {
  .actives__stage { --stage-h: 600px; --pool-x: 50%; --pool-y: 50%; --pool-w: 560px; --pool-h: 680px; }
  .actives__film { --fade: 64px; }
  .actives__body { margin-top: 64px; }
}

/* ---------- On the night (4): ledger + reading block + comparison ---------- */
.night__intro .lead { margin-top: 20px; color: var(--ink); max-width: 30ch; }
.ledger { display: grid; margin-top: 48px; border-top: var(--hair-w) solid var(--hairline-dark); }
.stat { display: grid; gap: 6px; padding: 24px 0; border-bottom: var(--hair-w) solid var(--hairline-dark); }
.stat__num { display: inline-flex; align-items: baseline; white-space: nowrap; }
/* count-up without layout shift (motion-spec-v3 §3.6): prefix and unit are static spans; the digits sit in a box
   exactly as wide as the final digit count, tabular figures, left-aligned */
.stat__num .count { display: inline-block; min-width: 2ch; text-align: left; }
.stat__num .count[data-count="4"] { min-width: 1ch; }
.stat__unit {
  font-size: var(--fs-h3);
  line-height: 1;
  font-weight: 400;
  color: var(--ink-muted);
  margin-left: 0.2em;
  letter-spacing: 0;
}
.stat__unit sup.fn, .stat__label sup.fn { margin-left: 2px; }
.stat__label { font-size: var(--fs-ledger-label); line-height: var(--lh-ledger-label); color: var(--ink-muted); }
.night__text { margin-top: 40px; color: var(--ink); }
@media (min-width: 768px) {
  .ledger { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 56px; }
  .stat { padding: 28px var(--gutter) 28px 0; }
  .stat + .stat { padding-left: var(--gutter); border-left: var(--hair-w) solid var(--hairline-dark); }
}
@media (min-width: 1024px) {
  .night__intro { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); align-items: end; }
  .night__intro .h2 { grid-column: 1 / span 6; }
  .night__intro .lead { grid-column: 7 / span 5; margin-top: 0; }
  .ledger { margin-top: 64px; }
  .stat { padding: 32px var(--gutter) 32px 0; }
  .night__text { margin-top: 48px; }
}

/* comparison v8 (design/direction-compare-v8.md §2-§3, master-decisions-v6 §11.19.1; < 768 re-ruled by §11.19.3 = r8.1): a product page, not a table.
   The markup stays one <table> with explicit roles; every <tr> is a CSS grid. Three objects in equal 9:10 boxes on one baseline head three
   columns; the Quattro stands in the site's pool on a 2 px ember plinth (the th's ::before, so the existing drawx / reveal hooks still apply).
   < 768 "aligned columns, honoured all the way down" (§11.19.3, Apple compare on a phone): the header and every fact row share ONE grid,
   1.3fr | 1fr | 1fr with a 12 px gap, so each value sits exactly under its object. Per row: the eyebrow label full width (13/18 muted,
   tracked 0.02em, sentence case), then the three values on one baseline: the Quattro's 18/28 500 ink, Pill and Injection 16/24 muted.
   No names in the body (the header carries them). Row rhythm 20 above the eyebrow / 4 / 16 below the values, one hairline between rows.
   >= 768 (unchanged since r8) the same rows are a real three-column grid: label | 1.4fr | 1fr | 1fr,
   one size per row, the Quattro column ink, the alternatives muted, the pair names hidden. Exactly four hairlines (header + three between
   rows), none between columns, no tint, no card, no radius, no icons, one shared drop-shadow on the three objects.
   Box sizes: 768 135 x 150 / 1024 150 x 166 / >= 1280 162 x 180 (§4.5 tokens). Below 768 the three boxes are equal to the 1fr column, 9:10 tall
   (98.8 x 109.8 at 390, 110.9 x 123.2 at 430, 89.7 x 99.7 at 360): a 108 px box does not fit a 1fr track of a 1.3 / 1 / 1 split of 350 px
   (3 x 108 + 24 = 348 only with equal columns), and a box that overhangs its track would break the very alignment this layout is for.
   The Quattro's box and plinth are 1 / 1.3 of their wider track, left-aligned: one left edge per column (box, name, value); the extra room
   of the product column sits after the vial, between the product and the pair. --cmp-q is the product track's fr value (fr cannot live in calc(),
   so the template repeats the 1.3 literally: change both together). Motion: motion-spec-compare-v8 (the drawx / rise16 rules live in the film layer below). */
.compare { margin-top: 56px; --cmp-q: 1.3; --cmp-cols: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr); --cmp-gap: 12px; --cmp-row-pt: 20px; --cmp-row-pb: 16px; --cmp-name-mt: 12px; --cmp-name-lh: var(--lh-small); }
.compare__table { display: flex; flex-direction: column; width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-small); line-height: var(--lh-small); color: var(--ink); }
.compare__caption { display: block; order: 3; text-align: left; padding-top: 16px; color: var(--ink-muted); font-size: var(--fs-caption); line-height: var(--lh-caption); max-width: var(--measure-fine); }
.compare__table thead { display: block; order: 1; }
.compare__table tbody { display: block; order: 2; }
.compare__table .compare__corner { display: none; }
.compare__table th, .compare__table td { text-align: left; vertical-align: top; padding: 0; font-weight: 400; hyphens: none; }
/* header: three equal stages on the shared grid, names on one shared baseline by construction (identical box, plinth room and margin in every column) */
.compare__head { display: grid; grid-template-columns: var(--cmp-cols); column-gap: var(--cmp-gap); padding-bottom: 20px; border-bottom: var(--hair-w) solid var(--hairline-dark); }
.compare__head th { position: relative; font-weight: 500; }
.compare__obj { position: relative; isolation: isolate; display: block; width: 100%; aspect-ratio: 9 / 10; overflow: visible; }   /* = the 1fr track: 98.8 x 109.8 at 390, 110.9 x 123.2 at 430 */
.compare__head .is-quattro .compare__obj { width: calc(100% / var(--cmp-q)); }   /* the same box inside the 1.3fr track */
.compare__obj img { position: relative; z-index: 1; display: block; width: 100%; height: 100%; object-fit: contain; object-position: 50% 50%; filter: drop-shadow(0 3px 6px rgba(5, 7, 10, 0.55)); }
/* the Quattro's stage: the site's pool (warm centre + lift, both to the transparent field by 62 percent of the radius), drawn on a box 24 px larger
   than the object box on every side; the radii are half that box, so the fade completes ~6 px inside the object box and no rectangle edge exists. */
.is-quattro .compare__obj::before { content: ""; position: absolute; inset: -24px; z-index: 0; pointer-events: none;
  background:
    radial-gradient(50% 50% at 50% 56%, var(--pool-warm) 0%, var(--field-0) 62%),
    radial-gradient(50% 50% at 50% 56%, var(--pool-lift) 0%, var(--field-0) 62%); }
/* the plinth: one 2 px ember floor line, the width of the object box, directly under it (draws left to right on entry: motion-spec-compare-v8, the drawx rules in the film layer below).
   Anchored from the cell's bottom edge (name line + its margin), so it sits on the box floor whatever the fluid box height is. */
.compare__head .is-quattro::before { content: ""; position: absolute; left: 0; width: calc(100% / var(--cmp-q)); bottom: calc(var(--cmp-name-lh) + var(--cmp-name-mt) - 2px); height: 2px; background: var(--accent); transform-origin: left; }
.compare__name { display: block; margin-top: var(--cmp-name-mt); font-weight: 500; font-size: var(--fs-small); line-height: var(--cmp-name-lh); color: var(--ink); }   /* margin = 2 px plinth room + 10 */
/* fact rows on the header's grid: eyebrow across, then the three values on one baseline under their objects */
.compare__table tbody tr { display: grid; grid-template-columns: var(--cmp-cols); column-gap: var(--cmp-gap); align-items: baseline; padding: var(--cmp-row-pt) 0 var(--cmp-row-pb); border-bottom: var(--hair-w) solid var(--hairline-dark); }
.compare__table tbody tr:last-child { border-bottom: 0; }
.compare__table tbody th { grid-column: 1 / -1; padding-bottom: 4px; font-size: 13px; line-height: 18px; letter-spacing: 0.02em; font-weight: 400; color: var(--ink-muted); }   /* the eyebrow (§11.19.3: 13/18 muted, tracked, sentence case) */
.compare__table tbody td { text-wrap: balance; }   /* two-line values break evenly: "Under the / tongue", "~30 to / 60 min", "Yes, can / delay onset" */
.compare__table tbody td.is-quattro { font-size: var(--fs-body); line-height: var(--lh-body); font-weight: 500; color: var(--ink); }
.compare__table tbody td:not(.is-quattro) { color: var(--ink-muted); }
.compare__row--num td { font-variant-numeric: lining-nums tabular-nums; }
@media (min-width: 768px) {
  /* the real three-column table: label 128 | the Quattro 1.4fr | Pill 1fr | Injection 1fr, the site gutter between columns (704 content: ~ 207 / 148 / 148 px) */
  .compare { margin-top: 72px; --cmp-obj-w: 135px; --cmp-obj-h: 150px; --cmp-label: 128px; --cmp-row-pt: 16px; --cmp-row-pb: 16px; --cmp-fs: var(--fs-small); --cmp-lh: var(--lh-small); --cmp-name-mt: 14px; --cmp-name-lh: var(--lh-body); }
  .compare__head, .compare__table tbody tr { grid-template-columns: var(--cmp-label) minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr); align-items: normal; column-gap: var(--gutter); }
  .compare__table .compare__corner { display: block; }
  .compare__obj, .compare__head .is-quattro .compare__obj { width: var(--cmp-obj-w); height: var(--cmp-obj-h); aspect-ratio: auto; }
  .compare__head .is-quattro::before { width: var(--cmp-obj-w); }
  .compare__name { font-size: var(--fs-body); }
  .compare__table tbody th, .compare__table tbody td.is-quattro, .compare__table tbody td { padding-bottom: 0; font-size: var(--cmp-fs); line-height: var(--cmp-lh); font-weight: 400; text-wrap: pretty; }
  .compare__table tbody th { grid-column: auto; letter-spacing: normal; font-weight: 500; color: var(--ink); }
}
@media (min-width: 1024px) {
  .compare { --cmp-obj-w: 150px; --cmp-obj-h: 166px; --cmp-label: min(20%, 224px); --cmp-row-pt: 18px; --cmp-row-pb: 18px; --cmp-fs: var(--fs-body); --cmp-lh: var(--lh-body); --cmp-name-lh: 26px; }
  .compare__head { padding-bottom: 24px; }
  .compare__name { font-size: 20px; }   /* direction §2.5 / §3 literal 20/26 at >= 1024 (the --fs-product token is 24/30 there; the name sits one step over the 18 px values, not three) */
}
@media (min-width: 1280px) {
  .compare { --cmp-obj-w: 162px; --cmp-obj-h: 180px; }
}

/* ---------- Who it is for (5): portrait + stacked text ---------- */
.who { display: grid; gap: 40px; }
.who__media {
  aspect-ratio: 1 / 1;
  border-radius: 20px;
  overflow: clip;
  background: var(--canvas-2);
}
.who__media picture { display: block; width: 100%; height: 100%; }
.who__media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%; }   /* polish-v4 §5: the still life's centre of interest sits lower than the portrait's */
.who__text { display: grid; gap: 40px; align-content: start; }
.who__for .h2 { margin-bottom: 20px; }
.who__for .lead { max-width: 34ch; }
.who__for .lead + p { margin-top: 24px; }
.who__for p + p { margin-top: 20px; }
/* "Who should not take it" (polish-v4 §6): a control-like hairline box (radius 12), 18/24 heading, 16/24 list in --light-ink (safety is never muted),
   the medication prose behind a native <details>; the four-hour line and the safety link always visible. Density, not focus. */
.who__not { margin-top: 0; padding: 20px; border: var(--hair-w) solid var(--hairline); border-radius: 12px; color: var(--light-ink); }
.who__not-title { font-size: var(--fs-body); line-height: var(--lh-small); font-weight: 500; letter-spacing: 0; margin-bottom: 12px; color: var(--light-ink); }
.who__not-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px 24px; font-size: var(--fs-small); line-height: var(--lh-small); }
.who__not-list li { position: relative; padding-left: 14px; }
.who__not-list li::before { content: ""; position: absolute; left: 0; top: 10px; width: 4px; height: 4px; border-radius: 999px; background: var(--light-ink); }   /* a 4 px ink bullet is a list marker, not a decorative dot */
.who__details { margin-top: 16px; border-top: var(--hair-w) solid var(--hairline); }
.who__details summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 48px;
  padding: 12px 0;
  font-size: var(--fs-faq);
  line-height: var(--lh-faq);
  font-weight: 500;
  color: var(--light-ink);
  border-radius: 12px;
}
.who__details summary::-webkit-details-marker { display: none; }
.who__details summary span { flex: 1 1 auto; }
.who__details summary .icon { flex: none; width: 22px; height: 22px; color: var(--accent); transition: transform 200ms var(--ease-move); }
.who__details[open] summary .icon { transform: rotate(45deg); }
.who__details summary:focus-visible { outline-offset: 0; }
.who__details-body { padding: 4px 0 8px; font-size: var(--fs-small); line-height: var(--lh-small); color: var(--light-ink); }
.who__details-body > * + * { margin-top: 12px; }
.who__details-body p { max-width: 50ch; }
.who__sub { font-weight: 500; }
.who__check-list { display: grid; gap: 6px; }
.who__check-list li { position: relative; padding-left: 14px; }
.who__check-list li::before { content: ""; position: absolute; left: 0; top: 10px; width: 4px; height: 4px; border-radius: 999px; background: var(--light-ink); }
.who__side { margin-top: 16px; font-size: var(--fs-small); line-height: var(--lh-small); max-width: 50ch; }
.who__emergency { margin-top: 12px; font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 500; max-width: 50ch; }
.who__link { margin: 12px 0 0; }
@media (min-width: 768px) {
  .who__media { aspect-ratio: 3 / 2; }
  .who__not { padding: 24px; }
  .who__not-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .who { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); align-items: start; }
  .who__media {
    grid-column: 1 / span 5;
    aspect-ratio: 4 / 5;
    position: sticky;
    top: calc(var(--nav-h) + 32px);
  }
  .who__text { grid-column: 7 / span 6; }
}

/* ---------- How you get it (6): sticky heading + numbered vertical list ---------- */
.how { display: grid; gap: 40px; }
.how__head .lead { margin-top: 20px; color: var(--light-ink); }
.steps { display: grid; position: relative; }
.steps::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: var(--hair-w); background: var(--hairline); transform-origin: top; opacity: 0; }
@media (min-width: 768px) { .steps::before { opacity: 1; } }
.step {
  position: relative;
  display: grid;
  gap: 12px;
  padding: 32px 0;
}
.step::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--hairline);
  transform-origin: left;
}
.step:first-child { border-top: var(--hair-w) solid var(--hairline); }
.step__num {
  font-size: var(--fs-stepnum);
  line-height: var(--lh-stepnum);
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -0.02em;
}
.step__body > * + * { margin-top: 10px; }
.step__time { font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 500; color: var(--light-ink); }
@media (min-width: 768px) {
  .how { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); align-items: start; }
  .how__head { grid-column: 1 / span 5; position: sticky; top: calc(var(--nav-h) + 32px); }
  .steps { grid-column: 6 / span 7; }
  .step { grid-template-columns: 3ch minmax(0, 1fr); gap: 24px; padding-left: 20px; }
  .step__num { margin-top: -4px; }
}
@media (min-width: 1024px) {
  .steps { grid-column: 7 / span 6; }
  .step { padding: 36px 0; }
}

/* ---------- Pricing (7): single tile, two inner columns ---------- */
.pricing .h2 { max-width: 24ch; }
.offer {
  margin-top: 40px;
  background: var(--canvas-2);
  border-radius: 20px;
  padding: 24px;
  display: grid;
  gap: 28px;
}
.offer__copy { display: grid; gap: 8px; }
.price { display: flex; align-items: baseline; gap: 10px; margin: 0; max-width: none; }
.price__amount { color: var(--accent); font-size: var(--fs-price); line-height: var(--lh-price); letter-spacing: var(--ls-price); }
.price__unit { font-size: var(--fs-body); line-height: var(--lh-body); color: var(--light-muted); }
.price__plan { font-size: var(--fs-body); line-height: var(--lh-body); color: var(--light-ink); margin: 0; }
.offer__lead { font-size: var(--fs-lead); line-height: var(--lh-lead); letter-spacing: var(--ls-lead); max-width: 36ch; margin-top: 12px; }
.offer__included { display: grid; gap: 12px; align-content: start; }
.offer__label { font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 500; color: var(--light-ink); }
.offer__list { display: grid; gap: 12px; }
.offer__list li { display: flex; gap: 12px; align-items: flex-start; font-size: var(--fs-body); line-height: var(--lh-body); }
.offer__list .icon { flex: none; width: 22px; height: 22px; margin-top: 3px; color: var(--accent); }
.offer__terms { display: grid; gap: 6px; font-weight: 500; }
.offer .btn { justify-self: start; }
.offer__tiers[hidden] { display: none; }
.disclaimer--compact { margin-top: 24px; }
@media (min-width: 768px) {
  .offer { padding: 32px; gap: 24px var(--gutter); grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .offer__copy { grid-column: 1 / span 6; }
  .offer__included { grid-column: 7 / span 6; grid-row: 1 / span 2; }
  .offer__terms { grid-column: 1 / span 6; }
  .offer .btn { grid-column: 1 / span 6; }
}
@media (min-width: 1024px) {
  .offer { padding: 40px; }
  .offer__copy, .offer__terms, .offer .btn { grid-column: 1 / span 5; }
  .offer__included { grid-column: 7 / span 6; }
}

/* ---------- FAQ (8) ---------- */
.faq .h2 { margin-bottom: 24px; }
.faq__list { max-width: 760px; }
.faq__item { border-bottom: var(--hair-w) solid var(--hairline); }
.faq__item summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  min-height: 56px;
  padding: 20px 0;
  font-size: var(--fs-faq);
  line-height: var(--lh-faq);
  font-weight: 500;
  color: var(--light-ink);
  border-radius: 12px;
  position: relative;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::before {
  content: "";
  position: absolute;
  inset: 0 -16px;
  border-radius: 12px;
  background: var(--canvas-2);
  opacity: 0;
  z-index: -1;
  transition: opacity var(--t-fast) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .faq__item summary:hover::before { opacity: 1; }
}
.faq__item summary .icon { flex: none; width: 22px; height: 22px; margin-top: 2px; color: var(--accent); transition: transform 200ms var(--ease-move); }
.faq__item[open]:not(.is-collapsed) summary .icon { transform: rotate(45deg); }
.faq__item summary:focus-visible { outline-offset: 0; }
.faq__item summary span { flex: 1 1 auto; }
/* Accordion (motion-spec-v3 §3.11): grid-template-rows 1fr -> 0fr, natively interruptible. Padding lives on the inner div. */
.faq__panel > div { padding: 0 0 24px; color: var(--light-muted); max-width: var(--measure-body); min-height: 0; overflow: hidden; }
.faq__panel > div > :first-child { margin-top: 0; }
.js .faq__panel { display: grid; grid-template-rows: 1fr; transition: grid-template-rows var(--t-med) var(--ease); }
.js .faq__item.is-collapsed .faq__panel { grid-template-rows: 0fr; transition-duration: 200ms; }
.js .faq__panel > div { transition: opacity var(--t-fast) var(--ease) 60ms; }
.js .faq__item.is-collapsed .faq__panel > div { opacity: 0; transition: opacity 120ms var(--ease); }
.faq__panel p + p { margin-top: 16px; }
.faq__panel a { color: var(--accent-ink); }
.faq__panel strong { color: var(--light-ink); }
.faq__more { margin-top: 32px; }

/* ---------- Final CTA (9): contained graphite tile ---------- */
.final__tile {
  border-radius: 0;
  margin-inline: calc(-1 * var(--pad));
  padding: 48px var(--pad) 32px;   /* r10.2: was 0 (the vial stood on the edge); the hand's fade now completes in the field */
  display: grid;
  gap: 32px;
  overflow: clip;
}
.final__copy .h2 { color: var(--ink); max-width: 18ch; }
.final__line { margin-top: 20px; color: var(--ink-muted); }
.final__price { margin-top: 16px; font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 500; color: var(--ink); }   /* §8.4 price line in the final tile (the sticky bar carries no price) */
.final__copy .btn { margin-top: 28px; }
.final__trust { display: grid; gap: 12px; margin-top: 32px; font-size: var(--fs-small); line-height: var(--lh-small); color: var(--ink-muted); }
.final__trust li { display: flex; gap: 10px; align-items: flex-start; }
.final__trust .icon { flex: none; width: 20px; height: 20px; margin-top: 2px; color: var(--accent-light); }
/* r10.2 (master §11.22.3.2): the visual IS the 4:5 hand still (220 / 260 / 300 px, right-aligned). Radial mask: opaque to 45 % of a 60 % ellipse, gone at 80 % -> the edge midpoints
   (0.83 of the radius) and the corners are at 0: the still ends ~8 px inside its own box, no rectangle on the field. Pool 1.2x behind it (the actives recipe); floor shadow off (the hand carries its own light). */
.final__visual { width: 220px; height: auto; margin-left: auto; margin-right: 0; display: block; --pool-x: 50%; --pool-y: 50%; --pool-w: 264px; --pool-h: 330px; }   /* --floor-w/h stay at the .stage default 0 */
.final__object { width: 100%; height: auto;
  -webkit-mask-image: radial-gradient(ellipse 60% 60% at 50% 50%, #000 45%, rgba(0, 0, 0, 0) 80%); mask-image: radial-gradient(ellipse 60% 60% at 50% 50%, #000 45%, rgba(0, 0, 0, 0) 80%); }
@media (min-width: 768px) {
  .final__tile { border-radius: 20px; margin-inline: 0; padding: 48px 40px; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); align-items: center; }
  .final__copy { grid-column: 1 / span 7; }
  .final__visual { grid-column: 8 / span 5; width: 260px; --pool-w: 312px; --pool-h: 390px; }
}
@media (min-width: 1024px) {
  .final__tile { padding: 48px; }
  .final__copy { grid-column: 1 / span 6; }
  .final__visual { width: 300px; --pool-w: 360px; --pool-h: 450px; }
  .final__trust { display: flex; flex-wrap: wrap; gap: 12px 28px; }
  .final__trust li { white-space: nowrap; }
}

/* ---------- Footer ---------- */
.footer {
  background: var(--canvas-2);
  border-top: var(--hair-w) solid var(--hairline);
  padding: 56px 0 40px;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--light-ink);
}
@media (max-width: 1023px) {
  .js .footer { padding-bottom: calc(40px + var(--bar-h)); }   /* the sticky bar never covers the last link */
}
.footer__row { display: grid; gap: 40px; }
.footer__brand > a { display: inline-flex; align-items: center; min-height: 48px; }
.footer__brand .wordmark { height: 30px; width: auto; color: var(--light-ink); }
.footer__brand p { margin-top: 16px; max-width: 30ch; color: var(--light-muted); }
.footer__lists { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px var(--gutter); }
.footer h2 { font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 500; margin-bottom: 8px; color: var(--light-ink); }
.footer li a { display: inline-flex; align-items: center; min-height: 48px; min-width: 48px; color: var(--light-muted); text-decoration: none; }
.footer li a:hover { color: var(--accent-ink); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.footer__contact[hidden] { display: none; }
.footer__disclaimer {
  margin-top: 48px;
  padding-top: 24px;
  border-top: var(--hair-w) solid var(--hairline-strong);
  display: grid;
  gap: 8px;
}
.footer__disclaimer-col { display: grid; gap: 8px; }
.disclaimer p { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--text-muted); max-width: var(--measure-fine); }
.disclaimer p + p { margin-top: 8px; }
.footer__disclaimer p + p, .footer__disclaimer-col p + p { margin-top: 0; }
.disclaimer .disclaimer__safety { font-size: var(--fs-small); line-height: var(--lh-small); color: var(--light-ink); font-weight: 500; }
.footer__bottom { margin-top: 32px; display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 16px; font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--light-muted); }
.footer__seal[hidden] { display: none; }
@media (min-width: 768px) {
  .footer__lists { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .footer { padding: 64px 0 40px; }
  .footer__row { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); }
  .footer__brand { grid-column: 1 / span 4; }
  .footer__lists { grid-column: 6 / span 7; grid-template-columns: 2fr 2fr 3fr; }
  .footer__disclaimer { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gutter); }
}

/* ---------- Subpages: reading blocks ---------- */
.page { padding-top: 48px; padding-bottom: var(--section); }
.page__head { max-width: var(--measure); }
.page__head .h1 { max-width: 18ch; }
.page__head .lead { margin-top: 24px; }
.page__head .page__head-body { margin-top: 20px; color: var(--light-ink); }
.page__head .caption { margin-top: 20px; }
.prose { max-width: var(--measure); margin-top: 40px; }
.prose > * + * { margin-top: 20px; }
.prose h2 { font-size: var(--fs-h3); line-height: var(--lh-h3); letter-spacing: -0.01em; font-weight: 500; margin-top: 48px; }
.prose h3 { font-size: var(--fs-body); line-height: var(--lh-body); font-weight: 500; margin-top: 32px; }
.prose ul { list-style: disc; padding-left: 22px; }
.prose ol { list-style: decimal; padding-left: 22px; }
.prose li + li { margin-top: 8px; }
.prose li { padding-left: 4px; }
.prose .faq__list { margin-top: 24px; }
.prose .emergency { font-weight: 500; }
.prose .hairline-top { border-top: var(--hair-w) solid var(--hairline); padding-top: 24px; margin-top: 40px; }
.prose table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); line-height: var(--lh-small); }
.prose th, .prose td { text-align: left; vertical-align: top; padding: 14px 16px 14px 0; border-bottom: var(--hair-w) solid var(--hairline); }
.prose th { font-weight: 500; }
.prose .footnotes { list-style: none; padding-left: 0; }
.prose .footnotes li { padding-left: 20px; }
@media (max-width: 767px) {
  .table--stack thead { display: none; }
  .table--stack, .table--stack tbody, .table--stack tr, .table--stack td { display: block; width: 100%; }
  .table--stack tr { padding: 12px 0; border-bottom: var(--hair-w) solid var(--hairline); }
  .table--stack td { border: 0; padding: 2px 0; }
  .table--stack td::before { content: attr(data-label); display: block; font-size: var(--fs-small); line-height: var(--lh-small); color: var(--light-muted); }
  .table--stack td:first-child { font-weight: 500; }
  .table--stack td:first-child::before { display: none; }
}
.page__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; margin-top: 32px; }
.prose .page__note { margin-top: 16px; color: var(--light-muted); }   /* /start: the one line under the disabled button (master-decisions §7.7) */
/* related-document link lists on the legal pages: footer pattern, >= 48 px rows (master-decisions §7.9, AUDIT r1 F9) */
.prose .related { list-style: none; padding-left: 0; }
.prose .related li { padding-left: 0; }
.prose .related li + li { margin-top: 0; }
.prose .related a { display: inline-flex; align-items: center; min-height: 48px; }
.page .footnotes { margin-top: 48px; }
.page .disclaimer--compact { margin-top: 32px; }
@media (min-width: 1024px) {
  .page { padding-top: 80px; }
  .prose h2 { margin-top: 64px; }
}

/* ---------- Forms (reserved for /start intake) ---------- */
.field { display: grid; gap: 8px; }
.field label { font-size: var(--fs-small); line-height: var(--lh-small); font-weight: 500; }
.field input, .field select, .field textarea {
  font: inherit;
  font-size: 18px;
  color: var(--light-ink);
  background: var(--paper);
  border: var(--hair-w) solid var(--hairline-strong);
  border-radius: 12px;
  min-height: 52px;
  padding: 0 16px;
}
.field input::placeholder { color: var(--light-muted); }
.field input:focus-visible { outline: 2px solid var(--focus-light); outline-offset: 0; border-color: transparent; }
.field.is-error input { border-color: var(--warn); }
.field .error { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--warn); }
.field .success { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--accent-ink); }

/* ---------- Motion (design/motion-spec-v3.md §3; hooks per direction-v3 F) ----------
   Hero entrance: CSS keyframes gated on html.js:not(.hero-seen) (once per session; the inline head script sets both),
   so it cannot leave content invisible if script timing slips and never replays within a session.
   Scroll reveals are gated on html.reveal-ready, which site.js sets only after marking everything already in view
   .is-in: without the script nothing is ever hidden. Only transform and opacity animate (plus the two named
   colour exceptions: .btn background and .fn-num colour). */
@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
@keyframes settle {
  from { transform: translateY(8px) scale(0.985); }
  to { transform: none; }
}
@keyframes settle-film {
  from { transform: translateY(8px); }
  to { transform: none; }
}
.js:not(.hero-seen) [data-motion="hero"] .hero__copy > * { animation: rise 420ms var(--ease) both; }
.js:not(.hero-seen) [data-motion="hero"] .hero__copy > :nth-child(2) { animation-delay: 50ms; }
.js:not(.hero-seen) [data-motion="hero"] .hero__copy > :nth-child(3) { animation-delay: 100ms; }
.js:not(.hero-seen) [data-motion="hero"] .hero__copy > :nth-child(4) { animation-delay: 150ms; }
.js:not(.hero-seen) [data-motion="hero"] .hero__stage { animation: settle-film var(--t-settle) var(--ease) both; }   /* stage only, translate only (no scale on a full-bleed frame): the poster <img> stays the LCP element */
@supports (animation-timing-function: linear(0, 1)) {
  .js:not(.hero-seen) [data-motion="hero"] .hero__stage { animation-timing-function: linear(0, 0.186 8%, 0.466 17%, 0.682 25%, 0.821 33%, 0.903 42%, 0.949 50%, 0.973 58%, 0.986 67%, 0.993 75%, 0.997 83%, 0.998 92%, 1); }
}

/* Reveals (§3.3, 3.4, 3.5, 3.7, 3.9, 3.10): 12 px rise + fade, 440 ms, once */
.reveal-ready:not(.sda) [data-reveal]:not(.is-in) { opacity: 0; transform: translateY(12px); }
.reveal-ready:not(.sda) [data-reveal] { transition: opacity var(--t-reveal) var(--ease), transform var(--t-reveal) var(--ease); }
.reveal-ready:not(.sda) [data-reveal-children]:not(.is-in) > * { opacity: 0; transform: translateY(12px); }
.reveal-ready:not(.sda) [data-reveal-children] > * { transition: opacity var(--t-reveal) var(--ease), transform var(--t-reveal) var(--ease); }
/* staggers per container: badges 60 ms, actives 60 ms, comparison objects 60 ms, steps 80 ms */
.reveal-ready:not(.sda) .trust__row > :nth-child(2) { transition-delay: 60ms; }
.reveal-ready:not(.sda) .trust__row > :nth-child(3) { transition-delay: 120ms; }
.reveal-ready:not(.sda) .trust__row > :nth-child(4) { transition-delay: 180ms; }
.reveal-ready:not(.sda) .trust__row > :nth-child(5) { transition-delay: 240ms; }
.reveal-ready:not(.sda) .actives__list > :nth-child(2) { transition-delay: 60ms; }
.reveal-ready:not(.sda) .actives__list > :nth-child(3) { transition-delay: 120ms; }
.reveal-ready:not(.sda) .actives__list > :nth-child(4) { transition-delay: 180ms; }
.reveal-ready:not(.sda) .steps > :nth-child(2) { transition-delay: 80ms; }
.reveal-ready:not(.sda) .steps > :nth-child(3) { transition-delay: 160ms; }
.reveal-ready:not(.sda) .compare__head > :nth-child(3) { transition-delay: 60ms; }
.reveal-ready:not(.sda) .compare__head > :nth-child(4) { transition-delay: 120ms; }
.reveal-ready:not(.sda) .compare__head:not(.is-in) .is-quattro::before { transform: scaleX(0); }
.reveal-ready:not(.sda) .compare__head .is-quattro::before { transition: transform var(--t-rule) var(--ease); }   /* motion-spec-compare-v8 §2.3: 0 ms delay, the plinth lands before the cell's 440 ms rise ends; the four body rows use the generic [data-reveal-children] rules above (440 ms, 0 delay, one unit per row) */
/* step hairlines draw in order: step delay + 200 ms (§3.9) */
.reveal-ready:not(.sda) .steps:not(.is-in) .step::after { transform: scaleX(0); }
.reveal-ready:not(.sda) .steps .step::after { transition: transform var(--t-rule) var(--ease) 200ms; }
.reveal-ready:not(.sda) .steps .step:nth-child(2)::after { transition-delay: 280ms; }
.reveal-ready:not(.sda) .steps .step:nth-child(3)::after { transition-delay: 360ms; }
/* pricing tile: only the check glyphs fade, 200 ms, 40 ms apart from 320 ms (§3.10) */
.reveal-ready:not(.sda) [data-reveal-glyphs]:not(.is-in) .icon { opacity: 0; }
.reveal-ready:not(.sda) [data-reveal-glyphs] .icon { transition: opacity 200ms var(--ease) 320ms; }
.reveal-ready:not(.sda) [data-reveal-glyphs] li:nth-child(2) .icon { transition-delay: 360ms; }
.reveal-ready:not(.sda) [data-reveal-glyphs] li:nth-child(3) .icon { transition-delay: 400ms; }
.reveal-ready:not(.sda) [data-reveal-glyphs] li:nth-child(4) .icon { transition-delay: 440ms; }
.reveal-ready:not(.sda) [data-reveal-glyphs] li:nth-child(5) .icon { transition-delay: 480ms; }

/* Reduced motion = static, not slower (§6). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; transition-delay: 0s !important; animation-duration: 0.01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
  .js [data-motion="hero"] .hero__copy > *,
  .js [data-motion="hero"] .hero__stage { animation: none; }
  .reveal-ready:not(.sda) [data-reveal]:not(.is-in), .reveal-ready:not(.sda) [data-reveal-children]:not(.is-in) > *, .reveal-ready:not(.sda) [data-reveal-glyphs]:not(.is-in) .icon { opacity: 1; transform: none; }
  .reveal-ready:not(.sda) .steps:not(.is-in) .step::after, .reveal-ready:not(.sda) .compare__head:not(.is-in) .is-quattro::before { transform: none; }
  .btn:active, .link-secondary:hover .icon { transform: none; }
  .faq__panel { transition: none; }
  .nav__panel, .nav__panel.is-open { transition: none; transform: none; }
  .ctabar { transition: none; }
}


/* ============================================================================================================
   v5 FILM LAYER (design/direction-v5.md §2-§4, design/motion-spec-v5.md, master-decisions-v5 §10.14/§10.20-§10.22)
   Property whitelist for everything that moves: transform, opacity, clip-path, mask positions, registered custom properties.
   html.motion-on = motion.js runs (not reduced motion, not save-data). html.sda = animation-timeline: view() supported.
   html:not(.motion-on) = the complete static page (no-JS, reduced motion, save-data): posters, no pin, nothing hidden.
   ============================================================================================================ */

/* ---- hero film: rules live in the Hero block above (r5.1) ---- */

/* ---- THE NIGHT SCENE v11: an unpinned scroll-driven frame scrub in a normally scrolling 4:5 box; the page never stops (master §11.23.3; §11.18 "no sticky, no track" stays) ----
   .scene = one grid block on the field: the film box, then the copy (caps band + facts) below it at 390; 768 = copy 42 / film 58 side by side; >= 1024 = copy cols 1-5,
   film cols 6-12. The film box is sized as in r6 (100 percent of its column, never taller than the viewport under the nav), so the whole picture is on screen when the kiss lands.
   Inside the box: the <canvas> (bottom; motion.js draws the frame the scroll asks for), the poster <img> (= the kiss frame) on top of it until the first frame is drawn (200 ms fade).
   overflow-x: clip on .scene: the film-reveal's 1.07 scale used to push the page's scrollWidth past the viewport (404 at 390, 783 at 768; r9 A.5 / r10 D.9) - clipped at the scene's edges now. */
.scene { position: relative; display: grid; grid-template-rows: auto auto; align-items: start; padding-block: 40px 8px; background: var(--field); color: var(--ink); overflow-x: clip; }
.scene__film {
  position: relative;
  isolation: isolate;
  width: min(100%, calc((100vh - var(--nav-h)) * 0.8));
  aspect-ratio: 4 / 5;
  margin: 0 auto;
  --fade: 64px;
  /* every non-viewport edge dissolves into the field (>= 48 px); left/right are viewport edges at 390 */
  -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%);
  mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%);
}
@supports (height: 1svh) { .scene__film { width: min(100%, calc((100svh - var(--nav-h)) * 0.8)); } }
.scene__canvas, .scene__poster { position: absolute; inset: 0; width: 100%; height: 100%; }
.scene__canvas { z-index: 0; display: block; background: var(--field); }   /* 4:5 backing store in a 4:5 box: no letterbox, no stretch */
.scene__poster { z-index: 1; opacity: 1; object-fit: cover; object-position: 50% 0; transition: opacity 200ms var(--ease); }
.scene__film.is-drawn .scene__poster { opacity: 0; }   /* the poster stays in the DOM under the canvas (the no-JS / reduced-motion / before-load image = the kiss frame) */
.scene__copy { position: relative; z-index: 2; padding: 20px var(--pad) 32px; }
/* the one caption, keyed to the scrub: hidden until the kiss lands (p' >= 0.85, data-step 0 -> 1; back to 0 on scroll-up), 240 ms in with a 6 px rise, 160 ms out on
   opacity alone (the transform resets after the fade, so the leaving line never moves). The band reserves its height, so the swap never moves the facts (CLS 0).
   Static page (no-JS, reduced motion, save-data, no canvas): the caption stands under the kiss poster. */
.scene__caps { position: relative; }
.scene__cap { margin: 0; font-size: 20px; line-height: 28px; color: var(--ink); max-width: 34ch; }
.motion-on .scene__caps { min-height: 56px; }   /* two lines reserved at 390 (one is used): the swap never moves the facts (CLS 0) */
.motion-on .scene__cap { position: absolute; left: 0; top: 0; margin: 0; opacity: 0; transform: translateY(6px);
  transition: opacity 160ms var(--ease), transform 0s linear 160ms; }
.motion-on .scene[data-step="1"] .scene__cap[data-step="1"] { opacity: 1; transform: none; transition: opacity 240ms var(--ease), transform 240ms var(--ease); }
.scene__facts { display: flex; flex-wrap: wrap; gap: 16px 28px; margin-top: 20px; }
.scene__fact { display: grid; gap: 2px; }
.scene__fact dt { font-size: var(--fs-small); line-height: var(--lh-small); color: var(--ink-muted); order: 2; }
.scene__fact dd { margin: 0; font-size: 32px; line-height: 36px; font-weight: 600; letter-spacing: -0.03em; color: var(--accent-light); font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.scene__tilde { font-size: 0.6em; color: var(--ink-muted); font-weight: 400; vertical-align: 0.12em; margin-right: 0.05em; }
@media (min-width: 768px) {
  .scene { grid-template-rows: none; grid-template-columns: 42fr 58fr; align-items: center; column-gap: var(--gutter); padding-block: 48px 24px; }
  .scene__film { grid-column: 2; grid-row: 1; margin: 0; width: min(100%, calc((100vh - var(--nav-h)) * 0.8)); margin-left: auto;
    -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%), linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 100%);
    mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%), linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 100%);
    -webkit-mask-composite: source-in; mask-composite: intersect; }
  .scene__copy { grid-column: 1; grid-row: 1; align-self: center; padding: 0 0 0 var(--pad); }
  .scene__cap { max-width: 26ch; }
  .scene__facts { display: grid; grid-template-columns: 1fr; gap: 16px; margin-top: 28px; }
}
@media (min-width: 1024px) {
  .scene { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); width: 100%; max-width: calc(var(--container-wide) + 2 * var(--pad)); margin-inline: auto; padding-inline: var(--pad); }
  .scene__film { grid-column: 6 / span 7; margin-inline: auto; --fade: 80px;
    -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%), linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%);
    mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%), linear-gradient(to right, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 3px, #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0, 0, 0, 0) calc(100% - 3px), rgba(0, 0, 0, 0) 100%); }
  .scene__copy { grid-column: 1 / span 5; padding: 0; }
  .scene__cap { font-size: 22px; line-height: 32px; letter-spacing: -0.005em; max-width: 26ch; }
  .motion-on .scene__caps { min-height: 64px; }
  .scene__facts { grid-template-columns: repeat(3, auto); justify-content: start; gap: 16px 32px; margin-top: 36px; }
}
/* the static page (no-JS, reduced motion, save-data): the kiss poster stands, the caption under it; the canvas stays blank underneath (0 frame requests) */
html:not(.motion-on) .scene__cap { position: static; opacity: 1; transform: none; transition: none; }
html:not(.motion-on) .scene__poster { transition: none; }

/* ---- TRANSITION 1 "the light comes up" (the pinned dawn track) is REMOVED at every width (master §11.18.3.5): #safety-summary keeps its act-start hairline and padding. ---- */

/* ---- scroll-driven beats (html.sda + motion-on): the thumb is the timeline; linear because the scroll is the easing ---- */
@keyframes rise16 { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes rise12 { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes rise40 { from { opacity: 0; transform: translateY(40px); } to { opacity: 1; transform: none; } }
@keyframes drop24 { from { opacity: 0; transform: translateY(-24px); } to { opacity: 1; transform: none; } }
@keyframes drawx { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes drawy { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
@keyframes hero-leave { from { transform: none; } to { transform: translateY(-20%); } }
@keyframes blind { from { clip-path: inset(0 0 100% 0 round 20px); opacity: 0.6; } to { clip-path: inset(0 round 20px); opacity: 1; } }
@keyframes film-reveal { from { clip-path: inset(22% 4% 0 4%); transform: scale(1.07) translateY(24px); opacity: 0.45; } 60% { opacity: 1; } to { clip-path: inset(0); transform: none; opacity: 1; } }
/* r10.2 (master §11.22.3.1): actives reveal (the film-reveal family, quieter) on the box; drift on the stage (box + pool as one object) - two elements, two transforms */
@keyframes actives-reveal { from { clip-path: inset(16% 0 0); transform: scale(1.06); opacity: 0.6; } to { clip-path: inset(0); transform: none; opacity: 1; } }
@keyframes actives-drift { from { transform: translateY(14px); } to { transform: translateY(-14px); } }
@supports (animation-timeline: view()) {
  /* hero: the copy leaves 1.2x faster than the page over the first viewport; the object stays pinned in its pool */
  @media (min-width: 1024px) {   /* r5.1: >= 1024 only. In the film fold (< 1024) the copy block is display: contents and the film sits in flow under the copy, so there is no pinned object to leave behind; copy and film scroll at 1x */
    .sda.motion-on .hero__copy { animation: hero-leave linear both; animation-timeline: scroll(root); animation-range: 0 100vh; }
    @supports (height: 1svh) { .sda.motion-on .hero__copy { animation-range: 0 100svh; } }
  }
  /* text blocks: done by the time the block is 60 percent inside the viewport */
  .sda.motion-on [data-reveal]:not(.hero__stage):not(.actives__stage):not(.offer):not(.final__tile) { animation: rise16 linear both; animation-timeline: view(); animation-range: entry 0% entry 60%; }
  .sda.motion-on [data-reveal-children] > * { animation: rise16 linear both; animation-timeline: view(); animation-range: entry 0% entry 60%; }
  /* spatial staggers: the tick runs in reading order as the row enters */
  .sda.motion-on .trust__row > :nth-child(2) { animation-range: entry 6% entry 66%; }
  .sda.motion-on .trust__row > :nth-child(3) { animation-range: entry 12% entry 72%; }
  .sda.motion-on .trust__row > :nth-child(4) { animation-range: entry 18% entry 78%; }
  .sda.motion-on .trust__row > :nth-child(5) { animation-range: entry 24% entry 84%; }
  .sda.motion-on .actives__list > :nth-child(2) { animation-range: entry 5% entry 65%; }
  .sda.motion-on .actives__list > :nth-child(3) { animation-range: entry 10% entry 70%; }
  .sda.motion-on .actives__list > :nth-child(4) { animation-range: entry 15% entry 75%; }
  .sda.motion-on .steps > :nth-child(2) { animation-range: entry 8% entry 68%; }
  .sda.motion-on .steps > :nth-child(3) { animation-range: entry 16% entry 76%; }
  .sda.motion-on .compare__head > :nth-child(3) { animation-range: entry 6% entry 66%; }
  .sda.motion-on .compare__head > :nth-child(4) { animation-range: entry 12% entry 72%; }
  /* trust: the two rules draw left to right as the row enters */
  .sda.motion-on .trust__row { view-timeline-name: --trust; }
  .sda.motion-on .trust__row::before, .sda.motion-on .trust__row::after { animation: drawx linear both; animation-timeline: --trust; animation-range: entry 0% entry 70%; }
  /* what's in it (r10.2, master §11.22.3.1): (a) the box unblinds 16 % -> 0 from the bottom, 1.06 -> 1, 0.6 -> 1 over entry 0-70 % (0-55 % from 1024) = 210 / 330 px;
     (b) the stage drifts 14 -> -14 px over its whole crossing (cover 0-100 %), linear: 28 px of counter-scroll that keeps the picture alive after the reveal.
     The film plays underneath from 35 percent visibility (motion.js). The stage has no entrance (excluded above). The fourth active's rule draws. */
  .sda.motion-on .actives__film { animation: actives-reveal linear both; animation-timeline: view(); animation-range: entry 0% entry 70%; }
  .sda.motion-on .actives__stage { animation: actives-drift linear both; animation-timeline: view(); animation-range: cover 0% cover 100%; }
  @media (min-width: 1024px) { .sda.motion-on .actives__film { animation-range: entry 0% entry 55%; } }
  /* the night picture (King 26.09. 11:40 "short scroll animation to the picture", kept by §11.23.3.3): the box unblinds from the bottom, settles from 1.07 to 1 and brightens while its top travels the lower ~85 % of the viewport (~400 px at 390); the faces begin to close the distance underneath (motion.js scrub, p 0.14 -> 0.77 over this range at 390), the kiss lands after the box is whole, the page never stops (master §11.18.8) */
  .sda.motion-on .scene__film { animation: film-reveal linear both; animation-timeline: view(); animation-range: entry 0% entry 85%; }
  @media (min-width: 1024px) { .sda.motion-on .scene__film { animation-range: entry 0% entry 60%; } }
  .sda.motion-on .actives__list { view-timeline-name: --actives; }
  .sda.motion-on .active--signal { position: relative; border-top-color: transparent; }
  .sda.motion-on .active--signal::before { content: ""; position: absolute; left: 0; right: 0; top: -2px; height: 2px; background: var(--accent); transform-origin: left; animation: drawx linear both; animation-timeline: --actives; animation-range: entry 30% entry 100%; }
  /* comparison (motion-spec-compare-v8 §2.2 / §6, plinth = the th's ::before): header cells rise in reading order (generic rule + the two offsets above);
     the plinth draws on the Quattro cell's own timeline, down by entry 45 %; each fact row's cells rise as one unit on the row's timeline (< 768),
     all rows as one block on the tbody's timeline (>= 768); the hairlines sit on the rows (timeline subjects, not animated) and never move */
  .sda.motion-on .compare__head .is-quattro { view-timeline-name: --cmpq; }
  .sda.motion-on .compare__head .is-quattro::before { animation: drawx linear both; animation-timeline: --cmpq; animation-range: entry 0% entry 45%; }
  .sda.motion-on .compare__table tbody tr { view-timeline-name: --row; }
  .sda.motion-on .compare__table tbody tr[data-reveal-children] > * { animation-timeline: --row; }
  @media (min-width: 768px) {
    .sda.motion-on .compare__table tbody { view-timeline-name: --cmpbody; }
    .sda.motion-on .compare__table tbody tr[data-reveal-children] > * { animation-timeline: --cmpbody; }
  }
  /* who it is for: the one photo tile arrives with the reader (clip from the top down); the safety box never hides */
  .sda.motion-on .who__media { animation: blind linear both; animation-timeline: view(); animation-range: entry 0% cover 35%; }
  /* how it works: the vertical rule draws downward; each numeral lands when its step crosses the lower half */
  .sda.motion-on .steps { view-timeline-name: --steps; }
  .sda.motion-on .steps::before { animation: drawy linear both; animation-timeline: --steps; animation-range: entry 0% entry 100%; }
  .sda.motion-on .step { view-timeline-name: --step; }
  .sda.motion-on .step__num { animation: rise12 linear both; animation-timeline: --step; animation-range: entry 30% entry 90%; }
  .sda.motion-on .step::after { animation: drawx linear both; animation-timeline: --step; animation-range: entry 40% entry 100%; }
  /* pricing: the tile rises as one block; the check glyphs tick in reading order; $109 never moves */
  .sda.motion-on .offer { animation: rise16 linear both; animation-timeline: view(); animation-range: entry 0% entry 50%; }
  .sda.motion-on .offer__list { view-timeline-name: --offer; }
  .sda.motion-on .offer__list .icon { animation: fadein linear both; animation-timeline: --offer; animation-range: entry 40% entry 100%; }
  .sda.motion-on .offer__list li:nth-child(2) .icon { animation-range: entry 46% entry 100%; }
  .sda.motion-on .offer__list li:nth-child(3) .icon { animation-range: entry 52% entry 100%; }
  .sda.motion-on .offer__list li:nth-child(4) .icon { animation-range: entry 58% entry 100%; }
  .sda.motion-on .offer__list li:nth-child(5) .icon { animation-range: entry 64% entry 100%; }
  /* faq: rows reveal in order, no stagger, done at 50 percent */
  .sda.motion-on .faq__item { animation: rise12 linear both; animation-timeline: view(); animation-range: entry 0% entry 50%; }
  /* final: the tile rises; the object rises out of the light act into the dark one (transition 2); glyphs tick */
  .sda.motion-on .final__tile { animation: rise16 linear both; animation-timeline: view(); animation-range: entry 0% entry 50%; }
  .sda.motion-on .final__object { animation: rise40 linear both; animation-timeline: view(); animation-range: entry 0% cover 40%; }
  .sda.motion-on .final__trust { view-timeline-name: --ftrust; }
  .sda.motion-on .final__trust .icon { animation: fadein linear both; animation-timeline: --ftrust; animation-range: entry 50% entry 100%; }
  .sda.motion-on .final__trust li:nth-child(2) .icon { animation-range: entry 56% entry 100%; }
  .sda.motion-on .final__trust li:nth-child(3) .icon { animation-range: entry 62% entry 100%; }
}

/* ---- ledger counter: @property integer, counted once on entry (motion-spec-v5 T8, PROTO-REPORT §3.2) ---- */
@property --n { syntax: "<integer>"; inherits: true; initial-value: 0; }
.motion-on.props .count { position: relative; color: transparent; }
.motion-on.props .count::after { content: counter(n); counter-reset: n calc(var(--n)); position: absolute; left: 0; top: 0; color: var(--numeral); }
.motion-on.props .ledger.is-in .count { animation: countup 800ms cubic-bezier(0.165, 0.84, 0.44, 1) both; }
@keyframes countup { from { --n: 0; } }

/* ---- reduced motion for the film layer: static, nothing pinned (nothing is), the poster until the reader taps play ---- */
@media (prefers-reduced-motion: reduce) {
  .scene__copy { opacity: 1 !important; }
  .scene__cap { position: static !important; opacity: 1 !important; transform: none !important; transition: none !important; }
  .scene__poster, .actives__poster { transition: none !important; }
  .hero__copy, [data-reveal], [data-reveal-children] > *, .step__num, .offer__list .icon, .final__trust .icon, .final__object, .who__media, .actives__stage, .actives__film, .offer, .final__tile, .faq__item, .trust__row::before, .trust__row::after, .steps::before, .step::after, .active--signal::before, .compare__table thead .is-quattro::before { animation: none !important; opacity: 1; transform: none; clip-path: none; }
  .count { animation: none !important; }
}

/* ============================================================================================================
   CRAFT r6.2 MOBILE PASS (master-decisions-v6 §11.16, King's 7 iPhone screens): every rule below is < 768 CSS px only.
   Nothing here touches 768 and up (verified by pixel diff of 768 x 1024 and 1440 x 900 before/after the pass).
   ============================================================================================================ */
/* ledger numerals in production: _headers ships `style-src 'self'`, which blocks the inline `style="--n: N"` on the three counts, so the
   @property counter printed 0 / 0 / 0 on King's phone (r62 repro y04900). The same values from the stylesheet; the inline attribute stays
   for engines without CSP and wins where it applies (identical result). Not a layout rule; all widths. */
.count[data-count="10"] { --n: 10; }
.count[data-count="4"] { --n: 4; }
.count[data-count="36"] { --n: 36; }
@media (max-width: 767px) {
  /* §11.20 (r9, supersedes §11.17): the hero stage is an autoplaying 9:16 film, "the hand and the vial" (hero-hand-1080x1920, 720 under prefers-reduced-data),
     object-fit cover in the film-fold stage (60 svh, 420-620 px; the base rule's 640 cap is 620 here), the poster <img> under it as LCP / no-JS / reduced-motion image.
     The frame is width-bound (1080 -> 390 = 0.361; 693 px of frame for a 506 px stage at 844), so the crop is vertical only: --film-y 20 percent takes a fifth of
     the surplus from the top and four fifths from the bottom (wrist, sleeve). Measured on the v9 poster (vial y 340-743, fist to ~1600 of 1920): cap top at
     85 / 68 / 94 px of the stage at 390x844 / 390x700 / 430x932 (clear of the 48 px top mask), vial 85-231 = the upper 17-46 percent, the fist fills the rest
     and the wrist dissolves in the bottom mask. The r6.3 pool, box masks and 460 px stage are gone with the frame scrub. */
  .hero__stage { max-height: 620px; --film-x: 50%; --film-y: 20%; }
  /* r10: the hero play button, the reduced-motion tap rule and the scroll-linked settle (§11.20.2.3) moved to the Hero block above: they apply at every width now (§11.21).
     §11.16.3 actives stage (300 px, centred) is the base rule of the What's in it block since r10 (the film box replaces the vial cutout); §11.16.4 (the centred vial act
     + the centred dose line under it) is retired with the act: the dose line stands under the list, left-aligned, as at every other width. */
  /* §11.16.5 ledger: one row, three columns, numerals ~40 px (the display token in this block only), labels 13 px, hairlines top and bottom only. */
  .ledger { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 12px; margin-top: 40px; border-bottom: var(--hair-w) solid var(--hairline-dark);
    --fs-display: 40px; --lh-display: 44px; --ls-display: -0.03em; }
  .stat { gap: 4px; padding: 16px 0; border-bottom: 0; }
  .stat__unit { font-size: 16px; margin-left: 0.15em; }
  .stat__label { font-size: 13px; line-height: 18px; }
  /* §11.16.6 comparison (continuous tint, 64 x 80 thumbs, inset labels) is REPLACED by direction-compare-v8 (§11.19.1): the v8 rules live in the
     comparison block above (fact rows, product first; no tint). Nothing to override here. */
  /* §11.16.7 (hard edge into the canvas act) and §11.16.8 (240 svh track) are RETIRED by §11.18.3: the dawn is gone at every width and the scene is in flow (rules above, no override here). */
  /* §11.16.9 reveal blocks: at 390 every [data-reveal] block is >= 212 px tall (who__for ~800, offer ~1 150), so "entry 60 percent" kept fully visible headlines
     at ~0.25 opacity. The view() timeline honours the root's scroll-padding-bottom (96 px, the sticky bar), so "entry 0" is the bar's top edge, not the
     viewport's: a 220 px range would finish 316 px above the viewport bottom (opacity 0.79 with the block's top at 70 percent of the viewport). 112 px finishes
     208 px above the viewport bottom (top at 75 percent of 844, 70 percent of 700), the block is fully inked before its top passes 70 percent on both heights (120 px measured 0.947 at 700).
     Same specificity as the base rules, later in the sheet. */
  .sda.motion-on [data-reveal]:not(.hero__stage):not(.actives__stage):not(.offer):not(.final__tile) { animation-range: entry 0% entry 112px; }
  .sda.motion-on .offer, .sda.motion-on .final__tile { animation-range: entry 0% entry 112px; }
}

/* ---------- Utilities ---------- */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}
[hidden] { display: none !important; }
