/* ==========================================================================
   Founding Season Integration Vortex™ — PPC Landing Page
   World: geological section. Quartz strata, a gold ore seam, mica fleck.
   Palette and type pinned by blueprint.md. Do not re-decide.
   ========================================================================== */

/* Fonts load from <head> in each document, not @import: an @import here would
   serialise the font request behind this stylesheet and delay LCP on paid traffic. */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Ground — mineral strata, alternating down the page */
  --quartz:        #FAF6EF;
  --white:         #FFFFFF;
  --quartz-soft:   #F5EFE6;

  /* Seam and accent */
  --gold:          #BB9269;
  --gold-quiet:    rgba(187, 146, 105, 0.32);
  --gold-hair:     rgba(187, 146, 105, 0.20);
  --mica:          #D6B699;
  --mica-fill:     rgba(214, 182, 153, 0.18);

  /* Gold #BB9269 is pinned for rules, borders, badges and active indicators —
     as TEXT it reads 2.47:1 on Soft Quartz. These are the same hue carried down
     to legibility: --gold-text clears 4.5:1 for small copy, --gold-mark clears
     the 3:1 non-text floor for icons and glyphs. Rules still use --gold. */
  --gold-text:     #85684B;
  --gold-mark:     #A8845F;

  /* Action */
  --ore:           #9E6455;
  --ore-deep:      #854E41;
  --ore-tint:      rgba(158, 100, 85, 0.10);

  /* Text */
  --ink:           #2A2421;
  --body:          #585556;
  /* The brief pins #7D7C7B for eyebrows and labels. At 12–13px that measures
     3.64:1 on Soft Quartz — below AA, on a page carrying medical and insurance
     microcopy. --body-quiet is the same grey carried to 4.52:1 and is what the
     page ships; the pinned value stays recorded here. */
  --label:         #7D7C7B;
  --body-quiet:    #6E6D6C;
  --placeholder:   #74716F;

  /* Type — SUBSTITUTION ON THE RECORD.
     The brief pins Nexa Bold (display) and Avenir Book (body). Both are licensed
     faces and neither is available to this project, so neither is fetched: the
     page ships Jost and Nunito Sans, chosen and locked in blueprint.md's Font
     Substitution block. The licensed names stay first in each stack, so dropping
     real webfont files in later upgrades the page with no code change. A visitor
     who already owns Nexa or Avenir gets it; nobody else is served a download. */
  --font-display: 'Jost', 'Nexa', system-ui, -apple-system, sans-serif;
  --font-body:    'Nunito Sans', 'Avenir', 'Avenir Next', system-ui, -apple-system, sans-serif;

  /* Rhythm — one spacing scale, whole page */
  --s-1:  0.5rem;
  --s-2:  0.75rem;
  --s-3:  1rem;
  --s-4:  1.5rem;
  --s-5:  2rem;
  --s-6:  3rem;
  --s-7:  4rem;
  --s-8:  6rem;
  --s-9:  8rem;

  --shell:    1200px;
  /* The shell's inline gutter. A fixed 1.5rem was a phone gutter applied to
     every width: from 1248px down to 768px it was the only margin left, so
     headlines and actions sat 24px from the glass and 14px from the seam.
     Fluid from 24px on phones to 48px from 1200px up. */
  --gutter:   clamp(1.5rem, 4vw, 3rem);
  --measure:  68ch;
  --radius:   3px;
  /* The second radius. 2px was hard-coded in four places — the placeholder tag, the
     savings badge and the two disclosure signs — while --radius carried 3px, so the
     system had an undeclared step. It is a real step, not drift: a 1.15rem sign at
     3px reads round. Declared, it can be reasoned about. */
  --radius-chip: 2px;

  /* Type scale. Colour, spacing, shadow, easing and measure were all tokenised and
     type was not: Section 4 alone declared fourteen raw font sizes. These are the
     ramp DESIGN.md already records, given names. Headings stay on their own clamp()
     expressions — they are fluid and do not belong to a fixed ramp.
     label-sm/label are chrome, small/reading/lead are the reading ladder, and
     subhead upward are display sizes. */
  --t-label-sm: 0.75rem;
  --t-label:    0.8125rem;
  --t-small:    0.9375rem;
  --t-reading:  1.0625rem;
  --t-lead:     1.125rem;
  --t-subhead:  1.25rem;
  --t-recap:    1.5rem;
  --t-code-sm:  1.75rem;
  --t-code-min: 2rem;
  --t-figure:   2.5rem;
  --t-code:     2.75rem;

  /* The band ladder — one column grid for the banded lists.
     Differentiation and the Journey are the same structural idea: a marker, a
     title, a body, separated by hairlines. They used to declare separate ladders
     (3.5/15, 2.5/17, 7/16), so their titles landed at different x down the page
     and the beds read as unrelated tables rather than one section through rock.
     One ladder, declared once. The marker column keeps 56px: it was sized for the
     since-removed timeline's "Step 4" at 48px, and dropping it to the Journey's
     34px diamond-plus-numeral would pull the Journey's titles left of the
     Differentiation bed's, which is the misalignment this exists to prevent. */
  --band-marker: 3.5rem;
  --band-title:  16rem;
  --band-gap:    var(--s-5);
  --band-gap-stacked: var(--s-2);

  /* Depth — offset plus soft blur, never a zero-offset halo */
  --lift-1: 0 1px 2px rgba(42, 36, 33, 0.04), 0 2px 8px rgba(42, 36, 33, 0.04);
  --lift-2: 0 2px 4px rgba(42, 36, 33, 0.05), 0 8px 24px rgba(42, 36, 33, 0.07);
  --lift-3: 0 4px 8px rgba(42, 36, 33, 0.06), 0 18px 48px rgba(42, 36, 33, 0.10);

  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  /* Brand bar. Three tiers, because the hero's CTA has to clear the fold on a
     ~730px laptop viewport (1920 at 125% scaling, minus browser chrome) and
     every pixel of header is taken from that budget. The stacked logo's tagline
     is texture at these sizes, as it is on ommassage.net. */
  --header-h: 4rem;       /* phones: 40px logo */
  --logo-h:   2.5rem;
  --desk-bar-h: 4rem;
}
@media (min-width: 900px) {
  :root { --header-h: 4rem; --logo-h: 2.75rem; }       /* short desktop: 44px logo */
}
@media (min-width: 900px) and (min-height: 820px) {
  :root { --header-h: 5.5rem; --logo-h: 3.5rem; }      /* tall desktop: 56px logo */
}

/* --------------------------------------------------------------------------
   2. Reset and browser surfaces
   The parts we did not draw still carry the design.
   -------------------------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
  /* The strata carry 6rem of their own block padding, so the old 3rem here
     stacked into ~9rem of dead space above every anchor target. Enough to
     clear the section's top hairline, no more. The bottom value clears the
     standing mobile action. */
  scroll-padding-top: var(--s-3);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--quartz);
  color: var(--body);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Display type only, and invisible at any normal size: it fires only on a word that
   cannot fit its column at all. At a 200% text setting the hero's 76px headline
   meets a 294px column, and without this one long word runs off the screen. It is
   deliberately NOT on <body>: inherited everywhere it would also break strings a
   reader has to copy exactly — the promo code first among them. */
.h1, .h2, .h3, .h4, .stage-card__title, .wt-stage__name, .faq__q-text {
  overflow-wrap: break-word;
}

::selection { background: var(--mica); color: var(--ink); }

:root { caret-color: var(--ore); accent-color: var(--ore); }

* { scrollbar-color: var(--gold-quiet) transparent; scrollbar-width: thin; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: var(--quartz-soft); }
*::-webkit-scrollbar-thumb { background: var(--gold-quiet); border-radius: 0; }
*::-webkit-scrollbar-thumb:hover { background: var(--gold); }

:focus-visible {
  outline: 2px solid var(--ore);
  outline-offset: 3px;
  border-radius: 1px;
}
:focus:not(:focus-visible) { outline: none; }

/* Inline links are small text, so they take Ore Deep (5.8–6.2:1): Ore itself is
   4.17–4.76:1 on the grounds and passes only as large text. */
a { color: var(--ore-deep); text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
a:not(.cta):hover { color: var(--ink); }

img, svg, video { display: block; max-width: 100%; }

figure { margin: 0; }

/* --------------------------------------------------------------------------
   3. Type scale
   Sizes from blueprint.md, adjusted for Jost's smaller optical size.
   -------------------------------------------------------------------------- */

/* Heading colour follows the Om Massage Brand Reference Guide, which sets headings
   and the wordmark in Ore — the same as ommassage.net. Ore on the three grounds
   measures 4.17–4.76:1, which clears AA only as large text (≥24px, or ≥18.66px
   bold). H1–H3 are all 21px bold or larger, so they carry Ore; H4 is 17px and
   steps down to Ore Deep (5.81–6.16:1), the same hue at a reading grade. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ore);
  font-weight: 700;
  margin: 0;
  text-wrap: balance;
}
h4, .h4 { color: var(--ore-deep); }

.h1 {
  font-size: clamp(2.375rem, 1.55rem + 3.4vw, 3.25rem); /* 38 → 52 */
  line-height: 1.15;
  letter-spacing: -0.022em;
}

.h2 {
  font-size: clamp(1.875rem, 1.5rem + 1.55vw, 2.25rem);  /* 30 → 36 */
  line-height: 1.25;
  letter-spacing: -0.018em;
}

.h3 {
  font-size: clamp(1.3125rem, 1.16rem + 0.63vw, 1.5rem);
  line-height: 1.3;
  letter-spacing: -0.012em;
}

.h4 {
  font-size: var(--t-reading);
  line-height: 1.35;
  font-weight: 600;
  letter-spacing: -0.005em;
}

/* Eyebrow — pinned by the brief. Nexa Bold uppercase 12–14px / 0.12em.
   Block, not flex: a flex container would tear the ™ off its word. */
.eyebrow {
  position: relative;
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-label);
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* The brand guide sets subheadings in Gold. Seam Gold as text is 2.62:1, so the
     eyebrow takes Gold Text — same hue, 4.50:1 on Soft Quartz, 4.78:1 on Quartz. */
  color: var(--gold-text);
  margin: 0 0 var(--s-3);
  padding-left: 2.5rem;
  max-width: 46ch;
}
.eyebrow::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.66em;
  width: 1.75rem;
  height: 1px;
  background: var(--gold);
}

p { margin: 0 0 var(--s-3); max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

.lead {
  font-size: var(--t-lead);
  line-height: 1.58;
  color: var(--body);
}

.supporting {
  font-size: var(--t-reading);
  color: var(--body-quiet);
}

strong, b { font-weight: 700; color: var(--ink); }

.tm { font-size: 0.62em; vertical-align: 0.55em; letter-spacing: 0; font-weight: 500; }

/* --------------------------------------------------------------------------
   4. Shell and strata
   -------------------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Every stratum's shell is a query container, so the beds inside it can be gated on
   the room they actually have rather than on the window. See The Matching-Unit Query
   Rule: the proof grid and the FAQ carry fixed rem tracks, and a px media query
   cannot see a reader's text-size setting grow them. The hero is excluded — its
   shell is a flex child inside the viewport-height budget and carries no rem-track
   grid to protect. */
.stratum:not(.hero) > .shell {
  container-type: inline-size;
  container-name: bed;
}

.stratum {
  position: relative;
  padding-block: var(--s-8);
}

/* One step down on phones: 6rem above and below every bed is most of a
   viewport of empty quartz at 390px. The beds keep their proportion to each
   other, they just stop out-measuring their own content. */
@media (max-width: 599px) {
  .stratum { padding-block: var(--s-7); }
}

.stratum--quartz { background: var(--quartz); }
.stratum--white  { background: var(--white); }
.stratum--soft   { background: var(--quartz-soft); }

/* The seam: a gold hairline at every stratum boundary. */
.stratum + .stratum::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent, var(--gold-hair) 12%, var(--gold-hair) 88%, transparent);
}

.stratum__head { margin-bottom: var(--s-6); }

/* The interval between a heading and the paragraph under it, wherever the pair
   occurs. This was seven inline margin-top declarations across two documents. */
.stratum__head p,
h2 + p,
h3 + p { margin-top: var(--s-3); }

/* --------------------------------------------------------------------------
   5. The ore seam — the page's through-line
   A fixed 1px rail on wide viewports, filled by scroll depth.
   -------------------------------------------------------------------------- */

.seam {
  position: fixed;
  top: 0;
  bottom: 0;
  left: max(calc((100vw - var(--shell)) / 2 - 2.5rem), 0.625rem);
  width: 1px;
  background: var(--gold-quiet);
  z-index: 5;
  pointer-events: none;
}

.seam__fill {
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 0;
  background: var(--gold);
  will-change: height;
}

/* The bead marks depth and inverts across the Journey. */
.seam__bead {
  position: absolute;
  left: 50%;
  top: 0;
  width: 7px;
  height: 7px;
  margin-left: -3.5px;
  margin-top: -3.5px;
  background: var(--ore);
  transform: rotate(45deg);
  will-change: top, transform;
}

/* Narrow viewports keep the seam: it is the page's through-line and the carrier
   of the signature, so it moves into the screen edge rather than disappearing. */
/* The rail's max() floors at 10px once (100vw - 1200px) / 2 - 2.5rem drops
   below it, which happens at 1300px — not 1180px. Below 1180 the bead shrank
   but between 1180 and 1300 it rode the screen edge at full size. One
   breakpoint, derived from the rail's own formula. */
@media (max-width: 1300px) {
  .seam { left: 0.625rem; }
  .seam__bead { width: 5px; height: 5px; margin-left: -2.5px; margin-top: -2.5px; }
}
@media (max-width: 420px) { .seam { left: 0.375rem; } }

/* --------------------------------------------------------------------------
   6. Actions
   Ore is reserved for the primary action. Nothing else uses it as a fill.
   -------------------------------------------------------------------------- */

.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  font-family: var(--font-display);
  font-size: var(--t-reading);
  font-weight: 600;
  letter-spacing: 0.005em;
  line-height: 1;
  color: var(--white);
  background: var(--ore);
  border: 1px solid var(--ore);
  border-radius: var(--radius);
  padding: 1.15rem 2rem;
  text-decoration: none;
  cursor: pointer;
  text-align: center;
  transition: background 0.35s var(--ease), box-shadow 0.35s var(--ease), transform 0.35s var(--ease);
  box-shadow: var(--lift-1);
}
.cta:hover {
  background: var(--ore-deep);
  border-color: var(--ore-deep);
  color: var(--white);
  box-shadow: var(--lift-2);
  transform: translateY(-1px);
}
.cta:active { transform: translateY(0); box-shadow: var(--lift-1); }
.cta--block { display: flex; width: 100%; }
.cta--lg { font-size: var(--t-lead); padding: 1.3rem 2.25rem; }

.cta[disabled], .cta[aria-disabled='true'] {
  background: var(--mica);
  border-color: var(--mica);
  color: var(--white);
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

/* Secondary anchor — typographic, never a second button. */
.anchor-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-display);
  font-size: var(--t-reading);
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--gold);
  padding-bottom: 0.3em;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
/* The link keeps its size; its target does not. 33px of type and underline is
   under the 44px touch floor, so an invisible box extends the hit area instead
   of padding, which would push the gold underline away from the words. */
.anchor-link { position: relative; }
.anchor-link::after {
  content: '';
  position: absolute;
  inset: -0.625rem -0.5rem;
}
.anchor-link:hover { color: var(--ore-deep); border-color: var(--ore); }
.anchor-link .glyph { transition: transform 0.4s var(--ease); }
.anchor-link:hover .glyph { transform: translateY(3px); }

.action-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4) var(--s-5);
  margin-top: var(--s-3);
}

/* --------------------------------------------------------------------------
   7. Placeholders — clearly labelled, correctly proportioned.
   Never a stock photo standing in for the real space.
   -------------------------------------------------------------------------- */

.placeholder {
  position: relative;
  background: var(--quartz-soft);
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
}
.placeholder::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle at 22% 28%, rgba(214, 182, 153, 0.42) 0 1px, transparent 1.6px),
    radial-gradient(circle at 68% 61%, rgba(214, 182, 153, 0.34) 0 1px, transparent 1.6px),
    radial-gradient(circle at 41% 79%, rgba(187, 146, 105, 0.30) 0 1px, transparent 1.6px),
    radial-gradient(circle at 84% 19%, rgba(187, 146, 105, 0.24) 0 1px, transparent 1.6px);
  background-size: 90px 90px, 130px 130px, 110px 110px, 160px 160px;
  opacity: 0.9;
}
.placeholder__tag {
  position: absolute;
  top: var(--s-3);
  left: var(--s-3);
  font-family: var(--font-display);
  font-size: var(--t-label-sm);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ore);
  background: var(--white);
  border: 1px solid var(--gold-quiet);
  padding: 0.4em 0.7em;
  border-radius: var(--radius-chip);
}
.placeholder__note {
  position: relative;
  padding: var(--s-4);
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--body);
  background: linear-gradient(to top, rgba(250, 246, 239, 0.97), rgba(250, 246, 239, 0.0));
  padding-top: var(--s-7);
}
.placeholder__note strong { display: block; margin-bottom: 0.15em; font-family: var(--font-display); }

/* The hero frame owns its ratio, so the placeholder and the video it stands in
   for fill the same box. Phones: 1:1, because the source footage is square and a
   square crops nothing (4:5 cost ~86px more and cut the sides). Desktop: the
   frame is the full height of the stratum. */
.placeholder--fill { aspect-ratio: auto; }
@media (max-width: 899px) {
  .hero .media-frame { aspect-ratio: 1 / 1; }
}
.ratio-4x5 { aspect-ratio: 4 / 5; }

/* Real photography sits in the same box a placeholder held: the ratio class
   owns the frame, the image fills it and crops rather than shifting layout. */
.portrait {
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--gold-quiet);
}
.ratio-16x9 { aspect-ratio: 16 / 9; }
.ratio-1x1 { aspect-ratio: 1 / 1; }

/* --------------------------------------------------------------------------
   7b. Brand bar and desktop standing action
   -------------------------------------------------------------------------- */

/* No ground of its own: the header sits on the page's Quartz, so the hero's
   half-bleed media can rise behind it to the top edge of the viewport. */
.site-header .shell {
  display: flex;
  align-items: center;
  height: var(--header-h);
}
.site-header__logo { height: var(--logo-h); width: auto; }

.desk-bar { display: none; }
@media (min-width: 900px) {
  html:has(.desk-bar) { scroll-padding-top: calc(var(--desk-bar-h) + var(--s-3)); }
  .desk-bar {
    display: block;
    position: fixed;
    inset-inline: 0;
    top: 0;
    z-index: 20;
    background: color-mix(in srgb, var(--quartz) 92%, transparent);
    border-bottom: 1px solid var(--gold-quiet);
    transform: translateY(-110%);
    transition: transform 0.5s var(--ease);
  }
  .desk-bar.is-up { transform: translateY(0); }
  .desk-bar__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-4);
    height: var(--desk-bar-h);
  }
  .desk-bar__mark { height: 2rem; width: auto; }
  .desk-bar .cta { padding-block: 0.8rem; box-shadow: var(--lift-2); }
}
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .desk-bar { background: var(--quartz); }
}
@media (prefers-reduced-motion: reduce) {
  .desk-bar { transition: none; }
}

/* --------------------------------------------------------------------------
   8. Section 1 — Hero
   -------------------------------------------------------------------------- */

/* The hero's own intervals, as tokens, so the short- and tall-desktop tiers
   below change rhythm in one place. Groups: [eyebrow + H1] · [subhead] ·
   [plate + CTA] · [fine print]. Tight inside a group, wider between groups. */
.hero {
  --hero-pad-top: var(--s-2);
  --hero-pad-bottom: var(--s-8);
  --hero-gap-head: var(--s-4);   /* H1 → subhead */
  --hero-gap-offer: var(--s-4);  /* subhead → plate */
  padding-block: var(--hero-pad-top) var(--hero-pad-bottom);
}

/* Mobile order follows the DOM: head → media → rest, per the brief.
   Desktop lifts the media into its own column beside both. */
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-5);
  align-items: start;
}

/* Narrow viewports: a tighter stack. Every value here is spacing or leading —
   no pinned content is cut. The action group keeps the page-wide 16px
   plate → CTA interval; the plinth carries the action below the real fold. */
@media (max-width: 899px) {
  .hero { --hero-pad-bottom: var(--s-7); }
  .hero__grid { gap: var(--s-4); }
  .hero .hero__sub { line-height: 1.5; }
  .snapshot { margin-top: var(--s-3); }
  /* The large variant buys presence through width on mobile, where the button
     is already full-bleed in its column; it does not also need the height. */
  .hero__rest .cta--lg { padding-block: 1.15rem; }
}

/* Below the two-column breakpoint the media follows the offer and the action.
   The brief numbers the visual at 4, ahead of the offer plate — but it also sets
   the standard this page is judged by, "clear in 10 seconds", and a 4:5 portrait
   in that slot pushes the price and the button off the first two screens. The
   offer leads on mobile; the media keeps its place on desktop. */
@media (max-width: 899px) {
  .hero__head  { order: 1; }
  .hero__rest  { order: 2; }
  .hero__media { order: 3; margin-top: var(--s-2); }
}

/* Desktop: the hero is at least one viewport tall (less the brand bar), so the
   next stratum never shows as an accidental sliver. Two empty rows above and
   below the copy take whatever height the viewport adds, the lower one heavier
   so the copy sits slightly above centre. On a short laptop there is nothing
   to add and both rows collapse to zero. */
@media (min-width: 900px) {
  .hero {
    --hero-pad-top: var(--s-2);
    --hero-pad-bottom: var(--s-7);
    --hero-gap-head: var(--s-2);
    --hero-gap-offer: var(--s-4);
    display: flex;
    flex-direction: column;
    min-height: calc(100svh - var(--header-h));
  }
  .hero > .shell { flex: 1; display: flex; }
  .hero__grid {
    flex: 1;
    grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
    grid-template-areas:
      'top   media'
      'head  media'
      'rest  media'
      'foot  media';
    grid-template-rows: 1fr auto auto 1.35fr;
    column-gap: var(--s-7);
    row-gap: 0;
  }
  .hero__head  { grid-area: head; }
  .hero__rest  { grid-area: rest; padding-top: var(--hero-gap-head); }
  .hero__media { grid-area: media; }
  .hero .eyebrow { margin-bottom: var(--s-2); }
  /* Short desktop: the CTA must clear a ~730px fold under the brand bar. */
  .hero .snapshot { padding: 1.25rem var(--s-4); }
  .hero .hero__sub { line-height: 1.5; }
}
/* Tall desktop: the room exists, so the groups get their full separation. */
@media (min-width: 900px) and (min-height: 820px) {
  .hero {
    --hero-pad-top: var(--s-4);
    --hero-gap-head: var(--s-4);
    --hero-gap-offer: var(--s-5);
  }
  .hero .eyebrow { margin-bottom: var(--s-3); }
  .hero .snapshot { padding: var(--s-4); }
  .hero .hero__sub { line-height: 1.55; }
}

.hero__sub {
  font-size: var(--t-reading);
  line-height: 1.55;
  margin-top: 0;
  /* Same 34 as the offer plate below it, in the same unit. As 34em against a
     17px subhead it measured 578px to the plate's 544px, so the two right
     edges in the hero's left column missed each other by 32px. */
  max-width: 34rem;
}

.hero__media {
  position: relative;
  display: flex;
  flex-direction: column;
}

.media-frame {
  position: relative;
  display: flex;
  overflow: hidden;
  background: var(--quartz-soft);
}
.media-frame > * { flex: 1; }

/* Taken out of flow on purpose. The frame owns its height — flex:1 against the
   hero grid on desktop, aspect-ratio 1/1 on mobile — and an in-flow child would
   override both with its own intrinsic ratio. The 9:16 hero still did exactly
   that: it stretched the media column and pushed the hero CTA 129px below a
   1440x900 fold, breaking The Viewport Hero Rule. */
.media-fill {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Half-bleed. The image is not a tile sitting in the layout; it is the stratum's
   own bed, running off the right edge of the viewport and the full height of the
   section. A geological section is cut off by its frame — beds run out of view.
   The negative margin measures shell edge to viewport edge, clamped so it still
   reaches the edge below the shell's max width. */
@media (min-width: 900px) {
  .hero__grid { align-items: stretch; }

  .hero__media {
    align-self: stretch;
    margin-right: calc(-1 * max((100vw - var(--shell)) / 2 + var(--gutter), var(--gutter)));
    /* Up through the hero's top padding and the brand bar, so the bed still
       starts at the viewport's top edge; down through the bottom padding. */
    margin-block: calc(-1 * (var(--hero-pad-top) + var(--header-h))) calc(-1 * var(--hero-pad-bottom));
    /* No margin-left: the column gap is the gutter. A 2rem margin here stacked
       on the 4rem column-gap, so the bed started 96px from the copy while its
       own grid track said 64px — the track boundary and the visible edge of
       the image disagreed. */
  }
  .media-frame { flex: 1; min-height: 32rem; }
  .hero__media .placeholder { aspect-ratio: auto; border: 0; border-radius: 0; }
}
.hero__caption {
  margin-top: var(--s-3);
  font-size: var(--t-small);
  color: var(--body-quiet);
  max-width: none;
}
@media (min-width: 900px) {
  /* Seated on the image as a bed label, not floating past the bleed edge.
     The band runs to the viewport edge with the bed, but its text stops on the
     shell's own right gutter — otherwise the caption was the one line on the
     page ragging 200px further right than every other line at 1440px. */
  .hero__caption {
    margin-top: 0;
    padding: var(--s-2) var(--s-4);
    padding-right: max(var(--gutter), calc((100vw - var(--shell)) / 2 + var(--gutter)));
    background: var(--quartz);
    border-top: 1px solid var(--gold);
    font-size: var(--t-label);
  }
}

/* Offer snapshot — the one plate on the page that earns full elevation. */
.snapshot {
  background: var(--white);
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius);
  padding: var(--s-4);
  margin-top: var(--hero-gap-offer, var(--s-4));
  box-shadow: var(--lift-2);
  max-width: 34rem;
}

.snapshot__name {
  font-family: var(--font-display);
  font-size: var(--t-subhead);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.snapshot__desc {
  margin-top: var(--s-1);
  /* Supporting copy inside the plate sits on the small step, not the reading
     step: the plate's hierarchy is name, then this, then the $295 figure. */
  font-size: var(--t-small);
  color: var(--body);
}

.price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--s-2) 0.9em;
}
.price__now {
  font-family: var(--font-display);
  font-size: var(--t-figure);
  font-weight: 700;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.03em;
}
.price__was {
  font-size: var(--t-reading);
  color: var(--body-quiet);
  text-decoration: line-through;
  text-decoration-color: var(--mica);
}

/* Centred, not baselined: a bordered chip hung from the $295 figure's baseline
   dropped its box well below the number's optical block. The price row keeps
   baseline alignment for the type beside it. */
.save-tag {
  display: inline-block;
  align-self: center;
  font-family: var(--font-display);
  font-size: var(--t-label-sm);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--mica-fill);
  border: 1px solid var(--gold-quiet);
  padding: 0.45em 0.75em;
  border-radius: var(--radius-chip);
}

/* Two intervals, measured ink to ink: ~12–16px inside a group (figure to tag,
   label to its list, item to item) and 24px between the price group and the
   inclusions, matching the plate's padding. The box values are smaller than the
   visible gaps because the label and list lines carry their own leading. */
.inclusions { margin-top: 1.25rem; }
.inclusions__label {
  font-family: var(--font-display);
  font-size: var(--t-label-sm);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--body-quiet);
  margin-bottom: var(--s-1);
}

.tick-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-1); }
.tick-list li {
  display: grid;
  grid-template-columns: 1.1rem 1fr;
  gap: 0.7em;
  align-items: start;
  /* Plate list copy sits with the plate's other supporting copy on the small
     step; the name and the $295 figure carry the plate's hierarchy. */
  font-size: var(--t-small);
  color: var(--ink);
  line-height: 1.5;
}
.tick-list svg { margin-top: 0.32em; color: var(--gold-mark); flex: none; }

/* Fine print after an action: one interval, page-wide. 24px from the button,
   a hairline opening the fine-print group, 16px to the words. The hero once
   declared its own 24px / no-rule override here, but .seasonality came later in
   the file at equal specificity and silently won, so the hero shipped 12px +
   rule + 12px while the Section 4 closer shipped 24 + rule + 16.

   `.fine-print` is the same component under an honest name; `.seasonality` stays
   because it is what the hero and the Section 4 closer carry, and both say when
   the offer runs. Use `.fine-print` for any other fine print after an action. */
.seasonality,
.fine-print {
  margin-top: var(--s-4);
  padding-top: var(--s-3);
  border-top: 1px solid var(--gold-hair);
  font-size: var(--t-label);
  line-height: 1.45;
  color: var(--body-quiet);
  max-width: 58ch;
}
/* In the hero the fine print takes the column's own 34rem, so its rule ends on
   the offer plate's right edge instead of short of it. */
.seasonality--hero {
  max-width: 34rem;
}

/* --------------------------------------------------------------------------
   9. Section 2 — Proof and differentiation
   Strata bands, not a row of identical cards.
   -------------------------------------------------------------------------- */

.diff {
  margin-top: var(--s-6);
  border-top: 1px solid var(--gold-hair);
  max-width: 66rem;
  container-type: inline-size;
  container-name: diff;
}

.diff__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--band-gap-stacked);
  padding-block: var(--s-5);
  border-bottom: 1px solid var(--gold-hair);
}

/* The Matching-Unit Query Rule, applied here as it already is on the walkthrough.
   The ladder's marker and title tracks are rem and grow with the reader's text
   setting; a px media query does not, so the bed stayed in three columns hundreds
   of pixels past the width where three columns fit and the clause track starved.
   51.75rem is this bed's own width at a 900px viewport, so at a 16px root nothing
   moves and above it the gate travels with the text. */
@container diff (min-width: 51.75rem) {
  .diff__item {
    grid-template-columns: var(--band-marker) minmax(0, var(--band-title)) minmax(0, 1fr);
    gap: var(--band-gap);
    align-items: baseline;
  }
}
@supports not (container-type: inline-size) {
  @media (min-width: 56.25rem) {
    .diff__item {
      grid-template-columns: var(--band-marker) minmax(0, var(--band-title)) minmax(0, 1fr);
      gap: var(--band-gap);
      align-items: baseline;
    }
  }
}

.diff__num {
  font-family: var(--font-display);
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--gold-text);
  letter-spacing: 0.08em;
}

.diff__title {
  font-family: var(--font-display);
  font-size: var(--t-reading);
  font-weight: 700;
  line-height: 1.35;
  color: var(--ink);
}

/* The band cells are <p> elements, so the global paragraph margin was adding
   1rem on top of every stacked gap — the beds read 28px apart where the token
   said 12px. The grid's gap is the only interval in a band. */
.diff__num,
.diff__title,
.journey__marker,
.journey__name { margin: 0; }

.diff__body { color: var(--body); }
.diff__body p { max-width: 58ch; }

/* Matthew authority block */
.authority {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-5);
  margin-top: var(--s-8);
  padding-top: var(--s-7);
  border-top: 1px solid var(--gold-hair);
}

@media (min-width: 900px) {
  .authority {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    gap: var(--s-7);
    align-items: start;
  }
}

.authority__credentials {
  list-style: none;
  margin: var(--s-4) 0 0;
  padding: 0;
  display: grid;
  gap: var(--s-2);
  border-top: 1px solid var(--gold-hair);
  padding-top: var(--s-4);
}
.authority__credentials li {
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--body);
  padding-left: 1.1rem;
  position: relative;
}
.authority__credentials li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  background: var(--gold);
  transform: rotate(45deg);
}

/* Guest proof */
.proof { margin-top: var(--s-8); padding-top: var(--s-7); border-top: 1px solid var(--gold-hair); }

/* Guest testimonials: a manual carousel, never auto-rotating. On desktop it
   joins the band ladder like the FAQ: heading left, slides in the body column.
   Controls sit above the slides, so the arrows never move when a short slide
   follows the long one. Without JavaScript every slide shows, stacked. */
/* Gated on the bed, not the window: this grid's first column is 21.5rem of fixed
   track and its second is capped in rem too, so at a large text setting a px query
   kept a 65rem layout inside a 56rem window and the control row ran off the side. */
@container bed (min-width: 51.75rem) {
  .proof {
    display: grid;
    grid-template-columns:
      calc(var(--band-marker) + var(--band-gap) + var(--band-title))
      minmax(0, 44rem);
    column-gap: var(--band-gap);
    align-items: start;
  }
}
@supports not (container-type: inline-size) {
  @media (min-width: 56.25rem) {
    .proof {
      display: grid;
      grid-template-columns:
        calc(var(--band-marker) + var(--band-gap) + var(--band-title))
        minmax(0, 44rem);
      column-gap: var(--band-gap);
      align-items: start;
    }
  }
}

.carousel { margin-top: var(--s-5); }
@media (min-width: 900px) { .carousel { margin-top: 0; } }

/* The control row is chrome measured in rem, so at a large text setting it grew
   past the bed: five marks plus two arrows plus the gap ran 18.75rem, which is
   600px at a 32px root inside a 328px phone column. It now yields in two stages —
   the marks shrink toward a 1.5rem floor that is still a comfortable target, and
   the row wraps the arrows onto their own line before anything can overflow. */
.carousel__controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--gold);
}
.carousel__controls[hidden] { display: none; }

.carousel__marks { display: flex; flex: 1 1 auto; min-width: 0; }
.carousel__mark {
  flex: 0 1 2.25rem;
  min-width: 1.5rem;
  width: 2.25rem;
  height: 2.75rem;
  padding: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  position: relative;
}
.carousel__mark::before {
  content: '';
  position: absolute;
  left: 0.25rem;
  right: 0.25rem;
  top: 50%;
  height: 2px;
  background: var(--gold-quiet);
  transition: background 0.3s var(--ease);
}
.carousel__mark:hover::before { background: var(--gold); }
.carousel__mark[aria-current='true']::before { background: var(--ore); }

.carousel__steps { display: flex; flex: none; gap: var(--s-1); margin-left: auto; }
.carousel__step {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  color: var(--ore-deep);
  background: transparent;
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.carousel__step:hover:not(:disabled) { border-color: var(--gold); background: var(--mica-fill); }
.carousel__step:disabled { color: var(--gold-mark); opacity: 0.45; cursor: default; }

.carousel__track { padding-top: var(--s-4); }

.reflection { margin: 0; }
.reflection blockquote { margin: 0; }
.reflection + .reflection { margin-top: var(--s-5); padding-top: var(--s-5); border-top: 1px solid var(--gold-hair); }
.reflection p {
  font-family: var(--font-display);
  font-size: clamp(1.3125rem, 1.16rem + 0.63vw, 1.5rem);
  line-height: 1.4;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
  max-width: 36ch;
  /* Hang the opening quote mark so the text edge stays flush. */
  text-indent: -0.4em;
}
.reflection .reflection__more {
  margin-top: var(--s-4);
  font-family: var(--font-body);
  font-size: var(--t-reading);
  line-height: 1.6;
  font-weight: 400;
  letter-spacing: normal;
  color: var(--body);
  max-width: 58ch;
  text-indent: -0.36em;
}

/* With JavaScript the slides share one grid cell; the track takes the current
   slide's height (set by script) and changes when the slide does. Hidden slides are
   visibility:hidden, so they leave the accessibility tree and tab order. */
.js .carousel.is-ready .carousel__track {
  display: grid;
  align-items: start;
  touch-action: pan-y;
}
.js .carousel.is-ready .reflection {
  grid-area: 1 / 1;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateX(var(--from, 1rem));
  transition: opacity 0.35s var(--ease), transform 0.6s var(--ease), visibility 0s linear 0.35s;
}
.js .carousel.is-ready .reflection.is-current {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.5s var(--ease) 0.1s, transform 0.6s var(--ease) 0.1s, visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .js .carousel.is-ready .carousel__track,
  .js .carousel.is-ready .reflection,
  .js .carousel.is-ready .reflection.is-current { transition: none; transform: none; }
}

.proof__note { margin-top: var(--s-4); max-width: 58ch; }

/* Every section ends on the same beat: centred, between two gold rules, on the
   inverted ground. Section 4's summary used to end left-aligned on a hairline,
   the one closer of four in a different grammar — and the one carrying the price. */
.callout,
.closing-value {
  margin-top: var(--s-7);
  padding: var(--s-6) var(--s-5);
  background: var(--quartz);
  border-block: 1px solid var(--gold);
  text-align: center;
}
.stratum--quartz .callout, .stratum--quartz .closing-value { background: var(--white); }
.stratum--soft .callout, .stratum--soft .closing-value { background: var(--white); }
.callout p {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 1.05rem + 0.85vw, 1.5rem);
  line-height: 1.4;
  font-weight: 500;
  color: var(--ink);
  margin-inline: auto;
  max-width: 30ch;
  letter-spacing: -0.01em;
}
.callout .action-row { justify-content: center; }

/* --------------------------------------------------------------------------
   10. Section 3 — The Journey
   Six stages on a descending arc. The bead inverts here.
   -------------------------------------------------------------------------- */

.journey { position: relative; margin-top: var(--s-6); }

.journey__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0;
  max-width: 66rem;
  container-type: inline-size;
  container-name: journey;
}

/* Below the band breakpoint every bed stacks in one column, so the marker, the
   name and the copy all start at the same left edge. The two-column mobile grid
   this replaces auto-placed the copy back under the marker, 64px off the name. */
.journey__stage {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--band-gap-stacked);
  padding-block: var(--s-5);
  border-bottom: 1px solid var(--gold-hair);
}
.journey__stage:first-child { border-top: 1px solid var(--gold-hair); }

/* The arc: each stage steps further from the seam, then returns. Full amplitude
   on desktop; half on phones, where most paid traffic lands, so the page's most
   distinctive structural idea is not a desktop-only feature. */
.journey__stage { padding-left: calc(var(--offset) / 2); }
.journey__stage:nth-child(1) { --offset: 0rem; }
.journey__stage:nth-child(2) { --offset: 1rem; }
.journey__stage:nth-child(3) { --offset: 2rem; }
.journey__stage:nth-child(4) { --offset: 2rem; }
.journey__stage:nth-child(5) { --offset: 1rem; }
.journey__stage:nth-child(6) { --offset: 0rem; }

/* Same repair as `.diff__item` and the walkthrough: gate the ladder in the unit its
   tracks are written in, and ask the bed rather than the window. */
@container journey (min-width: 51.75rem) {
  .journey__stage {
    grid-template-columns: var(--band-marker) minmax(0, var(--band-title)) minmax(0, 1fr);
    gap: var(--band-gap);
    align-items: baseline;
    padding-left: var(--offset);
  }
}
@supports not (container-type: inline-size) {
  @media (min-width: 56.25rem) {
    .journey__stage {
      grid-template-columns: var(--band-marker) minmax(0, var(--band-title)) minmax(0, 1fr);
      gap: var(--band-gap);
      align-items: baseline;
      padding-left: var(--offset);
    }
  }
}

.journey__marker {
  position: relative;
  font-family: var(--font-display);
  font-size: var(--t-label);
  font-weight: 600;
  color: var(--gold-text);
  letter-spacing: 0.08em;
}
/* The diamond sits at the marker column's own left edge, not 0.9rem outside it.
   Overhanging, it broke the section's left content edge on stages 1 and 6 —
   the two stages the Arc Rule holds flush against the seam. */
.journey__marker::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0.52em;
  width: 5px;
  height: 5px;
  background: var(--gold);
  transform: rotate(45deg);
}
/* The marker's own indent and its trailing rule belong to the three-column state,
   so they travel with the ladder's gate rather than with a second viewport query. */
.journey__marker::after { display: none; }
@container journey (min-width: 51.75rem) {
  .journey__marker { padding-left: 0.9rem; }
  .journey__marker::after { display: block; }
}
@supports not (container-type: inline-size) {
  @media (min-width: 56.25rem) {
    .journey__marker { padding-left: 0.9rem; }
    .journey__marker::after { display: block; }
  }
}

.journey__name {
  font-family: var(--font-display);
  font-size: var(--t-subhead);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.journey__copy { color: var(--body); }
.journey__copy p { max-width: 58ch; }

.pacing-note {
  margin-top: var(--s-5);
  font-size: var(--t-small);
  color: var(--body-quiet);
  font-style: italic;
  max-width: 58ch;
}

/* --------------------------------------------------------------------------
   11. Section 4 — What's included
   -------------------------------------------------------------------------- */

.offer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-5);
  margin-top: var(--s-6);
}
@media (min-width: 900px) {
  .offer-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: var(--s-6); align-items: start; }
}

.summary-card {
  background: var(--quartz);
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius);
  padding: var(--s-5);
  box-shadow: var(--lift-1);
}
.stratum--quartz .summary-card { background: var(--white); }

/* A bed, not a second plate. It shipped as the summary card's twin — same ground,
   border, radius and padding, differing only by one shadow — so two co-equal
   surfaces sat side by side and neither won. The plate rule settles which is which:
   a bordered, shadowed plate is for an offer, a form or a funnel terminus. The
   summary card is the offer; this is the arithmetic behind it. So it takes the
   stratum treatment instead — transparent ground, one gold rule on top, square
   corners — and the plate keeps its elevation alone. */
.value-block {
  border-top: 1px solid var(--gold);
  padding: var(--s-5) 0 0;
}

.value-list { list-style: none; margin: var(--s-3) 0 0; padding: 0; }
.value-list li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s-3);
  padding-block: var(--s-2);
  border-bottom: 1px solid var(--gold-hair);
  font-size: var(--t-small);
  line-height: 1.4;
}
.value-list li:last-child { border-bottom: 0; }
.value-list .v-name { color: var(--body); }
.value-list .v-sub {
  display: block;
  margin-top: 0.2rem;
  font-size: var(--t-label);
  line-height: 1.45;
  color: var(--body-quiet);
}
.value-list .v-amt {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.value-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s-3);
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--gold);
  font-family: var(--font-display);
}
.value-total__label { font-size: var(--t-small); color: var(--body); }
.value-total__amt { font-size: var(--t-recap); font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }

/* Same vocabulary as .price__was in the plate: the superseded figure goes quiet and
   takes a Mica strike, so the pair reads as a gap rather than as two facts. */
.value-total__amt--was {
  color: var(--body-quiet);
  text-decoration: line-through;
  text-decoration-color: var(--mica);
}

.value-total--price { border-top-color: var(--gold-hair); }

.value-gap {
  margin-top: var(--s-2);
  font-family: var(--font-display);
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--ore-deep);
}

.footnote {
  margin-top: var(--s-3);
  font-size: var(--t-label);
  line-height: 1.5;
  color: var(--body-quiet);
}

/* The plate's most valuable line, and until 2026-09-18 its quietest: it shipped at
   15px beside a "Save $55" badge worth about a fifth as much. It now reads at the
   plate's reading size with the amount in Ink, the same weight the prices take, so
   the two commercial facts in this plate are legible against each other. */
.insurance-line {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--gold-hair);
  font-size: var(--t-reading);
  line-height: 1.5;
  color: var(--body);
}
.insurance-line__amt {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.insurance-line a { font-weight: 600; }

/* Stage grid + shared detail panel */
.stages {
  margin-top: var(--s-7);
  padding-top: var(--s-6);
  border-top: 1px solid var(--gold-hair);
}

.stages__helper {
  font-size: var(--t-small);
  color: var(--body-quiet);
  margin-bottom: var(--s-4);
}

.stages__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-4);
}

/* The cards and their panels are siblings in one grid, so the panel can span both
   columns under the whole 2x2 block. `nth-of-type` used to place the cards, which
   worked only while the cards were <button> and the panels <div> — one element type
   each. They are all <div> now, so placement counts children: cards are 1/3/5/7 and
   panels 2/4/6/8. Keep that order, or restate the areas. */
@media (min-width: 900px) {
  .stages__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* The card's right padding used to be --s-5 on top of a --s-4 column gap, so the
       two top hairlines sat 24px apart while the text under them sat 56px apart: the
       rules read as nearly touching and the columns as far apart. The gap is now the
       only interval, and each rule ends exactly where its own content does. */
    column-gap: var(--s-5);
    row-gap: var(--s-4);
  }
  .stages__grid > .stage-card:nth-child(1) { grid-area: 1 / 1; }
  .stages__grid > .stage-card:nth-child(3) { grid-area: 1 / 2; }
  .stages__grid > .stage-card:nth-child(5) { grid-area: 2 / 1; }
  .stages__grid > .stage-card:nth-child(7) { grid-area: 2 / 2; }
  .stage-panel { grid-area: 3 / 1 / 4 / 3; }
}

/* A bed, not a control. This was a <button> wrapping a <ul>, which is an invalid
   content model and, worse, flattened the list into the button's accessible name —
   Stage 4 announced as a single 47-word string. The card is now a plain bed and the
   control is the toggle row at its foot, which is the only part that was ever doing
   anything. */
.stage-card {
  border-top: 1px solid var(--gold-hair);
  padding: var(--s-4) 0 var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  transition: border-top-color 0.3s var(--ease);
}
.stage-card > p { margin: 0; }
/* The top rule answers the toggle, not the bed: the bed is not clickable, so
   lighting the whole card on hover would promise a click that does not exist.
   Its own rule so a browser without :has() simply drops it. */
.stage-card:has(.stage-card__toggle:hover) { border-top-color: var(--gold); }
.stage-card:focus-within { border-top-color: var(--gold); }
.stage-card.is-open { border-top-color: var(--ore); }

.stage-card__kicker {
  font-family: var(--font-display);
  font-size: var(--t-label-sm);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-text);
}
.stage-card__title {
  font-family: var(--font-display);
  font-size: var(--t-subhead);
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.stage-card__benefit { font-size: var(--t-small); line-height: 1.55; color: var(--body); }

.stage-card__components {
  list-style: none;
  margin: var(--s-1) 0 0;
  padding: 0;
  display: grid;
  gap: var(--s-1);
}
.stage-card__components li {
  font-size: var(--t-label);
  line-height: 1.45;
  color: var(--ink);
  padding-left: 1.1rem;
  position: relative;
}
.stage-card__components li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.58em;
  width: 4px;
  height: 4px;
  background: var(--gold-mark);
  transform: rotate(45deg);
}

.stage-card__toggle {
  margin-top: auto;
  align-self: flex-start;
  background: transparent;
  border: 0;
  border-radius: var(--radius-chip);
  padding: var(--s-2) 0 0;
  text-align: left;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-display);
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--ore-deep);
}
.stage-card__toggle:hover { color: var(--ore); }
.stage-card__toggle .sign {
  display: inline-grid;
  place-items: center;
  width: 1.15rem;
  height: 1.15rem;
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius-chip);
  transition: transform 0.4s var(--ease), border-color 0.3s var(--ease);
}
.stage-card__toggle[aria-expanded='true'] .sign { transform: rotate(135deg); border-color: var(--ore); }
.stage-card__toggle .label-open { display: inline; }
.stage-card__toggle .label-close { display: none; }
.stage-card__toggle[aria-expanded='true'] .label-open { display: none; }
.stage-card__toggle[aria-expanded='true'] .label-close { display: inline; }

.stage-panel {
  background: var(--white);
  border: 0;
  border-block: 1px solid var(--gold);
  border-radius: 0;
  padding: var(--s-5) 0;
  box-shadow: none;
}
.stratum--white .stage-panel { background: transparent; }
.stage-panel[hidden] { display: none; }

.stage-panel__title {
  font-family: var(--font-display);
  font-size: var(--t-reading);
  font-weight: 700;
  color: var(--ink);
  margin-bottom: var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--gold-hair);
}

/* The card face names the components; this says what each one is. The names repeat
   here on purpose — a name above its own explanation is a heading, not duplication,
   and these are branded deliverables a reader is being asked to pay for, so leaving
   them unexplained turns an asset into a phrase. The failure this replaced was a
   thin payload, not the repetition: the old sentences ran eight to fifteen words and
   mostly restated the name. Two columns at the project's own 900px tier, not the
   720px one-off this rule used to carry. */
.detail-list { display: grid; gap: var(--s-5); margin: 0; }
@media (min-width: 900px) {
  .detail-list { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s-6); }
}
.detail-list dt {
  font-family: var(--font-display);
  font-size: var(--t-reading);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.35;
}
.detail-list dd {
  margin: 0.5em 0 0;
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--body);
  max-width: 58ch;
}
.detail-list .amt { color: var(--gold-text); font-weight: 600; font-size: var(--t-small); }

.flow-note {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--gold-hair);
  font-size: var(--t-small);
  color: var(--body-quiet);
  font-style: italic;
}

/* The summary is reading copy, not display type, so it keeps body size and
   takes the banded-list measure; centred, it is held to 58ch. */
.closing-value p { margin-inline: auto; max-width: 58ch; }
.closing-value .action-row { justify-content: center; }
/* Centred in the closer; its intervals are the page-wide fine-print ones. */
.closing-value .seasonality { margin-inline: auto; }

/* --------------------------------------------------------------------------
   12. Section 5 — What happens
   -------------------------------------------------------------------------- */

/* The five-step timeline that opened this section, and the toggle that hid the
   steps behind it, both came out: two numberings of one session, neither matching
   the four stages in Section 4 or the six in the Journey. The steps now carry the
   section directly, and the bed is the Band Ladder's third occupant again — the
   role `--band-marker`'s 3.5rem was sized for. See the Band Ladder Rule. */
.walkthrough { margin-top: var(--s-6); }

/* One column at every width, capped at the banded-list measure the other two
   ladder beds use. Two columns were tried twice: a 2x2 grid made the shortest
   stage in a row hold a void as tall as the longest, and two independent stacks
   put the four gold hairlines at three different heights, with Stage 4's rule
   crossing the left column mid-list. Unequal stages admit no third arrangement,
   and a sequence numbered 1 to 16 has no business being read down one column and
   up another — the entrance stagger was running 1+3, then 4, then 2. */
.walkthrough__body {
  margin-top: var(--s-5);
  display: grid;
  gap: var(--s-6);
  max-width: 66rem;
  container-type: inline-size;
  container-name: walkthrough;
}

/* The cadence, ink to ink: 34 above a stage title, 27 below it, 18 between steps,
   50 between stages. Ratios 1.9 : 1.5 : 1 : 2.8. Before this the same --s-3 token
   set both the title's margin and the row gap, so a stage title sat 1.08x further
   from its first step than the steps sat from each other and read as another row
   rather than as the head of a group. */
.wt-stage {
  border-top: 1px solid var(--gold);
  padding-top: var(--s-5);
}
.wt-stage__name {
  font-family: var(--font-display);
  font-size: var(--t-reading);
  font-weight: 700;
  color: var(--ink);
  margin-bottom: var(--s-4);
}
.wt-stage ol { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--s-4); }

/* Stacked below the ladder's own breakpoint, exactly as `.diff__item` and
   `.journey__stage` stack: numeral, then name, then clause. This replaced a
   private 599px rule that hung the numeral by hand, so the section is back to
   one tier instead of two. */
.wt-stage li {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-1);
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--body);
}

/* A container query, not a viewport one, and the unit is the point. The ladder's
   marker and title tracks are rem, so they grow with the root font size; a px
   media query does not. Raise the browser's text size and the title track reaches
   512px while the clause track — a bare `1fr` with a 0 floor — starves to 333px
   and then to 140px, one word per line, overflowing the viewport. The ladder
   stayed engaged hundreds of pixels past the point where it fit, because the query
   was asking about the window when the only question that matters is "does this
   bed have room for three columns".

   51.75rem is the width `.walkthrough__body` has at a 900px viewport, so at a 16px
   root the switch lands exactly where the viewport query used to and default
   rendering is unchanged. Above that root it moves with the text, which is the
   whole repair. Measuring the container rather than the window also means the bed
   is correct if it is ever nested or narrowed for any other reason.

   Stacked (below the threshold), a row's three parts bind at --s-1 against --s-4
   between rows, 3:1. The ladder's own --band-gap-stacked is 12px, which works for
   .diff__item and .journey__stage because every one of those rows carries a
   border-bottom to close it. These rows have only the stage hairline, so the gap
   does the work alone and has to be tighter.

   `.diff__item` and `.journey__stage` carry the same latent bug — rem tracks
   behind a px query — and have not been converted; their titles are short enough
   that the starve is far off, but it is the same defect. */
@container walkthrough (min-width: 51.75rem) {
  .wt-stage ol { gap: var(--s-3); }
  .wt-stage li {
    grid-template-columns: var(--band-marker) minmax(0, var(--band-title)) minmax(0, 1fr);
    gap: var(--band-gap);
    align-items: baseline;
  }
}

/* Without container query support the bed stays stacked, which is correct but
   costs the desktop ladder, so restore it on the old viewport gate there. */
@supports not (container-type: inline-size) {
  @media (min-width: 56.25rem) {
    .wt-stage ol { gap: var(--s-3); }
    .wt-stage li {
      grid-template-columns: var(--band-marker) minmax(0, var(--band-title)) minmax(0, 1fr);
      gap: var(--band-gap);
      align-items: baseline;
    }
  }
}

.wt-stage li .n {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--gold-text);
  font-size: var(--t-label);
  letter-spacing: 0.06em;
  white-space: nowrap;
}

/* The row is a marker, a name and a clause. The name is what a reader matches
   against the priced cards two sections up, so it takes the ladder's title column
   and Ink at 600; the clause follows in the body column, at the label step in Body
   Quiet, on the same 58ch measure the Journey's copy uses. Baseline alignment on
   the row replaced a 0.15em padding nudge on the numeral — the rest of the page
   aligns marker rows on the baseline, and the nudge broke whenever a name wrapped. */
.wt-step__name {
  display: block;
  font-weight: 600;
  color: var(--ink);
}
.wt-step__note {
  display: block;
  font-size: var(--t-label);
  line-height: 1.45;
  color: var(--body-quiet);
  max-width: 58ch;
}

/* --s-5, between the two intervals this bed already uses. The shared .action-row
   ships --s-3, which is the row-to-row gap, so the CTA read as one more step; the
   fix for that was --s-6, and that was wrong in the other direction. 48px is the
   stage interval, but what arrives at 48px in a stage is a 1px hairline whose
   content starts 33px further down. What arrives here is a 56px solid Ore block,
   so at the distance this bed trains the reader to expect a divider, the button
   read as the start of the next group rather than the close of this one. The hero
   puts 16px between its evidence and its action and the Section 4 closer 22px;
   32px is this bed's own --s-5 and sits between the row and the stage. */
.walkthrough .action-row { margin-top: var(--s-5); }

/* Fine print in this bed takes the ramp's bottom step and ends on the ladder.
   At the shared 13px it was set identically to the sixteen clauses above it —
   same size, family, weight, colour and 58ch measure — so the section's microcopy
   had no step down from its body copy, and isolated at x=168 on empty ground it
   read as larger than the type it qualifies. The hero and the Section 4 closer
   keep 13px, where it steps down from 17px body and works.

   The measure is the ladder's first two tracks, so the rule terminates at x=512,
   the right edge of .wt-step__name, .journey__name and .diff__title. At 58ch it
   ended at 620px: past the marker column, past the whole name column, and 76px
   into the clause column, on nothing. Inert on phones, where the column is
   narrower than the cap. */
.walkthrough .fine-print {
  font-size: var(--t-label-sm);
  max-width: calc(var(--band-marker) + var(--band-gap) + var(--band-title));
}

/* --------------------------------------------------------------------------
   13. Section 6 — Suitability, logistics, FAQ
   -------------------------------------------------------------------------- */

/* The risk-reversal bed. It borrows the `.info-card` idiom exactly — transparent
   ground, one Seam Gold top rule, `--s-4` above its title — because it is the same
   kind of object as the three beds below it, just wider and carrying more weight.
   Stratum-Not-Card Rule: no plate, no radius, no shadow.

   It carries no bottom rule on purpose. `.stage-panel` is the page's other
   detail-list bed and closes with `border-block`, but here the three `.info-card`
   top rules arrive `--s-6` below, and a closing rule would put four gold lines in
   two intervals. The gap and the cards' own rules do the separating.

   The payload is `.detail-list`, unchanged — the two-column term-and-explanation
   grammar Section 4's stage panels already use. Four entries land 2x2 above 900px
   and stack below it. No new component. */
.support {
  margin-top: var(--s-6);
  border-top: 1px solid var(--gold);
  padding-top: var(--s-4);
}
.support .h3 { margin-bottom: var(--s-3); }
/* The continuous-facilitation promise, on the lead step because it sits directly
   under a heading, held to the banded measure so it does not run the shell. */
.support .lead { max-width: 58ch; margin: 0 0 var(--s-5); }

.info-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-4);
  margin-top: var(--s-6);
}
@media (min-width: 900px) {
  /* Unequal beds still end on one line — the boxes used to hide the rag. */
  .info-grid { padding-bottom: var(--s-5); border-bottom: 1px solid var(--gold-hair); }
}
/* Weighted by what each bed carries. The brief pins every line to its card, so
   the beds are balanced by width instead of by moving content: the four-line
   Preparation bed gets room, the two-line Medical bed narrows and wraps. At
   equal thirds the Medical bed ended ~145px above the shared rule. */
@media (min-width: 900px) { .info-grid { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.1fr) minmax(0, 0.7fr); gap: var(--s-5); } }

.info-card {
  background: transparent;
  border: 0;
  border-top: 1px solid var(--gold);
  border-radius: 0;
  padding: var(--s-4) var(--s-4) 0 0;
}

.info-card__title {
  font-family: var(--font-display);
  font-size: var(--t-reading);
  font-weight: 700;
  color: var(--ink);
  margin-bottom: var(--s-3);
  line-height: 1.3;
}
.info-card ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.info-card li {
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--body);
  padding-left: 1.1rem;
  position: relative;
}
.info-card li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 4px;
  height: 4px;
  background: var(--gold);
  transform: rotate(45deg);
}
.info-card address + ul { margin-top: var(--s-3); }
.info-card address {
  font-style: normal;
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--body);
}

/* FAQ */
.faq { margin-top: var(--s-8); }
.faq__list { border-top: 1px solid var(--gold-hair); margin-top: var(--s-5); max-width: 44rem; }

/* On desktop the FAQ joins the band ladder: its heading spans the marker and
   title columns and holds its place while the answers scroll, and the list sits
   in the body column. A 44rem list alone at the left of a 72rem shell left 40%
   of the section empty, with the disclosure signs stranded mid-page. */
/* Same rem tracks, same repair as `.proof`: ask the bed, not the window. */
@container bed (min-width: 51.75rem) {
  .faq {
    display: grid;
    grid-template-columns:
      calc(var(--band-marker) + var(--band-gap) + var(--band-title))
      minmax(0, 44rem);
    column-gap: var(--band-gap);
    /* The heading sits on the first question's baseline, as a band marker sits
       on its title's. */
    align-items: baseline;
  }
  .faq > .h3 { position: sticky; top: var(--s-5); }
  .faq__list { margin-top: 0; }
}
@supports not (container-type: inline-size) {
  @media (min-width: 56.25rem) {
    .faq {
      display: grid;
      grid-template-columns:
        calc(var(--band-marker) + var(--band-gap) + var(--band-title))
        minmax(0, 44rem);
      column-gap: var(--band-gap);
      align-items: baseline;
    }
    .faq > .h3 { position: sticky; top: var(--s-5); }
    .faq__list { margin-top: 0; }
  }
}

.faq__item { border-bottom: 1px solid var(--gold-hair); }

.faq__q {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  background: transparent;
  border: 0;
  padding: var(--s-4) 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: var(--t-reading);
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
  transition: color 0.25s var(--ease);
}
.faq__q-text { flex: 1 1 auto; }
.faq__q:hover { color: var(--ore-deep); }
.faq__q .sign {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.15em;
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius-chip);
  color: var(--gold-mark);
  transition: transform 0.4s var(--ease), border-color 0.3s var(--ease), color 0.3s var(--ease);
}
.faq__q[aria-expanded='true'] .sign { transform: rotate(135deg); border-color: var(--ore); color: var(--ore); }

.faq__a { padding: 0 0 var(--s-5); }
.faq__a[hidden] { display: none; }
.faq__a p { font-size: var(--t-small); line-height: 1.62; max-width: 68ch; }
.faq__a p + p { margin-top: var(--s-3); }

/* --------------------------------------------------------------------------
   14. Section 7 — Lead capture
   -------------------------------------------------------------------------- */

.claim__card {
  background: var(--white);
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius);
  padding: clamp(var(--s-5), 4vw, var(--s-7));
  max-width: 580px;
  margin-inline: auto;
  box-shadow: var(--lift-3);
}

.claim__head { text-align: center; margin-bottom: var(--s-6); }
.claim__head .eyebrow {
  padding-left: 0;
  text-align: center;
  max-width: none;
  margin-inline: auto;
}
.claim__head .eyebrow::before {
  position: static;
  display: block;
  margin: 0 auto var(--s-3);
}
.claim__offer {
  margin-top: var(--s-4);
  font-size: var(--t-reading);
  line-height: 1.55;
  color: var(--body);
}

.field { margin-bottom: var(--s-4); }

.field label {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 0.5rem;
}
.field .optional { color: var(--body-quiet); font-weight: 500; }

.field input[type='text'],
.field input[type='email'],
.field input[type='tel'] {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--t-reading);
  line-height: 1.4;
  color: var(--ink);
  background: var(--quartz);
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius);
  padding: 0.95rem 1rem;
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.field input::placeholder { color: var(--placeholder); }
.field input:hover { border-color: var(--mica); }
.field input:focus {
  outline: none;
  border-color: var(--ore);
  background: var(--white);
  box-shadow: 0 0 0 3px var(--ore-tint);
}
.field input[aria-invalid='true'] { border-color: var(--ore); background: var(--ore-tint); }

.field__error {
  display: none;
  margin-top: 0.45rem;
  font-size: var(--t-label);
  line-height: 1.4;
  color: var(--ore-deep);
  font-weight: 600;
}
.field__error:not(:empty) { display: block; }

.consent {
  display: grid;
  grid-template-columns: 1.5rem 1fr;
  gap: 0.75rem;
  align-items: start;
  margin-block: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--gold-hair);
}
/* 24px, not the 20px it shipped at: WCAG 2.2 SC 2.5.8 sets 24×24 as the AA target
   floor, and the paired label extending the hit area does not excuse the box itself. */
.consent input[type='checkbox'] {
  width: 1.5rem;
  height: 1.5rem;
  margin: 0;
  accent-color: var(--ore);
  cursor: pointer;
}
.consent label {
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--body);
  cursor: pointer;
}
.consent .field__error { grid-column: 1 / -1; }

.form-microcopy {
  margin-top: var(--s-4);
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--body-quiet);
  text-align: center;
}

.form-status {
  margin-top: var(--s-4);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius);
  font-size: var(--t-small);
  line-height: 1.5;
  text-align: center;
}
.form-status[hidden] { display: none; }
.form-status--error { background: var(--ore-tint); border: 1px solid var(--ore); color: var(--ore-deep); }
.form-status--working { background: var(--mica-fill); border: 1px solid var(--gold-quiet); color: var(--body); }

/* --------------------------------------------------------------------------
   14b. Standing mobile action
   Desktop clears the fold with the real hero CTA; mobile cannot without cutting
   brief-pinned panel content, so the action follows the visitor instead.
   -------------------------------------------------------------------------- */

.mobile-cta {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 20;
  /* The shell's own gutter inline: a sliver of Quartz either side seats the
     plinth in the strata, and the button lines up with the content above it. */
  padding: var(--s-2) var(--gutter) calc(var(--s-2) + env(safe-area-inset-bottom, 0px));
  background: color-mix(in srgb, var(--quartz) 92%, transparent);
  border-top: 1px solid var(--gold-quiet);
  transform: translateY(110%);
  transition: transform 0.5s var(--ease);
  display: none;
}
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .mobile-cta { background: var(--quartz); }
}
.mobile-cta .cta { box-shadow: var(--lift-2); }

@media (max-width: 899px) {
  html:has(.mobile-cta) { scroll-padding-bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px)); }
  .mobile-cta { display: block; }
  .mobile-cta.is-up { transform: translateY(0); }
  /* Room for the bar so it never sits on the last line of the footer, held
     unconditionally: reserving it only while the bar is up changed
     scrollHeight mid-scroll and jumped the seam fill with it. The safe-area
     inset is part of the bar's height, so it is part of the reserve. */
  /* Scoped to the document that actually carries the plinth: thank-you.html
     has no standing action and must not reserve room for one. */
  body:has(.mobile-cta) { padding-bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px)); }
}

@media (prefers-reduced-motion: reduce) {
  .mobile-cta { transition: none; }
}

/* --------------------------------------------------------------------------
   15. Footer
   -------------------------------------------------------------------------- */

.site-footer {
  background: var(--white);
  border-top: 1px solid var(--gold-hair);
  padding-block: var(--s-6);
  font-size: var(--t-small);
  color: var(--body-quiet);
}
.site-footer .shell { display: grid; gap: var(--s-3); }
@media (min-width: 720px) {
  .site-footer .shell { grid-template-columns: 1fr auto; align-items: baseline; }
}
.site-footer__main { display: grid; gap: var(--s-2); }
.site-footer p { max-width: var(--measure); margin: 0; }
.site-footer .brand { font-family: var(--font-display); font-weight: 700; color: var(--ink); }

/* --------------------------------------------------------------------------
   16. Thank-you page
   -------------------------------------------------------------------------- */

/* svh, not vh, so the mobile URL bar does not add a scroll. The shell centres
   on auto margins rather than align-items: a flex item centred by margin still
   scrolls into view when the card outgrows the viewport, where a centred flex
   line clips off the top. */
.ty { min-height: calc(100svh - var(--header-h)); display: flex; padding-block: var(--s-7); }
.ty > .shell { margin-block: auto; }

.ty__card {
  background: var(--white);
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius);
  padding: clamp(var(--s-5), 4vw, var(--s-7));
  max-width: 640px;
  margin-inline: auto;
  box-shadow: var(--lift-3);
  text-align: center;
}

.ty__mark { color: var(--gold-mark); margin-inline: auto; margin-bottom: var(--s-5); }

.ty__lead { margin-top: var(--s-4); max-width: 44ch; }

/* A phone tier for the card's head. The page has exactly one decision on it, and
   until 2026-09-18 that decision shipped below the fold on every phone: the action
   sat at the foot of the card, under the dispatch line and the four-step recap. It
   moved up under the code, and these intervals close the last ~90px so the button
   clears an 844px viewport. Everything here is vertical rhythm — no type sizes, no
   colour, nothing that changes what the page says. A 667px phone still scrolls a
   little; the mark, the headline and a 2.75rem code cannot be compressed past that
   without taking the recognition the card is built on. */
@media (max-width: 599px) {
  .ty { padding-block: var(--s-5); }
  .ty__mark { margin-bottom: var(--s-3); }
  .ty__mark svg { width: 38px; height: 38px; }
  .ty__lead { margin-top: var(--s-3); }
  .promo { margin-top: var(--s-4); margin-bottom: var(--s-3); padding: var(--s-4); }
  .promo__copy { padding-block: 0.75rem; }
  /* The hero's CTA takes the same step down at this width, for the same reason. */
  .ty .cta--lg { padding-block: 1.15rem; }
}

.ty__card p { margin-inline: auto; }

.promo {
  margin-block: var(--s-6);
  padding: var(--s-5);
  background: var(--quartz);
  border: 1px solid var(--gold);
  border-radius: var(--radius);
}
.promo__label {
  font-family: var(--font-display);
  font-size: var(--t-label-sm);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--body-quiet);
}
/* The one string on this page a visitor has to reproduce exactly. It never breaks
   and never hyphenates: a code split over two lines is a code half of them will
   mistype. The clamp floor is set so nine tracked caps still fit the promo card's
   inner width on a 390px phone with room to spare. */
.promo__code {
  font-family: var(--font-display);
  font-size: clamp(var(--t-code-sm), 1.3rem + 2.2vw, var(--t-code));
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink);
  margin-block: var(--s-2);
  line-height: 1.1;
  white-space: nowrap;
  overflow-wrap: normal;
}
.promo__terms { font-size: var(--t-small); color: var(--body); }

.promo__copy {
  margin-top: var(--s-3);
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-display);
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--ore-deep);
  background: transparent;
  border: 1px solid var(--gold-quiet);
  border-radius: var(--radius);
  padding: 0.95rem 1.4rem;
  cursor: pointer;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.promo__copy:hover { border-color: var(--gold); background: var(--mica-fill); }

/* Opens the recap group below the action. The action used to be last on the card
   and this block sat above it, so the dispatch line needed only a bottom margin;
   now it is the first thing after the button and has to be pushed clear of it. */
.dispatch {
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--body);
  padding: var(--s-4);
  background: var(--quartz-soft);
  border-radius: var(--radius);
  margin-top: var(--s-6);
  margin-bottom: var(--s-5);
}

.steps { text-align: left; margin-bottom: var(--s-5); }
/* The card's last line, on the page's fine-print interval. */
.ty__close { margin-top: 0; }
.steps__title {
  font-family: var(--font-display);
  font-size: var(--t-label-sm);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--body-quiet);
  margin-bottom: var(--s-3);
}
.steps ol { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--s-3); counter-reset: step; }
.steps li {
  display: grid;
  grid-template-columns: 1.6rem 1fr;
  gap: 0.75em;
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--body);
  counter-increment: step;
}
.steps li > span { grid-column: 2; }
.steps li::before {
  content: counter(step);
  font-family: var(--font-display);
  font-size: var(--t-label);
  font-weight: 600;
  color: var(--gold-text);
  padding-top: 0.12em;
}

/* --------------------------------------------------------------------------
   17. Utilities
   -------------------------------------------------------------------------- */

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--s-3);
  z-index: 100;
  background: var(--ore);
  color: var(--white);
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-weight: 600;
  text-decoration: none;
  transition: top 0.3s var(--ease);
}
.skip-link:focus { top: var(--s-3); color: var(--white); }
/* a:not(.cta):hover outranks the rules above and would set Ink on Ore (3.2:1).
   Hover darkens the ground instead, as the CTA does. */
a.skip-link:hover { color: var(--white); background: var(--ore-deep); }

/* --------------------------------------------------------------------------
   18. Motion
   One authored moment: strata settle as they enter. Everything else is state.
   -------------------------------------------------------------------------- */

.rise {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: no-preference) {
  .js .rise {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.85s var(--ease), transform 0.85s var(--ease);
  }
  .js .rise.is-in { opacity: 1; transform: none; }
  .js .rise:nth-child(2) { transition-delay: 60ms; }
  .js .rise:nth-child(3) { transition-delay: 120ms; }
  .js .rise:nth-child(4) { transition-delay: 180ms; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .seam__bead { display: none; }
}

/* --------------------------------------------------------------------------
   19. Print
   -------------------------------------------------------------------------- */

@media print {
  .seam, .skip-link, .cta { display: none; }
  .stage-panel[hidden], .faq__a[hidden] { display: block !important; }
  /* Printing landscape crosses 900px, at which point the four force-shown panels all
     land in the same grid cell — 3 / 1 / 4 / 3 — and overprint one another. The grid
     is a screen affordance; on paper the stages read as one column in order. */
  .stages__grid { grid-template-columns: minmax(0, 1fr); }
  .stages__grid > .stage-card,
  .stage-panel { grid-area: auto; }
  .stage-card__toggle { display: none; }
  body { background: var(--white); }
}

/* --------------------------------------------------------------------------
   20. No JavaScript
   The disclosures used to ship closed — `hidden` in the markup, removed only by
   main.js — so with JS off the four stage panels and every FAQ answer were plain
   unreachable: about a third of the page's substance, including every component
   explanation a reader is being asked to pay for.

   They now ship OPEN and honest: no `hidden`, `aria-expanded="true"`, so the
   no-JS document states exactly what it shows. main.js collapses them on init and
   then stamps `is-ready` on <html>. The guard below covers the gap between first
   paint and that init, so a scripted visitor never sees the expanded state flash.
   `.js` is set by an inline script in <head>, not by main.js at the end of body,
   precisely so this guard is in force before the first paint.
   -------------------------------------------------------------------------- */

.js:not(.is-ready) .stage-panel,
.js:not(.is-ready) .faq__a { display: none; }

/* Without JS the toggles do nothing, so they do not ship as controls. The FAQ
   question stays visible — it is the heading of the answer under it — and only
   loses the sign that promised a state change. */
html:not(.js) .stage-card__toggle,
html:not(.js) .faq__q .sign { display: none; }
html:not(.js) .faq__q { cursor: default; padding-bottom: var(--s-2); }
html:not(.js) .faq__q:hover { color: var(--ink); }

/* Same overprint as print: four open panels cannot share one grid cell. */
html:not(.js) .stages__grid { grid-template-columns: minmax(0, 1fr); }
html:not(.js) .stages__grid > .stage-card,
html:not(.js) .stage-panel { grid-area: auto; }
