/* ============================================================
   JIIVE — HOME (v3 · gold period)
   Base, header, buttons, hero, scroll story and footer, ported from
   prototype/jiive-gold-period-prototype.html; the sections after the
   story live in css/home-sections.css. Only colours, fonts
   and text differ from the prototype; every value comes from
   css/tokens.css. The story stage, loader and rail are frozen by
   DESIGN.md "Scroll story contract".
   ============================================================ */

/* ---------- Base ---------- */
:root {
  box-sizing: border-box;
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
*, *::before, *::after { box-sizing: inherit; }
html {
  scroll-padding-top: calc(var(--size-header) + env(safe-area-inset-top, 0px));   /* anchors land below the fixed header */
  -webkit-tap-highlight-color: transparent;   /* every control has its own :active press instead */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
/* the menu sheet holds the page still while it is open (Lenis stops too) */
html.menu-open { overflow: hidden; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-emerald-deep);
  font-family: var(--font-body);
  font-weight: var(--weight-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;   /* a long URL or email wraps instead of widening the page */
  overflow-x: hidden;
}
body.locked { overflow: hidden; }
button { font: inherit; color: inherit; }
/* taps fire at once (no double-tap-zoom wait); controls don't select their label on long-press */
a, button, summary, label, [role="tab"] { touch-action: manipulation; }
.btn, .btn-text, .nav-toggle, .sheet-close, [role="tab"] {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
:focus-visible {
  outline: var(--size-focus) solid var(--color-vital-green);
  outline-offset: var(--size-focus-offset);
  border-radius: var(--radius-focus);
}
/* a skip-link or anchor target takes focus so the next Tab starts there; it is not a control, so no ring */
:is(main, section)[tabindex="-1"]:focus { outline: none; }
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-optical-sizing: auto;
  letter-spacing: var(--tracking-display);
  color: var(--color-emerald-ink);
  margin: 0;
  text-wrap: balance;
}
p { line-height: var(--leading-body); text-wrap: pretty; }

.mono {
  font-family: var(--font-mono);
  font-weight: var(--weight-mono);
  font-size: var(--text-mono-meta);
  letter-spacing: var(--tracking-meta);
  line-height: var(--leading-snug);
  text-transform: uppercase;
}

.skip-link {
  position: absolute;
  left: var(--space-md);
  top: var(--space-md);
  z-index: var(--z-skip);
  padding: var(--space-pill-compact-y) var(--space-pill-compact-x);
  border-radius: var(--radius-pill);
  background: var(--color-emerald-ink);
  color: var(--color-ink-contrast);
  font-weight: var(--weight-strong);
  text-decoration: none;
  transform: translateY(-200%);
}
.skip-link:focus-visible { transform: none; }

/* ---------- The period (polished gold bead) ----------
   The logo is artwork (assets/brand/jiive-wordmark*.png) with its dot lifted off;
   the gold period sits exactly where that dot was, in the header and the loader,
   and is the drop that falls into the hero. Margins in % are shares of the logo's
   width, so the bead stays centred on its spot at every size. */
.dot {
  position: absolute;
  left: var(--logo-dot-x);
  top: var(--logo-dot-y);
  width: var(--logo-dot-size);
  aspect-ratio: 1;
  margin: calc(var(--logo-dot-size) / -2) 0 0 calc(var(--logo-dot-size) / -2);
  border-radius: var(--radius-full);
  background: var(--gold-bead);
  box-shadow: var(--shadow-bead);
  animation: beat var(--beat-duration) var(--beat-ease) infinite;
}
.dot.gone { opacity: 0; animation: none; }
.dot.regrow { animation: regrow var(--dur-500) var(--ease-out) both; }
@keyframes beat {
  0%, 42%, 100% { transform: scale(1); }
  9% { transform: scale(1.3); }
  18% { transform: scale(1); }
  27% { transform: scale(1.15); }
}
@keyframes regrow {
  from { transform: scale(var(--story-regrow-from)); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* ---------- Loader ---------- */
.loader {
  position: fixed;
  inset: 0;
  z-index: var(--z-loader);
  display: grid;
  place-items: center;
  pointer-events: none;
}
.loader::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--color-bg);
  transition: opacity var(--story-loader-fade) var(--story-ease-fade);
}
.loader.out::before { opacity: 0; }
/* The loader's logo is the same artwork cut into its five letters, so they can still
   fade and rise one by one; at rest the slices meet exactly. 1em is about the old
   typeset size, so the letters travel (0.1em) as far as they did. */
.lw {
  --lw-h: var(--size-logo-loader);
  position: relative;
  display: flex;
  height: var(--lw-h);
  font-size: calc(var(--lw-h) * 0.8);
  visibility: hidden;
}
.lw.ready { visibility: visible; }
.lw .l {
  display: block;
  flex: none;
  height: 100%;
  width: calc(var(--lw-h) * var(--w));
  background: url("../assets/brand/jiive-wordmark@3x.png") no-repeat;
  background-size: auto 100%;
  background-position: calc(var(--lw-h) * var(--x) * -1) 0;
  opacity: 0;
  transform: translateY(var(--story-letter-travel));
  transition: opacity var(--story-letter-fade) var(--story-ease-fade), transform var(--story-letter-rise) var(--story-ease);
}
/* the cuts fall in the gaps between the letters (measured on the @3x artwork, 300 × 144), as shares of its height */
.lw .l:nth-child(1) { --x: 0;      --w: 0.3958; }   /* j */
.lw .l:nth-child(2) { --x: 0.3958; --w: 0.25; }     /* i */
.lw .l:nth-child(3) { --x: 0.6458; --w: 0.2257; }   /* i */
.lw .l:nth-child(4) { --x: 0.8715; --w: 0.4896; }   /* v */
.lw .l:nth-child(5) { --x: 1.3611; --w: 0.7222; }   /* e, and the room the period sits in */
.lw .l.in { opacity: 1; transform: none; }
html.repeat .loader { display: none; }

/* ---------- Canvas + progress rail ---------- */
#fx {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: var(--z-fx);
  pointer-events: none;
}
.rail {
  position: fixed;
  right: var(--size-rail-inset);
  top: var(--size-rail-top);
  height: var(--size-rail-length);
  width: var(--size-hairline);
  background: var(--color-border);
  z-index: var(--z-rail);
  opacity: 0;
  transition: opacity var(--story-rail-fade) var(--story-ease-fade);
  pointer-events: none;
}
/* after the boot fade-in, opacity is scroll-driven by js/story.js: no transition to lag behind it */
.rail.live { transition: none; }
.rail-fill {
  position: absolute;
  inset: 0;
  background: var(--color-vital-green);
  transform-origin: top;
  transform: scaleY(0);
}
.rail-dot {
  position: fixed;
  left: 0;
  top: 0;
  width: var(--size-rail-bead);
  height: var(--size-rail-bead);
  z-index: var(--z-rail-bead);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--story-rail-fade) var(--story-ease-fade);
}
.rail-dot i {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--gold-bead);
  box-shadow: var(--shadow-bead-px);
}
.rail-dot.landed i { animation: beat var(--beat-duration) var(--beat-ease) infinite; }
body.ready .rail-dot, body.ready .rail { opacity: 1; }

/* ---------- Header ---------- */
/* Fixed on every page (DESIGN.md site-header). Three surfaces, switched by js/nav.js:
   - .at-top: clear, at the very top of the page, so the drop can fall from the logo's
     dot with nothing over it (and the hero reads as one cream field);
   - default: cream glass with a hairline, once the page has scrolled;
   - .is-dark: emerald glass while the header sits over the story band or the footer.
   Only the surface colours and the logo's opacity change, over 200ms. Without JS the
   page's <noscript> keeps .at-top on the cream surface. */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: calc(var(--size-header) + env(safe-area-inset-top, 0px));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  padding: env(safe-area-inset-top, 0px) var(--grid-inline) 0;
  border-bottom: var(--size-hairline) solid var(--color-header-border);
  background-color: var(--color-header-bg);
  -webkit-backdrop-filter: blur(var(--size-blur));
  backdrop-filter: blur(var(--size-blur));
  z-index: var(--z-header);
  transition: background-color var(--dur-200) var(--ease-out), border-color var(--dur-200) var(--ease-out);
}
.nav.at-top {
  border-bottom-color: transparent;
  background-color: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
/* js/nav.js watches this to know the page is at its very top */
.nav-marker { position: absolute; top: 0; left: 0; width: var(--size-hairline); height: var(--size-hairline); pointer-events: none; }
.nav.is-dark {
  border-bottom-color: var(--color-header-border-dark);
  background-color: var(--color-header-bg-dark);
}
.logo {
  position: relative;
  display: block;
  flex: none;
  height: var(--size-logo);
  aspect-ratio: var(--logo-ratio);
}
.logo img { display: block; width: 100%; height: 100%; transition: opacity var(--dur-200) var(--ease-out); }
/* over a band the artwork turns cream (assets/brand/jiive-wordmark-light*.png); the gold period stays */
.logo .logo-light { position: absolute; inset: 0; opacity: 0; }
.nav.is-dark .logo-art { opacity: 0; }
.nav.is-dark .logo-light { opacity: 1; }
/* the tap area reaches 44px without changing the logo's box, which the loader's fly measures */
.logo::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: var(--size-tap);
  transform: translateY(-50%);
}
html.pre .nav .logo { visibility: hidden; }
html.repeat .nav .logo { visibility: visible; }
.nav-right { display: flex; align-items: center; gap: var(--space-nav); }
.nav-links { display: flex; gap: var(--space-nav); }
.nav-links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--size-tap);
  font-size: var(--text-caption);
  color: var(--color-emerald-deep);
  text-decoration: none;
  transition: color var(--dur-120) var(--ease-out);
}

/* ---------- Menu toggle and sheet (≤ 720px; built by js/nav.js) ---------- */
.nav-toggle, .sheet-close {
  display: none;
  place-items: center;
  flex: none;
  width: var(--size-tap);
  height: var(--size-tap);
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background-color: var(--color-emerald-ink);
  box-shadow: var(--shadow-glass-dark);
  color: var(--color-ink-contrast);
  cursor: pointer;
  position: relative;
  transition: transform var(--dur-320) var(--ease-out), background-color var(--dur-200) var(--ease-out), color var(--dur-200) var(--ease-out);
}
.sheet-close { display: grid; }
.nav-toggle:active, .sheet-close:active { transform: scale(var(--motion-press)); transition-duration: var(--dur-120); }
.nav-toggle svg, .sheet-close svg { width: var(--size-icon-lg); height: var(--size-icon-lg); }

/* a native <dialog> dropping from the top: enters over 320ms, leaves over 200ms */
.nav-sheet {
  position: fixed;
  inset: 0 0 auto;
  width: 100%;
  max-width: none;
  max-height: 100%;
  margin: 0;
  padding: calc(env(safe-area-inset-top, 0px) + var(--space-md)) var(--grid-inline) calc(env(safe-area-inset-bottom, 0px) + var(--space-lg));
  border: 0;
  border-radius: 0 0 var(--radius-card) var(--radius-card);
  background: var(--color-bg);
  color: var(--color-emerald-deep);
  box-shadow: var(--shadow-card);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateY(-100%);
  transition: transform var(--dur-200) var(--ease-out), overlay var(--dur-200) allow-discrete, display var(--dur-200) allow-discrete;
}
.nav-sheet[open] { transform: none; transition-duration: var(--dur-320); }
@starting-style { .nav-sheet[open] { transform: translateY(-100%); } }
.nav-sheet::backdrop {
  background: var(--color-backdrop);
  opacity: 0;
  transition: opacity var(--dur-200) var(--ease-out), overlay var(--dur-200) allow-discrete, display var(--dur-200) allow-discrete;
}
.nav-sheet[open]::backdrop { opacity: 1; transition-duration: var(--dur-320); }
@starting-style { .nav-sheet[open]::backdrop { opacity: 0; } }
/* "Menu", its hairline running to the close button */
.sheet-head { display: flex; align-items: center; gap: var(--space-md); }
.sheet-head::after {
  content: "";
  order: 1;
  flex: 1;
  height: var(--size-hairline);
  background: var(--color-border);
}
.sheet-head .sheet-close { order: 2; }
.sheet-links { margin: var(--space-sm) 0 0; padding: 0; list-style: none; }
.sheet-links li + li { border-top: var(--size-hairline) solid var(--color-border); }
.sheet-links a {
  display: flex;
  align-items: center;
  min-height: calc(var(--size-tap) + var(--space-xs));
  font-weight: var(--weight-medium);
  font-size: var(--text-card-title);
  line-height: var(--leading-snug);
  color: var(--color-emerald-deep);
  text-decoration: none;
  transition: color var(--dur-120) var(--ease-out);
}
.sheet-links a[aria-current="page"] { color: var(--color-vital-green); }
.sheet-cta { width: 100%; margin-top: var(--space-lg); }

/* ---------- Buttons: liquid glass ----------
   Every action is a liquid-glass pill (the supplied LiquidButton, ported to CSS). On cream it
   is emerald, with the glass rim and inner shading drawn in cream (--shadow-glass-dark), and
   on hover a very thin gold edge fades in (a layer's opacity, so the shadow never animates).
   On the bands it stays clear dark glass with no gold. It grows to 105% on hover over 320ms
   and presses to 0.97. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  min-height: var(--size-pill);
  padding: 0 var(--space-pill-x);
  border: 0;
  border-radius: var(--radius-pill);
  background-color: var(--color-emerald-ink);
  box-shadow: var(--shadow-glass-dark);
  color: var(--color-ink-contrast);
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-button);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  position: relative;
  transition: transform var(--dur-320) var(--ease-out), background-color var(--dur-200) var(--ease-out), color var(--dur-200) var(--ease-out);
}
/* the hover's gold edge: a hairline ring on its own layer, hidden at rest */
.btn::after, .nav-toggle::after, .sheet-close::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: var(--shadow-gold-edge);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-200) var(--ease-out);
}
/* press snaps (120ms); release and hover ease back over 320ms */
.btn:active { transform: scale(var(--motion-press)); transition-duration: var(--dur-120); }
.btn:disabled { opacity: 0.5; pointer-events: none; }
/* on the bands (footer CTA, header over the story or footer): clear dark glass, cream text, no gold */
.btn-light { background-color: transparent; box-shadow: var(--shadow-glass-dark); color: var(--color-ink-contrast); }
.btn-light::after, .nav.is-dark .nav-cta::after, .nav.is-dark .nav-toggle::after { display: none; }
/* the header's pill is compact so the header still fits a 320px screen */
.nav-cta { min-height: var(--size-tap); padding: 0 var(--space-pill-compact-x); }
/* the header over a band (site-header-on-dark): on-dark links, the dark glass pill and toggle */
.nav.is-dark .nav-links a { color: var(--color-on-dark-muted); }
.nav.is-dark .nav-links a[aria-current="page"] { color: var(--color-on-dark-accent); }
.nav.is-dark .nav-cta, .nav.is-dark .nav-toggle { background-color: transparent; box-shadow: var(--shadow-glass-dark); color: var(--color-ink-contrast); }
.btn-text {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: var(--size-tap);
  font-weight: var(--weight-medium);
  color: var(--color-vital-green);
  text-decoration: none;
  text-underline-offset: 0.25em;
  transition: transform var(--dur-200) var(--ease-out);
}
/* text links press like pills */
.btn-text:active { transform: scale(var(--motion-press)); transition-duration: var(--dur-120); }
.btn-text svg {
  width: var(--size-icon-md);
  height: var(--size-icon-md);
  flex: none;
  transition: transform var(--dur-200) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .nav-links a:hover, .sheet-links a:hover { color: var(--color-vital-green); }
  .nav.is-dark .nav-links a:hover { color: var(--color-ink-contrast); }
  /* glass pills grow on hover, and a hovered pill presses from its grown size */
  .btn:hover, .nav-toggle:hover, .sheet-close:hover { transform: scale(var(--motion-grow)); }
  .btn:hover:active, .nav-toggle:hover:active, .sheet-close:hover:active { transform: scale(var(--motion-grow)) scale(var(--motion-press)); }
  .btn:hover::after, .nav-toggle:hover::after, .sheet-close:hover::after { opacity: 1; }
  .btn-text:hover { text-decoration: underline; }
  /* the arrow nudges the way it points */
  .btn-text:hover svg { transform: translateY(var(--motion-nudge)); }
}

/* ---------- Hero (cell) ---------- */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  align-items: center;
  gap: var(--space-xl);
  padding: var(--space-hero-top) var(--grid-inline) var(--space-hero-bottom);
}
.hero-text { position: relative; z-index: var(--z-stage-copy); max-width: var(--size-hero-copy); }
/* first visit: the copy rises in under the loader's fading cover (html.hero-hidden is set in <head>) */
.hero-text > * { transition: opacity var(--dur-500) var(--ease-out), transform var(--dur-500) var(--ease-out); }
.hero-text > :nth-child(2) { transition-delay: var(--stagger); }
.hero-text > :nth-child(3) { transition-delay: calc(2 * var(--stagger)); }
html.hero-hidden .hero-text > * { opacity: 0; transform: translateY(var(--motion-rise)); }
.hero h1 {
  font-size: var(--text-hero);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-hero);
}
.lede {
  font-size: var(--text-lead);
  line-height: var(--leading-copy);
  color: var(--color-text-secondary);
  margin: var(--space-lg) 0 var(--space-xl);
  max-width: var(--measure);
}
.hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm) var(--space-lg); }
/* the entry price, on its own line under the actions */
.hero-price {
  flex-basis: 100%;
  margin: 0;
  font-size: var(--text-caption);
  line-height: var(--leading-copy);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cell-anchor { position: relative; justify-self: center; width: var(--size-hero-cell); aspect-ratio: 1 / 1; }
.hero-q {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: var(--z-stage-copy);
  pointer-events: none;
}
.hero-q span {
  font-family: var(--font-display);
  font-weight: var(--weight-numeral);
  font-optical-sizing: auto;
  font-size: var(--text-glyph);
  line-height: 1;
  color: var(--color-ink-contrast);
  filter: var(--filter-glyph);
  opacity: 0;
  transform: scale(var(--story-q-scale)) translateY(var(--story-q-travel));
  transition: opacity var(--story-q-fade) var(--story-ease-fade), transform var(--story-q-fade) var(--story-ease);
}
.hero-q span.in { opacity: 1; transform: none; }

/* ---------- Story (frozen stage) ---------- */
.story {
  position: relative;
  height: var(--story-height);
  background: var(--band-story);
  color: var(--color-ink-contrast);
}
.stage { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; }
.story-center { position: absolute; left: var(--story-center-x); top: var(--story-center-y); width: 0; height: 0; }
.caps {
  position: absolute;
  left: var(--story-caps-left);
  bottom: var(--story-caps-bottom);
  width: var(--story-caps-width);
  z-index: var(--z-stage-copy);
}
/* One caption at a time. Hidden captions wait below (ahead in the story) or
   just above (already passed), so the travel always follows the scroll
   direction. The outgoing caption leaves fast; the incoming one waits a
   beat, then its headline and line rise in, staggered. */
.cap { position: absolute; left: 0; bottom: 0; width: 100%; }
.cap h2, .cap p {
  opacity: 0;
  transform: translateY(var(--story-cap-travel));
  transition: opacity var(--story-cap-out) var(--ease-out), transform var(--story-cap-out) var(--ease-out);
}
.cap.past h2, .cap.past p { transform: translateY(calc(-1 * var(--story-cap-exit))); }
.cap.on h2, .cap.on p {
  opacity: 1;
  transform: none;
  transition-duration: var(--story-cap-in);
  transition-delay: var(--stagger);
}
.cap.on p { transition-delay: calc(2 * var(--stagger)); }
.cap h2 { font-size: var(--text-story); line-height: var(--leading-head); color: var(--color-ink-contrast); }
.cap p {
  margin: 0.6em 0 0;
  font-size: var(--text-story-sub);
  line-height: var(--leading-body);
  color: var(--color-on-dark-muted);
  max-width: var(--measure-caption);
}
.clabel {
  position: absolute;
  z-index: var(--z-stage-copy);
  font-size: var(--text-cluster-label);
  line-height: 1;
  color: var(--color-on-dark-muted);
  white-space: nowrap;
  opacity: 0;   /* opacity and rise are written per label by js/story.js */
  pointer-events: none;
}
.result {
  position: absolute;
  left: var(--story-center-x);
  top: var(--story-center-y);
  transform: translate(-50%, -50%);
  text-align: center;
  z-index: var(--z-stage-copy);
}
.res-num, .res-label { opacity: 0; }   /* scroll-driven by js/story.js */
.res-num {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--font-display);
  font-weight: var(--weight-numeral);
  font-optical-sizing: auto;
  font-size: var(--text-numeral);
  line-height: var(--leading-numeral);
  letter-spacing: var(--tracking-numeral);
  font-variant-numeric: tabular-nums;
  color: var(--color-ink-contrast);
}
.res-dot { display: inline-block; width: var(--size-period-numeral); height: var(--size-period-numeral); margin-left: 0.04em; }
.res-label {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--space-xs);
  margin: 0.4em 0 0;
  color: var(--color-on-dark-muted);
}

/* ---------- Section reveal (one per section) ----------
   js/reveal.js adds .reveal-wait only to sections still below the fold, so nothing
   is hidden without JS, under reduced motion, or when the page loads in view. */
.reveal { transition: opacity var(--dur-500) var(--ease-out), transform var(--dur-500) var(--ease-out); }
.reveal.reveal-wait { opacity: 0; transform: translateY(var(--motion-rise)); transition: none; }

/* ---------- Footer ---------- */
.end {
  position: relative;
  min-height: 85vh;
  min-height: 85svh;
  display: flex;
  flex-direction: column;
  background: var(--band-footer);
  color: var(--color-ink-contrast);
}
.end-close {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-section) var(--grid-inline) var(--space-block);
}
.end-line {
  margin: 0;
  max-width: var(--measure-footer);
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-optical-sizing: auto;
  font-size: var(--text-footer-line);
  line-height: var(--leading-footer);
  letter-spacing: var(--tracking-hero);
  color: var(--color-ink-contrast);
  text-wrap: balance;
}
.end-dot { display: inline-block; width: var(--size-period-numeral); height: var(--size-period-numeral); margin-left: 0.04em; }
.end-close .btn { margin-top: var(--space-xl); }
.end-legal {
  width: calc(100% - 2 * var(--grid-inline));
  max-width: var(--grid-max-width);
  margin: 0 auto;
  padding: var(--space-md) 0 var(--space-lg);
  border-top: var(--size-hairline) solid var(--color-on-dark-hairline);
  font-size: var(--text-caption);
  line-height: var(--leading-copy);
  color: var(--color-on-dark-muted);
}
.foot-nav { display: flex; flex-wrap: wrap; column-gap: var(--space-lg); }
.foot-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--size-tap);
  color: var(--color-on-dark-muted);
  text-decoration: none;
  transition: color var(--dur-120) var(--ease-out);
}
.end-legal p { margin: var(--space-xs) 0 0; max-width: var(--measure); line-height: var(--leading-copy); }
/* inline padding grows the hit area to the tap minimum without changing the line box */
.end-legal p a {
  padding-block: calc((var(--size-tap) - 1lh) / 2);
  color: var(--color-on-dark-muted);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
@media (hover: hover) and (pointer: fine) {
  .foot-nav a:hover, .end-legal p a:hover { color: var(--color-ink-contrast); }
}

/* ---------- Cookie bar (built by js/analytics.js on a first visit) ----------
   A small white card at the bottom, above the header and below the loader. It rises in
   over 320ms and leaves over 200ms; OK and Decline are equal compact pills. */
.consent {
  position: fixed;
  left: var(--grid-inline);
  right: var(--grid-inline);
  bottom: calc(var(--space-md) + env(safe-area-inset-bottom));
  z-index: var(--z-consent);
  max-width: var(--size-consent);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm) var(--space-lg);
  padding: var(--space-sm) var(--space-sm) var(--space-sm) var(--space-lg);
  border: var(--size-hairline) solid var(--color-border);
  border-radius: var(--radius-card);
  background-color: var(--color-surface);
  box-shadow: var(--shadow-card);
  opacity: 0;
  transform: translateY(var(--motion-rise));
  transition: opacity var(--dur-200) var(--ease-out), transform var(--dur-200) var(--ease-out);
}
.consent.is-in {
  opacity: 1;
  transform: none;
  transition-duration: var(--dur-320);
}
.consent-text {
  flex: 1 1 18rem;
  margin: 0;
  font-size: var(--text-caption);
  line-height: var(--leading-copy);
  color: var(--color-emerald-deep);
  text-wrap: pretty;
}
.consent-text a {
  color: var(--color-vital-green);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  white-space: nowrap;
}
.consent-actions { display: flex; gap: var(--space-xs); }
.consent-btn { min-height: var(--size-tap); padding: 0 var(--space-pill-compact-x); }
.consent-short { display: none; }
/* phones: one compact row (short text, smaller pills that still meet the tap size), at most 72px tall */
@media (max-width: 480px) {
  .consent {
    bottom: calc(var(--space-xs) + env(safe-area-inset-bottom));
    flex-wrap: nowrap;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-xs) var(--space-xs) var(--space-md);
  }
  .consent-text { flex: 1 1 auto; min-width: 0; line-height: var(--leading-snug); }
  .consent-long { display: none; }
  .consent-short { display: inline; }
  .consent-actions { flex: none; gap: var(--space-xxs); }
  .consent-btn { padding: 0 var(--space-sm); }
}

/* ---------- WhatsApp handoff (built by js/analytics.js) ----------
   Phones: a bottom sheet when WhatsApp doesn't open. Wide desktops: a centred box with a QR code.
   Both are native <dialog>s (top layer, so above the cookie bar); cream, card corners, soft card shadow.
   They fade and rise in over 320ms; under reduced motion they only fade. */
.wa-dialog {
  width: min(100% - 2 * var(--grid-inline), var(--size-wa-dialog));
  max-height: calc(100% - 2 * var(--space-md));
  margin: auto;
  padding: var(--space-lg);
  border: 0;
  border-radius: var(--radius-card);
  background: var(--color-bg);
  color: var(--color-emerald-deep);
  box-shadow: var(--shadow-card);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.wa-dialog[open] { animation: wa-in var(--dur-320) var(--ease-out); }
.wa-dialog::backdrop { background: var(--color-backdrop); }
.wa-dialog[open]::backdrop { animation: wa-fade var(--dur-320) var(--ease-out); }
@keyframes wa-in { from { opacity: 0; transform: translateY(var(--motion-rise)); } }
@keyframes wa-fade { from { opacity: 0; } }
/* the sheet sits at the foot of the screen, full width */
.wa-sheet {
  width: 100%;
  max-width: none;
  margin: auto 0 0;
  padding-bottom: calc(env(safe-area-inset-bottom, 0px) + var(--space-lg));
  border-radius: var(--radius-card) var(--radius-card) 0 0;
}
.wa-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); }
.wa-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-optical-sizing: auto;
  font-size: var(--text-title);
  line-height: var(--leading-head);
  letter-spacing: var(--tracking-display);
  color: var(--color-emerald-ink);
  text-wrap: balance;
}
.wa-actions { display: grid; gap: var(--space-xs); margin-top: var(--space-lg); }
.wa-actions .btn { width: 100%; }
.wa-number {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-xxs);
  width: 100%;
  min-height: var(--size-tap);
  margin-top: var(--space-md);
  padding: var(--space-sm) 0 0;
  border: 0;
  border-top: var(--size-hairline) solid var(--color-border);
  background: none;
  text-align: left;
  cursor: pointer;
}
.wa-number-n {
  font-weight: var(--weight-strong);
  font-size: var(--text-card-title);
  font-variant-numeric: tabular-nums;
  color: var(--color-vital-green);
}
.wa-number-hint { font-size: var(--text-caption); color: var(--color-text-secondary); }
.wa-status:empty { display: none; }
.wa-status { margin: var(--space-sm) 0 0; font-size: var(--text-caption); color: var(--color-text-secondary); overflow-wrap: anywhere; }
/* the QR code: emerald modules on white, with its quiet zone */
.wa-qr {
  width: var(--size-qr);
  aspect-ratio: 1;
  margin: var(--space-lg) auto 0;
  border-radius: var(--radius-input);
  background: var(--color-surface);
  color: var(--color-emerald-ink);
}
.wa-qr svg { display: block; width: 100%; height: 100%; }
.wa-qr-note { margin: var(--space-md) 0 0; text-align: center; font-size: var(--text-body); line-height: var(--leading-copy); }
.wa-web { display: flex; justify-content: center; margin-top: var(--space-xs); }
@media (prefers-reduced-motion: reduce) {
  @keyframes wa-in { from { opacity: 0; } }
}

/* ---------- Story: Skip (phones only) ----------
   A compact clear-glass pill at the foot of the pinned stage; it scrolls away with the stage. */
.story-skip { display: none; }
@media (max-width: 767px) {
  .story-skip {
    display: inline-flex;
    position: absolute;
    left: 0;
    right: 0;
    bottom: calc(var(--space-md) + env(safe-area-inset-bottom));
    z-index: var(--z-stage-copy);
    width: max-content;
    min-height: var(--size-tap);
    margin-inline: auto;
    padding: 0 var(--space-pill-compact-x);
  }
  .story-skip svg { width: var(--size-icon-sm); height: var(--size-icon-sm); }
}

/* ---------- Responsive ---------- */
@media (max-width: 760px) {
  .hero { grid-template-columns: 1fr; gap: var(--space-lg); align-content: start; }
  .cell-anchor { order: 2; }
  .hero-text { order: 1; }
  .lede { margin: var(--space-sm) 0 var(--space-lg); }
  .caps { right: var(--story-caps-left); text-align: center; }
  .cap p { margin-left: auto; margin-right: auto; }
  .clabel { display: none; }
}
@media (max-width: 720px) {
  .nav-links { display: none; }
  /* wordmark, CTA and menu toggle fit a 320px screen */
  .nav { gap: var(--space-sm); }
  .nav-right { gap: var(--space-xs); }
  /* its space is held from the first paint; js/nav.js shows it once the sheet exists (without JS it never appears) */
  .nav-toggle { display: grid; visibility: hidden; }
  .nav-toggle.is-ready { visibility: visible; }
}
@media (max-width: 360px) {
  .nav-cta { padding-inline: var(--space-md); }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .dot, .rail-dot.landed i { animation: none !important; }
  .hero-q span, .btn, .btn-text, .btn-text svg, .rail, .rail-dot, .hero-text > *, .reveal, .nav-toggle, .sheet-close, .nav, .nav-cta, .logo img { transition: none; }
  /* the cookie bar fades without rising */
  .consent { transform: none; }
  /* the menu sheet fades instead of dropping */
  .nav-sheet, .nav-sheet[open] { transform: none; transition: opacity var(--dur-200) var(--ease-out), overlay var(--dur-200) allow-discrete, display var(--dur-200) allow-discrete; }
  .nav-sheet { opacity: 0; }
  .nav-sheet[open] { opacity: 1; }
  @starting-style { .nav-sheet[open] { opacity: 0; transform: none; } }
  .btn-text:hover svg { transform: none; }
  /* captions still hand over, as a short crossfade with no movement */
  .cap h2, .cap p, .cap.past h2, .cap.past p { transform: none; }
  .cap h2, .cap p { transition: opacity var(--story-cap-out) var(--ease-out) !important; }
  .loader { display: none; }
  html.pre .nav .logo { visibility: visible; }
}
