/* MDRN marketing surface. Praxis-derived system re-skinned to the MDRN identity:
   warm paper + deep ink + signal green, Bricolage Grotesque display,
   Instrument Sans body, JetBrains Mono annotations.
   Loaded only by site pages, after app.css; body.site scopes every override. */

@font-face {
  font-family: "Bricolage Grotesque";
  src: url("/assets/fonts/bricolage-vf.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Sans";
  src: url("/assets/fonts/instrument-sans-vf.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/assets/fonts/jetbrains-mono-var.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

body.site {
  --disp: "Bricolage Grotesque", "Archivo Black", system-ui, sans-serif;
  --body: "Instrument Sans", -apple-system, system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;
  --accent-raw: #50C9F2;         /* bright: canvas + ink surfaces */
  --accent-raw-red: #E62B12;     /* the underline stroke from the emblem lockup */
  --track-mono: 0.13em;
  --t-mono: 0.72rem;
  --edge: clamp(1.25rem, 4vw, 4rem);
  --max-w: 90rem;
  --section-pad: clamp(5rem, 12vh, 9rem);
  font-family: var(--body);
  background: var(--paper);
}
/* ---------- surface system ----------
   Light and dark are BOTH first class here, chosen automatically from the
   visitor's system setting. What is fixed is not the palette but the MEANING
   of each role, and that is the part that was broken before:

     deep   always the most extreme surface. The brand moment.
     paper  the base reading surface.
     sunk   one step off paper, so adjacent reading sections separate.

   Polarity never inverts. In dark mode the reading surfaces lift toward
   charcoal instead of flipping to white, which is what used to drop three
   blinding slabs into the middle of a dark page. deep stays the darkest thing
   on screen in both schemes, so a dark section always reads as a dark section.

   Every section declares ONE surface. The surface re-declares the palette
   tokens locally, so a component written against --ink-2 or --paper-edge is
   correct on any surface in any scheme with no override rule anywhere. Read
   --paper as "this surface" and --ink as "on this surface". Surfaces nest: an
   inverted card inside a light section is just data-surface="deep" on it.

   Each token is declared twice on purpose. The plain value is the fallback for
   engines without light-dark(); they get the light scheme, which is complete
   and correct on its own. */
body.site { color-scheme: light dark; }
:root[data-theme="light"] body.site { color-scheme: light; }
:root[data-theme="dark"]  body.site { color-scheme: dark; }

body.site,
body.site [data-surface="paper"] {
  --paper: #FBFAF7;       --paper: light-dark(#FBFAF7, #1A1D22);
  --paper-raised: #FFFFFF; --paper-raised: light-dark(#FFFFFF, #22262C);
  --paper-sunk: #F2F0EA;  --paper-sunk: light-dark(#F2F0EA, #141619);
  --paper-edge: #E4E0D6;  --paper-edge: light-dark(#E4E0D6, #33383F);
  --ink: #14160F;         --ink: light-dark(#14160F, #F3F2EC);
  --ink-2: #4A4E42;       --ink-2: light-dark(#4A4E42, #C4C6BE);
  --ink-3: #686C61;       --ink-3: light-dark(#686C61, #9BA0A8);
  --ink-4: #A8ABA0;       --ink-4: light-dark(#A8ABA0, #6E737B);
  --accent-deep: #0D729D; --accent-deep: light-dark(#0D729D, #50C9F2);
  --on-signal: #FFFFFF;   --on-signal: light-dark(#FFFFFF, #06141B);
  --rule: #91918C;        --rule: light-dark(#91918C, #666869);
  --tick: #73736E;        --tick: light-dark(#73736E, #828383);
  --accent: var(--accent-deep); --acc: var(--accent-deep);
  --signal: var(--accent-deep); --signal-soft: color-mix(in srgb, var(--accent-deep) 12%, var(--paper));
  --signal-edge: color-mix(in srgb, var(--accent-deep) 34%, var(--paper));
}
/* One calm step off paper: enough to read as a separate section, never enough
   to read as a different colour. Light steps down, dark steps up. */
body.site [data-surface="sunk"] {
  --paper: #EFEDE5;       --paper: light-dark(#EFEDE5, #2C3038);
  --paper-raised: #FBFAF7; --paper-raised: light-dark(#FBFAF7, #363B44);
  --paper-sunk: #E6E3D9;  --paper-sunk: light-dark(#E6E3D9, #23262C);
  --paper-edge: #DBD7CA;  --paper-edge: light-dark(#DBD7CA, #434952);
  --ink: #14160F;         --ink: light-dark(#14160F, #F3F2EC);
  --ink-2: #4A4E42;       --ink-2: light-dark(#4A4E42, #C9CCD2);
  --ink-3: #686C61;       --ink-3: light-dark(#686C61, #A3A8B0);
  --ink-4: #A0A399;       --ink-4: light-dark(#A0A399, #767C85);
  --accent-deep: #0D729D; --accent-deep: light-dark(#0D729D, #6FD3F5);
  --on-signal: #FFFFFF;   --on-signal: light-dark(#FFFFFF, #06141B);
  --rule: #8A8A83;        --rule: light-dark(#8A8A83, #76787B);
  --tick: #6C6C65;        --tick: light-dark(#6C6C65, #959797);
  --accent: var(--accent-deep); --acc: var(--accent-deep);
  --signal: var(--accent-deep); --signal-soft: color-mix(in srgb, var(--accent-deep) 12%, var(--paper));
  --signal-edge: color-mix(in srgb, var(--accent-deep) 34%, var(--paper));
}
/* The brand moment: hero, the two argument sections, footer, menu, 404, and
   the intake reveal. Darkest surface on screen in either scheme. */
body.site [data-surface="deep"],
body.site.is-reveal,
body.site .menu-sheet {
  --paper: #0B0B0C;       --paper: light-dark(#0B0B0C, #050506);
  --paper-raised: #17181B; --paper-raised: light-dark(#17181B, #131417);
  --paper-sunk: #121316;  --paper-sunk: light-dark(#121316, #0A0A0C);
  --paper-edge: #2A2C31;  --paper-edge: light-dark(#2A2C31, #24262B);
  --ink: #F3F2EC;         --ink: light-dark(#F3F2EC, #F3F2EC);
  --ink-2: #C4C6BE;       --ink-2: light-dark(#C4C6BE, #C4C6BE);
  --ink-3: #90928B;       --ink-3: light-dark(#90928B, #9498A0);
  --ink-4: #63655E;       --ink-4: light-dark(#63655E, #666A72);
  --accent-deep: #50C9F2; --accent-deep: light-dark(#50C9F2, #50C9F2);
  --on-signal: #06141B;   --on-signal: light-dark(#06141B, #06141B);
  --rule: #5F5E5D;        --rule: light-dark(#5F5E5D, #5B5A59);
  --tick: #787875;        --tick: light-dark(#787875, #777774);
  /* THE REVEAL USED TO BREAK EVERY COMPONENT BUILT ON --signal.
     body.site.is-reveal is grouped into this block, and this block redefined
     the paper and ink ramps but never the accent family. So a choice card or
     a readout row moved onto the reveal resolved --signal-soft to #E2F1F8
     from the root, and painted near white on a near black ground. Anything
     written against the surface tokens now survives being moved here. */
  --accent: var(--accent-deep); --acc: var(--accent-deep);
  --signal: var(--accent-deep);
  --signal-soft: color-mix(in srgb, var(--accent-deep) 14%, var(--paper));
  --signal-edge: color-mix(in srgb, var(--accent-deep) 38%, var(--paper));
  --clay: #F4694E; --clay-soft: #2A130E; --on-clay: #1A0906;
  --caution: #D9BA65; --caution-soft: #241E0C;
}
body.site [data-surface] { background: var(--paper); color: var(--ink); }

body.site .wrap { width: min(100% - 2 * var(--edge), var(--max-w)); }

/* ---------- text roles ---------- */
body.site .display, body.site .xh1, body.site .xh2, body.site .xh3 {
  font-family: var(--disp);
  font-weight: 780;
  font-variation-settings: "wdth" 92, "opsz" 40;
  text-transform: uppercase;
  letter-spacing: -0.018em;
  line-height: 0.96;
  text-wrap: balance;
  margin: 0;
}
body.site .display { font-size: clamp(2.6rem, 10.5vw, 10rem); line-height: 0.9; }
body.site .xh2 { font-size: clamp(1.9rem, 4.6vw, 3.6rem); line-height: 1.02; }
body.site .xh3 { font-size: clamp(1.2rem, 2.2vw, 1.7rem); text-transform: none; letter-spacing: -0.01em; font-weight: 640; }
body.site .lead { font-size: clamp(1.1rem, 1.8vw, 1.4rem); line-height: 1.45; max-width: 36rem; text-wrap: pretty; }
body.site .copy { max-width: 38rem; color: var(--ink-2); text-wrap: pretty; }

body.site .xmono {
  font-family: var(--mono);
  font-size: var(--t-mono);
  font-weight: 500;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
}
body.site .xmono.dim { color: var(--ink-3); }
body.site .xmono.acc { color: var(--accent-deep); }
body.site .tag { display: inline-flex; gap: 0.6em; align-items: baseline; }
body.site .tag::before { content: "["; color: var(--ink-3); }
body.site .tag::after { content: "]"; color: var(--ink-3); }

/* ---------- sections ---------- */
body.site .xsection { position: relative; padding-block: var(--section-pad); background: var(--paper); color: var(--ink); }
/* Every section boundary is now a real tone change, so the hairline is no
   longer needed to separate sections. It survives only for a section that
   deliberately continues the one above it. */
body.site .xsection--hairline { border-top: 1px solid var(--paper-edge); }
body.site .xsection-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--s4); margin-bottom: clamp(2.5rem, 6vh, 4rem); }

/* The watermark sizes itself to its own word. A fixed 22vw only ever suited
   short words: anything longer ran past the edge and got sliced mid-letter,
   which reads as a broken element rather than a deliberate one. --wm-len is
   the character count, set on each instance. */
body.site .watermark {
  position: absolute; inset-inline: 0; top: 0.05em; z-index: 0;
  font-family: var(--disp); font-weight: 800;
  font-size: clamp(4rem, min(22vw, (100vw - 2 * var(--edge)) / (var(--wm-len, 6) * 0.62)), 20rem);
  font-variation-settings: "wdth" 100;
  text-transform: uppercase; letter-spacing: -0.02em; line-height: 1;
  color: currentColor; opacity: 0.045; white-space: nowrap; overflow: hidden;
  pointer-events: none; user-select: none;
}

/* ---------- fixed chrome ---------- */
/* Legibility must never depend on an observer. Over the hero (always near-black)
   the chrome is light; once scrolled past it the bar becomes a real surface with
   its own scrim, so it is readable over anything behind it. */
body.site .xheader {
  position: fixed; inset-inline: 0; top: 0; z-index: 40;
  color: #F3F2EC;
  transition: color var(--dur) ease, background-color var(--dur) ease;
  border-bottom: 1px solid transparent;
}
body.site .xheader.over-ink { color: #F3F2EC; }
body.site .xheader.is-scrolled {
  color: var(--ink);
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom-color: var(--paper-edge);
}
body.site .xheader .wrap {
  display: flex; align-items: center; justify-content: space-between;
  padding-block: var(--s4);
  /* space-between alone lets the wordmark and the CTA pill touch once the nav
     collapses. On a 375 wide screen the N was running into the pill's border. */
  gap: var(--s3);
}
/* Never shrink the wordmark: its letters are spaced, so a shrunk box lets the
   glyphs overflow and slide under the CTA rather than reflowing. It keeps its
   own width and the gap does the separating. */
body.site .xheader .mark { flex: 0 0 auto; }
body.site .xheader .mark { color: currentColor; }
body.site .xnav { display: flex; gap: var(--s5); }
body.site .xnav a { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: var(--track-mono); text-transform: uppercase; text-decoration: none; opacity: .7; transition: opacity var(--dur) ease; }
body.site .xnav a:hover, body.site .xnav a[aria-current="true"] { opacity: 1; }
@media (max-width: 860px) { body.site .xnav { display: none; } }
body.site .header-cta {
  font-family: var(--mono); font-size: var(--t-mono); font-weight: 600; letter-spacing: var(--track-mono);
  text-transform: uppercase; text-decoration: none; padding: 8px 16px;
  border: 1px solid currentColor; border-radius: var(--r-full);
  transition: background-color var(--dur) ease, color var(--dur) ease;
}
body.site .xheader:not(.over-ink) .header-cta:hover { background: var(--ink); color: var(--paper); }
body.site .xheader.over-ink .header-cta:hover { background: var(--paper); color: var(--ink); }

body.site .hud {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 40;
  color: #F3F2EC; transition: color var(--dur) ease; pointer-events: none;
}
body.site .hud.over-ink { color: #F3F2EC; }
/* Decoration must not crowd the offer. The readout fades in once the page is
   actually scrolling, so the first screen carries only load-bearing elements. */
body.site .hud { opacity: 0; transition: opacity var(--dur-slow) var(--ease), color var(--dur) ease; }
body.site .hud.is-scrolled, body.site.past-main .hud { opacity: 1; }
body.site .hud.is-scrolled { color: var(--ink); }
/* the inverted footer panel wins over both states */
body.site.past-main .xheader, body.site.past-main .hud { color: #F3F2EC; }
body.site.past-main .xheader { background: transparent; backdrop-filter: none; border-bottom-color: transparent; }
body.site .hud .wrap { display: flex; justify-content: space-between; padding-block: var(--s4); }
@media (max-width: 700px) { body.site .hud { display: none; } }

/* ---------- buttons (override app pills on site pages) ---------- */
body.site .btn {
  font-family: var(--mono); font-size: var(--t-mono); font-weight: 600;
  letter-spacing: var(--track-mono); text-transform: uppercase;
  padding: 1.05em 1.9em; border-radius: var(--r-full);
  background: var(--ink); color: var(--paper); border: 0;
  transition: transform var(--dur) var(--ease), background-color var(--dur) ease;
}
body.site .btn:hover { box-shadow: none; }
body.site .btn .btn-arrow { display: inline-block; transition: transform var(--dur) var(--ease); }
body.site .btn:hover .btn-arrow { transform: translateX(4px); }
body.site .btn-accent { background: var(--accent-deep); color: var(--on-signal); }
body.site .btn-ghost { background: transparent; color: currentColor; box-shadow: inset 0 0 0 1px currentColor; border: 0; }
body.site .btn-ghost:hover { background: transparent; }
/* No per-surface button overrides: --ink/--paper/--accent-deep/--on-signal all
   resolve from whichever surface the button is sitting on. */

/* ---------- hero: MaskedHero (pattern library). The wordmark is a knockout
   over motion; the ink plate covers everything else. ---------- */
/* The copy is bottom-justified and the wordmark is painted into whatever space
   is left above it. Once the stack grew past that space the two collided, so
   the top padding now RESERVES the wordmark band: content can never start
   higher than this, and the section simply grows and scrolls instead. */
body.site .xhero {
  min-height: 100svh; display: flex; flex-direction: column; justify-content: flex-end;
  padding-block: clamp(11rem, 26vh, 15rem) var(--s5);
  overflow: clip; position: relative;
  background: var(--paper); color: var(--ink);
}
body.site .xhero .hero-media { position: absolute; inset: 0; z-index: 0; background: var(--paper); }

/* one layer per letter, each clipped to its own glyph column at runtime */
body.site .xhero .lcell { position: absolute; inset: 0; overflow: hidden; }
body.site .xhero .lv {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  filter: saturate(.85) contrast(1.02);
  opacity: 0; transition: opacity .8s var(--ease);
  /* per-letter framing: pan and push each clip so the subject lands inside
     its own glyph rather than wherever the full-bleed crop happens to put it.
     --vx pans horizontally, --vy vertically, --vs pushes in. */
  transform: translate(var(--vx, 0%), var(--vy, 0%)) scale(var(--vs, 1));
  transform-origin: center center;
}
/* M: runner sits centre-frame, pull him left into the first glyph */
body.site .xhero .lcell[data-cell="0"] { --vx: -14%; --vs: 1.3; }
/* D: the exhale, panned left so the breath sits inside the bowl rather than
   against its right stem. */
body.site .xhero .lcell[data-cell="1"] { --vx: 5%; --vy: -16%; --vs: 1.05; }
/* R: the plate. Moved over from D, so it gains that same ~18% to land in the
   third glyph; the lift that brings the food into the band is unchanged. */
body.site .xhero .lcell[data-cell="2"] { --vx: -16%; --vy: -26%; --vs: 1.22; }
/* N: the threshold. The lit doorway is a narrow bright band in a very dark
   frame, so this pushes in hard and carries it across; without it the last
   glyph would render almost entirely black. */
body.site .xhero .lcell[data-cell="3"] { --vx: 14%; --vy: 6%; --vs: 1.74; }
body.site .xhero .lv.is-front { opacity: 1; }

/* the word column: big type rolling behind the final letterform */
/* the final letter is the brand itself: three windows into a life, one solid mark */
body.site .xhero .lcell-brand { background: var(--accent-raw); }

/* the rolling word, placed where it can actually be read */
body.site .xhero .wordroll {
  display: inline-block; min-width: 9ch; color: var(--accent-deep); font-weight: 600;
  transition: opacity .4s var(--ease);
}
body.site .xhero .wordroll.is-out { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  body.site .xhero .lv, body.site .xhero .wordroll { transition: none; }
}
body.site .xhero .hero-plate { position: absolute; inset: 0; z-index: 1; }
body.site .xhero .hero-plate svg { width: 100%; height: 100%; display: block; }
/* The letters ARE the windows, so every bit of ink is more visible footage.
   wdth runs to 100 in this face and was set to 92, and the tracking was pushing
   the glyphs apart into dead plate. Both now favour glyph area over air. */
body.site .xhero .mask-word {
  font-family: var(--disp); font-weight: 800;
  font-variation-settings: "wdth" 100;
  letter-spacing: -0.005em;
}
body.site .xhero > .wrap { position: relative; z-index: 2; }
/* No hairline in the hero. The red lockup stroke already separates the wordmark
   from the copy, and a second rule landing at nearly the same y read as a thin
   line running straight through the brand mark. */
body.site .xhero .hero-base { border-top: 0; padding-top: 0; }

/* the disclosure, set as a readable sentence rather than a cramped mono chip */
body.site .hero-fine {
  text-transform: none; letter-spacing: .01em; font-size: .78rem;
  line-height: 1.6; max-width: 32rem; margin: 0; opacity: .8;
}
/* The hero used to hand-paint all of this. It is data-surface="deep" now, so
   dim text, brackets and every button variant resolve from the surface. Only
   the ghost outline keeps a bespoke value: a softer rule than currentColor. */
body.site .xhero .btn-ghost { box-shadow: inset 0 0 0 1px rgba(243,242,236,.5); }
/* the lockup's red underline, drawn once under the knockout wordmark */
body.site .underline-stroke { display: block; width: min(92vw, 100%); height: auto; margin-top: calc(-1 * clamp(.4rem, 1.2vw, 1rem)); }
body.site .hero-meta { display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--s3); margin-bottom: var(--s5); }
/* A grid, not flex-wrap. As a flex row the two columns were sized by their own
   intrinsic text width: the promise strip refuses to wrap until it has to, so
   the CTA column measured ~700px, overflowed the row and dropped below the
   copy, leaving the hero as one narrow column with half the width empty. The
   grid decides the split by viewport, and minmax(0,..) makes the text wrap to
   its column instead of the column growing to the text. */
/* ============================================================
   ABOVE THE FOLD
   One descending ladder: brow, headline, one supporting line,
   one primary action, then fine print. Sized so the headline is
   unambiguously dominant (~2.5x the supporting copy), because
   the fold is judged on visual impression before it is read.
   ============================================================ */
/* ============================================================
   ABOVE THE FOLD
   Headline centred full width under the lockup rule; the panel
   and its disclosure hang off the left edge beneath it. One
   primary action, and it lives inside the panel.
   ============================================================ */
body.site .hero-base {
  display: grid; justify-items: start; text-align: left;
  grid-template-areas: "head" "sub" "reel" "fine";
  margin-top: var(--s4);
}
body.site .hero-h     { grid-area: head; }
body.site .hero-sub   { grid-area: sub; }
body.site .hero-reel { grid-area: reel; }
body.site .hero-fine  { grid-area: fine; }

/* Two columns once there is room: the panel states the offer, the hand units
   demonstrate it. Unboxed on purpose, so it reads as a diagram beside the card
   rather than a second card competing with it. */
@media (min-width: 900px) {
  body.site .hero-base {
    grid-template-areas:
      "head  head"
      "sub   reel"
      "fine  fine";
    /* The frame is capped instead of taking the whole remainder, because at
       16:9 a full-width frame would be ~86px taller than the panel and that
       height comes straight out of the wordmark's band above. Capped here it
       lands at roughly the panel's own height, so the row is unchanged.

       Narrower frame, BIGGER mark: the old clip was a small lockup floating in
       synthetic gutters, about 70% of its own width. This one fills 94% of the
       frame, so the mark actually renders larger than before despite the
       smaller box. */
    grid-template-columns: minmax(0, 1fr) min(50vw, 37rem);
    column-gap: clamp(2rem, 4vw, 3.5rem);
  }
  /* stretched to the panel's own height, so the pair shares a top and a
     bottom edge instead of one floating beside the other */
  body.site .hero-reel { align-self: center; justify-self: stretch; margin: 0; }
  body.site .hero-sub { justify-self: stretch; }
}

/* The frame is 16:9 because the brand reel is, and the reel has to fill it
   edge to edge with nothing invented at the sides.

   That constraint is geometric, not stylistic. The lockup occupies rows 49 to
   449 of the 480 tall source: the emblem at the top, the red rule at the
   bottom, 83% of the frame height. Cover-fitting that into the old 2.23:1 slot
   showed only a 383px centre slice, which cut the rule off entirely. Matching
   the slot to the source is the only way to keep the whole mark AND have no
   bars, so the frame takes the reel's shape rather than the reverse.

   The reel is capped rather than given the whole column, so at 16:9 it stays
   about as tall as the panel beside it and does not grow the row, which would
   come straight out of the wordmark's band above. */
body.site .hero-reel {
  position: relative; margin: 0; padding: 0;
  /* the video is absolutely positioned, so the frame has no content to size
     from. With an aspect-ratio and the grid's justify-items:start it collapses
     to nothing, so it has to be told to fill its column. */
  justify-self: stretch; width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 18px; overflow: hidden;
  border: 1px solid rgba(243,242,236,.11);
  background: #101011;
}
@media (max-width: 899px) { body.site .hero-reel { margin-top: var(--s5); } }
body.site .reel-v {
  position: absolute; inset: 0;
  display: block; width: 100%; height: 100%;
  object-fit: cover; opacity: 0;
  transition: opacity .6s var(--ease);
}
body.site .reel-v.is-ready { opacity: 1; }
@media (prefers-reduced-motion: reduce) { body.site .reel-v { transition: none; } }


/* the visual anchor. Sentence case, not the uppercase display setting: this is
   a sentence to be read, and all-caps measurably slows reading. */
body.site .hero-h {
  justify-self: stretch; text-align: center;
  font-family: var(--disp); font-weight: 660; letter-spacing: -0.03em;
  font-size: clamp(1.85rem, 3.5vw, 3rem); line-height: 1.06;
  margin: 0 0 clamp(1.5rem, 3.2vh, 2.25rem); text-wrap: balance; color: #F3F2EC;
}

/* ---------- the panel ----------
   Spacing is set per element rather than by one uniform gap: an even rhythm
   makes six items read as six unrelated lines. Grouping them (label tight to
   the pillars, pillars tight to each other, a real break before the close row)
   is what makes it read as composed. */
body.site .hero-sub {
  display: grid; gap: 0; justify-items: start;
  width: fit-content; max-width: min(30rem, 100%);
  margin: 0; text-align: left;
  padding: clamp(1.2rem, 2vw, 1.5rem) clamp(1.35rem, 2.2vw, 1.7rem);
  background: rgba(243,242,236,.05);
  border: 1px solid rgba(243,242,236,.11);
  border-radius: 18px;
  /* isolate makes this a stacking context, which pins the z-index:-1 watermark
     between the card's own background and its copy. Without it the negative
     layer escapes behind the hero entirely and never shows. */
  position: relative; isolation: isolate; overflow: hidden;
}
/* Sized to sit COMPLETE inside the card. Overscaled it gets cropped top and
   bottom by the card's own overflow and stops reading as a flame at all. */
body.site .hero-wm {
  position: absolute; z-index: -1; pointer-events: none;
  right: 2%; top: 50%; transform: translateY(-50%);
  height: 62%; width: auto; opacity: .085;
}
/* dropped below centre so the tip clears "How to wind down" above it */
@media (min-width: 900px) { body.site .hero-wm { height: 66%; right: 3%; top: 58%; } }
/* MUST live after the base rule, not up in the layout media query: the two have
   equal specificity, so the later one wins regardless of the media condition.
   The frame is capped at 16:9, which leaves the rest of the row to the panel;
   without releasing fit-content the panel keeps its 378px content width and the
   remainder opens as a 207px hole between the two. justify-self:stretch alone
   cannot do it, because stretch does not apply to a fit-content width. */
@media (min-width: 900px) {
  body.site .hero-sub { width: auto; max-width: none; }
}
body.site .hero-sub > .xmono.tag { margin-bottom: .85rem; }

/* Three rows on one grid, so every gloss starts on the same vertical line. That
   shared edge is what makes it scan as a structure rather than as three
   sentences that happen to sit under each other. */
body.site .hero-pillars {
  display: grid; grid-template-columns: 1fr; gap: .38rem 0;
  justify-self: stretch; margin: 0 0 .95rem;
}
body.site .pillar {
  display: grid; grid-template-columns: max-content 1fr;
  gap: 0 clamp(1rem, 2vw, 1.45rem); align-items: baseline;
}
body.site .hero-pillars dt {
  font-family: var(--disp); font-weight: 650; letter-spacing: -0.018em;
  font-size: 1.13rem; line-height: 1.2; color: #F3F2EC;
}
body.site .hero-pillars dd {
  margin: 0; font-size: .97rem; line-height: 1.2;
  color: rgba(243,242,236,.55);
}

body.site .hero-note {
  margin: 0; font-size: 1rem; line-height: 1.5;
  color: rgba(243,242,236,.7);
  /* stretch first: the panel sets justify-items:start, so without this the
     paragraph is content-sized and centring its text would do nothing */
  justify-self: stretch; text-align: center;
}
/* the break is deliberate, so it goes away only when the column is too narrow
   for the first claim to hold its own line anyway */
@media (max-width: 420px) { body.site .hero-note br { display: none; } }
body.site .hero-sub strong { color: #F3F2EC; font-weight: 600; }

/* The panel closes on a rule, then the action, centred beneath it. */
body.site .hero-close {
  position: relative;
  justify-self: stretch;
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: var(--s4);
  margin-top: 1.15rem; padding-top: .95rem;
}
/* the rule is a layer, not a border, so it can wipe left to right on entry */
body.site .hero-close::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 1px;
  background: rgba(243,242,236,.14); transform-origin: left center;
}
/* slightly tighter than the page buttons: it lives inside a panel, not on it */
body.site .hero-close .btn { padding: .85em 1.5em; }

/* ---- the panel's entrance ----
   Reads in the order the offer is meant to be read: the label, then the three
   pillars left to right, then the promise, then the rule wiping across to the
   action, then its terms, then the disclosure. Roughly 1.2s end to end, so it
   lands as a flourish rather than a wait, and the button is clickable the whole
   time.

   Every keyframe declares only `from`. The `to` is the element's own resting
   style, so the animation can only ever move something INTO its normal state,
   never out of one. With `backwards` fill the pre-delay frame is the `from`.
   Belt and braces on top of that: the whole sequence is scoped to a transient
   .is-entering class which site.js strips with a plain setTimeout once the
   sequence is over. So the resting state never depends on an animation firing,
   completing, or being honoured at all. With JS off, html.js is absent, no rule
   matches and everything is simply visible. */
@keyframes mdrn-rise { from { opacity: 0; transform: translateY(9px); } }
@keyframes mdrn-fold { from { opacity: 0; transform: perspective(700px) rotateX(-18deg) translateY(6px); } }
@keyframes mdrn-pop  { from { opacity: 0; transform: translateY(8px) scale(.96); } }
@keyframes mdrn-wipe { from { transform: scaleX(0); } }
@keyframes mdrn-glow { from { opacity: 0; transform: translateY(-50%) scale(1.06); } }

html.js body.site .is-entering .hero-wm            { animation: mdrn-glow 1.3s var(--ease)  180ms backwards; }
html.js body.site .is-entering .hero-sub > .tag    { animation: mdrn-rise  .5s var(--ease)   60ms backwards; }
html.js body.site .is-entering .pillar:nth-child(1){ animation: mdrn-fold .52s var(--ease)  170ms backwards; }
html.js body.site .is-entering .pillar:nth-child(2){ animation: mdrn-fold .52s var(--ease)  260ms backwards; }
html.js body.site .is-entering .pillar:nth-child(3){ animation: mdrn-fold .52s var(--ease)  350ms backwards; }
html.js body.site .is-entering .hero-note          { animation: mdrn-rise  .5s var(--ease)  460ms backwards; }
html.js body.site .is-entering .hero-close::before { animation: mdrn-wipe .58s var(--ease)  555ms backwards; }
html.js body.site .is-entering .hero-close .btn    { animation: mdrn-pop   .5s var(--ease)  620ms backwards; }
html.js body.site .is-entering .hero-promise       { animation: mdrn-rise  .5s var(--ease)  710ms backwards; }
html.js body.site .is-entering .hero-fine          { animation: mdrn-rise  .5s var(--ease)  800ms backwards; }

/* The global reduced-motion rule only collapses DURATION, which would leave a
   delayed element hidden for its full delay and then snap in. These have to be
   switched off outright. */
@media (prefers-reduced-motion: reduce) {
    html.js body.site .hero-sub > .tag,
  html.js body.site .pillar,
  html.js body.site .hero-note,
  html.js body.site .hero-close::before,
  html.js body.site .hero-close .btn,
  html.js body.site .hero-promise,
  html.js body.site .hero-fine { animation: none; }
}

/* ---- the panel, laid out for the width it actually has ----
   The frame is capped at 16:9, which leaves the panel the rest of the row: it
   is ~534px at 1280, not the ~378px its contents were composed for. Left as
   was, the three pillars used 40% of the width and the action floated centred
   in a wide empty band, which read as unfinished rather than spacious.

   Wide, the pillars run three across, the note spans the full measure, and the
   action row puts the button and its promise on one line at opposite ends. All
   of this MUST come after the base rules: equal specificity means source order
   decides, and this file has lost that argument several times before. */
@media (min-width: 900px) {
  /* dt over dd, three columns: column flow fills row 1 then row 2 of each */
  body.site .hero-pillars {
    grid-template-columns: repeat(3, 1fr);
    gap: 0 clamp(1rem, 2vw, 1.5rem);
    margin-bottom: 1.15rem;
  }
  body.site .pillar { display: block; }
  /* the deliberate break is for the narrow card; across the full measure it
     just leaves "log." stranded, so the line balances itself instead */
  body.site .hero-note br { display: none; }
  body.site .hero-note { text-wrap: balance; }
  body.site .hero-close { justify-content: space-between; gap: var(--s5); }
  body.site .hero-promise { margin: 0; text-align: right; flex: 0 1 auto; }
  /* the pillars now take two rows instead of three, so the card is shorter than
     the frame beside it. Stretching it and spreading the rows keeps the pair
     sharing a top and bottom edge. */
  body.site .hero-sub { align-self: stretch; align-content: space-between; }
}

body.site .hero-promise { justify-self: stretch; margin: .8rem 0 0; text-align: center; }

/* genuinely fine print: present and readable, never competing with the offer.
   The hand-rolled .42 alpha measured 3.75:1, under AA for 12px text, so this
   uses the surface's own dim token (6.25:1 on deep) instead. */
body.site .hero-fine {
  margin: var(--s4) 0 0; font-size: .75rem; line-height: 1.5;
  color: var(--ink-3); letter-spacing: .01em;
}

/* still used by the 404 button row */
body.site .hero-ctas { display: flex; gap: var(--s4); flex-wrap: wrap; align-items: center; }

body.site .display .acc-word { color: var(--accent-deep); }

/* ---------- fit lists (problem mirror + guardrail) ---------- */
body.site .manifesto-lede {
  font-family: var(--disp); font-size: clamp(1.7rem, 4.2vw, 3.4rem); font-weight: 700;
  font-variation-settings: "wdth" 94; line-height: 1.1; text-transform: uppercase;
  letter-spacing: -0.01em; max-width: 24ch; text-wrap: balance; position: relative; z-index: 1;
}
body.site .fit-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 6rem); margin-top: var(--s8); padding-top: var(--s6); border-top: 1px solid currentColor; position: relative; z-index: 1; }
@media (max-width: 760px) { body.site .fit-grid { grid-template-columns: 1fr; } }
body.site .fit-grid h3 { margin-bottom: var(--s4); }
body.site .fit-list { display: grid; gap: var(--s3); list-style: none; margin: 0; padding: 0; }
body.site .fit-list li { padding-left: 1.5em; position: relative; text-wrap: pretty; line-height: 1.5; }
body.site .fit-list li::before { content: "+"; position: absolute; left: 0; font-family: var(--mono); font-weight: 600; color: var(--accent-deep); }
body.site .fit-list--no li { opacity: .62; }
body.site .fit-list--no li::before { content: "\00d7"; color: inherit; opacity: .7; }

/* ---------- stage rows ---------- */
body.site .cap-list { border-top: 1px solid var(--paper-edge); }
body.site .cap-row {
  display: grid; grid-template-columns: 6ch 1fr 2fr; gap: clamp(1rem, 2.5vw, 1.5rem);
  align-items: baseline; padding-block: clamp(1.4rem, 3vh, 2.2rem);
  border-bottom: 1px solid var(--paper-edge);
  transition: background-color var(--dur) ease, padding-left var(--dur) var(--ease);
}
body.site .cap-row:hover { background: var(--paper-sunk); padding-left: var(--s3); }
body.site .cap-num { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: var(--track-mono); color: var(--accent-deep); }
body.site .cap-row h3 { font-family: var(--disp); font-weight: 700; font-variation-settings: "wdth" 96; text-transform: uppercase; font-size: clamp(1.2rem, 2.4vw, 1.9rem); }
body.site .cap-desc { color: var(--ink-2); max-width: 52ch; line-height: 1.55; }
@media (max-width: 760px) {
  body.site .cap-row { grid-template-columns: 6ch 1fr; }
  body.site .cap-desc { grid-column: 2; }
}

/* ---------- slant set: the /// motif as photo frames ----------
   Cards are skewed and the image counter-skewed inside, so the frame leans
   without distorting the photograph. Full-bleed, edge to edge. */
body.site #mdrn-life-05 { overflow-x: clip; }   /* 100vw ignores the scrollbar */
body.site .slantset {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(.7rem, 1.6vw, 1.6rem);
  width: 100vw; max-width: 100vw; margin-inline: calc(50% - 50vw);
  padding-inline: clamp(1.5rem, 5vw, 5rem);
}
body.site .slant { margin: 0; }
/* The skew makes the painted box wider than the layout box, which put 7px of
   horizontal scroll on every phone. Verified identical on production before
   the change, so this is an old defect rather than a new one. overflow-x:clip
   rather than hidden, because hidden creates a scroll container and would
   break any position:sticky inside the section. */
body.site .slantset { overflow-x: clip; }
body.site .slant-clip {
  position: relative; overflow: hidden;
  transform: skewX(-11deg);
  aspect-ratio: 3 / 3.4;
  background: var(--paper);
}
body.site .slant-clip img {
  position: absolute; top: 0; left: 50%;
  width: 132%; height: 100%;
  object-fit: cover;
  transform: translateX(-50%) skewX(11deg) scale(1.04);
  transition: transform var(--dur-slow) var(--ease);
}
body.site .slant:hover .slant-clip img { transform: translateX(-50%) skewX(11deg) scale(1.09); }
body.site .slant figcaption {
  display: flex; justify-content: space-between; gap: var(--s3);
  margin-top: var(--s4); flex-wrap: wrap;
}
@media (max-width: 760px) {
  body.site .slantset { grid-template-columns: 1fr; gap: var(--s6); }
  body.site .slant-clip { aspect-ratio: 4 / 3.4; transform: skewX(-7deg); }
  body.site .slant-clip img { transform: translateX(-50%) skewX(7deg) scale(1.04); width: 122%; }
  body.site .slant:hover .slant-clip img { transform: translateX(-50%) skewX(7deg) scale(1.04); }
}

/* dynamic entrance: the lean settles as the panel rises */
html.js body.site .slant {
  opacity: 0;
  transform: translateY(64px);
  transition: opacity .75s var(--ease), transform .75s var(--ease);
}
html.js body.site .slant .slant-clip {
  transform: skewX(-19deg) scaleY(.94);
  transition: transform .9s var(--ease);
}
html.js body.site .slant.is-inview { opacity: 1; transform: none; }
html.js body.site .slant.is-inview .slant-clip { transform: skewX(-11deg) scaleY(1); }
html.js body.site .slant[data-delay="1"],
html.js body.site .slant[data-delay="1"] .slant-clip { transition-delay: .12s; }
html.js body.site .slant[data-delay="2"],
html.js body.site .slant[data-delay="2"] .slant-clip { transition-delay: .24s; }
@media (max-width: 760px) {
  html.js body.site .slant .slant-clip { transform: skewX(-13deg) scaleY(.96); }
  html.js body.site .slant.is-inview .slant-clip { transform: skewX(-7deg) scaleY(1); }
}
@media (prefers-reduced-motion: reduce) {
  html.js body.site .slant { opacity: 1; transform: none; transition: none; }
  html.js body.site .slant .slant-clip,
  html.js body.site .slant.is-inview .slant-clip { transform: skewX(-11deg); transition: none; }
}

/* ---------- process ---------- */
body.site .xsteps { border-top: 1px solid var(--paper-edge); counter-reset: step; }
body.site .xstep {
  display: grid; grid-template-columns: 6ch 1fr; gap: clamp(1rem, 2.5vw, 1.5rem);
  padding-block: clamp(1.6rem, 3.5vh, 2.4rem); border-bottom: 1px solid var(--paper-edge);
  align-items: baseline;
}
body.site .xstep .n { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: var(--track-mono); color: var(--accent-deep); }
body.site .xstep h3 { margin-bottom: var(--s2); }
body.site .xstep p { color: var(--ink-2); max-width: 46rem; margin: 0; line-height: 1.6; }

/* ---------- stats ---------- */
body.site .stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s5); border-top: 1px solid currentColor; padding-top: var(--s6); position: relative; z-index: 1; }
@media (max-width: 760px) { body.site .stat-grid { grid-template-columns: repeat(2, 1fr); } }
body.site .stat-n { font-family: var(--disp); font-weight: 780; font-variation-settings: "wdth" 96; font-size: clamp(3rem, 8vw, 6.5rem); line-height: 1; font-variant-numeric: tabular-nums; }
body.site .stat-n .u { color: var(--accent-deep); }
body.site .stat-l { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: var(--track-mono); text-transform: uppercase; opacity: .7; margin-top: var(--s3); line-height: 1.6; max-width: 22ch; }

/* ---------- FAQ ---------- */
body.site .xfaq { border-top: 1px solid var(--paper-edge); }
body.site .xfaq details { border-bottom: 1px solid var(--paper-edge); }
body.site .xfaq summary {
  cursor: pointer; list-style: none; display: grid; grid-template-columns: 6ch 1fr auto;
  gap: clamp(1rem, 2.5vw, 1.5rem); align-items: baseline; padding-block: var(--s5);
}
body.site .xfaq summary::-webkit-details-marker { display: none; }
body.site .xfaq summary .q { font-family: var(--disp); font-weight: 660; font-variation-settings: "wdth" 96; font-size: clamp(1.05rem, 2vw, 1.45rem); }
body.site .xfaq summary .qn { font-family: var(--mono); font-size: var(--t-mono); color: var(--ink-3); }
body.site .xfaq summary .ind { font-family: var(--mono); color: var(--ink-3); transition: transform var(--dur) var(--ease); }
body.site .xfaq details[open] summary .ind { transform: rotate(45deg); }
body.site .xfaq .a { padding: 0 0 var(--s5); color: var(--ink-2); max-width: 46rem; line-height: 1.65; margin-left: calc(6ch + clamp(1rem, 2.5vw, 1.5rem)); }
@media (max-width: 700px) { body.site .xfaq .a { margin-left: 0; } }

/* ---------- CTA band ---------- */
body.site .cta-final { text-align: left; position: relative; z-index: 1; }
body.site .cta-final .display { font-size: clamp(2.2rem, 7.5vw, 6.5rem); }
body.site .cta-row { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s6); flex-wrap: wrap; margin-top: var(--s6); padding-top: var(--s5); border-top: 1px solid currentColor; }

/* ---------- footer ---------- */
body.site .xfooter { border-top: 1px solid var(--paper-edge); padding-block: var(--s6) calc(var(--s7) + var(--s4)); color: var(--ink-2); font-size: var(--t-small); }
body.site .xfooter a { color: inherit; }
body.site .xfooter .row { display: flex; justify-content: space-between; gap: var(--s4); flex-wrap: wrap; align-items: center; }

/* ---------- SplitText (pattern library #4): word-stagger hero choreography.
   Rest state = fully visible (the law: never gate visibility on an animation).
   The transient .pre class holds the hidden pose and is removed to enter. ---------- */
body.site [data-split] .w {
  display: inline-block;
  opacity: 1;
  transform: none;
  filter: none;
  transition: opacity .62s var(--ease), transform .62s var(--ease), filter .62s var(--ease);
  transition-delay: calc(var(--i) * 110ms);
}
body.site [data-split].pre .w {
  opacity: 0;
  transform: translateY(0.55em);
  filter: blur(6px);
  transition: none;
}
body.site [data-split].settled .w { transition: none; transition-delay: 0s; }
@media (prefers-reduced-motion: reduce) {
  body.site [data-split] .w, body.site [data-split].pre .w {
    opacity: 1; transform: none; filter: none; transition: none;
  }
}

/* ---------- TextRoll (pattern library #9): stacked-copy hover roll ---------- */
body.site .roll { position: relative; overflow: clip; display: inline-flex; flex-direction: column; height: 1.25em; line-height: 1.25; }
body.site .roll > span { display: block; transition: transform var(--dur) var(--ease); }
body.site .roll > span[aria-hidden] { position: static; user-select: none; }
body.site a:hover .roll > span, body.site .roll:hover > span { transform: translateY(-1.25em); }
@media (prefers-reduced-motion: reduce) { body.site a:hover .roll > span, body.site .roll:hover > span { transform: none; } }

/* ---------- StickyDeck (pattern library #3): pinned process scene, zero JS ---------- */
body.site .deck { display: grid; gap: var(--s5); }
body.site .deck-card {
  position: sticky;
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: var(--r-lg);
  padding: clamp(1.8rem, 4vw, 3rem);
  box-shadow: var(--shadow-md);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: clamp(1.2rem, 3vw, 2.5rem);
  align-items: start;
  min-height: 15rem;
}
body.site .deck-card:nth-child(1) { top: 88px; }
body.site .deck-card:nth-child(2) { top: 104px; }
body.site .deck-card:nth-child(3) { top: 120px; }
body.site .deck-card:nth-child(4) { top: 136px; }
body.site .deck-card .dn {
  font-family: var(--disp); font-weight: 780; font-variation-settings: "wdth" 96;
  font-size: clamp(2.6rem, 6vw, 4.5rem); line-height: 1; color: var(--accent-deep);
}
body.site .deck-card h3 { margin-bottom: var(--s3); }
body.site .deck-card p { color: var(--ink-2); max-width: 42rem; margin: 0; line-height: 1.6; }
@media (max-width: 640px) { body.site .deck-card { grid-template-columns: 1fr; min-height: 0; } }

/* ---------- MarkerHighlight: background-size sweep on a key phrase ---------- */
body.site .markr {
  background-image: linear-gradient(color-mix(in srgb, var(--accent-raw) 32%, transparent), color-mix(in srgb, var(--accent-raw) 32%, transparent));
  background-repeat: no-repeat;
  background-size: 0% 42%;
  background-position: 0 78%;
  transition: background-size .9s var(--ease) .25s;
}
html.js body.site .markr.is-inview { background-size: 100% 42%; }
html:not(.js) body.site .markr { background-size: 100% 42%; }
@media (prefers-reduced-motion: reduce) { body.site .markr { background-size: 100% 42%; transition: none; } }

/* ---------- FooterReveal (wave-2): footer pinned under the page, revealed at the end ---------- */
body.site .page-over { position: relative; z-index: 1; background: var(--paper); box-shadow: 0 24px 48px rgba(0,0,0,.18); }
body.site .xfooter-reveal {
  position: sticky; bottom: 0; z-index: 0;
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  /* top pad clears the fixed header so the tagline never runs under the nav */
  padding-block: clamp(6rem, 12vh, 9rem) calc(var(--s6) + var(--s4));
}
body.site .xfooter-reveal .display {
  font-size: clamp(1.9rem, 6.2vw, 5.4rem);
  line-height: .98;
}
body.site .xfooter-reveal .frow {
  display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s6);
  flex-wrap: wrap; margin-top: var(--s6); padding-top: var(--s5);
  border-top: 1px solid color-mix(in srgb, var(--ink) 22%, transparent);
}
body.site .xfooter-reveal .legal { display: flex; gap: var(--s5); flex-wrap: wrap; }
body.site .xfooter-reveal a:not(.btn) { color: inherit; }
body.site .xfooter-reveal .tiny { color: var(--ink-3); }

/* ---------- reveals ---------- */
html.js body.site .reveal { opacity: 0; transform: translateY(18px); transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease); }
html.js body.site .reveal.is-inview { opacity: 1; transform: none; }
html.js body.site .reveal[data-delay="1"] { transition-delay: 90ms; }
html.js body.site .reveal[data-delay="2"] { transition-delay: 180ms; }
html.js body.site .reveal[data-delay="3"] { transition-delay: 270ms; }
@media (prefers-reduced-motion: reduce) {
  html.js body.site .reveal { opacity: 1; transform: none; transition: none; }
}

/* The footer panel is a deep surface like any other, so the accent no longer
   has to be flipped by hand to keep "Stay Modern." legible. */
body.site .xfooter-reveal .acc-word { color: var(--accent-deep); }

/* the horizontal lockup, sitting in the negative space beside the tagline */
/* the lockup sits in the negative space beside the short last line */
body.site .tagrow { position: relative; }
body.site .lockup-h {
  display: flex; align-items: center; gap: clamp(.5rem, 1.1vw, .9rem);
}
body.site .lockup-h img { width: clamp(34px, 4.2vw, 62px); height: auto; display: block; }
body.site .lockup-h .lockup-word {
  font-family: var(--disp); font-weight: 800;
  font-variation-settings: "wdth" 92;
  font-size: clamp(1.05rem, 2.5vw, 2rem);
  letter-spacing: .14em; line-height: 1;
  padding-bottom: .14em;
  border-bottom: clamp(3px, .34vw, 6px) solid #E62B12;
}
@media (min-width: 900px) {
  body.site .lockup-h { position: absolute; right: 0; bottom: .35em; }
}
@media (max-width: 899px) {
  body.site .lockup-h { margin-top: var(--s5); }
}

/* ============================================================
   THE INTAKE
   Same typography, same colour, same rules as the marketing
   surface. A funnel that changes design language halfway
   through reads as a handoff to a different company.
   ============================================================ */

body.site.intake { background: var(--paper); }
/* THIS RULE DID NOTHING FOR MONTHS.
   app.css:28 sets .narrow { max-width: var(--measure) } and --measure is
   34rem, and max-width beats width, so the intake rendered in a 544px column
   while this line asked for 736px. Raising the token is the fix, because the
   token is the thing app.css is actually reading. 192px of instrument surface
   came back for one declaration. */
body.site.intake { --measure: 46rem; }
body.site.intake .wrap.narrow { width: min(100% - 2 * var(--edge), var(--measure)); }

/* ---------- the bar ---------- */
body.site .intake-bar {
  position: fixed; inset: 0 0 auto 0; z-index: 40;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(14px) saturate(1.3);
  border-bottom: 1px solid var(--paper-edge);
  color: var(--ink);
}
body.site .intake-bar .wrap { display: flex; align-items: center; justify-content: space-between; padding-block: var(--s4); }
body.site .intake-bar .steps-meter { height: 3px; margin: 0; border-radius: 0; background: var(--paper-edge); }
body.site .intake-bar .steps-fill { background: var(--accent-raw-red, #E62B12); }
body.site .intake-main { padding-top: clamp(6.5rem, 12vh, 8rem); padding-bottom: clamp(8rem, 16vh, 10rem); }

/* ---------- a step ---------- */
body.site .step-h {
  font-family: var(--disp); font-weight: 680; letter-spacing: -0.028em;
  font-size: clamp(1.75rem, 4.4vw, 2.9rem); line-height: 1.04;
  margin-top: var(--s4); text-wrap: balance;
}
body.site .step-sub {
  font-size: clamp(1rem, 1.5vw, 1.15rem); line-height: 1.55;
  color: var(--ink-2); margin-top: var(--s4); max-width: 34rem; text-wrap: pretty;
}
body.site .step-panel { animation: stepin .42s var(--ease) both; }
@keyframes stepin { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { body.site .step-panel { animation: none; } }

body.site .intake .field { margin-top: var(--s6); margin-bottom: 0; }
body.site .intake .field > .lab {
  font-family: var(--disp); font-weight: 620; letter-spacing: -0.018em;
  font-size: 1.08rem; margin-bottom: var(--s3); display: block; line-height: 1.3;
}
body.site .intake .field > .hint { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .04em; color: var(--ink-3); margin-top: var(--s3); margin-bottom: 0; }
body.site .intake input[type="text"], body.site .intake input[type="email"], body.site .intake textarea {
  font-family: var(--body); font-size: 1.05rem; border-radius: 12px;
  border: 1px solid var(--paper-edge); background: var(--paper-raised); padding: 14px 16px;
}
body.site .intake .choice {
  border-radius: 12px; border: 1px solid var(--paper-edge); background: var(--paper-raised);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
body.site .intake .choice:hover { border-color: var(--ink-4); transform: translateY(-1px); }
body.site .intake .choice-t { font-family: var(--disp); font-weight: 600; letter-spacing: -0.012em; font-size: 1.02rem; }
body.site .intake .choice:has(input:checked) { border-color: var(--accent-deep); background: var(--signal-soft); }
body.site .intake .tiny { margin-top: var(--s5); color: var(--ink-3); }

/* the consent promise, written as a list because that is how it gets read */
body.site .promise {
  margin-top: var(--s6); padding: var(--s5); border-radius: 14px;
  background: var(--paper-sunk); border-left: 3px solid var(--accent-raw-red, #E62B12);
}
body.site .promise h3 { font-family: var(--disp); font-weight: 640; letter-spacing: -0.018em; font-size: 1.05rem; }
body.site .promise ul { margin: var(--s3) 0 0; padding: 0; list-style: none; display: grid; gap: var(--s2); }
body.site .promise li { position: relative; padding-left: 1.4em; color: var(--ink-2); line-height: 1.5; }
body.site .promise li::before { content: "+"; position: absolute; left: 0; font-family: var(--mono); font-weight: 600; color: var(--accent-deep); }

/* ---------- the sticky foot ---------- */
body.site .intake-foot {
  position: fixed; inset: auto 0 0 0; z-index: 40; margin: 0;
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  backdrop-filter: blur(14px) saturate(1.3);
  border-top: 1px solid var(--paper-edge);
  padding-bottom: env(safe-area-inset-bottom);
}
body.site .intake-foot .wrap { display: flex; gap: var(--s3); justify-content: space-between; align-items: center; padding-block: var(--s4); }
body.site .intake-foot #next { margin-left: auto; }
body.site .intake-foot[hidden] { display: none; }

/* ============================================================
   THE REVEAL
   The payoff goes dark on purpose: it is the one moment in the
   funnel that should feel like an arrival rather than a form.
   ============================================================ */

body.site.is-reveal { background: var(--paper); }
body.site.is-reveal .intake-bar {
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  border-bottom-color: rgba(243,242,236,.14); color: #F3F2EC;
}
body.site.is-reveal .intake-bar .steps-meter { background: rgba(243,242,236,.16); }
body.site.is-reveal #stepcount { display: none; }
body.site.is-reveal { color: #F3F2EC; }
body.site.is-reveal .step-h { color: #F3F2EC; }
body.site.is-reveal .step-sub { color: rgba(243,242,236,.7); }
body.site.is-reveal .xmono.dim { color: rgba(243,242,236,.55); }
body.site.is-reveal .tag::before, body.site.is-reveal .tag::after { color: rgba(243,242,236,.4); }
body.site.is-reveal .xmono.acc { color: var(--accent-raw); }
body.site.is-reveal .tiny { color: rgba(243,242,236,.5); }

#reveal { animation: revealin .6s var(--ease) both; }
@keyframes revealin { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { #reveal { animation: none; } }

body.site .held {
  margin-top: var(--s5); padding: var(--s4) var(--s5); border-radius: 12px;
  background: rgba(80,201,242,.09); border-left: 3px solid var(--accent-raw);
}
body.site .held h3 { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: var(--track-mono); text-transform: uppercase; color: var(--accent-raw); }
body.site .held p { margin-top: var(--s2); color: rgba(243,242,236,.82); line-height: 1.5; }

body.site .tease-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
  margin-top: var(--s7); background: rgba(243,242,236,.14);
  border: 1px solid rgba(243,242,236,.14); border-radius: 14px; overflow: hidden;
}
@media (min-width: 700px) { body.site .tease-grid { grid-template-columns: repeat(4, 1fr); } }
body.site .tease-stat { background: var(--paper); padding: var(--s5) var(--s4); }
body.site .tease-n {
  font-family: var(--disp); font-weight: 700; letter-spacing: -0.04em;
  font-size: clamp(2.4rem, 6vw, 3.4rem); line-height: 1; color: var(--accent-raw);
}
body.site .tease-l { font-size: .92rem; line-height: 1.35; color: rgba(243,242,236,.62); margin-top: var(--s2); text-wrap: pretty; }

body.site .tease-plate {
  margin-top: var(--s5); padding: var(--s5);
  border: 1px solid rgba(243,242,236,.14); border-radius: 14px;
}
body.site .tease-plate-v {
  font-family: var(--disp); font-weight: 620; letter-spacing: -0.02em;
  font-size: clamp(1.1rem, 2.4vw, 1.5rem); line-height: 1.3; margin-top: var(--s3); color: #F3F2EC;
}

body.site .tease-three { margin-top: var(--s5); }
body.site .tease-three ol { margin: var(--s3) 0 0; padding: 0; list-style: none; counter-reset: t; display: grid; gap: var(--s2); }
body.site .tease-three li {
  counter-increment: t; position: relative; padding: var(--s3) 0 var(--s3) 2.4em;
  border-bottom: 1px solid rgba(243,242,236,.12);
  font-family: var(--disp); font-weight: 580; letter-spacing: -0.015em; font-size: 1.1rem; color: #F3F2EC;
}
body.site .tease-three li::before {
  content: counter(t, decimal-leading-zero); position: absolute; left: 0; top: var(--s3);
  font-family: var(--mono); font-size: var(--t-mono); font-weight: 600;
  letter-spacing: var(--track-mono); color: var(--accent-raw-red, #E62B12);
}
body.site .tease-three .tiny { margin-top: var(--s4); }

/* ---------- the gate ---------- */
body.site .gate {
  margin-top: var(--s7); padding: clamp(1.5rem, 4vw, 2.5rem);
  background: var(--paper); color: var(--ink); border-radius: 18px;
}
body.site .gate-h { font-family: var(--disp); font-weight: 680; letter-spacing: -0.028em; font-size: clamp(1.5rem, 3.2vw, 2.1rem); line-height: 1.05; }
body.site .gate-sub { margin-top: var(--s3); color: var(--ink-2); line-height: 1.5; max-width: 30rem; }
body.site .gate-fields { display: grid; grid-template-columns: 1fr; gap: var(--s4); margin-top: var(--s5); }
@media (min-width: 620px) { body.site .gate-fields { grid-template-columns: 1fr 1fr; } body.site .gfield-wide { grid-column: 1 / -1; } }
body.site .gfield { display: block; }
body.site .gfield > span {
  display: block; font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: var(--track-mono); text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--s2);
}
body.site .gate input[type="text"], body.site .gate input[type="email"] {
  width: 100%; font-family: var(--body); font-size: 1.05rem; color: var(--ink);
  background: var(--paper-raised); border: 1px solid var(--paper-edge); border-radius: 11px; padding: 14px 16px;
}
body.site .gate input:focus { border-color: var(--accent-deep); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-deep) 22%, transparent); outline: none; }
body.site .gfield.has-error input { border-color: var(--clay); box-shadow: 0 0 0 4px color-mix(in srgb, var(--clay) 18%, transparent); }
body.site .gerr { display: block; margin-top: 6px; font-size: .88rem; color: var(--clay); }
body.site .opt { display: flex; gap: var(--s3); align-items: flex-start; margin-top: var(--s4); font-size: .95rem; color: var(--ink-2); line-height: 1.45; cursor: pointer; }
body.site .opt input { margin-top: .25em; accent-color: var(--accent-deep); width: 18px; height: 18px; flex: none; }
body.site .gate-go { margin-top: var(--s5); width: 100%; justify-content: center; }
@media (min-width: 620px) { body.site .gate-go { width: auto; } }
body.site .gate-go:disabled { opacity: .55; cursor: progress; }
body.site .gate-fine { margin-top: var(--s4); font-family: var(--mono); font-size: var(--t-mono); letter-spacing: .04em; color: var(--ink-3); }

/* ---------- delivered ---------- */
#delivered { animation: revealin .5s var(--ease) both; }
body.site .done-actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s6); }
body.site.is-reveal .done-actions .btn-ghost { color: #F3F2EC; box-shadow: inset 0 0 0 1px rgba(243,242,236,.45); }

/* the guardrail stop, on the dark surface */
body.site .intake .guard-stop { margin-top: var(--s6); background: rgba(244,105,78,.1); border-left-color: #F4694E; }
body.site .intake .guard-stop h3 { color: #F4694E; font-family: var(--disp); font-weight: 640; letter-spacing: -0.018em; }
body.site .intake .guard-stop p { margin-top: var(--s3); line-height: 1.55; color: var(--ink-2); }

/* ============================================================
   WHO THIS IS FOR + the honest early-days panel
   ============================================================ */

body.site .xheader-end { display: flex; align-items: center; gap: 12px; }

body.site .who-grid { display: grid; grid-template-columns: 1fr; gap: 1px; background: var(--paper-edge); border: 1px solid var(--paper-edge); border-radius: 16px; overflow: hidden; }
@media (min-width: 760px) { body.site .who-grid { grid-template-columns: 1fr 1fr; } }
body.site .who { background: var(--paper); padding: clamp(1.4rem, 3vw, 2.2rem); }
body.site .who > .xmono { display: block; margin-bottom: var(--s4); }
body.site .who h3 { font-family: var(--disp); font-weight: 640; letter-spacing: -0.022em; font-size: clamp(1.1rem, 2vw, 1.35rem); line-height: 1.2; text-wrap: balance; }
body.site .who p { margin-top: var(--s3); color: var(--ink-2); line-height: 1.55; text-wrap: pretty; }

body.site .early {
  margin-top: var(--s7); padding: clamp(1.6rem, 4vw, 3rem);
  border-radius: 18px;
}
body.site .early > .xmono { color: var(--accent-deep); }
body.site .early h3 { font-family: var(--disp); font-weight: 680; letter-spacing: -0.03em; font-size: clamp(1.5rem, 3.4vw, 2.3rem); line-height: 1.05; margin-top: var(--s3); text-wrap: balance; }
body.site .early p { margin-top: var(--s4); max-width: 40rem; line-height: 1.6; opacity: .78; text-wrap: pretty; }
body.site .early .btn { margin-top: var(--s5); }

/* The 404 hero: layout only. Its darkness comes from data-surface="deep",
   the same way every other dark area on the site gets it. */
body.site .xhero-lite { min-height: 76vh; display: flex; align-items: center; }
body.site .xhero-lite .lead { color: var(--ink-2); }

/* ============================================================
   MOBILE MENU
   ============================================================ */

body.site .menu-btn { display: none; }
@media (max-width: 860px) {
  body.site .xheader-end .signin { display: none; }
  body.site .menu-btn {
    display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
    width: 40px; height: 40px; padding: 0 9px; border: 0; background: transparent;
    color: currentColor; cursor: pointer; border-radius: 999px;
  }
  body.site .menu-btn span[aria-hidden] { display: block; height: 1.5px; width: 100%; background: currentColor; transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease); }
  body.site .menu-btn[aria-expanded="true"] span[aria-hidden]:first-child { transform: translateY(3.25px) rotate(45deg); }
  body.site .menu-btn[aria-expanded="true"] span[aria-hidden]:nth-child(2) { transform: translateY(-3.25px) rotate(-45deg); }
}
body.menu-open { overflow: hidden; }
/* A fixed dark surface, not var(--ink): those tokens invert with the colour
   scheme, which flipped the sheet to paper-on-paper in dark mode and made the
   quieter links disappear. The hero and the reveal are committed dark too. */
body.site .menu-sheet {
  position: fixed; inset: 0; z-index: 60; background: var(--paper); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .24s var(--ease);
}
/* the toggle has to stay above its own sheet, or there is no visible way out */
body.menu-open .xheader { z-index: 70; color: #F3F2EC; background: transparent; backdrop-filter: none; border-bottom-color: transparent; }
body.site .menu-sheet.is-open { opacity: 1; }
body.site .menu-sheet[hidden] { display: none; }
body.site .menu-sheet nav { display: grid; gap: var(--s5); text-align: center; padding: var(--s6); width: min(100%, 30rem); }
body.site .menu-sheet nav a {
  font-family: var(--disp); font-weight: 640; letter-spacing: -0.028em;
  font-size: clamp(1.7rem, 8vw, 2.4rem); line-height: 1; color: #F3F2EC; text-decoration: none;
}
body.site .menu-sheet .menu-cta { font-size: 1rem; letter-spacing: var(--track-mono); justify-self: center; margin-top: var(--s3); background: var(--accent-raw); color: #06141B; }
body.site .menu-sheet .menu-signin { font-size: var(--t-mono); font-family: var(--mono); color: rgba(243,242,236,.6); letter-spacing: var(--track-mono); text-transform: uppercase; }

/* [hidden] is a low-specificity UA rule, so any component that sets display
   (every .btn does) silently defeats it. This puts it back. */
body.site [hidden] { display: none !important; }

/* the promise strip: break between claims, never inside one */
body.site .promise-strip span { white-space: nowrap; }
body.site .promise-strip i { font-style: normal; margin: 0 .2em; opacity: .45; }




/* ============================================================
   SHOP
   Everything reads from the surface tokens, so a card is correct on paper,
   sunk or deep without a single per-surface override.
   ============================================================ */
body.site .btn-sm { padding: .6em 1.1em; font-size: .68rem; }
body.site .pill {
  display: inline-block; font-family: var(--mono); font-size: .64rem;
  letter-spacing: var(--track-mono); text-transform: uppercase;
  padding: 3px 9px; border-radius: var(--r-full);
  background: var(--paper-raised); color: var(--ink-2); border: 1px solid var(--paper-edge);
}
body.site .pill-signal { color: var(--accent-deep); border-color: var(--accent-deep); }
body.site .muted { color: var(--ink-3); }

body.site .shop-notice {
  margin-bottom: var(--s6); padding: clamp(1.2rem, 3vw, 1.8rem);
  border: 1px solid var(--paper-edge); border-left: 3px solid var(--accent-raw-red, #E62B12);
  border-radius: 14px; background: var(--paper-sunk);
}
body.site .shop-notice p { margin: var(--s3) 0 0; max-width: 46rem; line-height: 1.55; }
body.site .shop-notice .btn { margin-top: var(--s4); }

body.site .skugrid {
  display: grid; gap: clamp(1rem, 2vw, 1.4rem);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
body.site .skucard {
  display: grid; gap: var(--s3); align-content: start;
  padding: clamp(1.2rem, 2.4vw, 1.6rem);
  border: 1px solid var(--paper-edge); border-radius: 16px;
  background: var(--paper-raised); color: inherit; text-decoration: none;
  transition: transform var(--dur) var(--ease), border-color var(--dur) ease;
}
body.site .skucard:hover { transform: translateY(-2px); border-color: var(--ink-4); }
body.site .skucard-ico { display: block; width: 34px; height: 34px; color: var(--accent-deep); }
/* the icon set is stroke-based with fill:none. Styling colour alone leaves
   them filled solid black, which is how they first shipped here. */
body.site .skucard-ico svg, body.site .prod-fig svg, body.site .cartrow-ico svg {
  stroke: var(--accent-deep); fill: none;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
body.site .skucard-ico svg { width: 100%; height: 100%; }
body.site .skucard-name { font-family: var(--disp); font-weight: 650; font-size: 1.15rem; letter-spacing: -0.02em; }
body.site .skucard-why { color: var(--ink-2); line-height: 1.5; font-size: .95rem; }
body.site .skucard-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s2); }
body.site .skucard-price { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: var(--track-mono); }

body.site .prod { display: grid; gap: clamp(1.5rem, 4vw, 3rem); margin-top: var(--s5); }
@media (min-width: 820px) { body.site .prod { grid-template-columns: 18rem 1fr; align-items: start; } }
body.site .prod-fig {
  display: grid; place-items: center; aspect-ratio: 1;
  border: 1px solid var(--paper-edge); border-radius: 18px; background: var(--paper-raised);
}
body.site .prod-fig svg { width: 42%; height: 42%; color: var(--accent-deep); }
body.site .prod-price { font-family: var(--mono); font-size: 1rem; letter-spacing: var(--track-mono); margin-top: var(--s4); color: var(--accent-deep); }
body.site .prod-skip { margin-top: var(--s4); color: var(--ink-3); line-height: 1.55; max-width: 40rem; }
body.site .prod-buy { display: flex; gap: var(--s4); align-items: flex-end; flex-wrap: wrap; margin-top: var(--s6); }
body.site .prod-buy select {
  font-family: var(--body); font-size: 1rem; color: var(--ink);
  background: var(--paper-raised); border: 1px solid var(--paper-edge);
  border-radius: 11px; padding: 12px 14px; min-width: 6rem;
}

body.site .cartlist { margin-top: var(--s5); border-top: 1px solid var(--paper-edge); }
body.site .cartrow {
  display: grid; align-items: center; gap: var(--s4);
  grid-template-columns: 42px 1fr auto auto;
  padding-block: var(--s4); border-bottom: 1px solid var(--paper-edge);
}
@media (max-width: 640px) { body.site .cartrow { grid-template-columns: 42px 1fr; } }
body.site .cartrow-ico { width: 30px; height: 30px; color: var(--accent-deep); }
body.site .cartrow-ico svg { width: 100%; height: 100%; }
body.site .cartrow-name { font-weight: 600; }
body.site .cartrow-price { color: var(--ink-3); font-size: .9rem; }
body.site .cartrow-qty { display: flex; gap: var(--s3); align-items: center; }
body.site .cartrow-qty select {
  font-family: var(--body); color: var(--ink); background: var(--paper-raised);
  border: 1px solid var(--paper-edge); border-radius: 9px; padding: 8px 10px;
}
body.site .cartrow-total { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: var(--track-mono); }
body.site .cartfoot {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s4); margin-top: var(--s5);
}
body.site .cartfoot-total { font-family: var(--disp); font-weight: 700; font-size: clamp(1.6rem, 4vw, 2.4rem); letter-spacing: -0.02em; }

/* two real choices, never a pre-ticked recurring default */
body.site .buy-choice { display: flex; gap: var(--s4); flex-wrap: wrap; }
body.site .buy-choice .btn { display: grid; gap: 3px; text-align: center; line-height: 1.2; }
body.site .buy-note {
  display: block; font-size: .58rem; letter-spacing: .06em;
  opacity: .72; text-transform: none; font-weight: 500;
}
body.site .buy-fine { margin-top: var(--s4); font-size: .88rem; color: var(--ink-3); line-height: 1.5; }
body.site .cart-saved {
  margin-top: var(--s3); color: var(--accent-deep); font-size: .95rem; line-height: 1.5;
}

/* section 01: the emotional lede above the numbered steps, and the ask below */
body.site .deck-lede {
  max-width: 46rem; margin: 0 0 clamp(2rem, 4vh, 3rem);
  font-size: clamp(1.05rem, 1.6vw, 1.25rem); line-height: 1.55;
  color: var(--ink-2); text-wrap: pretty;
}
body.site .deck-close {
  display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap;
  margin-top: clamp(2.5rem, 5vh, 3.5rem);
  padding-top: var(--s5); border-top: 1px solid var(--paper-edge);
}
body.site .deck-close p { margin: 0; }

/* The exact form, in the same position on the page as it sits on the pack.
   Mono and accent because it is a specification, not prose. */
body.site .skucard-form, body.site .prod-form {
  font-family: var(--mono); font-size: .68rem; letter-spacing: var(--track-mono);
  text-transform: uppercase; color: var(--accent-deep); margin: 0;
}
body.site .prod-form { margin-top: var(--s3); }

/* The fit panel: who it suits, then who can skip it. Deliberately NOT red and
   deliberately not an imperative. A red keyline and "do not buy" is the visual
   grammar of a hazard label, which is alarming on a calm product and makes red
   mean two contradictory things when red is the brand's signature rule. */
body.site .fitpanel {
  margin-top: var(--s5); padding: clamp(1rem, 2.2vw, 1.35rem);
  border: 1px solid var(--paper-edge); border-radius: 14px;
  max-width: 40rem;
}
body.site .fit-h {
  margin: 0; font-family: var(--mono); font-size: var(--t-mono);
  letter-spacing: var(--track-mono); text-transform: uppercase; color: var(--accent-deep);
}
body.site .fit-h--skip { margin-top: var(--s4); color: var(--ink-3); }
body.site .fit-b { margin: var(--s2) 0 0; line-height: 1.55; color: var(--ink-2); }
body.site .fit-b--skip { color: var(--ink-3); }

/* ============================================================
   /continue — the offer. Two tier cards inside one form; the radio is the
   card. Everything reads from surface tokens, so the deep section needs no
   per-card overrides.
   ============================================================ */

/* ---------- the offer ---------- *
   The page asks for money once. Everything here exists to answer a question
   somebody has at the moment they are deciding, in the order they ask it:
   what arrives, why it is free first, what it costs, what happens if I hate
   it, and why I should believe any of you. */
body.site .offer-block { margin-top: clamp(2rem, 4vw, 3rem); }
body.site .offer-list {
  display: grid; gap: var(--s3); margin: var(--s5) 0 0; padding: 0; list-style: none;
}
body.site .offer-list li {
  position: relative; padding-left: 1.6rem; color: var(--ink-2);
  font-size: clamp(1rem, .4vw + .95rem, 1.08rem); line-height: 1.55;
}
/* A rule rather than a bullet. The list is five specific objects, and a row
   of dots makes them read as marketing points instead. */
body.site .offer-list li::before {
  content: ""; position: absolute; left: 0; top: .72em;
  width: .9rem; height: 2px; background: var(--acc); border-radius: 2px;
}
body.site .offer-list strong { color: var(--ink); font-weight: 600; }

body.site .guarantee {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding: clamp(1.3rem, 2.6vw, 1.8rem);
  border: 1px solid var(--signal-edge); border-radius: 18px;
  background: var(--signal-soft);
}
body.site .guarantee-h {
  font-family: var(--disp); font-weight: 700;
  font-size: clamp(1.25rem, 1.4vw + 1rem, 1.75rem); line-height: 1.15;
  color: var(--ink); margin-top: var(--s3);
}
body.site .guarantee .lead { color: var(--ink-2); }

body.site .offer-proof {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--paper-edge); padding-top: clamp(1.5rem, 3vw, 2.25rem);
}

body.site .tiergrid { display: grid; gap: clamp(1rem, 2vw, 1.5rem); }
@media (min-width: 720px) { body.site .tiergrid { grid-template-columns: 1fr 1fr; align-items: stretch; } }
body.site .tiercard {
  display: grid; gap: var(--s3); align-content: start;
  padding: clamp(1.3rem, 2.6vw, 1.8rem);
  border: 1px solid var(--paper-edge); border-radius: 18px;
  background: var(--paper-raised); cursor: pointer;
  transition: border-color var(--dur) ease, transform var(--dur) var(--ease);
}
body.site .tiercard:hover { transform: translateY(-2px); }
/* Selected and focused states. The server-rendered .is-picked is the fallback
   for engines without :has(), so the default choice is never invisible, and
   :focus-within makes the radio reachable by keyboard even though it is
   visually hidden. */
body.site .tiercard.is-picked,
body.site .tiercard:has(input:checked) { border-color: var(--accent-deep); box-shadow: inset 0 0 0 1px var(--accent-deep); }
body.site .tiercard:has(input:checked) ~ .tiercard.is-picked:not(:has(input:checked)) { border-color: var(--paper-edge); box-shadow: none; }
body.site .tiercard:focus-within { outline: 2px solid var(--accent-deep); outline-offset: 3px; }
body.site .tiercard input { position: absolute; opacity: 0; width: 1px; height: 1px; }
body.site .tiercard-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); }
body.site .tiercard-name { font-family: var(--disp); font-weight: 700; font-size: 1.3rem; letter-spacing: -0.02em; }
body.site .tiercard-price { font-family: var(--disp); font-weight: 780; font-size: clamp(1.9rem, 4vw, 2.5rem); letter-spacing: -0.02em; }
body.site .tiercard-price em { font-style: normal; font-family: var(--mono); font-size: var(--t-mono); letter-spacing: var(--track-mono); text-transform: uppercase; color: var(--ink-3); }
body.site .tiercard-free { font-family: var(--mono); font-size: var(--t-mono); letter-spacing: var(--track-mono); text-transform: uppercase; color: var(--accent-deep); }
body.site .tiercard-terms { color: var(--ink-2); font-size: .92rem; line-height: 1.55; }
body.site .tiercard-eff { color: var(--ink-3); font-size: .85rem; border-top: 1px solid var(--paper-edge); padding-top: var(--s3); }

/* the post-delivery doorway on the intake reveal (deep surface) */
body.site .keep-going {
  margin-top: var(--s6); padding: clamp(1.2rem, 3vw, 1.6rem);
  border: 1px solid rgba(243,242,236,.14); border-radius: 14px; max-width: 44rem;
}
body.site .keep-going .kg-line { margin: var(--s3) 0 0; line-height: 1.55; color: rgba(243,242,236,.82); }
body.site .keep-going .kg-line.dim { color: rgba(243,242,236,.55); font-size: .92rem; }
body.site .keep-going .btn { margin-top: var(--s4); }

/* dictation on the intake (deep surface): same control, surface-token driven */
body.site .dictate { position: relative; display: block; }
body.site .dictate > textarea, body.site .dictate > input { width: 100%; padding-right: 48px; }
body.site .dictate-btn {
  position: absolute; top: 8px; right: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  border: 1px solid var(--paper-edge); border-radius: var(--r-full);
  background: var(--paper-raised); color: var(--ink-3); cursor: pointer;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease;
}
body.site .dictate-btn:hover { color: var(--ink); border-color: var(--ink-4); }
body.site .dictate-btn:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 2px; }
body.site .dictate.is-listening .dictate-btn { color: var(--on-signal); background: var(--accent-deep); border-color: var(--accent-deep); }
body.site .dictate.is-listening .dictate-btn::after {
  content: ""; position: absolute; inset: -4px; border-radius: inherit;
  border: 2px solid var(--accent-deep); opacity: .5; animation: dictate-pulse 1.6s ease-out infinite;
}
@keyframes dictate-pulse { to { transform: scale(1.35); opacity: 0 } }
@media (prefers-reduced-motion: reduce) { body.site .dictate.is-listening .dictate-btn::after { animation: none; opacity: .6 } }
body.site .dictate-status { margin: var(--s2) 0 0; font-size: .82rem; line-height: 1.4; color: var(--ink-3); min-height: 1.1em; }

/* ============================================================
   PLATFORM LAYER
   The details that decide whether a web app reads as an app or as a website
   in a browser. None of it is decorative; each rule fixes a specific tell.
   ============================================================ */

/* 1. The grey flash on tap is the loudest "this is a web page" signal there
      is. Removing it without replacing the feedback is worse, so every
      interactive thing gets a real pressed state below. */
a, button, [role="button"], label, summary, .choice, .floor-item, .ck-opt, .tiercard, .skucard {
  -webkit-tap-highlight-color: transparent;
}
/* 2. touch-action: manipulation kills the 300ms double-tap-zoom wait on
      controls, which is what makes taps feel laggy rather than instant. */
a, button, [role="button"], input, select, textarea, label, summary {
  touch-action: manipulation;
}
/* 3. Pressed states, since the highlight is gone. Scale is deliberately tiny:
      enough to feel, not enough to look like a toy. */
@media (hover: none) {
  button:active, .btn:active, [role="button"]:active,
  .choice:active, .floor-item:active, .ck-opt:active, .skucard:active, .tiercard:active {
    transform: scale(.985);
  }
  .btn, button, .choice, .floor-item, .ck-opt, .skucard, .tiercard { transition: transform .08s ease-out; }
}
@media (prefers-reduced-motion: reduce) {
  button:active, .btn:active, [role="button"]:active,
  .choice:active, .floor-item:active, .ck-opt:active, .skucard:active, .tiercard:active { transform: none; }
}

/* 4. Scroll chaining. Without this, scrolling past the end of a panel drags
      the page behind it, which no native app does. */
html { overscroll-behavior-y: none; }
body { overscroll-behavior: none; }

/* 5. iOS silently inflates text in landscape unless told not to. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* 6. Any control under 16px makes iOS zoom the whole page on focus, and the
      page never zooms back. This is a floor, not a style. */
input, select, textarea { font-size: max(16px, 1rem); }

/* 7. Chrome, not content, should not be selectable: long-pressing a nav label
      and getting a text-selection popover is a browser behaviour, not an app
      one. Body copy stays selectable on purpose. */
.appbar, .tabbar, .xheader, .xnav, .dictate-btn, .readout dt { -webkit-user-select: none; user-select: none; }

/* 8. Fixed chrome has to clear the notch in landscape too, not just the home
      indicator at the bottom. */
.appbar, .xheader { padding-top: env(safe-area-inset-top); }
.appbar, .xheader, .tabbar, main, .wrap {
  padding-left: max(var(--edge, 0px), env(safe-area-inset-left));
  padding-right: max(var(--edge, 0px), env(safe-area-inset-right));
}

/* 9. Touch targets. WCAG 2.2 asks 24px; native guidance asks 44. Chrome takes
      the larger number because a mistap in a nav is more costly than one in a
      list. */
.tabbar a, .appbar a, .appbar button, .dictate-btn { min-height: 44px; min-width: 44px; }

/* 10. In an installed app there is no browser chrome to fall back on, so the
       standalone class (set by app.js) gets a little more room at the top and
       loses anything that only makes sense in a tab. */
.is-standalone .appbar { padding-top: max(env(safe-area-inset-top), 12px); }

/* ---- invitation ribbon -------------------------------------------------
   Shown only to someone who arrived on a member's link. It sits between the
   header and the hero rather than floating, because it is a fact about the
   visit, not an ad, and a dismissible overlay would just be one more thing
   to close. */
.invite-ribbon {
  /* Two things bury this if you let them. The header is fixed and the hero
     deliberately slides under it, so the top padding clears the bar. And the
     footer-reveal is a sticky layer the page content sits above via a z-index
     on main, so anything outside main paints underneath it. Joining that same
     layer is what makes the ribbon visible at all. */
  position: relative;
  z-index: 1;
  padding: calc(4.3rem + var(--s3)) 0 var(--s3);
  border-bottom: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
}
.invite-ribbon p {
  margin: 0;
  font-size: .95rem;
  line-height: 1.5;
  color: var(--ink-2);
}
.invite-ribbon strong { color: var(--ink); }
@media (max-width: 40rem) {
  .invite-ribbon p { font-size: .88rem; }
}

/* ---- intake resume notice ----------------------------------------------
   Shown only when answers were restored from this device. It states what
   happened and offers the way out, because a form that refills itself with
   no explanation reads as surveillance rather than convenience. */
.resume-note {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
  margin-bottom: var(--s5); padding: var(--s3) var(--s4);
  border: 1px solid var(--line); border-radius: var(--r2, 10px);
  font-size: .9rem; color: var(--ink-2);
}
.resume-note .linkish {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: var(--ink); text-decoration: underline;
  text-underline-offset: 3px;
}
.resume-note .linkish:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---- the promises page -------------------------------------------------
   Eight statements, set large. The first version rendered fifty assertion
   names in monospace, which read as a changelog and buried the one claim that
   matters. The proof is now a number, and the list is folded away for the few
   who want it. */
.promises { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s7); counter-reset: p; }
/* SCOPED, BECAUSE THIS CLASS NAME IS USED TWICE IN THE PRODUCT.
   Unscoped, this matched the consent block on the intake as well, and because
   it sits 560 lines below that block's own rule it won on display. So the
   safety consent, the single most legally important screen in the funnel, laid
   its heading and its list out side by side in two narrow columns on a phone.
   Two different things wanted the same word; only one of them gets the bare
   selector, and it is not this one. */
.promises .promise { display: flex; gap: var(--s5); align-items: flex-start; }
.promises .promise-n {
  flex: none; font: 600 .8rem/1.6 var(--font-mono, ui-monospace, monospace);
  color: var(--accent); padding-top: .45rem; letter-spacing: .08em;
}
.promises .promise h2 { font-size: clamp(1.4rem, 3.4vw, 2.05rem); line-height: 1.18; margin: 0; letter-spacing: -.01em; }
.promises .promise p { margin: var(--s3) 0 0; font-size: 1.02rem; line-height: 1.65; color: var(--ink-2); max-width: 40rem; }

.promise-proof { margin-top: var(--s8); border-top: 1px solid var(--line); padding-top: var(--s5); }
.promise-proof summary {
  cursor: pointer; font: 600 .92rem/1 inherit; color: var(--ink-2);
  list-style: none; display: inline-flex; align-items: center; gap: .5rem;
}
.promise-proof summary::-webkit-details-marker { display: none; }
.promise-proof summary::after { content: '+'; color: var(--accent); font-weight: 700; }
.promise-proof[open] summary::after { content: '\2212'; }
.promise-proof summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.promise-proof ul { margin: var(--s4) 0 0; padding: 0; list-style: none; display: grid; gap: .55rem; }
.promise-proof li {
  font: 400 .86rem/1.5 var(--font-mono, ui-monospace, monospace);
  color: var(--ink-3); padding-left: 1rem; position: relative;
}
.promise-proof li::before { content: ''; position: absolute; left: 0; top: .55rem;
  width: .3rem; height: .3rem; border-radius: 50%; background: var(--accent); }

/* ---- guides ------------------------------------------------------------- */
.guidegrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); gap: var(--s4); }
.guidecard {
  display: flex; flex-direction: column; gap: var(--s3);
  padding: var(--s6); text-decoration: none; color: inherit;
  border: 1px solid var(--line); border-radius: var(--r3, 14px);
  transition: border-color .18s ease, transform .18s ease;
}
.guidecard:hover { border-color: var(--accent); transform: translateY(-2px); }
.guidecard:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.guidecard h2 { font-size: 1.32rem; line-height: 1.25; margin: 0; }
.guidecard p { margin: 0; color: var(--ink-2); font-size: .95rem; line-height: 1.6; }
.guidecard-go { margin-top: auto; font-size: .88rem; color: var(--accent); font-weight: 600; }
.guidelist { margin: var(--s5) 0 0; display: grid; gap: var(--s4); }
.guidelist dt { font-weight: 600; color: var(--ink); }
.guidelist dd { margin: 4px 0 0; color: var(--ink-2); line-height: 1.65; }
@media (prefers-reduced-motion: reduce) { .guidecard { transition: none; } .guidecard:hover { transform: none; } }

/* ---- save my place ------------------------------------------------------
   Sits in the flow above the footer controls rather than over them. No modal,
   no exit-intent popup: someone leaving is allowed to leave. */
.savebar {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  margin-top: var(--s6); padding: var(--s4);
  border: 1px solid var(--line); border-radius: var(--r2, 10px);
  font-size: .9rem; color: var(--ink-2);
}
.savebar-field {
  flex: 1 1 13rem; min-width: 0; padding: .6rem .8rem;
  font: 400 .92rem/1.2 inherit; color: var(--ink);
  background: var(--surface-2, transparent);
  border: 1px solid var(--line); border-radius: var(--r2, 8px);
}
.savebar-field:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ============================================================
   THE READOUT
   The panel that fills in beside the questions. Instrument
   register: hairlines at --rule, labels at --tick, tabular
   figures on everything that can change, and no idle animation.
   The only thing that moves is the thing that just changed.
   ============================================================ */
body.site .rd-panel {
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--paper-raised);
  padding: var(--s5);
  /* Tabular figures on the whole panel, not just the numerals. Instrument
     Sans swings 275 units per 1000em between its "1" and its "0", so a value
     that updates from 15 to 20 visibly jumps sideways without this, and one
     horizontal shift destroys the instrument illusion faster than anything
     else on the page. Both non-mono faces already carry the feature. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}
body.site .rd-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap; width: 100%;
  padding: 0 0 var(--s3); margin: 0;
  border: 0; border-bottom: 1px solid var(--rule);
  background: none; color: inherit; text-align: left;
  font: inherit; cursor: default;
}
body.site .rd-chev { display: none; }
body.site .rd-line { display: none; }
body.site .rd-count-short { display: none; }
body.site .rd-title {
  margin: 0; font-family: var(--mono); font-size: var(--t-micro);
  text-transform: uppercase; letter-spacing: .1em; color: var(--ink);
  /* MIL-STD-1472H puts stroke width at 1/6 to 1/7 of character height for
     dark on light. JetBrains Mono at 400 is thinner than the 1/8 floor, so
     every mono label in the instrument layer sits at 540 in light and 460 in
     dark, which is also why dark mode used to look thin next to light. */
  font-weight: 540;
}
body.site .rd-count {
  margin: 0; font-family: var(--mono); font-size: var(--t-micro);
  color: var(--tick); font-weight: 460;
}
body.site .rd-body { display: grid; gap: var(--s5); padding-top: var(--s4); }
body.site .rd-rest { margin: 0; color: var(--ink-3); font-size: var(--t-small); }
body.site .rd-group { display: grid; gap: var(--s2); }
body.site .rd-gtitle {
  margin: 0 0 var(--s1); font-family: var(--mono); font-size: .75rem;
  text-transform: uppercase; letter-spacing: .12em; color: var(--tick);
  font-weight: 540;
}
body.site .rd-list { margin: 0; display: grid; gap: 0; }
body.site .rd-row {
  display: grid; gap: 2px;
  padding: var(--s3) 0 var(--s3) var(--s3);
  border-top: 1px solid var(--rule);
  /* the accent rail is always present and always transparent, so a change
     does not shift the row sideways when it lights */
  box-shadow: inset 2px 0 0 transparent;
  opacity: 0;
  transform: translateY(calc(var(--travel) * 6px));
  transition: opacity var(--dur-240) var(--ease-out),
              transform var(--dur-240) var(--ease-out),
              box-shadow var(--dur-400) var(--ease-std);
}
body.site .rd-row:first-child { border-top: 0; }
body.site .rd-row.is-in { opacity: 1; transform: none; }
/* THE ONLY ANIMATION IN THE PANEL. It answers one question, "did that tap do
   anything", and it has to answer it inside a frame. */
body.site .rd-row.is-moved { box-shadow: inset 2px 0 0 var(--accent-deep); }
/* 12px floor. At .72rem this was 11.5px, and it is the label telling somebody
   what the value beside it means. */
body.site .rd-k {
  margin: 0; font-family: var(--mono); font-size: .75rem;
  text-transform: uppercase; letter-spacing: .08em; color: var(--tick);
  font-weight: 460;
}
body.site .rd-v {
  margin: 0; font-size: var(--t-small); line-height: 1.45; color: var(--ink);
  transition: color var(--dur-110) var(--ease-std);
}
body.site .rd-ul { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--s2); }
body.site .rd-ul li {
  position: relative; padding-left: var(--s5);
  font-size: var(--t-small); line-height: 1.45; color: var(--ink-2);
  opacity: 0; transition: opacity var(--dur-240) var(--ease-out);
}
body.site .rd-ul li.is-in { opacity: 1; }
body.site .rd-ul li::before {
  content: ''; position: absolute; left: 0; top: .55em;
  width: 10px; height: 1px; background: var(--accent-deep);
}
body.site .rd-supp {
  margin: 0; padding-top: var(--s4); border-top: 1px solid var(--rule);
  font-size: var(--t-small); color: var(--ink-2); line-height: 1.45;
}
/* The moment the product says no to itself. Worth the ink. */
body.site .rd-supp.is-none { color: var(--ink); }
/* Visually hidden, but a screen reader needs the change announced or the
   whole feature is invisible to it. */
body.site .rd-say {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Windows High Contrast forces box-shadow to none and cannot be overridden,
   so the one signal a row changed would silently disappear. Give it a border
   that the forced palette keeps. */
@media (forced-colors: active) {
  body.site .rd-row.is-moved { border-left: 2px solid Highlight; padding-left: calc(var(--s3) - 2px); }
}

/* ---- the phone ----------------------------------------------------------
   A step panel is most of a phone screen on its own, so there is no inline
   position that keeps the readout in view: below the question is below the
   fold, and above it pushes the question off the top. Both were tried and
   measured. So on a narrow screen the panel docks above the fixed footer,
   where the one line that just changed is permanently in view and the whole
   document is one tap away. Every tap visibly pays, which is the entire point,
   and it costs a strip rather than a screen. */
body.site .rd-wrap { margin-top: var(--s5); }

@media (max-width: 1039px) {
  body.site.intake .rd-wrap {
    position: fixed; left: 0; right: 0; bottom: var(--foot-h, 76px);
    z-index: 39; margin: 0;
    padding: 0 var(--edge) var(--s2);
    pointer-events: none;
  }
  body.site.intake .rd-panel {
    pointer-events: auto;
    padding: var(--s3) var(--s4);
    background: color-mix(in srgb, var(--paper-raised) 94%, transparent);
    backdrop-filter: blur(14px) saturate(1.3);
    box-shadow: var(--shadow-md);
  }
  body.site.intake .rd-head {
    padding-bottom: 0; border-bottom: 0; cursor: pointer;
    align-items: center; flex-wrap: nowrap; gap: var(--s3);
  }
  body.site.intake .rd-title { flex: 0 1 auto; white-space: nowrap; }
  body.site.intake .rd-count { flex: 1 1 auto; text-align: right; white-space: nowrap; }
  body.site.intake .rd-count-long { display: none; }
  body.site.intake .rd-count-short { display: inline; }
  body.site.intake .rd-chev {
    display: block; width: 10px; height: 10px; flex: none;
    border-right: 1.5px solid var(--tick); border-bottom: 1.5px solid var(--tick);
    transform: rotate(-135deg) translate(-2px, -2px);
    transition: transform var(--dur-240) var(--ease-std);
  }
  body.site.intake .rd-panel.is-open .rd-chev { transform: rotate(45deg) translate(-1px, -1px); }
  /* the one line that just moved, always in view */
  body.site.intake .rd-line {
    display: block; margin: var(--s2) 0 0;
    font-size: var(--t-small); line-height: 1.4; color: var(--ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  body.site.intake .rd-line.is-new { animation: rd-lit var(--dur-700) var(--ease-std); }
  body.site.intake .rd-panel .rd-body,
  body.site.intake .rd-panel .rd-supp { display: none; }
  body.site.intake .rd-panel.is-open .rd-body { display: grid; max-height: 52vh; overflow-y: auto; }
  body.site.intake .rd-panel.is-open .rd-supp { display: block; }
  body.site.intake .rd-panel.is-open .rd-line { display: none; }
  body.site.intake .rd-panel.is-open .rd-head { border-bottom: 1px solid var(--rule); padding-bottom: var(--s3); }
  /* The docked strip floats over the column, so the column has to reserve the
     height it actually occupies. Measured rather than guessed, because the
     panel grows a line whenever an answer does and a fixed guess was already
     hiding the third of three answers on step one. */
  body.site.intake .intake-main {
    padding-bottom: calc(var(--rd-h, 96px) + var(--foot-h, 76px) + var(--s5));
  }
}
@keyframes rd-lit { from { color: var(--accent-deep) } to { color: var(--ink) } }
@media (prefers-reduced-motion: reduce) {
  body.site.intake .rd-line.is-new { animation: none; }
}
@media (min-width: 1040px) {
  /* The single column intake reads at 46rem. Two columns need room for both,
     and at 46rem the content box is 634px, so a 20rem panel took half the
     reading column and left the questions narrower than the readout. The
     reading measure is what is being protected here, not the panel. */
  body.site.intake { --measure: 60rem; }
  body.site.intake .intake-cols {
    display: grid; grid-template-columns: minmax(24rem, 1fr) 19rem;
    gap: var(--s7); align-items: start;
  }
  body.site .rd-wrap { margin-top: 0; position: sticky; top: var(--s6); }
  /* A sticky panel that outgrows the viewport strands its own bottom rows
     where nothing can scroll them into view. */
  body.site .rd-panel { max-height: calc(100vh - var(--s8)); overflow-y: auto; }
}

/* Every question says what it moves and what it cannot touch.
   The CANNOT clause is the ownable move: nobody in this category writes one,
   MDRN is already bound to it by the deploy gate, and it is the sentence that
   turns an assessment from extraction into explanation. Phrased as a mechanic,
   never as a denial, because a denial implies an accusation. */
body.site .q-does, body.site .q-cannot {
  margin: var(--s3) 0 0; font-size: var(--t-micro); line-height: 1.5;
  color: var(--ink-3);
}
body.site .q-does span, body.site .q-cannot span {
  font-family: var(--mono); font-weight: 540; font-size: .75rem;
  text-transform: uppercase; letter-spacing: .1em; color: var(--tick);
  margin-right: .5em;
}
body.site .q-cannot { color: var(--ink-3); }

/* ============================================================
   THE FOLD'S FIRST QUESTION
   Three links, not a form, so it works with no JavaScript and
   survives a right-click into a new tab. The answer travels in
   the URL and is confirmed on the next screen rather than
   assumed, because a choice somebody cannot see or change is
   not a choice they made.
   ============================================================ */
body.site .hero-q {
  margin: 0 0 var(--s3); font-weight: 600; font-size: var(--t-body);
  color: var(--ink);
}
body.site .hero-goals { display: grid; gap: var(--s2); }
body.site .goalcard {
  display: grid; gap: 2px;
  padding: var(--s3) var(--s4);
  border: 1px solid var(--rule); border-radius: var(--r-sm);
  background: var(--paper-raised);
  text-decoration: none; color: inherit;
  transition: border-color var(--dur-150) var(--ease-std),
              background-color var(--dur-150) var(--ease-std),
              transform var(--dur-150) var(--ease-out);
}
body.site .goalcard:hover {
  border-color: var(--accent-deep);
  background: var(--signal-soft);
  transform: translateY(calc(var(--travel) * -1px));
}
body.site .goalcard:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 3px; }
body.site .goalcard-t { font-weight: 600; font-size: var(--t-body); }
body.site .goalcard-d { font-size: var(--t-small); color: var(--ink-3); line-height: 1.4; }
@media (min-width: 700px) {
  body.site .hero-goals { grid-template-columns: repeat(3, 1fr); }
  body.site .goalcard { padding: var(--s4); }
}

/* ============================================================
   THE CAPTURE
   A camera view and three readouts, all of which describe the
   photograph. The guide is a frame, never a figure: drawing a
   silhouette over somebody is the system's guess about where a
   body is, painted as though it were a picture of them.
   ============================================================ */
body.site .cap { display: grid; gap: var(--s4); }
body.site .cap-stage {
  position: relative; aspect-ratio: 3 / 4; overflow: hidden;
  border: 1px solid var(--rule); border-radius: var(--r-md);
  background: var(--paper-sunk);
}
body.site .cap-stage video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
/* Corner marks only. A full rectangle reads as a viewfinder from a film about
   surveillance; four corners read as a frame you stand inside. */
body.site .cap-guide { position: absolute; inset: 8% 14%; pointer-events: none; }
body.site .cap-guide::before, body.site .cap-guide::after {
  content: ''; position: absolute; width: 28px; height: 28px;
  border: 1.5px solid var(--accent-deep);
}
body.site .cap-guide::before { top: 0; left: 0; border-right: 0; border-bottom: 0; }
body.site .cap-guide::after { bottom: 0; right: 0; border-left: 0; border-top: 0; }
body.site .cap-read {
  display: grid; gap: 0;
  border: 1px solid var(--rule); border-radius: var(--r-sm);
  font-variant-numeric: tabular-nums;
}
body.site .cap-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3);
  padding: var(--s3) var(--s4); border-top: 1px solid var(--rule);
}
body.site .cap-row:first-child { border-top: 0; }
body.site .cap-k {
  font-family: var(--mono); font-size: .75rem; font-weight: 460;
  text-transform: uppercase; letter-spacing: .08em; color: var(--tick);
}
body.site .cap-state {
  font-size: var(--t-small); color: var(--ink);
  transition: color var(--dur-110) var(--ease-std);
}
/* Two states, and neither is an alarm. The warm one is advice about a
   photograph, so it uses the caution token rather than clay, which this
   product reserves for things that are actually wrong. */
body.site .cap-state.is-ok { color: var(--ink); }
body.site .cap-state.is-warn { color: var(--caution); }
body.site .cap-note { margin: 0; font-size: var(--t-micro); color: var(--ink-3); line-height: 1.5; }
body.site .cap-bar { display: flex; gap: var(--s3); align-items: center; flex-wrap: wrap; }
body.site .cap:not(.is-live) .cap-stage { display: none; }
body.site .cap:not(.is-live) .cap-read { display: none; }

/* the optional step */
body.site .scan-choice { display: flex; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s5); }
body.site .scan-choice .btn { flex: 1 1 14rem; justify-content: center; }
body.site .step-scan .promise em { color: var(--ink-2); font-style: italic; }
body.site .scan-status-line {
  margin: 0 0 var(--s4); font-family: var(--mono); font-size: .75rem; font-weight: 460;
  text-transform: uppercase; letter-spacing: .1em; color: var(--tick);
}
body.site .scanlines { display: grid; gap: var(--s3); }
body.site .scanline {
  padding: var(--s3) 0 var(--s3) var(--s4);
  border-left: 2px solid var(--accent-deep);
  opacity: 0; transform: translateY(calc(var(--travel) * 6px));
  transition: opacity var(--dur-240) var(--ease-out), transform var(--dur-240) var(--ease-out);
}
body.site .scanline.is-in { opacity: 1; transform: none; }
body.site .scanline-focus {
  display: block; font-family: var(--mono); font-size: .75rem; font-weight: 540;
  text-transform: uppercase; letter-spacing: .1em; color: var(--tick); margin-bottom: 2px;
}
body.site .scanline-note { margin: 0; font-size: var(--t-body); color: var(--ink); line-height: 1.45; }
body.site .scanline-action { margin: var(--s2) 0 0; font-size: var(--t-small); color: var(--ink-2); line-height: 1.45; }
body.site .scan-summary { margin: var(--s4) 0 0; font-size: var(--t-body); color: var(--ink); }
body.site .scan-abort { margin: var(--s4) 0 0; font-size: var(--t-small); color: var(--caution); line-height: 1.5; }
body.site .scan-drop {
  display: grid; gap: 2px; padding: var(--s5); cursor: pointer; text-align: center;
  border: 1px dashed var(--rule); border-radius: var(--r-md); background: var(--paper-raised);
}
body.site .scan-drop input { position: absolute; opacity: 0; width: 1px; height: 1px; }
body.site .scan-drop-label { font-weight: 600; }
body.site .scan-drop-hint { font-size: var(--t-micro); color: var(--ink-3); }

/* The trace. Sits over the video, under nothing, and never touches the file
   that gets uploaded: burning a skeleton into the photograph would send a
   machine's drawing of somebody's body to a server, which is a different thing
   from sending a photograph. */
body.site .cap-trace {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none;
  /* The tracer reads this, not the custom property. getPropertyValue on a
     custom property returns the unresolved token stream, literally
     "light-dark(#0D729D, #50C9F2)", which canvas cannot parse. `color` is a
     real property, so the browser resolves it to rgb() before anyone reads it,
     and it tracks the surface and the scheme for free. */
  color: var(--accent-deep);
}
body.site .cap-offer {
  display: flex; gap: var(--s3); align-items: center; flex-wrap: wrap;
  padding: var(--s3) var(--s4);
  border: 1px dashed var(--rule); border-radius: var(--r-sm);
}
body.site .cap-offer-note {
  flex: 1 1 16rem; font-size: var(--t-micro); color: var(--ink-3); line-height: 1.5;
}
body.site .cap-offer[hidden] { display: none; }

/* The cue and the countdown sit over the video, because that is where somebody
   three metres away with their hands at their sides is looking. */
body.site .cap-cue {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: var(--s4) var(--s4) var(--s5);
  display: grid; gap: var(--s2); justify-items: center; text-align: center;
  background: linear-gradient(to top, rgba(0,0,0,.78), rgba(0,0,0,0));
  pointer-events: none;
}
body.site .cap-cue-t {
  margin: 0; font-size: var(--t-body); font-weight: 600; color: #fff;
  text-wrap: balance; max-width: 22rem;
}
body.site .cap-cue-n {
  margin: 0; font-family: var(--mono); font-weight: 460;
  font-size: 2.4rem; line-height: 1; color: #fff;
  font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1;
  /* tabular figures matter more here than anywhere: 15 to 14 to 13 without
     them shifts sideways every second, which is the one animation on screen */
}
body.site .cap-cue[hidden] { display: none; }

/* Four slots, filled as the sequence runs. It says how far through somebody is
   without a bar claiming to know how long anything takes. */
body.site .cap-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s2); }
body.site .cap-shot {
  aspect-ratio: 3 / 5; border: 1px dashed var(--rule); border-radius: var(--r-sm);
  display: grid; place-items: center; position: relative; overflow: hidden;
}
body.site .cap-shot.is-done { border-style: solid; border-color: var(--accent-deep); }
body.site .cap-shot canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
body.site .cap-shot-k {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--tick); z-index: 1;
}
body.site .cap-shot.is-done .cap-shot-k { display: none; }
body.site .cap-strip[hidden] { display: none; }

/* The outlines, kept. Drawings rather than photographs: a traced boundary with
   no face, no skin and nothing that identifies anybody, which is exactly why
   these can be shown back when a photograph cannot. */
body.site .scan-outlines { margin-top: var(--s5); display: grid; gap: var(--s3); }
body.site .scan-outlines-k {
  margin: 0; font-family: var(--mono); font-size: .75rem; font-weight: 540;
  text-transform: uppercase; letter-spacing: .1em; color: var(--tick);
}
body.site .scan-outline-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s3); }
body.site .scan-outline {
  display: grid; gap: var(--s2); justify-items: center;
  padding: var(--s3); border: 1px solid var(--rule); border-radius: var(--r-sm);
  background: var(--paper-sunk);
}
body.site .scan-outline canvas { width: 100%; height: auto; display: block; }
body.site .scan-outline-k {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--tick);
}
@media (max-width: 480px) {
  body.site .scan-outline-row { grid-template-columns: repeat(2, 1fr); }
}

/* THE INTERIOR FOOTER.
   The homepage closes with a full-bleed reveal that is a designed moment. Every
   other surface had no footer at all, so the legal links, including the consumer
   health data policy the statute requires to be reachable, existed only on the
   front page. This is furniture rather than a closing argument, so it stays
   quiet: a hairline, generous air, and the same legal row. */
.xfooter-min {
  margin-top: var(--s9);
  padding: var(--s7) 0 var(--s6);
  border-top: 1px solid var(--paper-edge);
}
.xfooter-min .frow {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s5); flex-wrap: wrap;
}
.xfooter-min .legal { display: flex; gap: var(--s5); flex-wrap: wrap; }
@media (max-width: 640px) {
  .xfooter-min { padding-top: var(--s6); }
  .xfooter-min .frow { align-items: flex-start; }
  .xfooter-min .legal { gap: var(--s4); }
}
