/*
 * Fynrox — landing page styles
 *
 * Design tokens below are ported 1:1 from apps/user-mobile/src/theme/tokens.ts
 * (Design System v2, 31 Aug 2026 — the OLED-first "instrument panel" look).
 * This page deliberately does not implement a light theme: the shipped app
 * has no light palette either (tokens.ts defines one dark system only), so
 * matching it exactly means staying dark-only here too, on purpose.
 *
 * Fonts are self-hosted: assets/css/fonts.css declares them and every
 * page links it ahead of this file. Nothing loads from Google Fonts, so
 * no third party sees a visitor before they answer the cookie banner.
 *
 * 18 Oct 2026: the inner pages now share the rebuilt homepage's look
 * (assets/css/home.css): white canvas, ink and mint, Bricolage Grotesque /
 * Figtree / IBM Plex Mono, a dark header, hero band and footer. The tokens
 * below carry most of it; the "Homepage look" block at the end of this
 * file does the rest.
 */

/* ---------------------------------------------------------------------- */
/* Tokens                                                                  */
/* ---------------------------------------------------------------------- */

:root {
  color-scheme: light;

  /* Surfaces — cream canvas, white cards, a deeper cream for insets.
   * surface-high is the DARKEST of the four, so it is the worst case for
   * every text token below; that is the surface the contrast test
   * measures against. */
  --bg: #F5F5F5;
  --surface: #FFFFFF;
  --surface-raised: #FFFFFF;
  --surface-high: #F5F5F5;
  --border: #E5E5E5;
  --border-strong: rgba(10, 10, 10, 0.24);

  /* Text */
  --text-primary: #0A0A0A;
  --text-secondary: #525252;
  /*
   * Measured, not eyeballed — the same discipline the dark palette
   * learned the hard way. Every value below clears 4.5:1 against all
   * four surfaces, worst case on --surface-high:
   *
   *   text-primary   14.58:1   accent        4.95:1
   *   text-secondary  7.12:1   accent-alt    6.85:1
   *   text-muted      5.21:1   success       5.43:1
   *   orange          6.11:1   warning       6.03:1
   *   pink            5.96:1   danger        6.33:1
   *   cyan            5.11:1   ai-accent     5.41:1
   *
   * The brand's own slate (#8E9194) and gold (#DA9F3E) are 2.88:1 and
   * 2.12:1 on cream. Neither can carry text, so --text-muted and
   * --accent are darkened derivations of them rather than the brand
   * values themselves. The gold is still the gold — it just does its
   * job as a fill (--accent-fill), where charcoal on it is 7.47:1.
   */
  /* 18 Oct 2026 homepage palette: on #F5F5F5 (the darkest surface now)
   * text-muted is 4.89:1 and accent 5.9:1; ink on mint fill is 11:1. */
  --text-muted: #6B6B6B;
  /** Ink that sits ON --accent-fill (mint). */
  --text-on-accent: #0A0A0A;

  /* Brand gold.
   *
   * Two tokens on purpose, and the split is load-bearing. --accent is
   * ink: links, dots, focus rings, meter bars — anything whose colour
   * has to be legible against cream. --accent-fill is the brand gold
   * itself, used only as a background with --text-on-accent on top.
   *
   * Using one token for both is what made the light theme fail: gold
   * reads beautifully as a fill and is unreadable as text. There is a
   * test (landingAccentFill in apps/api/tests/landingTheme.test.ts)
   * asserting --accent-fill never appears in a `color:` declaration, so
   * this is enforced rather than remembered. */
  --accent: #1C6B44;
  --accent-alt: #145233;
  --accent-fill: #70D4A8;
  --accent-fill-strong: #5CC596;
  --accent-soft: rgba(112, 212, 168, 0.22);

  /* AI accent — reserved for AI Coach touchpoints only, same rule the app follows */
  --ai-accent: #5B4BC4;
  --ai-accent-soft: rgba(91, 75, 196, 0.14);

  /* Status */
  --success: #1C6B44;
  --success-soft: rgba(28, 107, 68, 0.12);
  --warning: #7A4E00;
  --warning-soft: rgba(122, 78, 0, 0.12);
  --danger: #A3201A;
  --danger-soft: rgba(163, 32, 26, 0.10);

  /* Secondary data hues, darkened for a light canvas */
  --orange: #9A3418;
  --orange-soft: rgba(154, 52, 24, 0.12);
  --pink: #9B2D63;
  --pink-soft: rgba(155, 45, 99, 0.12);
  --cyan: #1E6B7A;
  --cyan-soft: rgba(30, 107, 122, 0.12);

  --overlay: rgba(26, 26, 26, 0.55);

  /* Type — Archivo Black for display, Inter for body, JetBrains Mono for
   * data. Archivo Black ships one weight (400) and is already black, so
   * never set font-weight on it; see .u-display. */
  --font-display: "Bricolage Grotesque", Figtree, ui-sans-serif, system-ui, sans-serif;
  --font-body: Figtree, ui-sans-serif, system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", monospace;

  /* Spacing (4/8/16/24/32/48 from tokens.ts, extended upward for web sections) */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 1rem;
  --space-4: 1.5rem;
  --space-5: 2rem;
  --space-6: 3rem;
  --space-7: 4rem;
  --space-8: 6rem;

  /* Radius */
  --radius-xs: 6px;
  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-card: 18px;
  --radius-lg: 24px;
  --radius-pill: 999px;

  /* Elevation. A light theme cannot borrow the dark one's shadows: the
   * same rgba(0,0,0,.35) that reads as depth on #0b0c10 reads as dirt
   * on cream. These are much softer and tinted with the brand charcoal
   * rather than pure black. */
  --shadow-card: 0 2px 4px rgba(26, 26, 26, 0.04), 0 8px 24px rgba(26, 26, 26, 0.07);
  --shadow-floating: 0 4px 10px rgba(26, 26, 26, 0.06), 0 18px 40px rgba(26, 26, 26, 0.12);

  /* Was 1180px, which left ~370px of dead gutter each side at 1920 and
   * made a wide screen look like a phone layout stranded in the middle.
   * Wide enough to use the display, capped so a 2560px monitor does not
   * stretch body copy past a readable measure — long-form pages pull
   * this in again with .wrap--reading below. */
  --container-max: 1240px;
  --container-reading: 880px;
  --header-h: 72px;

  /* Motion. One easing and three durations, so every transition on the
   * site moves the same way. Honoured by the reduced-motion block at the
   * end of this file. */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur-fast: 0.18s;
  --dur: 0.32s;
  --dur-slow: 0.6s;
}

/* ---------------------------------------------------------------------- */
/* Reset                                                                   */
/* ---------------------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 12px);
}

@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;
    scroll-behavior: auto !important;
  }
}

body {
  margin: 0;
  /* White page, cream panels — the artboard's arrangement. The site had
     cream as the canvas, which left nothing for a panel to sit against. */
  background: var(--surface);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

a {
  color: inherit;
}

h1,
h2,
h3,
p,
ul {
  margin: 0;
}

ul {
  padding: 0;
  list-style: none;
}

button {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--accent-fill);
  color: var(--text-on-accent);
  padding: 0.75rem 1.25rem;
  border-radius: 0 0 var(--radius-sm) 0;
  font-family: var(--font-body);
  font-weight: 700;
  text-decoration: none;
}

.skip-link:focus {
  left: 0;
}

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

/* ---------------------------------------------------------------------- */
/* Layout utilities                                                        */
/* ---------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 3.5rem);
}

/* Long-form text (legal, articles, FAQ answers) keeps a readable measure
   rather than running the full 1560px — 1560px of 16px prose is roughly
   190 characters a line, about triple what is comfortable. */
.wrap--reading {
  max-width: var(--container-reading);
}

/* Breaks a child out of .wrap to the full viewport width. The negative
   margin is the container's own gutter plus however much of the page is
   margin at this width, so it works at every breakpoint without a media
   query. */
.full-bleed {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

.section-eyebrow {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-3);
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

/* A short bar of the real brand gold in front of every section label.
 * The label text itself has to be the darker ink gold — #DA9F3E is
 * 2.12:1 on cream and this is 13px — but a 2.5rem solid bar is a
 * graphic, not text, so it can be the brand colour at full strength.
 * That is what puts the actual gold on the page rather than only on
 * buttons. */
.section-eyebrow::before {
  content: "";
  flex: none;
  width: 2.5rem;
  height: 3px;
  border-radius: 2px;
  background: var(--accent-fill);
}

.section-title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.012em;
  text-transform: uppercase;
  font-size: clamp(1.5rem, 1.25rem + 1.1vw, 2.25rem);
  color: var(--text-primary);
  max-width: 40rem;
}

.section-subtitle {
  font-family: var(--font-body);
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.125rem);
  color: var(--text-secondary);
  max-width: 42rem;
  margin-top: var(--space-3);
}

/* ---------------------------------------------------------------------- */
/* Buttons & pills                                                        */
/* ---------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.15;
  /* Not nowrap. Uppercasing these and adding 0.08em of tracking made
     "Creator Partner Portal login" wider than a 390px phone, and nowrap
     turned that into 41px of horizontal page scroll rather than a second
     line. Long labels are rare and a wrapped button is fine; a page that
     scrolls sideways on a phone is not. */
  text-wrap: balance;
  max-width: 100%;
  text-align: center;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 1.05em 1.6em;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease,
    border-color 0.15s ease;
}

.btn svg {
  width: 1.1em;
  height: 1.1em;
  flex: none;
}

.btn--primary {
  background: var(--text-primary);
  color: var(--bg);
  box-shadow: 0 6px 16px rgba(26, 26, 26, 0.18);
}

.btn--primary:hover {
  background: #000000;
  transform: translateY(-1px);
  box-shadow: 0 10px 24px rgba(26, 26, 26, 0.24);
}

.coach-app {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: flex-start;
}

.coach-app > div {
  flex: 1 1 280px;
  min-width: 0;
}

.coach-app__icon {
  border-radius: 22px;
}

.coach-app__steps {
  margin: 16px 0 24px;
  padding-left: 20px;
}

.page-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
}

.btn--ghost {
  background: transparent;
  color: var(--text-primary);
  border-width: 1.5px;
  border-color: var(--text-primary);
}

.btn--ghost:hover {
  background: rgba(26, 26, 26, 0.04);
  transform: translateY(-1px);
}

.btn--sm {
  padding: 0.6em 1.1em;
  font-size: 0.8125rem;
}

.btn--lg {
  padding: 1em 1.75rem;
  font-size: 1rem;
}

.btn--block {
  width: 100%;
}

.btn.is-pending,
.btn[disabled] {
  background: var(--surface-high);
  color: var(--text-secondary);
  border: 1px dashed var(--border-strong);
  box-shadow: none;
  cursor: not-allowed;
}

.btn.is-pending:hover,
.btn[disabled]:hover {
  transform: none;
  background: var(--surface-high);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  padding: 0.35em 0.85em;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}

.pill--pending {
  background: var(--warning-soft);
  color: var(--warning);
}

.pill--live {
  background: var(--success-soft);
  color: var(--success);
}

.pill--set {
  background: var(--accent-soft);
  color: var(--accent);
}

.pill__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

/* ---------------------------------------------------------------------- */
/* Header                                                                  */
/* ---------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  background: rgba(246, 244, 235, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: background-color 0.2s ease, border-color 0.2s ease;
  padding-top: env(safe-area-inset-top);
  padding-block: 0.6rem;
}

.site-header.is-scrolled {
  background: rgba(246, 244, 235, 0.94);
  border-bottom-color: var(--border);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--text-primary);
}

.brand__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.125rem;
  height: 1.5rem;
  flex: none;
}

/* Two gold chevrons and a charcoal one, as on the supplied logo sheet.
 * `fill` on the <svg> rather than per <path> so the tail can override
 * it, and so the mark inverts as one unit on the dark band below. */
.brand__mark svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: var(--accent-fill);
}

.brand__mark-tail {
  fill: var(--text-primary);
}

.brand__word {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.1rem;
  letter-spacing: -0.01em;
}

.nav {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  row-gap: 0.5rem;
  gap: var(--space-4);
}

.nav__link {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--text-secondary);
  text-decoration: none;
  transition: color 0.15s ease;
}

.nav__link:hover {
  color: var(--text-primary);
}

.nav__link[aria-current="page"] {
  color: var(--accent);
}

@media (max-width: 480px) {
  .nav__link {
    display: none;
  }
}

/* ---------------------------------------------------------------------- */
/* Inner-page hero (no floating instrument cards)                         */
/* ---------------------------------------------------------------------- */

.page-hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(3rem, 5vw + 1rem, 4.5rem) clamp(2.5rem, 4vw + 1rem, 3.5rem);
  border-bottom: 1px solid var(--border);
}

.page-hero__inner {
  position: relative;
  z-index: 1;
  max-width: 44rem;
}

.page-hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.08;
  text-transform: uppercase;
  font-size: clamp(1.75rem, 1.4rem + 1.6vw, 2.75rem);
  color: var(--text-primary);
}

.page-hero__subtitle {
  margin-top: var(--space-4);
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.1875rem);
  color: var(--text-secondary);
  max-width: 38rem;
}

.page-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

/* ---------------------------------------------------------------------- */
/* Generic content section                                                */
/* ---------------------------------------------------------------------- */

.content-section {
  padding-block: clamp(3.5rem, 5vw, 5.5rem);
  border-top: 1px solid var(--border);
}

.content-section--raised {
  background: var(--surface);
}

.content-section__head {
  max-width: 44rem;
}

/* Simple numbered step list (used on partner pages) */
.step-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

@media (min-width: 720px) {
  .step-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.step-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--space-5);
}

.step-card__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.9rem;
  margin-bottom: var(--space-3);
}

.step-card__title {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--text-primary);
}

.step-card__body {
  margin-top: var(--space-2);
  font-size: 0.9375rem;
  color: var(--text-secondary);
}

/* Stat row (used on partner + about pages) */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
  margin-top: var(--space-6);
}

@media (min-width: 720px) {
  .stat-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.stat-card {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  text-align: left;
}

.stat-card__value {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--accent);
}

.stat-card__label {
  margin-top: 0.3rem;
  font-size: 0.8125rem;
  color: var(--text-secondary);
}

/* ---------------------------------------------------------------------- */
/* Pricing                                                                 */
/* ---------------------------------------------------------------------- */

.pricing-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

@media (min-width: 720px) {
  .pricing-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  /* Two plans for now (Basic and Prime): two equal columns, centred. */
  .pricing-grid--two {
    grid-template-columns: repeat(2, 1fr);
    max-width: 820px;
    margin-inline: auto;
  }
}

.pricing-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--space-5);
}

.pricing-card--highlight {
  background: var(--surface-raised);
  border-color: var(--accent);
  box-shadow: var(--shadow-card);
}

.pricing-card__badge {
  position: absolute;
  top: -0.75rem;
  left: var(--space-5);
  background: var(--accent-fill);
  color: var(--text-on-accent);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.3em 0.75em;
  border-radius: var(--radius-pill);
}

.pricing-card__name {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--text-primary);
}

.pricing-card__price {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 2.25rem;
  letter-spacing: -0.02em;
  color: var(--text-primary);
}

.pricing-card__price span {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.95rem;
  color: var(--text-secondary);
}

.pricing-card__annual {
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.pricing-card__offer {
  margin-top: 0.15rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-secondary);
}

/* The highlighted plan's button uses the mint accent, like the header CTA. */
.pricing-card--highlight .btn--primary {
  background: var(--accent-fill);
  color: var(--text-on-accent);
  box-shadow: none;
}

.pricing-card--highlight .btn--primary:hover {
  background: #8adcb9;
}

.pricing-card__list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  font-size: 0.9375rem;
  color: var(--text-secondary);
}

.pricing-card__list li {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
}

.pricing-card__list li::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  margin-top: 0.55em;
  border-radius: 50%;
  background: var(--accent);
}

.note-box {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  font-size: 0.875rem;
  color: var(--text-secondary);
  margin-top: var(--space-6);
}

.note-box strong {
  color: var(--text-primary);
}

/* ---------------------------------------------------------------------- */
/* Legal / long-form content                                              */
/* ---------------------------------------------------------------------- */

.legal {
  padding-block: clamp(3rem, 5vw, 4.5rem);
}

.legal__wrap {
  max-width: 44rem;
}

.legal__updated {
  font-size: 0.8125rem;
  color: var(--text-muted);
  margin-bottom: var(--space-5);
}

.legal h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.375rem;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  margin-top: var(--space-7);
  margin-bottom: var(--space-3);
}

.legal h2:first-of-type {
  margin-top: 0;
}

.legal h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--text-primary);
  margin-top: var(--space-5);
  margin-bottom: var(--space-2);
}

.legal p {
  font-size: 0.9375rem;
  color: var(--text-secondary);
  margin-top: var(--space-3);
}

.legal ul {
  margin-top: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.legal li {
  font-size: 0.9375rem;
  color: var(--text-secondary);
  padding-left: 1.1rem;
  position: relative;
}

.legal li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

.legal a {
  color: var(--accent);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

.legal strong {
  color: var(--text-primary);
}

/* ---------------------------------------------------------------------- */
/* Support / contact                                                      */
/* ---------------------------------------------------------------------- */

.support-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

@media (min-width: 720px) {
  .support-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.faq {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-6);
  max-width: 48rem;
}

.faq-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
}

.faq-item summary {
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--text-primary);
  list-style: none;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary::after {
  content: "+";
  float: right;
  color: var(--accent);
  font-family: var(--font-mono);
}

.faq-item[open] summary::after {
  content: "\2212";
}

.faq-item p {
  margin-top: var(--space-3);
  font-size: 0.9375rem;
  color: var(--text-secondary);
}

/* ---------------------------------------------------------------------- */
/* Hero                                                                    */
/* ---------------------------------------------------------------------- */

.hero {
  position: relative;
  overflow: hidden;
  /* An inset cream panel with a 22px radius, as on the artboard, rather
     than a band running the full width of the window. */
  background: var(--bg);
  border-radius: 22px;
  margin: 1.125rem 1.125rem 0;
  padding-block: clamp(2rem, 2.5vw + 0.75rem, 3.25rem) clamp(2.5rem, 3vw + 1rem, 4rem);
}

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* The dark theme's dot grid was white at 5% — invisible on cream. This
 * is the same idea inverted: charcoal dots at 5%, masked to fade out,
 * so the hero has texture without a second colour in it. */
.hero__bg::before {
  content: "";
  position: absolute;
  inset: -15%;
  background-image: radial-gradient(rgba(26, 26, 26, 0.055) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(62% 58% at 32% 28%, #000 0%, transparent 74%);
  mask-image: radial-gradient(62% 58% at 32% 28%, #000 0%, transparent 74%);
  opacity: 0.85;
}

/* One warm gold wash, where the dark theme had three coloured glows
 * (mint, violet, infrared). Three glows on a light canvas muddy it; the
 * brand has one accent, so the hero gets one. */
.hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(52% 46% at 88% 4%, rgba(218, 159, 62, 0.20), transparent 64%),
    radial-gradient(44% 40% at 4% 92%, rgba(218, 159, 62, 0.10), transparent 62%);
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-7);
  align-items: center;
}

.hero__content {
  max-width: 40rem;
}

.eyebrow {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55em;
  font-family: var(--font-body);
  font-size: 0.8125rem;
  color: var(--text-secondary);
  margin-bottom: var(--space-4);
}

.eyebrow__mark {
  font-family: var(--font-mono);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent);
}

.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 1.08;
  font-size: clamp(2rem, 1.35rem + 2.1vw, 3.125rem);
  color: var(--text-primary);
}

.hero__subtitle {
  margin-top: var(--space-4);
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.1875rem);
  color: var(--text-secondary);
  max-width: 34rem;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

.hero__note {
  margin-top: var(--space-4);
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* Floating instrument-panel cards */
.hero__visual {
  position: static;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.float-card {
  /* relative so z-index applies while the cards are stacked in flow;
     the 900px block below switches them to absolute. */
  position: relative;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--space-4);
  box-shadow: var(--shadow-floating);
  width: 100%;
  max-width: 22rem;
}

.float-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.float-card__title {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--text-primary);
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
}

.dot--ai {
  background: var(--ai-accent);
  box-shadow: 0 0 0 3px var(--ai-accent-soft);
}

.float-card--chat .float-card__head {
  justify-content: flex-start;
  gap: 0.6rem;
}

.float-card__body {
  margin-top: var(--space-3);
  font-size: 0.9375rem;
  color: var(--text-secondary);
  line-height: 1.5;
}

.meter-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: var(--space-3);
}

.meter {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.meter__label {
  font-size: 0.75rem;
  color: var(--text-secondary);
  width: 3.4rem;
  flex: none;
}

.meter__bar {
  flex: 1;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-high);
  overflow: hidden;
}

.meter__bar i {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent-alt), var(--accent));
}

.float-card__metric {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.85rem;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin-top: var(--space-2);
}

.float-card__metric span {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.6em;
  color: var(--text-secondary);
  margin-left: 0.2em;
  margin-right: 0.5em;
}

.float-card__meta {
  display: block;
  margin-top: var(--space-2);
  font-size: 0.75rem;
  color: var(--text-muted);
}

@media (min-width: 900px) {
  .hero__inner {
    /* More room for the headline than for the media: the media bleeds
       off the right edge and gains the gutter back anyway. */
    grid-template-columns: 1.2fr 0.8fr;
  }

  .hero__visual {
    position: relative;
    min-height: 26rem;
  }

  .float-card {
    position: absolute;
    width: 19rem;
    max-width: none;
  }

  .float-card--chat {
    top: 0;
    left: 0;
    transform: rotate(-2deg);
  }

  .float-card--stat {
    top: 9.5rem;
    right: 0;
    width: 17rem;
    transform: rotate(2deg);
  }

  .float-card--set {
    bottom: 0;
    left: 2.5rem;
    width: 16rem;
    transform: rotate(-1.5deg);
  }
}

/* ---------------------------------------------------------------------- */
/* Features                                                                */
/* ---------------------------------------------------------------------- */

.features {
  padding-block: clamp(4rem, 6vw, 6.5rem);
  border-top: 1px solid var(--border);
}

.feature-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

@media (min-width: 640px) {
  .feature-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .feature-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  /* Four programmes read as a 2 × 2 grid rather than 3 + 1. */
  .feature-grid--two {
    grid-template-columns: repeat(2, 1fr);
  }
}

.feature-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  transition: border-color 0.15s ease, transform 0.15s ease, background-color 0.15s ease;
}

.feature-card:hover {
  border-color: var(--border-strong);
  background: var(--surface-raised);
  transform: translateY(-2px);
}

.feature-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
}

.feature-card__icon svg {
  width: 1.4rem;
  height: 1.4rem;
}

.feature-card[data-accent="mint"] .feature-card__icon {
  background: var(--accent-soft);
  color: var(--accent);
}

.feature-card[data-accent="pink"] .feature-card__icon {
  background: var(--pink-soft);
  color: var(--pink);
}

.feature-card[data-accent="cyan"] .feature-card__icon {
  background: var(--cyan-soft);
  color: var(--cyan);
}

.feature-card[data-accent="violet"] .feature-card__icon {
  background: var(--ai-accent-soft);
  color: var(--ai-accent);
}

.feature-card[data-accent="success"] .feature-card__icon {
  background: var(--success-soft);
  color: var(--success);
}

.feature-card[data-accent="orange"] .feature-card__icon {
  background: var(--orange-soft);
  color: var(--orange);
}

.feature-card__title {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.125rem;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}

.feature-card__body {
  margin-top: var(--space-2);
  font-size: 0.9375rem;
  color: var(--text-secondary);
}

/* Programme cards: duration above the title, "who it's for" below the promise. */
.feature-card__meta {
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--accent);
}

.feature-card__for {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
  font-size: 0.875rem;
  color: var(--text-muted);
}

.feature-card__note {
  display: block;
  margin-top: var(--space-3);
  font-family: var(--font-body);
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------------- */
/* Download                                                                */
/* ---------------------------------------------------------------------- */

.download {
  padding-block: clamp(4rem, 6vw, 6.5rem);
  background: var(--surface);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.download-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

/* Android is the only platform card now. Two fixed columns left the right
   one empty, so the tracks are capped and auto-fit instead: a lone card is
   centred at a readable width, and a second card would sit beside it again
   when there is room for both. */
@media (min-width: 720px) {
  .download-grid {
    grid-template-columns: repeat(auto-fit, minmax(0, 32rem));
    justify-content: center;
  }
}

.platform-card {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.platform-card__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.platform-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-md);
  background: var(--surface-high);
  color: var(--text-primary);
  flex: none;
}

.platform-card__icon svg {
  width: 1.6rem;
  height: 1.6rem;
}

.platform-card__title {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--text-primary);
}

.platform-card__subtitle {
  margin-top: 0.2rem;
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.platform-card__body {
  font-size: 0.9375rem;
  color: var(--text-secondary);
}

.platform-card__footnote {
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* "Version 0.10.0" under each Download button; the number is rewritten by
   scripts/publish-apk-link.mjs after every Android build. */
.apk-version {
  font-size: 0.8125rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.apk-version--coach {
  margin-top: 12px;
}

.platform-card__footnote a {
  color: var(--text-secondary);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

/* ---------------------------------------------------------------------- */
/* CTA strip                                                               */
/* ---------------------------------------------------------------------- */

.cta-strip {
  padding-block: clamp(3rem, 5vw, 4.5rem);
}

.cta-strip__inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-4);
}

.cta-strip__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.02em;
  font-size: clamp(1.5rem, 1.3rem + 1vw, 2rem);
  max-width: 30rem;
}

@media (min-width: 720px) {
  .cta-strip__inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

/* ---------------------------------------------------------------------- */
/* Footer                                                                  */
/* ---------------------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--border);
  padding-block: clamp(2.5rem, 4vw, 3.5rem) calc(clamp(2rem, 3vw, 2.5rem) + env(safe-area-inset-bottom));
  background: var(--bg);
}

.footer__inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--border);
}

@media (min-width: 720px) {
  .footer__inner {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
  }
}

.footer__brand {
  max-width: 22rem;
}

.footer__tagline {
  margin-top: var(--space-3);
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5) var(--space-6);
}

.footer__col-title {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}

.footer__col-link {
  display: block;
  font-size: 0.9375rem;
  color: var(--text-secondary);
  text-decoration: none;
  margin-top: 0.5rem;
  transition: color 0.15s ease;
}

.footer__col-link:hover {
  color: var(--text-primary);
}

.footer__legal-item {
  font-size: 0.9375rem;
  color: var(--text-secondary);
  margin-top: 0.5rem;
}

.footer__legal-note {
  color: var(--text-muted);
  font-size: 0.8125rem;
}

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.footer__copy {
  margin-top: var(--space-4);
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/*
 * Language picker. Hidden by the `hidden` attribute in the markup and
 * un-hidden by assets/js/i18n.js once there is more than one language
 * to choose between, which is the same honest order the mobile nav
 * toggle uses: a control that cannot do anything is worse than no
 * control.
 */
.footer__lang-wrap {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.footer__lang-wrap[hidden] {
  /* `hidden` loses to `display: flex` in the cascade — the same bug the
     forms had, and the reason .form[hidden] exists further up. */
  display: none;
}

.footer__lang-label {
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.footer__lang {
  font-family: inherit;
  font-size: 0.8125rem;
  color: var(--text-primary);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.35rem 0.6rem;
}

.footer__lang:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ------------------------------------------------------------------
   Cookie consent banner (W-M3)
   Fixed to the bottom rather than an overlay: a modal that blocks the
   page until you choose is a dark pattern in the other direction, and
   this site's content is readable whether or not you have decided.
   ------------------------------------------------------------------ */
.cookie-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  background: var(--surface, #ffffff);
  border-top: 1px solid var(--border, rgba(26, 26, 26, 0.12));
  box-shadow: 0 -4px 28px rgba(26, 26, 26, 0.12);
  padding: 14px 0;
}

.cookie-bar__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.cookie-bar__text {
  margin: 0;
  flex: 1 1 320px;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--text-secondary, #4a4d51);
}

.cookie-bar__actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

@media (max-width: 560px) {
  .cookie-bar__actions {
    width: 100%;
  }
  .cookie-bar__actions .btn {
    flex: 1;
  }
}

/* ---------------------------------------------------------------------- */
/* Mobile navigation (spec §8 — "mobile navigation")                       */
/* ---------------------------------------------------------------------- */

/*
 * The nav used to be one flat row that simply wrapped on a phone, which
 * put eight links and a button over three lines above the fold. Below
 * 900px it collapses behind a toggle instead; above it, nothing changes.
 *
 * The toggle is a real <button aria-expanded>, and the panel is hidden
 * with `display:none` rather than opacity — a link a sighted user cannot
 * see must not be reachable by tab or read by a screen reader either.
 */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  /* 44px minimum touch target. */
  min-width: 44px;
  min-height: 44px;
  padding: 0 var(--space-3);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
}

.nav-toggle__bars {
  display: inline-flex;
  flex-direction: column;
  gap: 3px;
}

.nav-toggle__bars span {
  display: block;
  width: 16px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}

@media (min-width: 900px) {
  .nav-toggle {
    display: none;
  }
}

@media (max-width: 899px) {
  /*
   * Scoped to `.has-nav-toggle`, which main.js adds to <html> only once
   * it has a working toggle to offer. Without JS the nav keeps its old
   * wrapped layout — visually busier, but reachable, which a collapsed
   * panel with no button to open it would not be.
   */
  .has-nav-toggle .nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--space-3);
    background: var(--surface);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 18px 40px rgba(26, 26, 26, 0.16);
  }

  .has-nav-toggle .nav.is-open {
    display: flex;
  }

  .has-nav-toggle .nav .nav__link {
    /* Undo the ≤480px `display: none` above: inside the open panel the
       links are the whole point. */
    display: block;
    padding: 0.85rem 0.5rem;
    border-bottom: 1px solid var(--border);
  }

  .has-nav-toggle .nav .btn {
    margin-top: var(--space-3);
    text-align: center;
  }

  .site-header__inner {
    position: relative;
  }
}

/* ---------------------------------------------------------------------- */
/* Forms (spec §8 — Early Access, partner applications, contact)           */
/* ---------------------------------------------------------------------- */

.form {
  margin-top: var(--space-6);
  display: grid;
  gap: var(--space-4);
  max-width: 34rem;
}

/*
 * `display: grid` beats the `hidden` attribute, so a form hidden on
 * success stayed on screen underneath its own "you're on the list"
 * message. Found by driving the real page, not by reading this file.
 * Scoped to the elements that set a display, rather than a blanket
 * `[hidden] { display: none !important }`.
 */
.form[hidden],
.form-state[hidden],
.field[hidden] {
  display: none;
}

.form--wide {
  max-width: none;
}

@media (min-width: 720px) {
  .form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
  }
}

.field {
  display: grid;
  gap: 0.4rem;
}

.field__label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary);
}

.field__hint {
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.field__input,
.field__textarea,
.field__select {
  width: 100%;
  /* 44px minimum, so the tap target matches the buttons. */
  min-height: 44px;
  padding: 0.7rem 0.85rem;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 1rem;
}

.field__textarea {
  min-height: 8rem;
  resize: vertical;
}

.field__input:focus-visible,
.field__textarea:focus-visible,
.field__select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/*
 * Field-level errors, driven by the API's own `fields` array rather than
 * by a second copy of the validation rules in the browser. A form that
 * disagrees with the server about what is valid is a form that rejects
 * submissions the server would have accepted.
 */
.field.is-invalid .field__input,
.field.is-invalid .field__textarea,
.field.is-invalid .field__select {
  border-color: var(--danger);
}

.field__error {
  font-size: 0.8125rem;
  color: var(--danger);
}

.field__error:empty {
  display: none;
}

.field--check {
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--space-3);
}

.field--check input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin-top: 0.15rem;
  accent-color: var(--accent);
}

.field--check .field__label {
  font-weight: 500;
  color: var(--text-secondary);
}

/*
 * The four states §8 names for these forms. Each is a real region with
 * `role="status"`, so the outcome is announced rather than merely
 * appearing somewhere below the fold.
 */
.form-state {
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-raised);
}

.form-state__title {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--text-primary);
}

.form-state__body {
  margin-top: var(--space-2);
  font-size: 0.9375rem;
  color: var(--text-secondary);
}

.form-state--success {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.form-state--error {
  border-color: var(--danger);
}

.form-state--known {
  border-color: var(--border-strong);
}

/* ---------------------------------------------------------------------- */
/* Learn (spec §8 — Learn category index + article template)               */
/* ---------------------------------------------------------------------- */

.article-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

@media (min-width: 720px) {
  .article-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.article-card {
  display: block;
  padding: var(--space-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  color: inherit;
  text-decoration: none;
}

.article-card:hover,
.article-card:focus-visible {
  border-color: var(--accent);
}

.article-card__category {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}

.article-card__title {
  margin-top: var(--space-2);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--text-primary);
}

.article-card__body {
  margin-top: var(--space-2);
  font-size: 0.9375rem;
  color: var(--text-secondary);
}

.article-card__meta {
  margin-top: var(--space-3);
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* The article template itself — reuses the legal pages' reading column,
   which is already tuned for long-form text. */
.article__meta {
  margin-top: var(--space-3);
  font-size: 0.875rem;
  color: var(--text-muted);
}

.article__review {
  margin-top: var(--space-6);
  padding: var(--space-4);
  border-left: 3px solid var(--accent);
  background: var(--surface-raised);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  font-size: 0.9375rem;
  color: var(--text-secondary);
}

/* ---------------------------------------------------------------------- */
/* Photography and motion — added 3 Oct 2026 with the light theme          */
/* ---------------------------------------------------------------------- */

/*
 * The hero's media panel.
 *
 * The float cards used to hover over a blank gradient. They now sit over
 * real footage, which is the whole point of the cards: app UI on top of
 * the training it describes.
 *
 * The poster image is always in the markup and always loads. The video
 * element carries no `src` — assets/js/main.js attaches one only on a
 * wide viewport, on a connection that is not metered or saving data, and
 * never when the visitor prefers reduced motion. So the 7.6 MB download
 * is opt-in by capability rather than something every phone pays for,
 * and a visitor with JavaScript off sees the still.
 */
.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface-high);
  box-shadow: var(--shadow-floating);
}

.hero__media img,
.hero__media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The video sits over the still and fades in once it can actually play,
   so a slow start shows the poster rather than a black rectangle. */
.hero__media video {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease);
}

.hero__media video.is-playing {
  opacity: 1;
}

/* Warms the footage toward the brand and keeps the white float cards
   legible over whatever frame happens to be showing. */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(190deg, rgba(26, 26, 26, 0.12) 0%, rgba(26, 26, 26, 0.42) 100%);
}

.hero__visual {
  position: relative;
  min-height: 420px;
  isolation: isolate;
}

/* z-index only. Setting `position` here would override the absolute
   placement in the 900px block above, which is what the cards' desktop
   composition is built from. */
.hero__visual > .float-card {
  z-index: 1;
}

/* ---- Editorial photo band ------------------------------------------- */

/*
 * A full-width photograph with a caption column beside it. Used between
 * card sections to break the rhythm — the reference layout's "picture,
 * then claim, then picture" cadence.
 */
.photo-band {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  align-items: center;
}

/* The positioning parent for the overlapping inset. It must sit OUTSIDE
   .photo-band__media, whose overflow:hidden rounds the main photograph
   and was also clipping the frame that is supposed to hang off it. */
.photo-band__frame {
  position: relative;
}

.photo-band__media {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface-high);
  aspect-ratio: 4 / 3;
  box-shadow: var(--shadow-card);
}

.photo-band__media picture {
  display: contents;
}

.photo-band__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* A small second frame, overlapped onto the first — the offset detail
   shot from the reference layout. Hidden below the two-column
   breakpoint, where there is no room to overlap anything. */
.photo-band__inset {
  display: none;
}

.photo-band__label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}

.photo-band__title {
  margin-top: var(--space-3);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.6rem, 3vw + 0.5rem, 2.4rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: var(--text-primary);
}

.photo-band__body {
  margin-top: var(--space-3);
  color: var(--text-secondary);
  line-height: 1.7;
}

/* ---- Dark guidance band --------------------------------------------- */

/*
 * The one charcoal section on the site. It carries the human-coach
 * story, so it gets the two coach photographs and inverts the palette.
 *
 * Inverting by redefining the tokens inside the block, rather than
 * writing new rules, means every component dropped in here — buttons,
 * eyebrows, the brand mark — adapts without being special-cased. The
 * values are the light palette's dark counterparts and are measured:
 * cream on charcoal is 15.80:1, and the gold is the brand gold at
 * 7.47:1, which is legible on charcoal in a way it never was on cream.
 */
.band-dark {
  --bg: #0A0A0A;
  --surface: #1A1A1A;
  --surface-raised: #1F1F1F;
  --surface-high: #2E2E2E;
  --border: #2E2E2E;
  --border-strong: rgba(255, 255, 255, 0.3);
  --text-primary: #FFFFFF;
  --text-secondary: #E5E5E5;
  --text-muted: #A3A3A3;
  --accent: #70D4A8;
  --accent-alt: #8ADCB9;
  --accent-fill: #70D4A8;
  --text-on-accent: #0A0A0A;
  --accent-soft: rgba(112, 212, 168, 0.2);

  background: var(--bg);
  color: var(--text-primary);
}

.band-dark .brand__mark-tail {
  fill: var(--text-primary);
}

.band-dark .section-title,
.band-dark .photo-band__title {
  color: var(--text-primary);
}

/* The group shot, with the individual portrait overlapping its corner. */
.coach-stack {
  position: relative;
}

.coach-stack__main {
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--surface-high);
}

.coach-stack__main img,
.coach-stack__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.coach-stack__portrait {
  display: none;
}

/* ---- Reveal on scroll ------------------------------------------------ */

/*
 * Gated on `.has-js`, which assets/js/main.js sets on <html> before
 * first paint. Without that gate an `opacity: 0` start state would hide
 * every section permanently for a visitor whose JavaScript fails to
 * run — the classic way a scroll animation takes a site down.
 */
.has-js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
}

.has-js .reveal.is-in {
  opacity: 1;
  transform: none;
}

/* Children stagger, so a row of cards arrives as a row rather than as
   one block. Four steps is enough for every grid on the site. */
.has-js .reveal--stagger > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
}

.has-js .reveal--stagger.is-in > * {
  opacity: 1;
  transform: none;
}

.has-js .reveal--stagger.is-in > *:nth-child(2) { transition-delay: 0.08s; }
.has-js .reveal--stagger.is-in > *:nth-child(3) { transition-delay: 0.16s; }
.has-js .reveal--stagger.is-in > *:nth-child(4) { transition-delay: 0.24s; }

/*
 * The global reduced-motion block near the top of this file already
 * collapses every duration to 0.001ms, which lands these elements on
 * their final state instantly. The start state still has to be undone
 * explicitly: a transition that never runs would otherwise leave
 * opacity at 0 forever.
 */
@media (prefers-reduced-motion: reduce) {
  .has-js .reveal,
  .has-js .reveal.is-in,
  .has-js .reveal--stagger > *,
  .has-js .reveal--stagger.is-in > * {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ---- Two-column and up ---------------------------------------------- */

@media (min-width: 900px) {
  .photo-band {
    grid-template-columns: 1.05fr 0.95fr;
    gap: var(--space-7);
  }

  /* On the frame, not the media: the media is nested inside the frame
     now, and `order` only applies to a grid child. */
  .photo-band--flip .photo-band__frame {
    order: 2;
  }

  .photo-band__inset {
    display: block;
    position: absolute;
    right: -2.25rem;
    bottom: -2.25rem;
    width: 11.5rem;
    aspect-ratio: 4 / 3;
    border-radius: var(--radius-md);
    overflow: hidden;
    border: 6px solid var(--bg);
    box-shadow: var(--shadow-floating);
    background: var(--surface-high);
  }

  .photo-band__inset img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }

  .coach-stack__portrait {
    display: block;
    position: absolute;
    left: -2.5rem;
    bottom: -2rem;
    width: 10.5rem;
    aspect-ratio: 4 / 5;
    border-radius: var(--radius-md);
    overflow: hidden;
    border: 6px solid var(--bg);
    box-shadow: var(--shadow-floating);
  }

  .hero__visual {
    min-height: 520px;
  }
}

/* The dark band's two-column layout: photographs on one side, the
   closing call to action on the other. Below 900px the stack collapses
   and the portrait overlay is hidden by the rule above, so the group
   shot simply sits over the text. */
.band-dark .cta-strip__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: center;
}

.band-dark .cta-strip__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-4);
}

@media (min-width: 900px) {
  .band-dark .cta-strip__inner {
    grid-template-columns: 0.85fr 1fr;
    gap: var(--space-8);
  }

  .band-dark .coach-stack {
    margin-left: 2.5rem;
  }
}

/* ---------------------------------------------------------------------- */
/* Contained imagery                                                       */
/* ---------------------------------------------------------------------- */

/*
 * The photographs used to run to the edge of the glass. The artboard
 * keeps them inside the column, in rounded frames, and that is what was
 * signed off — a bled photograph under a rounded panel also has nowhere
 * to bleed to. The --bleed variable and the rules that used it are gone
 * rather than left switched off.
 */
.band-dark {
  overflow: hidden;
}

@media (min-width: 900px) {
  .photo-band {
    padding-bottom: 2.5rem;
  }

  /* The detail frame overlaps the photograph's outer corner. */
  .photo-band .photo-band__inset {
    right: -1.5rem;
    left: auto;
    bottom: -1.5rem;
    width: 9.5rem;
  }

  .photo-band--flip .photo-band__inset {
    right: auto;
    left: -1.5rem;
  }

  .photo-band--flip .photo-band__frame {
    order: 2;
  }
}


@media (min-width: 900px) {
  .photo-band {
    padding-bottom: 2.5rem;
  }
}

/* ---------------------------------------------------------------------- */
/* Homepage look (18 Oct 2026)                                             */
/* The inner pages follow the rebuilt homepage (assets/css/home.css): a    */
/* dark header, hero band and footer, Bricolage headings in sentence case, */
/* mono section labels with a mint dot, and sentence-case pill buttons.    */
/* ---------------------------------------------------------------------- */

/* Display type: Bricolage is a variable font with real weights, unlike
   Archivo Black, so headings set a weight and drop the all-caps. */
.section-title,
.page-hero__title,
.legal h2,
.hero__title,
.cta-strip__title,
.photo-band__title {
  font-weight: 800;
  text-transform: none;
  letter-spacing: -0.02em;
}

.brand__word {
  font-weight: 700;
  font-size: 1.375rem;
}

.section-eyebrow {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.75rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-primary);
  gap: 0.5rem;
}

.section-eyebrow::before {
  width: 9px;
  height: 9px;
  border-radius: 50%;
}

.band-dark .section-eyebrow {
  color: var(--accent);
}

.btn {
  font-size: 0.9375rem;
  letter-spacing: 0;
  text-transform: none;
}

/* The logo is the blue F image now (replacing the chevron SVG). */
.brand__mark {
  width: 2rem;
  height: 2rem;
}

.brand__mark img {
  display: block;
  width: 100%;
  height: 100%;
}

/* Dark header, hero band and footer, using the same tokens as .band-dark. */
.site-header,
.page-hero,
.site-footer {
  --bg: #0A0A0A;
  --surface: #1A1A1A;
  --surface-raised: #1F1F1F;
  --surface-high: #2E2E2E;
  --border: #2E2E2E;
  --text-primary: #FFFFFF;
  --text-secondary: #A3A3A3;
  --text-muted: #A3A3A3;
  --accent: #70D4A8;
  --accent-alt: #8ADCB9;
  --accent-fill: #70D4A8;
  --text-on-accent: #0A0A0A;
  color: var(--text-primary);
}

.site-header,
.site-header.is-scrolled {
  background: var(--bg);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: var(--border);
}

.page-hero,
.site-footer {
  background: var(--bg);
}

.page-hero {
  border-bottom: 0;
}

.nav__link {
  font-weight: 400;
  font-size: 1rem;
}

.nav__link[aria-current="page"] {
  color: var(--text-primary);
}

/* On dark backgrounds the main button is the homepage's mint pill; on
   light sections it stays ink. */
.site-header .btn--primary,
.page-hero .btn--primary,
.band-dark .btn--primary {
  background: var(--accent-fill);
  color: var(--text-on-accent);
  box-shadow: none;
}

.site-header .btn--primary:hover,
.page-hero .btn--primary:hover,
.band-dark .btn--primary:hover {
  background: #8ADCB9;
}

/* Social profiles in the footer. */
.footer__social {
  display: flex;
  gap: 10px;
  margin-top: var(--space-4);
  padding: 0;
  list-style: none;
}

.footer__social-link {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--text-primary);
  transition: color 0.15s ease, border-color 0.15s ease;
}

.footer__social-link:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Programme pages: photo and list beside each other, photos in black and white. */
@media (min-width: 900px) {
  .programme-band {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--space-6);
  }
}

.programme-photo img {
  filter: grayscale(1);
}

.check-list {
  display: grid;
  gap: var(--space-3);
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
}

.check-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-weight: 600;
}

.check-list li::before {
  content: "";
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  border-radius: 50%;
  background: var(--accent-fill, #70d4a8) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.5 8.2l2.2 2.2 4.8-4.8' fill='none' stroke='%230a0a0a' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 18px no-repeat;
}

.programme-for-label {
  margin-top: var(--space-5);
}

.programme-link {
  display: inline-block;
  margin-top: var(--space-3);
  font-weight: 700;
  color: var(--accent-text, var(--text-primary));
  text-underline-offset: 3px;
}

.feature-card__title .programme-link {
  margin-top: 0;
  color: inherit;
}

@media (min-width: 1100px) {
  .programme-steps {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (min-width: 720px) and (max-width: 1099px) {
  .programme-steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
