/* ==========================================================================
   Lango Forward — langoforward.org
   Design system: ALL-DARK theme (owner decision 2026-08-18), pill labels,
   split section headers, card grids, single purple accent. Section rhythm
   comes from two alternating dark surfaces (--paper vs --paper-soft), not
   light/dark. The former light values are kept in comments per token.
   No external dependencies — no CDN fonts, no frameworks. Deploy anywhere.

   THE ONE RULE THAT KEEPS THIS ALIGNED:
   containers CENTRE, measures CAP TEXT — never both on one element.
   A max-width on a centring container silently re-indents everything inside
   it. That was this file's original bug: .hero__inner carried max-width:860
   inside a 1160 wrap, so the hero copy sat ~150px right of every card below.
   Put max-width on the TEXT (left-aligned in flow) and the fault is
   structurally impossible.
   ========================================================================== */

:root {
  /* Accent — from the Lango Ecosystem investor deck */
  --purple-600: #6D28D9;
  --purple-500: #7C3AED;
  --purple-400: #A855F7;
  --purple-tint: rgba(124, 58, 237, 0.18);  /* light theme was #F3EDFF */
  --purple-glow: rgba(124, 58, 237, 0.18);

  /* Surfaces — all dark. --paper/--paper-soft keep their NAMES so every
     component keeps working; their VALUES are now the two dark surfaces. */
  --ink: #14111C;
  --ink-soft: #1E1929;
  --ink-card: #211B2E;
  --paper: #14111C;        /* light theme was #FFFFFF */
  --paper-soft: #191424;   /* light theme was #F7F7F9 */

  /* Text */
  --text-strong: #FFFFFF;  /* light theme was #16131F */
  --text-muted: #A29EB2;   /* light theme was #63616E */
  --text-on-ink: #FFFFFF;
  --text-muted-on-ink: #A29EB2;

  /* Lines */
  --line-light: #2E2840;   /* light theme was #E6E4EC */
  --line-dark: #2E2840;

  --radius: 14px;
  --radius-sm: 10px;

  /* Column system ---------------------------------------------------------
     .wrap is the ONLY container. Every span derives from --content, so
     changing --maxw or --gap moves the whole page at once. 2, 3, 4 and 6 all
     divide 12, so any repeat(N, 1fr) grid at --gap lands on 12-column lines
     without declaring twelve tracks. */
  --maxw: 1160px;
  --gutter: 24px;
  --gap: 24px;            /* the ONE grid gutter — do not introduce a second */
  --content: calc(var(--maxw) - (var(--gutter) * 2));      /* 1112px   */
  --col: calc((var(--content) - (var(--gap) * 11)) / 12);  /*   70.667 */
  --span-6: calc((var(--col) * 6) + (var(--gap) * 5));     /*  544     */
  --span-8: calc((var(--col) * 8) + (var(--gap) * 7));     /*  733.33  */
  --span-9: calc((var(--col) * 9) + (var(--gap) * 8));     /*  828     */

  /* Measures cap TEXT only. See the header comment. */
  --measure-display: var(--span-9);
  --measure-lede: var(--span-6);
  --measure-cta: var(--span-8);

  /* Vertical rhythm. The top four steps are redefined once at <=680px, and
     that is how mobile section padding is derived — no per-selector
     overrides in the media query. */
  --space-2xs: 8px;
  --space-xs: 16px;
  --space-sm: 24px;
  --space-md: 32px;
  --space-lg: 48px;
  --space-xl: 64px;
  --space-2xl: 96px;
  --space-3xl: 128px;

  --header-h: 72px;
  /* Card padding equals the grid gap, so text-to-text across a gutter is
     exactly two rhythm steps. Interior and exterior share one scale. */
  --card-pad: var(--space-sm);

  /* Type scale -----------------------------------------------------------
     Named steps. Every font-size in this file resolves to one of these.
     No half-pixel sizes: a half-pixel size is a correction, not a step —
     this file previously carried 16 distinct sizes, three of them halves. */
  --fs-label: 12px;                    /* uppercase micro-labels           */
  --fs-2xs: 13px;                      /* form labels, fine print          */
  --fs-xs: 14px;                       /* nav, footer links, form status   */
  --fs-sm: 15px;                       /* card bodies, product lines       */
  --fs-base: 17px;                     /* body default                     */
  --fs-md: 19px;                       /* section support, h3, CTA body    */
  --fs-lg: 21px;                       /* hero sub                         */
  --fs-h2: clamp(27px, 3.4vw, 38px);
  --fs-h1: clamp(38px, 5.4vw, 60px);

  /* Weights ---------------------------------------------------------------
     700 is the heaviest weight EVERY family in this stack actually ships.
     800 does NOT exist in Segoe UI or Roboto: under CSS font matching a
     request at 800 searches upward, so it resolves to Black 900 on Windows
     and Android while rendering as designed on macOS. The page then looks
     materially different on a school's Windows laptop than on the machine
     it was designed on. Hierarchy comes from size and colour instead. */
  --w-body: 400;
  --w-strong: 600;
  --w-display: 700;

  /* Optical tracking. Negative tracking is a display-SIZE correction, so it
     scales with size and reaches zero at body size — never a blanket. */
  --ls-h1: -0.022em;
  --ls-h2: -0.018em;
  --ls-h3: -0.005em;
  --ls-body: 0;
  --ls-label: 0.08em;

  /* Leading. Larger text needs relatively less. */
  --lh-h1: 1.05;
  --lh-h2: 1.12;
  --lh-h3: 1.3;
  --lh-lead: 1.5;
  --lh-body: 1.6;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto,
    "Helvetica Neue", Arial, sans-serif;
}

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

/* Native UI (selects, scrollbars, autofill) renders dark to match. */
html { scroll-behavior: smooth; color-scheme: dark; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  color: var(--text-strong);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

/* Layout ----------------------------------------------------------------- */
.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.section { padding: var(--space-2xl) 0; }

.section--dark {
  background: var(--ink);
  color: var(--text-on-ink);
}
.section--soft { background: var(--paper-soft); }

/* The sticky header is --header-h tall. Without this, an in-page anchor
   lands the section's top edge underneath it and the pill is hidden. */
section[id] { scroll-margin-top: calc(var(--header-h) + var(--space-sm)); }

/* Section header: pill → headline left, support right -------------------- */
/* ONE uppercase micro-label specification, replacing five. The same role was
   previously set four different ways (11px/700/0.14em, /0.12em, /0.12em,
   10px/700/0.1em) — a difference a professional eye registers as sloppiness
   without being able to name it. */
.pill,
.stage__age,
.footer__col h4,
.eco-group__title {
  font-size: var(--fs-label);
  font-weight: var(--w-strong);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  line-height: 1.2;
}

.pill {
  display: inline-block;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--line-light);
  color: var(--text-muted);
  margin-bottom: var(--space-sm);
}
.section--dark .pill {
  border-color: var(--line-dark);
  color: var(--text-muted-on-ink);
}
.pill--accent {
  border-color: rgba(124, 58, 237, 0.35);
  color: var(--purple-400);
}

.sec-head {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--gap);
  row-gap: 0;
  align-items: baseline;
  margin-bottom: var(--space-lg);
}
/* The pill is a LABEL for the section, not a peer of the support text — it
   gets its own full-width row. That leaves the headline and its subtitle
   alone in row two, where align-items:baseline makes their first baselines
   match exactly, at any wrap count and any font metric. This is what
   replaced a hand-tuned `padding-top: 6px` on .sec-support that drifted
   every time a heading wrapped differently. */
.sec-head .pill { grid-column: 1 / -1; justify-self: start; }
/* Optical breathing room comes from padding INSIDE the cell, never from a
   wider gutter — so the column line stays at x=568, which is card 3's left
   edge in a 4-up. One vertical line runs down the whole page. */
.sec-head h2 { grid-column: 1; padding-right: var(--space-lg); }
.sec-head .sec-support { grid-column: 2; }

h1, h2, h3 { margin: 0; font-weight: var(--w-display); }

h1 {
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  letter-spacing: var(--ls-h1);
  text-wrap: balance;
}
h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  text-wrap: balance;
}
h3 {
  font-size: var(--fs-md);
  font-weight: var(--w-strong);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
}

.sec-support {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--fs-md);
  line-height: var(--lh-lead);
  text-wrap: pretty;
}
.section--dark .sec-support { color: var(--text-muted-on-ink); }

/* Header ----------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(20, 17, 28, 0.88);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line-light);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  height: var(--header-h);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: var(--w-display);
  font-size: var(--fs-md);
  letter-spacing: -0.015em;
  text-decoration: none;
  white-space: nowrap;
}
/* The real mark (assets/logo.png, transparent) — no gradient placeholder. */
.brand__mark {
  width: 28px;
  height: 28px;
  object-fit: contain;
  flex: 0 0 auto;
}
.site-footer .brand { color: #fff; }

.nav {
  display: flex;
  gap: 28px;
  margin-left: auto;
}
.nav a {
  text-decoration: none;
  font-size: var(--fs-xs);
  font-weight: var(--w-strong);
  color: var(--text-muted);
}
.nav a:hover { color: var(--text-strong); }
/* Shown only inside the open mobile nav — see the 680px query. Scoped to
   .nav for specificity (0,2,0): a bare .nav-cta ties with .btn's
   `display: inline-flex`, which is declared later in the file and would win. */
.nav .nav-cta { display: none; }

.nav-toggle {
  display: none;
  margin-left: auto;
  background: none;
  border: 1px solid var(--line-light);
  border-radius: 8px;
  padding: 8px 12px;
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: var(--w-strong);
  cursor: pointer;
}

/* Buttons ---------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  font-weight: var(--w-strong);
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.btn:hover { transform: translateY(-1px); }

.btn--primary {
  background: linear-gradient(100deg, var(--purple-600), var(--purple-400));
  color: #fff;
  box-shadow: 0 8px 24px var(--purple-glow);
}
.btn--primary:hover { box-shadow: 0 12px 30px rgba(124, 58, 237, 0.28); }

.btn--ghost {
  border-color: var(--line-light);
  color: var(--text-strong);
  background: transparent;
}
.section--dark .btn--ghost,
.hero .btn--ghost {
  border-color: var(--line-dark);
  color: #fff;
}
.btn--sm { padding: 10px 16px; font-size: var(--fs-xs); }
.btn__arrow { font-size: var(--fs-sm); line-height: 1; }

/* Hero ------------------------------------------------------------------- */
.hero {
  background: var(--ink);
  color: var(--text-on-ink);
  padding: var(--space-3xl) 0 var(--space-2xl);
  position: relative;
  overflow: hidden;
}
.hero::after {
  content: "";
  position: absolute;
  right: -180px;
  top: -140px;
  width: 620px;
  height: 620px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(124, 58, 237, 0.22), transparent 66%);
  pointer-events: none;
}
/* NO max-width here — this is a container. See the file header.
   Two columns ≥941px: copy left, illustrative record card right. */
.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--space-lg) var(--gap);
  align-items: center;
}

/* Grid child: min-width 0 stops long words forcing the column wider. */
.hero__copy { min-width: 0; }

/* Record card — decorative illustration of the four-stage record.
   Purely presentational; the markup is aria-hidden. */
.hero__visual { display: flex; justify-content: flex-end; }
.record {
  width: 100%;
  max-width: 420px;
  border: 1px solid var(--line-dark);
  border-radius: var(--radius);
  background: linear-gradient(160deg, var(--ink-soft), var(--ink-card));
  padding: var(--card-pad);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(124, 58, 237, 0.08);
}
.record__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: var(--space-xs);
  border-bottom: 1px solid var(--line-dark);
  margin-bottom: var(--space-xs);
}
.record__mark {
  width: 34px;
  height: 34px;
  object-fit: contain;
  flex: 0 0 auto;
}
.record__title { font-weight: var(--w-strong); font-size: var(--fs-sm); }
/* Visible honesty marker: the card is a drawing, not product data. */
.record__tag {
  margin-left: auto;
  align-self: flex-start;
  font-size: 10px;
  font-weight: var(--w-strong);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-muted-on-ink);
  border: 1px solid var(--line-dark);
  border-radius: 999px;
  padding: 3px 8px;
}
.record__sub { font-size: var(--fs-2xs); color: var(--text-muted-on-ink); }
.record__row {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) 96px;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
}
.record__row + .record__row { border-top: 1px solid rgba(46, 40, 64, 0.6); }
.record__icon {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: rgba(124, 58, 237, 0.18);
  color: var(--purple-400);
  display: grid;
  place-items: center;
}
.record__icon svg { width: 16px; height: 16px; }
.record__meta { display: flex; flex-direction: column; min-width: 0; }
.record__stage { font-size: var(--fs-2xs); font-weight: var(--w-strong); }
.record__what {
  font-size: 11px;
  color: var(--text-muted-on-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.record__bar {
  height: 6px;
  border-radius: 999px;
  background: rgba(46, 40, 64, 0.9);
  overflow: hidden;
}
.record__bar i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--purple-600), var(--purple-400));
}
.record__foot {
  margin-top: var(--space-xs);
  padding-top: var(--space-xs);
  border-top: 1px solid var(--line-dark);
  font-size: var(--fs-label);
  font-weight: var(--w-strong);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--purple-400);
}

.hero h1 {
  /* em, NOT px — characters-per-line then stays constant wherever the clamp
     lands, which is what actually fixes the orphan. A px measure paired with
     a clamped font-size rags differently at every viewport width. min() keeps
     the column token authoritative wherever it is the tighter of the two. */
  max-width: min(var(--measure-display), 14em);
  margin-bottom: var(--space-sm);
}
.hero__sub {
  font-size: var(--fs-lg);
  line-height: var(--lh-lead);
  color: var(--text-muted-on-ink);
  max-width: var(--measure-lede);
  margin: 0 0 var(--space-md);
  text-wrap: pretty;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-xs); }

/* Cards ------------------------------------------------------------------ */
.grid { display: grid; gap: var(--gap); }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Content cards stay TOP-aligned — deliberately NOT space-between. Grid
   already equalises the box heights; space inside a border is invisible,
   whereas ragged text tops are not. */
.card {
  border: 1px solid var(--line-light);
  border-radius: var(--radius);
  background: var(--ink-card);
  padding: var(--card-pad);
  position: relative;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
/* Same lift as .tile:hover — owner decision 2026-08-19: every tile-shaped
   surface hovers identically (tiles, cards, journey stages). */
.card:hover {
  transform: translateY(-3px);
  border-color: rgba(124, 58, 237, 0.45);
  box-shadow: 0 12px 32px rgba(124, 58, 237, 0.2);
}
.section--dark .card {
  background: var(--ink-card);
  border-color: var(--line-dark);
}

.card__icon {
  width: 54px;
  height: 54px;
  border-radius: var(--radius-sm);
  background: var(--purple-tint);
  color: var(--purple-400);
  display: grid;
  place-items: center;
  margin-bottom: var(--space-sm);
}
.card__icon svg { width: 28px; height: 28px; }
.section--dark .card__icon {
  background: rgba(124, 58, 237, 0.2);
  color: var(--purple-400);
}


.card p {
  margin: var(--space-2xs) 0 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  text-wrap: pretty;
}
.section--dark .card p { color: var(--text-muted-on-ink); }

/* Check list inside audience cards ---------------------------------------- */
.checks {
  list-style: none;
  margin: var(--space-xs) 0 0;
  padding: var(--space-xs) 0 0;
  border-top: 1px solid var(--line-light);
}
.checks li {
  position: relative;
  padding: 5px 0 5px 26px;
  font-size: var(--fs-2xs);
  line-height: 1.5;
  color: var(--text-muted);
  text-wrap: pretty;
}
.checks li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 5px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--purple-tint);
  color: var(--purple-400);
  font-size: 11px;
  font-weight: var(--w-display);
  display: grid;
  place-items: center;
}

/* Phoneme demo — decorative sound-by-sound scoring strip ------------------- */
.phoneme {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-xs);
  border: 1px solid var(--line-dark);
  border-radius: var(--radius);
  background: var(--ink-card);
  padding: var(--space-xs) var(--card-pad);
  margin-bottom: var(--gap);
}
.phoneme__word {
  font-size: var(--fs-md);
  font-weight: var(--w-display);
}
.phoneme__arrow { color: var(--text-muted-on-ink); }
.phoneme__chip {
  font-size: var(--fs-2xs);
  font-weight: var(--w-strong);
  padding: 5px 11px;
  border-radius: 8px;
  border: 1px solid var(--line-dark);
  background: var(--ink-soft);
  color: var(--text-muted-on-ink);
}
.phoneme__chip--flag {
  border-color: rgba(124, 58, 237, 0.6);
  background: rgba(124, 58, 237, 0.2);
  color: var(--purple-400);
  box-shadow: 0 0 0 3px var(--purple-glow);
}
.phoneme__note {
  margin-left: auto;
  font-size: var(--fs-2xs);
  color: var(--text-muted-on-ink);
}

/* Journey ---------------------------------------------------------------- */
/* A connecting rail + one dot per stage make "one record" visible as a line.
   The rail only exists at 4-up (>940px); wrapped layouts drop it. */
.journey {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gap);
  position: relative;
  padding-top: 28px;
}
.journey::before {
  content: "";
  position: absolute;
  top: 10px;
  left: 6px;
  right: 6px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--purple-600), var(--purple-400));
  opacity: 0.45;
}
.stage__dot {
  position: absolute;
  top: -23px;
  left: var(--card-pad);
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--purple-400);
  box-shadow: 0 0 0 4px rgba(124, 58, 237, 0.22);
}
.stage {
  border: 1px solid var(--line-light);
  border-radius: var(--radius);
  padding: var(--card-pad);
  background: var(--ink-card);
  position: relative;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.stage:hover {
  transform: translateY(-3px);
  border-color: rgba(124, 58, 237, 0.45);
  box-shadow: 0 12px 32px rgba(124, 58, 237, 0.2);
}
.stage__products {
  margin-top: var(--space-xs);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.chip {
  font-size: 11px;
  font-weight: var(--w-strong);
  letter-spacing: 0.02em;
  color: var(--purple-400);
  border: 1px solid rgba(124, 58, 237, 0.35);
  background: rgba(124, 58, 237, 0.1);
  padding: 3px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.stage__age {
  color: var(--purple-400);
  margin-bottom: var(--space-xs);
}
.stage h3 { margin-bottom: var(--space-2xs); }
.stage p {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--text-muted);
  text-wrap: pretty;
}

/* Ecosystem tiles --------------------------------------------------------- */
/* Product tiles grouped by where they live in the learner's day. One-line
   descriptions per the content spec; the richness is visual, not verbal. */
.eco-group { margin-bottom: var(--space-lg); }
.eco-group:last-child { margin-bottom: 0; }
.eco-group__title {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--text-muted);
  margin-bottom: var(--space-sm);
}
/* Rule line after the group title — carries the eye across the row. */
.eco-group__title::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line-light);
}
.tile {
  border: 1px solid var(--line-light);
  border-radius: var(--radius);
  background: var(--ink-card);
  padding: var(--card-pad);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.tile:hover {
  transform: translateY(-3px);
  border-color: rgba(124, 58, 237, 0.45);
  box-shadow: 0 12px 32px rgba(124, 58, 237, 0.2);
}
.tile__icon {
  width: 54px;
  height: 54px;
  border-radius: var(--radius-sm);
  background: var(--purple-tint);
  color: var(--purple-400);
  display: grid;
  place-items: center;
  margin-bottom: var(--space-xs);
}
.tile__icon svg { width: 28px; height: 28px; }
.tile__name {
  margin: 0;
  font-size: var(--fs-sm);
  font-weight: var(--w-strong);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
}
.tile__desc {
  margin: var(--space-2xs) 0 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: 1.5;
  text-wrap: pretty;
}

/* Less-screen spotlight -------------------------------------------------- */
/* Two elaborated panels inside The Ecosystem; the ONE place tile copy runs
   longer than a single line (deliberate exception to the one-line tile
   constraint — this is a section band, not a tile). */
.spotlight {
  margin-top: var(--space-lg);
  border: 1px solid var(--line-light);
  border-radius: var(--radius);
  background: var(--paper-soft);
  border-top: 3px solid transparent;
  border-image: linear-gradient(90deg, var(--purple-600), var(--purple-400)) 1;
  padding: var(--card-pad);
}
.spotlight__head h3 {
  margin: 0 0 var(--space-2xs);
  font-size: var(--fs-lg);
}
.spotlight__head p {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  max-width: var(--measure-lede);
  text-wrap: pretty;
}
.spotlight__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap);
  margin-top: var(--space-md);
}
.spotlight__panel {
  border: 1px solid var(--line-light);
  border-radius: var(--radius);
  background: var(--ink-card);
  padding: var(--card-pad);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.spotlight__panel:hover {
  transform: translateY(-3px);
  border-color: rgba(124, 58, 237, 0.45);
  box-shadow: 0 12px 32px rgba(124, 58, 237, 0.2);
}
.spotlight__panel h4 {
  margin: 0 0 var(--space-2xs);
  font-size: var(--fs-md);
  font-weight: var(--w-strong);
}
.spotlight__panel p {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  text-wrap: pretty;
}

/* Closing CTA ------------------------------------------------------------ */
.cta {
  text-align: center;
  /* 96px top / 64px bottom: the top edge is a hard gradient rule needing
     clearance; the bottom is a hairline into the footer, whose own 64px
     completes a composite 128px (= --space-3xl) content-to-content gap.
     Same top-heavy idiom as .hero. Token-only — see the 680px note. */
  padding: var(--space-2xl) 0 var(--space-xl);
  background: var(--paper-soft);
  border-top: 3px solid transparent;
  border-image: linear-gradient(90deg, var(--purple-600), var(--purple-400)) 1;
}
.cta h2 { max-width: var(--measure-cta); margin: 0 auto var(--space-sm); }
/* .cta .cta__alt out-specifies the generic .cta p rule above (no !important) */
.cta .cta__alt {
  max-width: var(--measure-lede);
  margin: var(--space-lg) auto var(--space-sm);
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
}
.cta p {
  max-width: var(--measure-lede);
  margin: 0 auto var(--space-lg);
  color: var(--text-muted);
  font-size: var(--fs-md);
  line-height: var(--lh-lead);
  text-wrap: pretty;
}

/* Reduced motion: hover lifts are decorative; honour the OS setting.
   (Added 2026-08-19 round-10 — the transform surface grew to four classes.) */
@media (prefers-reduced-motion: reduce) {
  .tile, .card, .stage, .spotlight__panel, .btn { transition: none; }
  .tile:hover, .card:hover, .stage:hover, .spotlight__panel:hover, .btn:hover {
    transform: none;
  }
}

/* Footer ----------------------------------------------------------------- */
.site-footer {
  background: var(--ink);
  color: var(--text-on-ink);
  border-top: 1px solid var(--line-dark);
  padding: var(--space-xl) 0 var(--space-lg);
}
/* Twelve real tracks so the spans stay proportional at every width. 6/3/3
   puts the link columns at x=568 and x=852 — cards 3 and 4 in a 4-up. */
.footer__grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gap);
  padding-bottom: var(--space-lg);
  border-bottom: 1px solid var(--line-dark);
}
.footer__grid > :first-child { grid-column: span 6; }
.footer__col { grid-column: span 3; }
.footer__tag {
  margin: var(--space-xs) 0 0;
  color: var(--text-muted-on-ink);
  font-size: var(--fs-xs);
  max-width: 300px;
}
.footer__col h4 {
  margin: 0 0 var(--space-xs);
  color: var(--text-muted-on-ink);
}
.footer__col a {
  display: block;
  text-decoration: none;
  color: #D6D3E0;
  font-size: var(--fs-xs);
  padding: 5px 0;
}
.footer__col a:hover { color: #fff; }
.footer__base {
  padding-top: var(--space-md);
  display: flex;
  justify-content: space-between;
  gap: var(--space-sm);
  flex-wrap: wrap;
  font-size: var(--fs-2xs);
  color: var(--text-muted-on-ink);
}
.footer__base--bare { border: 0; padding-top: 0; }

/* Contact page ----------------------------------------------------------- */
.contact-layout {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gap);
  align-items: start;
}
/* nth-child rather than classes: the columns are bare divs, and this avoids
   an HTML change for no behavioural gain. */
.contact-layout > :nth-child(1) { grid-column: span 5; padding-right: var(--space-lg); }
.contact-layout > :nth-child(2) { grid-column: span 7; }
/* On a contact page the FORM is the hero, not the headline. A 38px heading in
   a 5-span column beside a 7-span form competes with the thing it introduces —
   and at a 401px text box, 38px cannot fit "Tell us your setting." on one
   line anyway. */
.contact-layout h1,
.contact-layout h2 { font-size: clamp(26px, 2.8vw, 32px); }
.contact-layout .sec-support { margin-top: var(--space-sm); }
/* Compact "what a demo covers" rows — small icon chip + title + one line.
   Deliberately NOT cards: the form panel is the page's one raised object. */
.demo-list { margin-top: var(--space-md); }
.demo-item {
  display: flex;
  gap: var(--space-xs);
  padding: var(--space-xs) 0;
  border-top: 1px solid var(--line-light);
}
.demo-item__icon {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  border-radius: var(--radius-sm);
  background: var(--purple-tint);
  color: var(--purple-400);
  display: grid;
  place-items: center;
}
.demo-item__icon svg { width: 20px; height: 20px; }
.demo-item h3 {
  margin: 0 0 2px;
  font-size: var(--fs-sm);
  font-weight: var(--w-strong);
  line-height: var(--lh-h3);
}
.demo-item p {
  margin: 0;
  font-size: var(--fs-2xs);
  line-height: 1.5;
  color: var(--text-muted);
  text-wrap: pretty;
}

/* The form is the page's hero: one raised panel anchors it. */
.form-panel {
  background: var(--ink-card);
  border: 1px solid var(--line-light);
  border-radius: var(--radius);
  padding: var(--space-md);
}

/* The reply promise is a commitment, not fine print — one step up in size,
   weight and colour from the collection notice below it. */
.form-reply {
  margin: var(--space-xs) 0 0;
  font-size: var(--fs-xs);
  font-weight: var(--w-strong);
  color: var(--text-strong);
}
.field label .opt { font-weight: var(--w-body); color: var(--text-muted); }

.field { margin-bottom: var(--space-xs); }
.field label {
  display: block;
  font-size: var(--fs-2xs);
  font-weight: var(--w-strong);
  margin-bottom: 7px;
}
.field input,
.field select,
.field textarea {
  width: 100%;
  font: inherit;
  font-size: var(--fs-sm);
  padding: 12px 14px;
  border: 1px solid var(--line-light);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--text-strong);
}
/* Custom chevron: the native arrow hugs the right border. appearance:none
   drops it; the inline data-URI chevron (no external request) sits 14px in,
   matching the input padding, with reserved right padding so long option
   text never runs under it. */
.field select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A29EB2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 16px 16px;
  padding-right: 42px;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--purple-500);
  box-shadow: 0 0 0 3px var(--purple-glow);
}
.field textarea { min-height: 130px; resize: vertical; }
.field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap); }

.form-note {
  margin-top: var(--space-xs);
  font-size: var(--fs-xs);
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  display: none;
}
.form-note--error {
  display: block;
  background: rgba(153, 27, 27, 0.18);
  border: 1px solid rgba(252, 165, 165, 0.35);
  color: #FCA5A5;
}
.form-note--ok {
  display: block;
  background: var(--purple-tint);
  border: 1px solid rgba(124, 58, 237, 0.4);
  color: var(--purple-400);
}


/* Enquiry-form additions -------------------------------------------------- */

/* Honeypot. Off-screen rather than display:none — many bots skip
   display:none fields, which defeats the trap. Deliberately NOT aria-hidden:
   wrapping a focusable element in aria-hidden is invalid ARIA and an audit
   flags it. Instead the label tells a screen-reader user to leave it blank.
   Never remove the off-screen rule without also removing the field — a
   VISIBLE honeypot asks real users to leave a box empty. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-consent {
  margin: var(--space-2xs) 0 0;
  font-size: var(--fs-2xs);
  line-height: 1.55;
  color: var(--text-muted);
  text-wrap: pretty;
}
.form-consent a {
  color: var(--purple-400);
  text-decoration: underline;
}


/* Responsive ------------------------------------------------------------- */
@media (max-width: 940px) {
  .sec-head { grid-template-columns: 1fr; margin-bottom: var(--space-md); }
  .sec-head h2,
  .sec-head .sec-support { grid-column: 1 / -1; padding-right: 0; }
  .sec-head .sec-support { margin-top: var(--space-sm); }

  .grid--3, .grid--4, .journey { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Hero stacks; the record card sits under the copy at natural width. */
  .hero__inner { grid-template-columns: 1fr; }
  .hero__visual { justify-content: flex-start; }

  /* The journey rail assumes a single 4-up row; wrapped layouts drop it. */
  .journey { padding-top: 0; }
  .journey::before { display: none; }
  .stage__dot { display: none; }

  /* These MUST match the base rules' specificity (0,2,0), or the span
     declarations win and grid generates implicit columns — the layout
     collapses instead of degrading. */
  .contact-layout { grid-template-columns: 1fr; gap: var(--space-lg); }
  .contact-layout > :nth-child(1),
  .contact-layout > :nth-child(2) { grid-column: 1 / -1; padding-right: 0; }

  .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-lg) var(--gap); }
  .footer__grid > :first-child,
  .footer__col { grid-column: auto; }
}

@media (max-width: 680px) {
  /* Section rhythm scales HERE, once, by redefining the tokens. Do NOT
     re-add per-selector padding overrides for .section / .hero / .cta —
     that is how .cta previously kept its 112px desktop padding on phones. */
  :root {
    --space-3xl: 88px;
    --space-2xl: 72px;
    --space-xl: 56px;
    --space-lg: 40px;
  }

  .nav { display: none; }
  .nav.is-open {
    display: flex;
    position: absolute;
    top: var(--header-h);
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    background: var(--ink);
    border-bottom: 1px solid var(--line-light);
    padding: var(--space-2xs) var(--gutter) var(--space-xs);
  }
  .nav.is-open a { padding: 12px 0; }
  .nav-toggle { display: block; }

  /* The header button cannot share 342px with the brand and the Menu toggle,
     so it is hidden — but the primary action must stay reachable, or it
     vanishes the moment the visitor scrolls past the hero. Two replacements:
     the CTA becomes the last item in the open nav panel, and a header with no
     nav (the privacy page) keeps its button, since nothing competes for the
     space there. */
  .header-cta { display: none; }
  .site-header--minimal .header-cta { display: inline-flex; }
  .nav.is-open .nav-cta {
    display: inline-flex;
    justify-content: center;
    margin: var(--space-2xs) 0 var(--space-2xs);
  }

  .grid--2, .grid--3, .grid--4, .journey, .spotlight__grid { grid-template-columns: 1fr; }


  .field-row { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: 1fr; }
}
