/* ==========================================================================
   myBJJ Miyazawa — site.css
   Hand-written design system. No build step, no framework.

   Contents
   01. Reset
   02. Design tokens (light + dark)
   03. Base typography
   04. Layout primitives
   05. Header / navigation
   06. Buttons + links
   07. Belt rail + section furniture
   08. Hero
   09. Cards, programs, instructors
   10. Photo slots + placeholders
   11. Schedule
   12. Testimonials + trust bar
   13. Forms
   14. FAQ / accordion
   15. Pricing table
   16. Blog + prose
   17. Footer + mobile action bar
   18. Motion
   19. Print
   ========================================================================== */

/* 01. Reset ---------------------------------------------------------------- */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100dvh;
}

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

img, video { height: auto; }

input, button, textarea, select { font: inherit; color: inherit; }

/* Long unbreakable tokens (emails, URLs, addresses) must reflow rather than
   widen their column. */
p, h1, h2, h3, h4, h5, h6, li, dd, dt, td, th, a, summary, figcaption,
blockquote, label { overflow-wrap: anywhere; }

/* Flex and grid children default to min-width:auto, which lets one wide child
   push a whole track past the viewport. Opt them out. */
.card, .card__body, .stack > *, .stack-lg > *, .grid > *, .price-card, .quote {
  min-width: 0;
}

ul[class], ol[class] { list-style: none; padding: 0; }

:target { scroll-margin-top: 6rem; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* 02. Design tokens -------------------------------------------------------- */
/* Light is the base definition. Dark redefines only what changes, once for
   system preference and once for the explicit toggle, so both directions win. */

:root {
  /* -- Palette: drawn from the myBJJ Team badge. One blue, one cool neutral.
        --brand-blue is sampled from the logo mark; --brand-grey from its ring. */
  --brand-blue:  #11569c;
  --brand-deep:  #0d4a88;
  --brand-grey:  #e6e7e8;
  --paper:       #ffffff;
  --paper-cool:  #f4f6f9;
  --paper-sunk:  #e9edf2;
  --ink:         #0f1a26;
  --ink-2:       #3d4b5c;
  --ink-3:       #5f6d7e;
  --blue-wash:   #e4edf7;

  /* -- Semantic surface + text */
  --bg:            var(--paper-cool);
  --bg-raised:     var(--paper);
  --bg-sunken:     var(--paper-sunk);
  --bg-inverse:    #0d1826;
  --text:          var(--ink);
  --text-muted:    var(--ink-2);   /* 8.2:1 on --bg */
  --text-subtle:   var(--ink-3);   /* 4.9:1 on --bg — still AA for body */
  --text-inverse:  #f4f6f9;
  --border:        #d6dde6;
  --border-strong: #b6c1cd;
  /* Boundaries of real controls (inputs, chips, outline buttons) need 3:1
     against the page — --border and --border-strong are decorative only. */
  --border-input:  #7a8899;   /* 3.34:1 on --bg */

  /* -- Semantic accent. The logo blue is dark enough to serve as both a button
        fill (white text, 7.4:1) and an inline link colour (6.8:1). */
  --accent:          var(--brand-blue);
  --accent-hover:    var(--brand-deep);
  --accent-ink:      var(--brand-deep);  /* inline text links — 8.2:1 */
  --accent-contrast: #ffffff;
  --accent-wash:     var(--blue-wash);
  --focus:           #0f1a26;

  /* -- Status */
  --ok:      #1f6b4a;
  --ok-wash: #dff0e7;
  --warn:      #8a5a10;
  --warn-wash: #f8eeda;

  /* -- Belt colours (used decoratively and in the beginner rail) */
  --belt-white:  #ffffff;
  --belt-blue:   #2a4b8d;
  --belt-purple: #55307e;
  --belt-brown:  #5a3a25;
  --belt-black:  #14110e;

  /* -- Type */
  --font-display: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body: "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --step--2: clamp(0.75rem, 0.735rem + 0.08vw, 0.8125rem);
  --step--1: clamp(0.875rem, 0.85rem + 0.12vw, 0.9375rem);
  --step-0:  clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
  --step-1:  clamp(1.125rem, 1.06rem + 0.3vw, 1.3125rem);
  --step-2:  clamp(1.375rem, 1.24rem + 0.65vw, 1.75rem);
  --step-3:  clamp(1.625rem, 1.36rem + 1.3vw, 2.375rem);
  --step-4:  clamp(2rem, 1.5rem + 2.4vw, 3.25rem);
  --step-5:  clamp(2.5rem, 1.55rem + 4.6vw, 5rem);

  --leading-tight: 1.06;
  --leading-snug:  1.25;
  --leading-body:  1.72;

  /* -- Space: 4/8 rhythm */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 2.5rem;
  --space-8: 3rem;
  --space-9: 4rem;
  --space-10: 5rem;
  --space-11: 6.5rem;
  --space-12: 8rem;

  --section-y: clamp(4.5rem, 2.5rem + 7vw, 9rem);
  --gutter: clamp(1.25rem, 0.7rem + 2.4vw, 3rem);
  --container: 78rem;
  --measure: 64ch;

  /* -- Shape + depth. One elevation scale, used consistently. */
  --radius-sm: 6px;
  --radius:    10px;
  --radius-lg: 18px;
  --radius-pill: 999px;

  --shadow-1: 0 1px 2px rgba(13, 24, 38, 0.05), 0 1px 3px rgba(13, 24, 38, 0.05);
  --shadow-2: 0 2px 4px rgba(13, 24, 38, 0.04), 0 6px 16px rgba(13, 24, 38, 0.07);
  --shadow-3: 0 8px 20px rgba(13, 24, 38, 0.09), 0 20px 48px rgba(13, 24, 38, 0.1);

  /* -- Motion tokens. Distance and complexity pick the duration, not habit. */
  --dur-tap:    120ms;   /* press feedback */
  --dur-micro:  180ms;   /* colour, opacity, small state */
  --dur-move:   320ms;   /* element travels a short distance */
  --dur-enter:  520ms;   /* content revealing on scroll */
  --dur-exit:   300ms;   /* ~60% of enter */
  --ease-out:   cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in:    cubic-bezier(0.55, 0, 1, 0.45);
  --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);

  /* -- Layering scale */
  --z-base: 0;
  --z-raised: 10;
  --z-sticky: 20;
  --z-header: 40;
  --z-overlay: 100;
  --z-toast: 1000;

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:            #0d1420;
    --bg-raised:     #151d2b;
    --bg-sunken:     #090e17;
    --bg-inverse:    #f4f6f9;
    --text:          #e6ecf4;
    --text-muted:    #b3becd;
    --text-subtle:   #8b98a8;
    --text-inverse:  #0f1a26;
    --border:        #24303f;
    --border-strong: #37455a;
    --border-input:  #5d6c80;

    --accent:          #6ba6e8;
    --accent-hover:    #8bbcf0;
    --accent-ink:      #7fb2ec;
    --accent-contrast: #061223;
    --accent-wash:     #13243a;
    --focus:           #b9d4f5;

    --ok:      #6fc9a0;
    --ok-wash: #10241d;
    --warn:      #e2b661;
    --warn-wash: #2a2113;

    --belt-white: #e8edf4;
    --belt-black: #4c5766;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 2px 4px rgba(0, 0, 0, 0.35), 0 6px 16px rgba(0, 0, 0, 0.4);
    --shadow-3: 0 8px 20px rgba(0, 0, 0, 0.45), 0 20px 48px rgba(0, 0, 0, 0.5);
  }
}

:root[data-theme="dark"] {
  --bg:            #0d1420;
  --bg-raised:     #151d2b;
  --bg-sunken:     #090e17;
  --bg-inverse:    #f4f6f9;
  --text:          #e6ecf4;
  --text-muted:    #b3becd;
  --text-subtle:   #8b98a8;
  --text-inverse:  #0f1a26;
  --border:        #24303f;
  --border-strong: #37455a;
  --border-input:  #5d6c80;

  --accent:          #6ba6e8;
  --accent-hover:    #8bbcf0;
  --accent-ink:      #7fb2ec;
  --accent-contrast: #061223;
  --accent-wash:     #13243a;
  --focus:           #b9d4f5;

  --ok:      #6fc9a0;
  --ok-wash: #10241d;
  --warn:      #e2b661;
  --warn-wash: #2a2113;

  --belt-white: #e8edf4;
  --belt-black: #4c5766;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 2px 4px rgba(0, 0, 0, 0.35), 0 6px 16px rgba(0, 0, 0, 0.4);
  --shadow-3: 0 8px 20px rgba(0, 0, 0, 0.45), 0 20px 48px rgba(0, 0, 0, 0.5);
}

/* 03. Base typography ------------------------------------------------------ */

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  font-feature-settings: "ss01" 1;
  transition: background-color var(--dur-micro) linear, color var(--dur-micro) linear;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: var(--leading-tight);
  /* Tight, even tracking is what makes a grotesque read as considered rather
     than as a default system font. */
  letter-spacing: -0.028em;
  text-wrap: balance;
}

h3, h4 { letter-spacing: -0.018em; }

h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); line-height: var(--leading-snug); }
h4 { font-size: var(--step-1); line-height: var(--leading-snug); letter-spacing: -0.005em; }

p, li { text-wrap: pretty; }

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--text-muted);
  max-width: 46ch;
}

/* Long-form paragraphs never exceed a comfortable measure, whatever column
   they land in. This is most of the difference between "readable" and "wall". */
.stack > p,
.prose > p,
.card__body > p { max-width: 62ch; }

.stack > p + p { margin-top: var(--space-4); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-ink);
  margin-bottom: var(--space-4);
}

.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 2px;
  background: currentColor;
  flex: none;
}

.text-muted { color: var(--text-muted); }
.text-subtle { color: var(--text-subtle); }
.measure { max-width: var(--measure); }
.measure-tight { max-width: 44ch; }
.nums { font-variant-numeric: tabular-nums; }

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

.skip-link {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: var(--z-toast);
  padding: var(--space-3) var(--space-5);
  background: var(--accent);
  color: var(--accent-contrast);
  border-radius: var(--radius);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-150%);
  transition: transform var(--dur-micro) var(--ease-out);
}

.skip-link:focus-visible { transform: translateY(0); }

/* Focus: one visible treatment everywhere, never removed. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 3px;
}

::selection { background: var(--accent); color: var(--accent-contrast); }

/* 04. Layout primitives ---------------------------------------------------- */

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

.container-narrow { max-width: 52rem; }

.section { padding-block: var(--section-y); }
.section-sunken { background: var(--bg-sunken); }
.section-raised { background: var(--bg-raised); }

.section-inverse {
  background: var(--bg-inverse);
  color: var(--text-inverse);
}
.section-inverse h2, .section-inverse h3 { color: var(--text-inverse); }
.section-inverse .lede { color: color-mix(in srgb, var(--text-inverse) 76%, transparent); }
.section-inverse .eyebrow { color: color-mix(in srgb, var(--text-inverse) 82%, transparent); }

.stack > * + * { margin-block-start: var(--flow, var(--space-4)); }
.stack-lg > * + * { margin-block-start: var(--space-6); }

.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

.grid { display: grid; gap: var(--space-5); }

.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 13.5rem), 1fr)); }

.section-head {
  display: grid;
  gap: var(--space-4);
  margin-block-end: var(--space-8);
  max-width: 60ch;
}

.section-head--split {
  max-width: none;
  grid-template-columns: 1fr;
  align-items: end;
}

@media (min-width: 60rem) {
  .section-head--split {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: var(--space-8);
  }
}

.divider { border: 0; border-top: 1px solid var(--border); margin-block: var(--space-8); }

/* 05. Header / navigation -------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px) saturate(1.4);
  -webkit-backdrop-filter: blur(12px) saturate(1.4);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-micro) linear, background-color var(--dur-micro) linear;
}

.site-header[data-scrolled="true"] {
  border-bottom-color: var(--border);
  background: color-mix(in srgb, var(--bg) 96%, transparent);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: 4.5rem;
  padding-block: var(--space-3);
}

@media (min-width: 64rem) {
  .header-inner { min-height: 5.25rem; }
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: var(--text);
  margin-inline-end: auto;
  /* Guarantees clearance from the nav even when the header is packed. */
  padding-inline-end: var(--space-4);
  /* Shrinkable so the header still fits at 320px. */
  flex: 0 1 auto;
  min-width: 0;
  /* The logo is a link home, so it gets a full-size touch target like every
     other control in the header. Without this the mark plus two text lines
     only measure 36px tall. */
  min-height: 44px;
}

/* The academy crest, beside the original mark. A roundel still reads as a
   badge at this size even though the brushwork does not. */
.brand__crest {
  height: 40px;
  width: 40px;
  flex: none;
  margin-inline-start: var(--space-3);
  align-self: center;
}

@media (max-width: 30rem) {
  .brand__crest { display: none; }
}

/* Miyazawa family kamon. Pure black line art on transparency, so dark mode
   flips it to white rather than needing a second file. */
.kamon {
  width: 44px;
  height: 44px;
  flex: none;
}
.kamon--lg { width: 76px; height: 76px; margin-bottom: var(--space-4); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .kamon { filter: invert(1); }
}
:root[data-theme="dark"] .kamon { filter: invert(1); }
:root[data-theme="light"] .kamon { filter: none; }

.name-with-kamon {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

/* The painted wordmark suits the kids page, where the rest of the site’s
   restraint matters less. */
.kids-wordmark {
  width: clamp(11rem, 26vw, 15rem);
  height: auto;
  display: block;
  margin-bottom: var(--space-4);
}
}

/* Below 360px the tagline is what pushes the header past the viewport. */
@media (max-width: 22.5rem) {
  .brand__sub { display: none; }
  .header-inner { gap: var(--space-3); }
}

/* The mark is drawn in currentColor so it reads as brand blue in the header and
   inherits the light footer text on the inverse background. */
.brand__mark { width: 2.25rem; height: 2.25rem; flex: none; color: var(--accent); }
.site-footer .brand__mark { color: currentColor; }

.logo-badge {
  width: min(15rem, 60vw);
  height: auto;
  margin-inline: auto;
}

/* Toshi's own academy crest. Used only where the page is about his club
   specifically — the blue myBJJ Team mark stays in the header and footer. */
.crest { width: 9.5rem; height: auto; }
.crest--sm { width: 5.75rem; }

@media (max-width: 47.99rem) {
  .crest { width: 7rem; }
  .crest--sm { width: 4.5rem; }
}

.brand__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
  line-height: 1.05;
  /* The wordmark must never wrap — below 360px the tagline is hidden instead. */
  white-space: nowrap;
}

.brand__sub {
  display: block;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-subtle);
  margin-top: 2px;
}

.nav { display: none; }

@media (min-width: 64rem) {
  .nav { display: flex; align-items: center; gap: var(--space-1); }
}

.nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: var(--step--1);
  font-weight: 500;
  text-decoration: none;
  /* Seven items plus a CTA is tight at 1024–1200px; wrapping looks broken. */
  white-space: nowrap;
  transition: color var(--dur-micro) linear, background-color var(--dur-micro) linear;
}

.nav__link:hover { color: var(--text); background: var(--bg-sunken); }

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

@media (min-width: 80rem) {
  .nav__link { padding-inline: var(--space-3); }
}

.nav__link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: var(--space-2);
  right: var(--space-2);
  bottom: 6px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
}

.header-actions { display: flex; align-items: center; gap: var(--space-2); flex: none; }

/* Scoped to .header-actions so it outranks the later `.btn { display: inline-flex }`.
   On phones the sticky bottom bar already carries the call. */
.header-actions .header-call { display: none; letter-spacing: 0.01em; }

@media (min-width: 48rem) {
  .header-actions .header-call { display: inline-flex; }
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: color var(--dur-micro) linear, border-color var(--dur-micro) linear,
              background-color var(--dur-micro) linear;
}

.icon-btn:hover { color: var(--text); border-color: var(--border-strong); background: var(--bg-sunken); }
.icon-btn:active { background: var(--accent-wash); }
.icon-btn svg { width: 20px; height: 20px; }

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

/* Theme toggle shows one icon per theme, chosen with CSS so it is correct
   before any script runs. */
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-sun { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .icon-moon { display: block; }
}

/* Mobile menu panel */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--bg);
  padding-bottom: env(safe-area-inset-bottom);
  visibility: hidden;
  opacity: 0;
  transition: opacity var(--dur-exit) var(--ease-in), visibility 0s linear var(--dur-exit);
}

.mobile-menu[data-open="true"] {
  visibility: visible;
  opacity: 1;
  transition: opacity var(--dur-move) var(--ease-out), visibility 0s;
}

.mobile-menu__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 4.5rem;
  padding: var(--space-3) var(--gutter);
  border-bottom: 1px solid var(--border);
}

.mobile-menu__body {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-6) var(--gutter) var(--space-9);
}

.mobile-nav { display: grid; gap: var(--space-1); }

.mobile-nav__group {
  margin-top: var(--space-6);
  margin-bottom: var(--space-1);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-subtle);
}

.mobile-nav__group:first-child { margin-top: 0; }

.mobile-nav__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 56px;
  padding: var(--space-3) var(--space-3);
  border-bottom: 1px solid var(--border);
  color: var(--text);
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  text-decoration: none;
  opacity: 1;
}

.mobile-nav__link[aria-current="page"] { color: var(--accent-ink); }
.mobile-nav__link svg { width: 18px; height: 18px; color: var(--text-subtle); flex: none; }

.js .mobile-menu[data-open="true"] .mobile-nav__link {
  animation: rise-in var(--dur-enter) var(--ease-out) backwards;
  animation-delay: calc(var(--i, 0) * 40ms + 60ms);
}

/* 06. Buttons + links ------------------------------------------------------ */

a { color: var(--accent-ink); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: var(--space-3) var(--space-6);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  white-space: nowrap;
  transition: background-color var(--dur-micro) linear, color var(--dur-micro) linear,
              border-color var(--dur-micro) linear, transform var(--dur-tap) var(--ease-out),
              box-shadow var(--dur-micro) linear;
}

.btn svg { width: 18px; height: 18px; flex: none; }

.btn:active { transform: scale(0.97); }

.btn-primary {
  background: var(--accent);
  color: var(--accent-contrast);
  box-shadow: var(--shadow-1);
}

.btn-primary:hover { background: var(--accent-hover); box-shadow: var(--shadow-2); }

.btn-secondary {
  background: transparent;
  color: var(--text);
  border-color: var(--border-input);
}

.btn-secondary:hover { background: var(--bg-sunken); border-color: var(--text-subtle); }

.btn-ghost { background: transparent; color: var(--text-muted); padding-inline: var(--space-4); }
.btn-ghost:hover { color: var(--text); background: var(--bg-sunken); }

.section-inverse .btn-secondary {
  color: var(--text-inverse);
  border-color: color-mix(in srgb, var(--text-inverse) 40%, transparent);
}

.section-inverse .btn-secondary:hover {
  background: color-mix(in srgb, var(--text-inverse) 12%, transparent);
  border-color: var(--text-inverse);
}

.btn-lg { min-height: 56px; padding-inline: var(--space-7); font-size: var(--step-0); }
.btn-block { width: 100%; }

/* nowrap keeps normal labels tidy, but a long CTA on a 320px phone has to be
   allowed to wrap or it pushes the whole page sideways. */
@media (max-width: 30rem) {
  .btn { white-space: normal; text-align: center; max-width: 100%; }
  .btn-lg { padding-inline: var(--space-5); }
  .feature-band { padding: var(--space-5); }
}

.btn[aria-disabled="true"], .btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

.btn[data-loading="true"] .btn__label { opacity: 0.6; }

.spinner {
  width: 16px; height: 16px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}

/* Text link with a moving underline — transform only, no layout shift. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--accent-ink);
  text-decoration: none;
}

.link-arrow svg {
  width: 16px; height: 16px;
  transition: transform var(--dur-move) var(--ease-out);
}

.link-arrow:hover svg { transform: translateX(4px); }
.link-arrow span { text-decoration: underline; text-underline-offset: 0.2em; }

/* 07. Belt rail + section furniture --------------------------------------- */

/* The belt rail is the site's signature: the IBJJF belt order used as a
   structural rule instead of a decorative gradient. */
.belt-rail {
  display: flex;
  width: 100%;
  height: 4px;
  border-radius: 2px;
  overflow: hidden;
}

.belt-rail span { flex: 1; }
.belt-rail span:nth-child(1) { background: var(--belt-white); box-shadow: inset 0 0 0 1px var(--border); }
.belt-rail span:nth-child(2) { background: var(--belt-blue); }
.belt-rail span:nth-child(3) { background: var(--belt-purple); }
.belt-rail span:nth-child(4) { background: var(--belt-brown); }
.belt-rail span:nth-child(5) { background: var(--belt-black); }

.belt-rail--short { max-width: 7rem; }

/* Scroll progress, transform-driven so it never triggers layout. */
.scroll-progress {
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  height: 3px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
  z-index: var(--z-toast);
  pointer-events: none;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.3rem var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  font-size: var(--step--2);
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-muted);
}

.badge svg { width: 13px; height: 13px; flex: none; }

/* Meaning never rests on colour alone — every badge carries an icon and words. */
.badge-beginner { background: var(--ok-wash); border-color: color-mix(in srgb, var(--ok) 35%, transparent); color: var(--ok); }
.badge-accent { background: var(--accent-wash); border-color: color-mix(in srgb, var(--accent) 30%, transparent); color: var(--accent-ink); }
.badge-todo { background: var(--warn-wash); border-color: color-mix(in srgb, var(--warn) 35%, transparent); color: var(--warn); }

/* Pre-launch only. Deleting the element from each page removes it entirely —
   see README.md § Going live. */
.preview-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--gutter);
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--border);
  color: var(--text-subtle);
  font-size: 0.75rem;
  line-height: 1.45;
  text-align: center;
}

.preview-banner svg { width: 14px; height: 14px; flex: none; color: var(--text-subtle); }
.preview-banner strong { color: var(--text-muted); }

.notice {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border: 0;
  border-left: 2px solid var(--border-strong);
  border-radius: 0;
  background: transparent;
  color: var(--text-subtle);
  font-size: var(--step--1);
}

.notice svg { width: 18px; height: 18px; flex: none; color: var(--text-subtle); margin-top: 3px; }
.notice strong { display: block; margin-bottom: var(--space-1); color: var(--text-muted); }
.notice a { color: var(--text); }

/* 08. Hero ----------------------------------------------------------------- */

/* Deliberately asymmetric: copy sits in a left column, the image bleeds off the
   right edge, and a live "today" card overlaps the seam. Not a centred hero. */
.hero {
  position: relative;
  padding-block: clamp(2.5rem, 1rem + 6vw, 5rem) 0;
  overflow: clip;
}

.hero__grid {
  display: grid;
  gap: var(--space-7);
  align-items: center;
}

@media (min-width: 64rem) {
  .hero__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: var(--space-8);
    padding-block-end: var(--space-10);
  }
}

.hero__copy { max-width: 34rem; }

.hero h1 {
  font-size: var(--step-5);
  font-weight: 800;
  letter-spacing: -0.035em;
  margin-block: var(--space-4) var(--space-5);
}

.hero h1 em {
  font-style: normal;
  color: var(--accent-ink);
}

.hero__actions { margin-block-start: var(--space-7); }

.hero__proof {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  margin-block-start: var(--space-7);
  padding-block-start: var(--space-5);
  border-top: 1px solid var(--border);
  font-size: var(--step--1);
  color: var(--text-muted);
}

.hero__media { position: relative; }

@media (min-width: 64rem) {
  /* Bleed the image to the viewport edge without causing horizontal scroll. */
  .hero__media { margin-inline-end: calc(-1 * var(--gutter)); }
}

@media (min-width: 90rem) {
  .hero__media {
    margin-inline-end: calc((var(--container) - 100vw) / 2 - var(--gutter));
  }
}

.hero__card {
  position: relative;
  margin-top: calc(-1 * var(--space-8));
  margin-inline: var(--gutter);
  padding: var(--space-5);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  z-index: var(--z-raised);
}

@media (min-width: 64rem) {
  .hero__card {
    position: absolute;
    left: calc(-1 * var(--space-8));
    bottom: var(--space-7);
    width: 19rem;
    margin: 0;
  }
}

.hero__card h2 {
  font-family: var(--font-body);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-subtle);
  margin-bottom: var(--space-4);
}

.today-list { display: grid; gap: var(--space-3); }

.today-list li {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: var(--space-3);
  align-items: baseline;
  font-size: var(--step--1);
}

.today-list time {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
}

.today-list span { color: var(--text-muted); }

/* The empty state is prose, not a time/name pair — let it use the full width. */
.today-list li.today-empty {
  grid-template-columns: 1fr;
  color: var(--text-muted);
}

/* -- Feature band: the two-location membership offer ---------------------- */

.feature-band {
  display: grid;
  gap: var(--space-7);
  padding: var(--space-7);
  background: var(--accent-wash);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
  border-radius: var(--radius-lg);
}

@media (min-width: 60rem) {
  .feature-band {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: var(--space-8);
    padding: var(--space-8);
    align-items: center;
  }
}

.venue-list { display: grid; gap: var(--space-4); }

.venue-list li {
  padding: var(--space-5);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.venue-list__tag {
  display: inline-block;
  margin-bottom: var(--space-2);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

.venue-list__addr { font-size: var(--step--1); color: var(--text); }
.venue-list__days { font-size: var(--step--1); color: var(--text-muted); margin-top: var(--space-1); }

/* 09. Cards, programs, instructors ---------------------------------------- */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform var(--dur-move) var(--ease-out),
              box-shadow var(--dur-move) var(--ease-out),
              border-color var(--dur-micro) linear;
}

.card__body { padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-3); flex: 1; }
.card__body > .cluster { margin-top: auto; padding-top: var(--space-2); }

/* A card's heading level follows the page outline, not the card — style both. */
.card :is(h2, h3) { font-size: var(--step-1); line-height: var(--leading-snug); }

.card p { font-size: var(--step--1); color: var(--text-muted); }

.card-link:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); border-color: var(--border-strong); }
.card-link:has(a:focus-visible) { box-shadow: var(--shadow-2); }

/* Whole card clickable, but the accessible name comes from the real link. */
.card-link .stretched::after {
  content: "";
  position: absolute;
  inset: 0;
}

.program-card .photo-slot { aspect-ratio: 4 / 3; }

.instructor-card .photo-slot { aspect-ratio: 3 / 4; }

.card__body dl {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-2) var(--space-4);
  font-size: var(--step--1);
  margin-block: var(--space-2);
}

.card__body dt { color: var(--text-subtle); font-weight: 500; }
.card__body dd { color: var(--text); margin: 0; }

.step-list { counter-reset: step; display: grid; gap: var(--space-5); }

.step-list > li {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-4) var(--space-5);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--border);
}

.step-list > li:last-child { border-bottom: 0; padding-bottom: 0; }

.step-list > li::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  grid-row: span 2;
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.step-list h3 { font-size: var(--step-1); margin-bottom: var(--space-2); }
.step-list p { color: var(--text-muted); max-width: 58ch; }
.step-list .step-time {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-subtle);
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--space-1);
}

/* 10. Photo slots + placeholders ------------------------------------------ */

/* Every image slot reserves its box with aspect-ratio so nothing shifts, and
   ships a designed gi-weave placeholder rather than a grey rectangle. */
.photo-slot {
  position: relative;
  aspect-ratio: 3 / 2;
  background-color: var(--bg-sunken);
  background-image:
    repeating-linear-gradient(45deg,
      color-mix(in srgb, var(--accent) 8%, transparent) 0 2px,
      transparent 2px 7px),
    repeating-linear-gradient(-45deg,
      color-mix(in srgb, var(--accent) 6%, transparent) 0 2px,
      transparent 2px 7px);
  overflow: hidden;
  display: grid;
  place-items: center;
  isolation: isolate;
}

.photo-slot img { width: 100%; height: 100%; object-fit: cover; }

.photo-slot__label {
  position: absolute;
  left: var(--space-3);
  bottom: var(--space-3);
  padding: 0.25rem var(--space-3);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  border: 1px solid var(--border);
  color: var(--text-subtle);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-family: var(--font-body);
}

.photo-slot__icon { width: 44px; height: 44px; color: var(--border-strong); }

.photo-slot--hero { aspect-ratio: 4 / 5; border-radius: var(--radius-lg); }

@media (min-width: 64rem) {
  .photo-slot--hero { aspect-ratio: 3 / 4; border-radius: var(--radius-lg) 0 0 var(--radius-lg); }
}

.photo-slot--wide { aspect-ratio: 16 / 9; border-radius: var(--radius-lg); }
.photo-slot--square { aspect-ratio: 1; border-radius: var(--radius); }

/* Content the gym still has to supply. Styled so it reads as an intentional
   slot, never as finished copy. */
.placeholder {
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--bg-sunken);
  padding: var(--space-6);
  display: grid;
  gap: var(--space-3);
}

.placeholder__tag {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-subtle);
}

.placeholder__tag svg { width: 14px; height: 14px; }
.placeholder p { color: var(--text-muted); font-size: var(--step--1); }
.placeholder .fill { color: var(--text); font-weight: 600; }

/* Inline "not confirmed yet" marker for single facts. */
.tbc {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  padding: 0.05em 0.4em;
  border-radius: var(--radius-sm);
  /* Neutral, not amber. A pending value should read as a quiet gap, not as a
     warning sticker plastered over a finished design. */
  background: color-mix(in srgb, var(--text-subtle) 12%, transparent);
  border: 0;
  /* --text-subtle on a sunken surface lands at 4.49:1, a hair under AA. */
  color: var(--text-muted);
  font-size: 0.9em;
  font-weight: 600;
  font-family: var(--font-body);
  /* Must wrap: this marker sometimes holds a short "TBC" and sometimes a whole
     sentence, and a nowrap sentence forces its grid track wider than the page. */
  white-space: normal;
}

/* 11. Schedule ------------------------------------------------------------- */

.schedule-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-5);
  border-block: 1px solid var(--border);
  margin-block-end: var(--space-6);
}

.filter-group { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }

.filter-group__label {
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-subtle);
  margin-inline-end: var(--space-2);
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-muted);
  font-size: var(--step--1);
  font-weight: 500;
  cursor: pointer;
  touch-action: manipulation;
  transition: background-color var(--dur-micro) linear, color var(--dur-micro) linear,
              border-color var(--dur-micro) linear;
}

.chip:hover { color: var(--text); background: var(--bg-sunken); }

.chip[aria-pressed="true"], .chip[aria-selected="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
  font-weight: 600;
}

.chip svg { width: 14px; height: 14px; }

/* Day tabs: the mobile view of the week. Real tab semantics, keyboard driven. */
.day-tabs {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  padding-block-end: var(--space-3);
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.day-tabs::-webkit-scrollbar { height: 4px; }
.day-tabs::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 2px; }

.day-tab {
  scroll-snap-align: start;
  flex: none;
  display: grid;
  gap: 2px;
  justify-items: center;
  min-width: 4.25rem;
  min-height: 60px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--text-muted);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  touch-action: manipulation;
  transition: background-color var(--dur-micro) linear, color var(--dur-micro) linear,
              border-color var(--dur-micro) linear;
}

.day-tab .day-num {
  font-size: var(--step-1);
  font-family: var(--font-display);
  letter-spacing: 0;
  text-transform: none;
  font-variant-numeric: tabular-nums;
}

.day-tab[aria-selected="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

.day-tab[data-today="true"]:not([aria-selected="true"]) { border-color: var(--accent); color: var(--accent-ink); }

@media (min-width: 64rem) { .day-tabs { display: none; } }

.schedule-day { display: grid; gap: var(--space-3); }
.schedule-day[hidden] { display: none; }

@media (min-width: 64rem) {
  /* Desktop: all seven days visible as columns. */
  .schedule-week {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: var(--space-3);
    align-items: start;
  }
  .schedule-day, .schedule-day[hidden] { display: grid; }
  .schedule-day { gap: var(--space-2); }
}

.schedule-day__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 2px solid var(--border);
  margin-bottom: var(--space-1);
}

.schedule-day__head :is(h2, h3) { font-size: var(--step-1); }

@media (min-width: 64rem) {
  .schedule-day__head :is(h2, h3) { font-size: var(--step-0); font-family: var(--font-body); font-weight: 600; }
}

.schedule-day[data-today="true"] .schedule-day__head { border-bottom-color: var(--accent); }

.schedule-day[data-today="true"] .schedule-day__head :is(h2, h3)::after {
  content: "Today";
  display: inline-block;
  margin-inline-start: var(--space-2);
  padding: 0.1rem 0.5rem;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-contrast);
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  vertical-align: middle;
}

.class-block {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
  transition: border-color var(--dur-micro) linear, background-color var(--dur-micro) linear;
}

.class-block:hover { border-color: var(--border-strong); background: var(--bg-sunken); }
/* The left edge encodes venue, matching the legend swatches. */
.class-block[data-venue="carlingford"] { border-left-color: var(--accent); }
.class-block[data-venue="sevenhills"] { border-left-color: var(--belt-purple); }
.class-block[hidden] { display: none; }

.class-block time {
  font-size: var(--step--1);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.class-block .class-name { font-size: var(--step--1); color: var(--text); font-weight: 500; }
.class-block .class-meta { font-size: var(--step--2); color: var(--text-subtle); }

.class-block .badge {
  justify-self: start;
  margin-top: var(--space-1);
  padding-block: 0.15rem;
  font-size: 0.6875rem;
}

.schedule-empty {
  padding: var(--space-5);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-subtle);
  font-size: var(--step--1);
  text-align: center;
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  font-size: var(--step--1);
  color: var(--text-muted);
}

.legend__item { display: inline-flex; align-items: center; gap: var(--space-2); }

.legend__swatch {
  width: 3px;
  height: 1.1em;
  border-radius: 2px;
  background: var(--border-strong);
  flex: none;
}

/* 12. Testimonials + trust bar -------------------------------------------- */

.trust-bar {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: var(--space-5) var(--space-6);
  padding-block: var(--space-7);
  border-block: 1px solid var(--border);
}

.trust-item { display: grid; gap: var(--space-1); }

.trust-item__value {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

/* A pending value should read as an empty slot, not as a headline. */
.trust-item__value .tbc { font-size: 0.5em; vertical-align: middle; }

.trust-item__label {
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-subtle);
}

.quote {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  height: 100%;
}

.quote blockquote {
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--text);
  flex: 1;
}

.quote figcaption {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--step--1);
  color: var(--text-muted);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}

.quote .avatar {
  width: 42px; height: 42px;
  border-radius: 50%;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  display: grid;
  place-items: center;
  flex: none;
  color: var(--text-subtle);
}

.quote .avatar svg { width: 20px; height: 20px; }

.rating { display: inline-flex; align-items: center; gap: var(--space-2); }
.rating svg { width: 16px; height: 16px; color: var(--accent); }

/* 13. Forms ---------------------------------------------------------------- */

.form { display: grid; gap: var(--space-5); }

.field { display: grid; gap: var(--space-2); }

.field label {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--text);
}

.field .req { color: var(--accent-ink); }

.field .hint {
  font-size: var(--step--2);
  color: var(--text-subtle);
  line-height: 1.5;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 48px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--text);
  font-size: 1rem; /* 16px — stops iOS zooming the page on focus */
  transition: border-color var(--dur-micro) linear, box-shadow var(--dur-micro) linear;
}

.field textarea { min-height: 8rem; resize: vertical; line-height: 1.55; }

.field select {
  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='%236d6355' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  background-size: 18px;
  padding-inline-end: var(--space-9);
}

.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--text-subtle); }

.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 1px;
  border-color: var(--focus);
}

.field input[aria-invalid="true"],
.field select[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
  border-color: var(--accent);
  box-shadow: inset 3px 0 0 var(--accent);
}

.field-error {
  display: none;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--step--2);
  font-weight: 600;
  color: var(--accent-ink);
}

.field-error svg { width: 14px; height: 14px; flex: none; }
/* Grouped controls (checkbox/radio sets) carry the state on the fieldset,
   so the error has to key off both. */
.field[data-invalid="true"] .field-error,
fieldset[data-invalid="true"] .field-error { display: flex; }

.error-summary {
  padding: var(--space-5);
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent-wash);
  color: var(--text);
}

.error-summary[hidden] { display: none; }
.error-summary h2 { font-size: var(--step-1); margin-bottom: var(--space-3); }
.error-summary ul { display: grid; gap: var(--space-2); padding-left: var(--space-5); }
.error-summary a { color: var(--accent-ink); font-weight: 600; }

.form-success {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-6);
  border: 1px solid color-mix(in srgb, var(--ok) 40%, transparent);
  border-radius: var(--radius);
  background: var(--ok-wash);
}

.form-success[hidden] { display: none; }
.form-success svg { width: 28px; height: 28px; color: var(--ok); }
.form-success h2 { font-size: var(--step-2); }

/* The same block reports failure and the not-yet-connected state. A green
   tick above "That didn’t send" reads as success at a glance, so recolour
   by state rather than adding a second component. */
.form-success[data-state="error"] {
  border-color: color-mix(in srgb, var(--warn) 45%, transparent);
  background: var(--warn-wash);
}
.form-success[data-state="error"] svg { color: var(--warn); }

.form-success[data-state="unconfigured"] {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: var(--accent-wash);
}
.form-success[data-state="unconfigured"] svg { color: var(--accent); }

fieldset { border: 0; padding: 0; }
legend { font-weight: 600; font-size: var(--step--1); padding: 0; margin-bottom: var(--space-3); }

.choice-row { display: grid; gap: var(--space-2); }

.choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-height: 48px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  cursor: pointer;
  font-size: var(--step--1);
  transition: border-color var(--dur-micro) linear, background-color var(--dur-micro) linear;
}

.choice:hover { border-color: var(--border-strong); }
.choice input { width: 20px; height: 20px; min-height: 0; accent-color: var(--accent); flex: none; margin-top: 2px; }
.choice:has(input:checked) { border-color: var(--accent); background: var(--accent-wash); }

/* 14. FAQ / accordion ------------------------------------------------------ */

.faq { display: grid; gap: 0; border-top: 1px solid var(--border); }

.faq details {
  border-bottom: 1px solid var(--border);
}

.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 60px;
  padding: var(--space-4) 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--text);
  transition: color var(--dur-micro) linear;
}

.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent-ink); }

.faq summary .chevron {
  width: 20px; height: 20px;
  flex: none;
  color: var(--text-subtle);
  transition: transform var(--dur-move) var(--ease-out);
}

.faq details[open] summary .chevron { transform: rotate(180deg); }

.faq__answer { padding-bottom: var(--space-5); max-width: 62ch; }
.faq__answer p + p { margin-top: var(--space-3); }
.faq__answer { color: var(--text-muted); }

/* 15. Pricing -------------------------------------------------------------- */

.price-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  align-items: stretch;
}

.price-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.price-card[data-featured="true"] {
  border-color: var(--accent);
  border-width: 2px;
  box-shadow: var(--shadow-2);
}

.price-card__amount {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.price-card__amount .per {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--text-subtle);
}

/* align-content keeps the rows packed at the top. Without it the grid stretches
   to fill the card, so a 3-item list sits at wider spacing than a 4-item one
   sitting beside it. */
.tick-list { display: grid; gap: var(--space-3); flex: 1; align-content: start; }

.tick-list li {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: var(--space-3);
  align-items: start;
  font-size: var(--step--1);
  color: var(--text-muted);
}

.tick-list svg { width: 18px; height: 18px; margin-top: 3px; color: var(--ok); }
.tick-list li[data-excluded="true"] svg { color: var(--text-subtle); }
.tick-list li[data-excluded="true"] { color: var(--text-subtle); }

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  -webkit-overflow-scrolling: touch;
}

table { border-collapse: collapse; width: 100%; font-size: var(--step--1); }

th, td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

thead th {
  background: var(--bg-sunken);
  font-weight: 600;
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-subtle);
  white-space: nowrap;
}

tbody tr:last-child td { border-bottom: 0; }
td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* 16. Blog + prose --------------------------------------------------------- */

.post-card .photo-slot { aspect-ratio: 16 / 10; }
.post-card__meta { display: flex; flex-wrap: wrap; gap: var(--space-3); font-size: var(--step--2); color: var(--text-subtle); }

.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--space-5); }
.prose h2 { font-size: var(--step-3); margin-top: var(--space-9); }
.prose h3 { font-size: var(--step-2); margin-top: var(--space-7); }
.prose ul, .prose ol { display: grid; gap: var(--space-3); padding-left: var(--space-6); }
.prose li::marker { color: var(--accent); }
.prose blockquote {
  border-left: 3px solid var(--accent);
  padding-left: var(--space-5);
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--text);
}
.prose strong { font-weight: 600; color: var(--text); }
.prose hr { border: 0; border-top: 1px solid var(--border); margin-block: var(--space-8); }

.breadcrumb { font-size: var(--step--2); color: var(--text-subtle); margin-bottom: var(--space-5); }
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; padding: 0; list-style: none; }
.breadcrumb li:not(:last-child)::after { content: "/"; margin-inline-start: var(--space-2); color: var(--border-strong); }
.breadcrumb a { color: var(--text-subtle); }
.breadcrumb a:hover { color: var(--text); }

.page-head { padding-block: var(--space-8) var(--space-7); }
.page-head h1 { max-width: 20ch; margin-bottom: var(--space-5); }

/* 17. Footer + mobile action bar ------------------------------------------ */

.site-footer {
  background: var(--bg-inverse);
  color: var(--text-inverse);
  padding-block: var(--space-9) var(--space-7);
  margin-top: var(--section-y);
}

.site-footer a { color: color-mix(in srgb, var(--text-inverse) 78%, transparent); text-decoration: none; }
.site-footer a:hover { color: var(--text-inverse); text-decoration: underline; }

/* Above phones the groups stay open and read as plain columns. They carry
   the open attribute from the markup, and site.js only collapses them below
   this width — so with JavaScript off, every link is still reachable. */
@media (min-width: 40rem) {
  .footer-group > summary { cursor: default; pointer-events: none; }
  .footer-group__chev { display: none; }
}

.footer-grid {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

/* Footer link groups collapse on phones. On a 375px screen the expanded
   footer ran 1299px — 1.6 screens of links below the content. Native
   <details>, so no JavaScript and it still works if CSS fails. */
.footer-group > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  cursor: pointer;
  list-style: none;
}
.footer-group > summary::-webkit-details-marker { display: none; }
.footer-group > summary h2 { margin-bottom: 0; }
.footer-group__chev {
  width: 18px; height: 18px; flex: none;
  color: color-mix(in srgb, var(--text-inverse) 55%, transparent);
  transition: transform var(--dur-micro) ease;
}
.footer-group[open] > summary .footer-group__chev { transform: rotate(180deg); }

.footer-grid h2 {
  font-family: var(--font-body);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--text-inverse) 60%, transparent);
  margin-bottom: var(--space-4);
}

.footer-grid ul { display: grid; gap: var(--space-3); font-size: var(--step--1); }
.footer-grid li a { display: inline-flex; min-height: 32px; align-items: center; }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-6);
  justify-content: space-between;
  align-items: center;
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid color-mix(in srgb, var(--text-inverse) 18%, transparent);
  font-size: var(--step--2);
  color: color-mix(in srgb, var(--text-inverse) 62%, transparent);
}

.footer-bottom__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-6);
}

.footer-credit {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}
.footer-credit svg { width: 13px; height: 13px; flex-shrink: 0; }
.footer-credit:hover { color: var(--text-inverse); }

.social-row { display: flex; gap: var(--space-2); }

.social-row a {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border: 1px solid color-mix(in srgb, var(--text-inverse) 22%, transparent);
  border-radius: var(--radius);
  transition: background-color var(--dur-micro) linear, border-color var(--dur-micro) linear;
}

.social-row a:hover {
  background: color-mix(in srgb, var(--text-inverse) 12%, transparent);
  border-color: var(--text-inverse);
  text-decoration: none;
}

.social-row svg { width: 20px; height: 20px; }

/* Persistent mobile conversion bar. Sits above the home indicator. */
.action-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--z-sticky);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-3);
  padding: var(--space-3) var(--gutter);
  padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
  transform: translateY(110%);
  transition: transform var(--dur-move) var(--ease-out);
}

.action-bar[data-visible="true"] { transform: translateY(0); }
.no-js .action-bar { transform: translateY(0); }

@media (min-width: 48rem) { .action-bar { display: none; } }

/* Reserve room so the bar never covers the end of the page or a focused field. */
@media (max-width: 47.99rem) {
  body { padding-bottom: calc(4.75rem + env(safe-area-inset-bottom)); }
}

.action-bar .icon-btn { width: 48px; height: 48px; border-color: var(--border-strong); }

/* 20. Navigation menus ----------------------------------------------------- */

/* Desktop dropdowns open on hover and on keyboard focus, so they work with
   scripting disabled. JS only adds Escape-to-close. */
.nav__item { position: relative; display: flex; }

.nav__menu {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 15rem;
  padding: var(--space-2);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  display: grid;
  gap: 2px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--dur-micro) linear, transform var(--dur-move) var(--ease-out),
              visibility 0s linear var(--dur-micro);
  z-index: var(--z-header);
}

.nav__item:hover .nav__menu,
.nav__item:focus-within .nav__menu,
.nav__item[data-open="true"] .nav__menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition-delay: 0s;
}

.nav__menu a {
  display: grid;
  gap: 1px;
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: var(--step--1);
  font-weight: 600;
  text-decoration: none;
}

.nav__menu a small {
  font-weight: 400;
  font-size: var(--step--2);
  color: var(--text-subtle);
}

.nav__menu a:hover { background: var(--accent-wash); color: var(--accent-ink); }
.nav__menu a:hover small { color: var(--accent-ink); }

.nav__link .caret { width: 14px; height: 14px; margin-left: 2px; opacity: .65; }

/* 21. Philosophy ----------------------------------------------------------- */

.split-head {
  display: grid;
  gap: var(--space-5);
  padding-block-end: var(--space-8);
}

@media (min-width: 60rem) {
  .split-head {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-9);
    align-items: start;
  }
}

/* Deliberately a step down from a full section head: this is meant to be read
   quickly, not admired. */
.split-head h2 { font-size: var(--step-3); }
.split-head__lede { font-size: var(--step-0); line-height: 1.6; color: var(--text-muted); max-width: 46ch; }
.split-head__lede + p { margin-top: var(--space-4); color: var(--text-muted); font-size: var(--step--1); }

/* Principles sit in one row divided by hairlines rather than boxed cards. */
.principles {
  display: grid;
  gap: var(--space-6);
  border-top: 1px solid var(--border);
  padding-top: var(--space-7);
}

@media (min-width: 60rem) {
  .principles {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
  }
  .principles > * + * {
    border-left: 1px solid var(--border);
    padding-left: var(--space-7);
    margin-left: var(--space-7);
  }
}

@media (max-width: 59.99rem) {
  .principles > * + * { border-top: 1px solid var(--border); padding-top: var(--space-6); }
}

.principle__num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--accent-ink);
  margin-bottom: var(--space-3);
  font-variant-numeric: tabular-nums;
}

.principle h3 { font-size: var(--step-1); margin-bottom: var(--space-2); }
.principle p { color: var(--text-muted); font-size: var(--step--1); max-width: 34ch; }

/* -- Kids band: the parents' pitch, directly under the hero --------------- */

.kids-band__grid { display: grid; gap: var(--space-7); }

@media (min-width: 62rem) {
  .kids-band__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-9);
    align-items: center;
  }
}

.kids-band h2 { font-size: var(--step-4); color: var(--text-inverse); }

.kids-band__claim {
  margin-top: var(--space-5);
  font-size: var(--step-1);
  line-height: 1.5;
  color: color-mix(in srgb, var(--text-inverse) 82%, transparent);
  max-width: 40ch;
}

.kids-band__claim strong { color: var(--text-inverse); }

.kids-band__facts {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.kids-fact {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-5);
  border: 1px solid color-mix(in srgb, var(--text-inverse) 20%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--text-inverse) 6%, transparent);
}

.kids-fact__value {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.kids-fact__label {
  font-size: var(--step--2);
  line-height: 1.45;
  color: color-mix(in srgb, var(--text-inverse) 74%, transparent);
}

/* On a dark band the light-mode brand blue is too dark to read. */
.section-inverse .kids-fact__value { color: #7fb2ec; }

/* -- Pull quote: breaks a long read into chapters ------------------------- */

.pullquote {
  margin-block: var(--space-7);
  padding-left: var(--space-6);
  border-left: 2px solid var(--accent);
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.025em;
  color: var(--text);
  max-width: 24ch;
}

@media (min-width: 60rem) {
  .pullquote { max-width: 20ch; }
}

/* -- Lineage chain -------------------------------------------------------- */

.lineage { display: grid; gap: 0; counter-reset: none; }

.lineage li {
  position: relative;
  display: grid;
  gap: var(--space-1);
  padding: var(--space-4) 0 var(--space-4) var(--space-7);
}

/* The connecting rail and node, drawn rather than imaged. */
.lineage li::before {
  content: "";
  position: absolute;
  left: 7px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--border-strong);
}

.lineage li:first-child::before { top: 50%; }
.lineage li:last-child::before { bottom: 50%; }

.lineage li::after {
  content: "";
  position: absolute;
  left: 0;
  top: calc(50% - 8px);
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--bg-sunken);
  border: 3px solid var(--border-strong);
}

.lineage li:last-child::after { border-color: var(--accent); background: var(--accent); }

.lineage__name {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 700;
  letter-spacing: -0.02em;
}

.lineage li:last-child .lineage__name { color: var(--accent-ink); }
.lineage__note { font-size: var(--step--1); color: var(--text-muted); }

/* -- Impact block: claim, contrast, conclusion ---------------------------- */

.impact { display: grid; gap: var(--space-8); }
.impact__head { max-width: 46rem; }
.impact h2 { font-size: var(--step-4); color: var(--text-inverse); }

.impact__claim {
  margin-top: var(--space-5);
  font-size: var(--step-1);
  line-height: 1.45;
  color: color-mix(in srgb, var(--text-inverse) 84%, transparent);
  max-width: 34ch;
}

.contrast { display: grid; gap: var(--space-4); }

@media (min-width: 48rem) {
  .contrast { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-5); }
}

.contrast__col {
  padding: var(--space-6);
  border: 1px solid color-mix(in srgb, var(--text-inverse) 18%, transparent);
  border-radius: var(--radius-lg);
}

.contrast__col--good {
  border-color: color-mix(in srgb, #7fb2ec 55%, transparent);
  background: color-mix(in srgb, #7fb2ec 10%, transparent);
}

.contrast__title {
  font-family: var(--font-display);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid color-mix(in srgb, var(--text-inverse) 18%, transparent);
}

.contrast__title--bad  { color: color-mix(in srgb, var(--text-inverse) 60%, transparent); }
.contrast__title--good { color: #7fb2ec; }

.contrast__col ul { display: grid; gap: var(--space-3); list-style: none; padding: 0; }

.contrast__col li {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: color-mix(in srgb, var(--text-inverse) 66%, transparent);
}

.contrast__col--good li { color: var(--text-inverse); }

.impact__close {
  font-size: var(--step-1);
  line-height: 1.55;
  color: color-mix(in srgb, var(--text-inverse) 76%, transparent);
  max-width: 52ch;
}

.impact__close strong { color: var(--text-inverse); }

/* -- Compact class list --------------------------------------------------- */

.class-list { display: grid; gap: var(--space-4); }

.class-list li {
  display: grid;
  gap: var(--space-1);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
}

.class-list li:last-child { border-bottom: 0; padding-bottom: 0; }

.class-list__name {
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: 700;
  letter-spacing: -0.015em;
}

.class-list__when {
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

.class-list__note { font-size: var(--step--1); color: var(--text-muted); }

.class-list__link {
  justify-self: start;
  font-size: var(--step--2);
  font-weight: 600;
  /* 44px in both directions — a short label like "Details" is only ~40px wide. */
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
}

/* 22. Steps (First day) ---------------------------------------------------- */

.steps { display: grid; gap: var(--space-5); counter-reset: stepnum; }

@media (min-width: 52rem) {
  .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.step-card {
  position: relative;
  display: grid;
  gap: var(--space-3);
  padding: var(--space-6);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.step-card__badge {
  counter-increment: stepnum;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-contrast);
  font-family: var(--font-display);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.step-card__badge::after { content: counter(stepnum); }
.step-card h3 { font-size: var(--step-1); }
.step-card p { color: var(--text-muted); font-size: var(--step--1); }

/* 23. FAQ split ------------------------------------------------------------ */

.faq-split { display: grid; gap: var(--space-7); }

@media (min-width: 62rem) {
  .faq-split {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: var(--space-9);
    align-items: start;
  }
  .faq-split__aside { position: sticky; top: 7rem; }
}

.faq-split .faq { border-top: 1px solid var(--border); }

/* 24. Explore grid (home page menu) ---------------------------------------- */

.explore-grid {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.explore-card {
  position: relative;
  display: grid;
  gap: var(--space-2);
  align-content: start;
  padding: var(--space-5);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--text);
  transition: transform var(--dur-move) var(--ease-out),
              border-color var(--dur-micro) linear,
              box-shadow var(--dur-move) var(--ease-out);
}

.explore-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: var(--shadow-2);
}

.explore-card__icon {
  width: 22px; height: 22px;
  color: var(--accent);
  margin-bottom: var(--space-1);
}

.explore-card strong { font-family: var(--font-display); font-size: var(--step-0); letter-spacing: -0.015em; }
.explore-card span { font-size: var(--step--2); color: var(--text-subtle); line-height: 1.5; }

/* 25. Stat row ------------------------------------------------------------- */

.stat-row {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  padding: var(--space-7);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.stat { display: grid; gap: var(--space-2); }

.stat__value {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
}

.stat__label { font-size: var(--step--1); color: var(--text-muted); line-height: 1.45; }

/* 26. Sticky aside card ---------------------------------------------------- */

@media (min-width: 62rem) {
  .sticky-card { position: sticky; top: 7rem; }
}

/* 27. Prep stages ---------------------------------------------------------- */

.stage-list { display: grid; gap: var(--space-4); counter-reset: stage; }

.stage {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-4) var(--space-5);
  align-items: start;
  padding: var(--space-5);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
}

.stage::before {
  counter-increment: stage;
  content: counter(stage, decimal-leading-zero);
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.stage h3 { font-size: var(--step-1); margin-bottom: var(--space-2); }
.stage p { color: var(--text-muted); font-size: var(--step--1); }

/* 28. Gallery + lightbox --------------------------------------------------- */

/* CSS columns give a true masonry flow without JS or fixed row heights. */
.masonry {
  column-count: 1;
  column-gap: var(--space-4);
}

@media (min-width: 40rem)  { .masonry { column-count: 2; } }
@media (min-width: 64rem)  { .masonry { column-count: 3; } }
@media (min-width: 90rem)  { .masonry { column-count: 4; } }

.masonry > * {
  break-inside: avoid;
  margin-bottom: var(--space-4);
}

.gallery-item {
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-sunken);
  cursor: zoom-in;
  text-align: left;
  transition: transform var(--dur-move) var(--ease-out),
              box-shadow var(--dur-move) var(--ease-out),
              border-color var(--dur-micro) linear;
}

.gallery-item:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); border-color: var(--accent); }
.gallery-item .photo-slot { border-radius: 0; }
.gallery-item figcaption {
  padding: var(--space-3) var(--space-4);
  font-size: var(--step--2);
  color: var(--text-muted);
  background: var(--bg-raised);
}

.gallery-empty,
.gallery-loading {
  display: grid;
  place-items: center;
  gap: var(--space-4);
  padding: var(--space-10) var(--space-5);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  color: var(--text-subtle);
  text-align: center;
}

.gallery-empty[hidden], .gallery-loading[hidden] { display: none; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--space-4);
  padding: var(--space-4);
  padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
  /* Measured against the real photo behind it, not a reused token opacity. */
  background: rgba(6, 12, 20, 0.92);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  visibility: hidden;
  opacity: 0;
  transition: opacity var(--dur-exit) var(--ease-in), visibility 0s linear var(--dur-exit);
}

.lightbox[data-open="true"] {
  visibility: visible;
  opacity: 1;
  transition: opacity var(--dur-move) var(--ease-out), visibility 0s;
}

.lightbox__bar { display: flex; justify-content: flex-end; }

.lightbox__close {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-4);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: var(--radius-pill);
  background: transparent;
  color: #fff;
  font-size: var(--step--1);
  font-weight: 600;
  cursor: pointer;
}

.lightbox__close:hover { background: rgba(255, 255, 255, 0.14); border-color: #fff; }
.lightbox__close svg { width: 18px; height: 18px; }

.lightbox__stage { display: grid; place-items: center; min-height: 0; }
.lightbox__stage img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--radius); }

.lightbox__stage .photo-slot {
  width: min(56rem, 100%);
  aspect-ratio: 3 / 2;
  border-radius: var(--radius);
}

.lightbox__caption {
  color: rgba(255, 255, 255, 0.86);
  font-size: var(--step--1);
  text-align: center;
  max-width: 60ch;
  margin-inline: auto;
}

.lightbox__caption:empty { display: none; }

/* ==========================================================================
   29. MOBILE PASS
   Not "the desktop layout, narrower". These are deliberate decisions about
   what a phone should hide, tighten and resize. Most traffic arrives here.
   ========================================================================== */

/* -- Header: Book on mobile, phone + theme on desktop ---------------------- */

.header-actions .header-book { display: inline-flex; padding-inline: var(--space-5); }
.header-actions .theme-toggle { display: none; }
.mobile-menu__head .theme-toggle { display: inline-flex; }

@media (min-width: 48rem) {
  .header-actions .header-book { display: none; }
  .header-actions .theme-toggle { display: inline-flex; }
  .mobile-menu__head .theme-toggle { display: none; }
}

@media (max-width: 47.99rem) {

  /* --- HIDE: things that only make sense with a mouse and a wide screen --- */

  /* Breadcrumbs duplicate the back button and the menu on a phone. */
  .breadcrumb { display: none; }

  /* The tagline collides with the Book button and adds nothing on a phone —
     the wordmark alone is the identity here. */
  .brand__sub { display: none; }
  .brand__name { font-size: 1rem; }

  /* Decorative photo-slot captions add noise in a narrow column. */
  .photo-slot__label { font-size: 0.625rem; padding: 0.15rem var(--space-2); }

  /* The scroll-progress hairline is desktop affordance; the phone has a bar. */
  .scroll-progress { display: none; }

  /* --- TIGHTEN: reclaim vertical space without cramping ------------------- */

  :root {
    --section-y: 3.25rem;
    --space-8: 2.25rem;
    --space-9: 2.75rem;
  }

  .card__body { padding: var(--space-5); }
  .feature-band { gap: var(--space-5); }
  .split-head { padding-block-end: var(--space-6); gap: var(--space-4); }
  .section-head { margin-block-end: var(--space-6); }
  .page-head { padding-block: var(--space-6) var(--space-5); }
  .stack-lg > * + * { margin-block-start: var(--space-5); }
  .principles { padding-top: var(--space-5); }
  .principles > * + * { padding-top: var(--space-5); }

  .site-footer { padding-block: var(--space-7) var(--space-6); margin-top: var(--space-8); }
  /* One column: the collapsed headings are short, and two narrow columns
     were wrapping every link onto a second line. */
  .footer-grid { gap: var(--space-4); grid-template-columns: 1fr; }
  .footer-group > summary { min-height: 48px; }
  .footer-grid > *:first-child { grid-column: 1 / -1; }
  .footer-grid ul { gap: var(--space-2); font-size: 0.8125rem; }
  .footer-grid li a { min-height: 40px; }

  .preview-banner { text-align: left; padding-block: var(--space-2); }

  /* --- RESIZE: proportions tuned for a hand, not a monitor ---------------- */

  /* A 4:5 hero eats most of a phone screen before any copy appears. */
  /* The hero is a 3:4 portrait dropped into a 5:4 landscape box here, so 176px
     of it is cropped. Centred, that cut the thrown student’s hands and the mat
     out of frame and left the figure floating. Bias the crop downward so the
     whole throw reads, mat included. */
  .photo-slot--hero { aspect-ratio: 5 / 4; }
  .photo-slot--hero img { object-position: 50% 65%; }

  /* Twelve full-width cards is a scroll marathon; two columns is one screen. */
  .explore-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
  .explore-card { padding: var(--space-4); }
  .explore-card strong { font-size: var(--step--1); }
  .explore-card span { display: none; }
  .explore-card__icon { width: 20px; height: 20px; }

  /* A single-column gallery is 14 screens tall. Two reads as a collage. */
  .masonry { column-count: 2; column-gap: var(--space-2); }
  .masonry > * { margin-bottom: var(--space-2); }
  .gallery-item figcaption { padding: var(--space-2) var(--space-3); font-size: 0.6875rem; }

  /* Maps are orientation, not exploration, on a phone. */
  iframe[src*="openstreetmap"] { min-height: 15rem !important; height: 15rem !important; }

  /* Buttons go full width so the thumb has the whole row. */
  .hero__actions .btn,
  .page-head .cluster > .btn { width: 100%; }

  .kids-band__facts { gap: var(--space-2); }
  .kids-fact { padding: var(--space-4); }
  .stat-row { padding: var(--space-5); gap: var(--space-4); }
  .quote { padding: var(--space-5); }
  .price-card { padding: var(--space-5); }
  .contrast__col { padding: var(--space-5); }
  .lineage li { padding-block: var(--space-3); }

  /* Tables scroll rather than shrink to unreadable. */
  .table-wrap table { min-width: 30rem; }
}

/* Very small phones: drop the tagline so the wordmark never truncates. */
@media (max-width: 22.5rem) {
  .header-actions .header-book { padding-inline: var(--space-4); }
}

/* 18. Motion --------------------------------------------------------------- */

/* Reveals only exist when JS is running, so content is visible by default and
   the page is complete with scripting disabled. */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity var(--dur-enter) var(--ease-out),
              transform var(--dur-enter) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

.js [data-reveal].is-revealed {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  will-change: auto;
}

.js [data-reveal="scale"] { transform: translate3d(0, 12px, 0) scale(0.985); }
.js [data-reveal="scale"].is-revealed { transform: none; }

.js [data-reveal="left"] { transform: translate3d(-20px, 0, 0); }
.js [data-reveal="left"].is-revealed { transform: none; }

@keyframes rise-in {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to { opacity: 1; transform: none; }
}

@keyframes spin { to { transform: rotate(360deg); } }

@keyframes hero-settle {
  from { transform: scale(1.06); }
  to { transform: scale(1); }
}

.js .hero .photo-slot > * { animation: hero-settle 1200ms var(--ease-out) both; }

/* Honour the user's setting: keep meaning, drop the movement. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .js [data-reveal] { opacity: 1; transform: none; }
  .action-bar { transform: translateY(0); }
}

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

@media print {
  .site-header, .site-footer, .action-bar, .scroll-progress,
  .day-tabs, .schedule-toolbar, .no-print { display: none !important; }

  :root { --bg: #fff; --bg-raised: #fff; --text: #000; --text-muted: #333; --border: #bbb; }

  body { padding: 0; font-size: 11pt; }

  .schedule-week { display: grid !important; grid-template-columns: repeat(7, 1fr) !important; gap: 6pt; }
  .schedule-day, .schedule-day[hidden] { display: grid !important; }
  .class-block { break-inside: avoid; border: 1px solid #ccc; padding: 4pt 6pt; }
  .class-block[hidden] { display: grid !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
  .section { padding-block: 12pt; }
}
