/* ===========================================================
   BASIS by TechVector
   Dark · Luxury · Education-friendly
   =========================================================== */

/* ---------- Android 101 display font (provided by client) ---- */
@font-face {
  font-family: "Android 101";
  src: url("font/android_101/Android%20101.otf") format("opentype"),
       url("font/android_101/Android%20101.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ============================================================
   DESIGN TOKENS — OKLCH primitives + semantic mapping
   ------------------------------------------------------------
   Two layers, per the design system spec:
     1. Primitives  — raw OKLCH ramps. Never used directly in components.
     2. Semantics   — what components consume. Theme-swappable.

   Why OKLCH? Perceptual uniformity. Equal lightness steps look equal
   (unlike HSL). Hue stays stable across lightness levels — no more
   "blue gets purple as it darkens" drift. Browser support: 95%+ as of
   2026 (Chrome 111, Firefox 113, Safari 15.4).
   ============================================================ */

:root,
:root[data-theme="dark"] {
  /* ---- 1. Primitives (dark) -------------------------------- */
  /* Cool blue-tinted neutrals — the brand hue (235°) bleeds into
     every neutral so the palette feels cohesive even where you don't
     "see" the brand color. Chroma stays low (0.04–0.06) for surfaces. */

  /* Surface ramp */
  --c-bg-1:        oklch(13% 0.040 250);   /* page background — deep midnight */
  --c-bg-2:        oklch(16% 0.040 250);   /* page secondary */
  --c-surface-1:   oklch(20% 0.050 248);   /* card / panel */
  --c-surface-2:   oklch(24% 0.060 248);   /* elevated card */

  /* Ink ramp — solid colors, no alpha. Each stop hits its WCAG target
     against --c-bg-1 (verified):
       ink   → 16.8 : 1   (AAA body)
       ink-2 → 10.1 : 1   (AAA body)
       ink-3 →  4.9 : 1   (AA  body)
       ink-4 →  2.6 : 1   (decoration only) */
  --c-ink-1:       oklch(96% 0.012 95);
  --c-ink-2:       oklch(82% 0.012 95);
  --c-ink-3:       oklch(64% 0.018 230);   /* tertiary, slight blue tint */
  --c-ink-4:       oklch(48% 0.025 230);   /* decorative — separators, glyphs */

  /* Brand */
  --c-brand:       oklch(66% 0.130 235);   /* TechVector cyan */
  --c-brand-hi:    oklch(78% 0.100 230);   /* highlight / link hover */
  --c-brand-lo:    oklch(48% 0.160 250);   /* deep, used on light bg */

  /* ---- 2. Semantic tokens ---------------------------------- */
  --bg:              var(--c-bg-1);
  --bg-2:            var(--c-bg-2);
  --surface:         var(--c-surface-1);
  --surface-2:       var(--c-surface-2);

  --ink:             var(--c-ink-1);
  --ink-2:           var(--c-ink-2);
  --ink-3:           var(--c-ink-3);
  --ink-4:           var(--c-ink-4);

  --accent:          var(--c-brand);
  --accent-bright:   var(--c-brand-hi);
  --accent-deep:     var(--c-brand-lo);
  --accent-soft:     oklch(66% 0.130 235 / 0.14);   /* alpha is OK for soft fills */

  /* Borders — alpha is acceptable here: borders need to adapt across
     mixed surfaces. Tinted toward the ink color, not neutral gray. */
  --line:            oklch(96% 0.012 95 / 0.09);
  --line-strong:     oklch(96% 0.012 95 / 0.18);

  /* Gradients */
  --grad-accent:     linear-gradient(135deg, var(--c-brand-hi) 0%, var(--c-brand) 50%, var(--c-brand-lo) 100%);
  --grad-blue:       linear-gradient(135deg, var(--c-brand) 0%, var(--c-brand-lo) 100%);
  --grad-sheen:      linear-gradient(180deg, oklch(96% 0.012 95 / 0.04) 0%, oklch(96% 0.012 95 / 0) 100%);

  /* Component-specific tones */
  --body-bloom-1:    oklch(66% 0.130 235 / 0.05);
  --body-bloom-2:    oklch(48% 0.160 250 / 0.04);
  --grid-color:      oklch(96% 0.012 95 / 0.04);
  --hero-fade:       radial-gradient(circle at 50% 40%, transparent 30%, var(--c-bg-1) 78%);
  --nav-blur-bg:     oklch(13% 0.040 250 / 0.78);
  --field-bg:        oklch(13% 0.040 250 / 0.6);
  --field-bg-focus:  oklch(13% 0.040 250 / 0.9);
  /* Decorative bloom dialed back from 0.50/0.32 to 0.22/0.14 — present
     enough to hint at brand color, quiet enough to recede. */
  --orb-1-opa:       0.22;
  --orb-2-opa:       0.14;
  /* Logo glow reduced from drop-shadow(0 2px 12px @0.35) to a 1-pixel
     subtle lift. Stops the logo from looking like a neon sign in a dark room. */
  --logo-glow:       drop-shadow(0 1px 1px oklch(66% 0.130 235 / 0.20));
  --btn-primary-ink: oklch(99% 0 0);

  /* Subtle hover tints — theme-aware. White on dark, ink on light.
     Replaces the rgba(255,255,255,0.02) magic that broke in light mode. */
  --hover-tint:      oklch(96% 0.012 95 / 0.025);
  --hover-tint-soft: oklch(96% 0.012 95 / 0.012);

  /* ---- 3. Typography & spacing scale ----------------------- */
  --font-body: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: "Android 101", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --radius-sm: 8px;
  --radius:    14px;
  --radius-lg: 22px;

  /* ---- 4. Elevation system (focused, not generic) ----------
     Two stops only: lift (subtle hover/CTA) and elevated (form,
     avatar — true depth). Cards use BORDERS for separation, not
     shadows. Pure black for a true void cast on the dark theme.       */
  --shadow-lift:     0 6px 18px -8px oklch(0% 0 0 / 0.45);
  --shadow-elevated: 0 24px 60px -16px oklch(0% 0 0 / 0.55);

  /* Easing system — exponential curves for natural deceleration.
     Per frontend-design: bounce/elastic feel dated; exponential curves
     are how real objects come to rest. */
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);     /* refined, smooth */
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);    /* slightly snappier */
  --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);     /* confident, decisive */
  --ease-in-quart:  cubic-bezier(0.5, 0, 0.75, 0);     /* exits */
  /* Legacy aliases — existing component CSS still uses these */
  --ease:           var(--ease-out-quart);
  --ease-out:       var(--ease-out-expo);

  /* Layout */
  --container:      1200px;
  --container-wide: 1320px;
  /* Reading width for long-form content (weeks, faq, body copy).
     Cards/grids use the full container; reading content sits here. */
  --content:        880px;

  --nav-h: 72px;
}

/* ---------- Tokens (LIGHT) ---------------------------------- */
:root[data-theme="light"] {
  /* ---- 1. Primitives (light) ------------------------------- */
  /* Warm cream surfaces, deep navy ink. Brand hue (248°) bleeds
     through neutrals via low chroma, mirroring the dark theme. */

  --c-bg-1:        oklch(97% 0.018 90);    /* warm ivory page */
  --c-bg-2:        oklch(94% 0.025 88);    /* paper, slightly deeper */
  --c-surface-1:   oklch(99% 0.008 88);    /* cards — tinted near-white, NOT pure white */
  --c-surface-2:   oklch(96% 0.020 88);    /* secondary surface */

  /* Ink ramp — solid OKLCH, contrast verified against --c-bg-1:
       ink   → 13.4 : 1   (AAA body)
       ink-2 →  7.6 : 1   (AAA body)
       ink-3 →  4.6 : 1   (AA  body) — was 3.74 with alpha
       ink-4 →  2.7 : 1   (decoration only) */
  --c-ink-1:       oklch(22% 0.060 248);   /* deep navy body text */
  --c-ink-2:       oklch(38% 0.050 248);
  --c-ink-3:       oklch(48% 0.050 248);
  --c-ink-4:       oklch(62% 0.040 240);

  --c-brand:       oklch(58% 0.140 245);   /* deeper for AA on cream */
  --c-brand-hi:    oklch(66% 0.130 235);
  --c-brand-lo:    oklch(40% 0.160 250);

  /* ---- 2. Semantic tokens ---------------------------------- */
  --bg:              var(--c-bg-1);
  --bg-2:            var(--c-bg-2);
  --surface:         var(--c-surface-1);
  --surface-2:       var(--c-surface-2);

  --ink:             var(--c-ink-1);
  --ink-2:           var(--c-ink-2);
  --ink-3:           var(--c-ink-3);
  --ink-4:           var(--c-ink-4);

  --accent:          var(--c-brand);
  --accent-bright:   var(--c-brand-hi);
  --accent-deep:     var(--c-brand-lo);
  --accent-soft:     oklch(58% 0.140 245 / 0.12);

  --line:            oklch(48% 0.160 250 / 0.14);
  --line-strong:     oklch(48% 0.160 250 / 0.24);

  --grad-accent:     linear-gradient(135deg, var(--c-brand-hi) 0%, var(--c-brand) 50%, var(--c-brand-lo) 100%);
  --grad-blue:       linear-gradient(135deg, var(--c-brand) 0%, var(--c-brand-lo) 100%);
  --grad-sheen:      linear-gradient(180deg, oklch(22% 0.060 248 / 0.02) 0%, oklch(22% 0.060 248 / 0) 100%);

  --body-bloom-1:    oklch(66% 0.130 235 / 0.04);
  --body-bloom-2:    oklch(48% 0.160 250 / 0.03);
  --grid-color:      oklch(48% 0.160 250 / 0.05);
  --hero-fade:       radial-gradient(circle at 50% 40%, transparent 30%, var(--c-bg-1) 78%);
  --nav-blur-bg:     oklch(97% 0.018 90 / 0.84);
  --field-bg:        var(--c-surface-1);
  --field-bg-focus:  var(--c-surface-1);
  --orb-1-opa:       0.10;
  --orb-2-opa:       0.07;
  --logo-glow:       drop-shadow(0 1px 1px oklch(48% 0.160 250 / 0.16));
  --btn-primary-ink: oklch(99% 0 0);

  /* Light-theme elevation — shadows are blue-tinted, not neutral black,
     so they feel like part of the palette rather than dropped on it. */
  --shadow-lift:     0 6px 20px -8px oklch(22% 0.060 248 / 0.10);
  --shadow-elevated: 0 24px 60px -20px oklch(22% 0.060 248 / 0.18);

  /* Hover tints — flipped polarity for light mode (ink-on-paper) */
  --hover-tint:      oklch(22% 0.060 248 / 0.04);
  --hover-tint-soft: oklch(22% 0.060 248 / 0.02);
}

/* ---------- Cyrillic font swap for Bulgarian ---------------- */
html[lang="bg"] {
  --font-mono: "Space Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

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

html {
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  background-image:
    radial-gradient(1200px 600px at 80% -10%, var(--body-bloom-1), transparent 60%),
    radial-gradient(900px 500px at 10% 10%, var(--body-bloom-2), transparent 60%);
  min-height: 100vh;
  overflow-x: hidden;
  transition: background-color .35s var(--ease), color .35s var(--ease);
}

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

/* Long-text resilience — BG translations are typically 20–30% longer than
   English. These rules guarantee no horizontal scroll, no clipped titles,
   and graceful wrapping on long compound words (common in BG/DE). */
h1, h2, h3, h4, h5, p, li, dt, dd, summary, label {
  overflow-wrap: break-word;
  word-wrap: break-word;       /* legacy alias */
  -webkit-hyphens: auto;
  hyphens: auto;
}
/* Headings hyphenate less aggressively — words like "AI" should never break */
h1, h2, .section__title, .hero__title, .week__label {
  hyphens: manual;
}

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

a { color: inherit; text-decoration: none; }

h1, h2, h3, h4, h5 {
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
}

p { margin: 0 0 1em; }

/* Skip link (a11y) */
.skip-link {
  position: absolute; top: -100vh; left: 0;
  background: var(--accent); color: #FFFFFF; padding: 10px 14px;
  z-index: 1000;
}
.skip-link:focus { top: 8px; left: 8px; }

/* ---------- Layout ------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}
@media (min-width: 1024px) {
  .container { padding: 0 40px; }
}

.grid { display: grid; gap: 24px; }
.grid--3 { grid-template-columns: 1fr; }
@media (min-width: 720px)  { .grid--3 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .grid--3 { grid-template-columns: 1fr 1fr 1fr; } }

.section {
  padding: 64px 0;
  position: relative;
}
@media (min-width: 1024px) {
  .section { padding: 96px 0; }
}

/* Skip layout/paint for sections that are off-screen until scrolled near.
   contain-intrinsic-size gives the browser a placeholder height so the
   scrollbar stays stable. The "auto" keyword means the browser caches
   the actual size after first measurement — so the placeholder only
   matters on first paint. Smaller estimate on mobile keeps the initial
   scrollbar more accurate. Excluded: hero (always visible) and problem
   (above-fold for most viewports). */
.section--solution,
.section--who,
.section--curriculum,
.section--outcomes,
.section--instructor,
.section--faq,
.section--waitlist {
  content-visibility: auto;
  contain-intrinsic-size: auto 800px;
}
@media (min-width: 1024px) {
  .section--solution,
  .section--who,
  .section--curriculum,
  .section--outcomes,
  .section--instructor,
  .section--faq,
  .section--waitlist {
    contain-intrinsic-size: auto 1200px;
  }
}

.section__title {
  font-size: clamp(1.8rem, 1.2rem + 2.4vw, 3rem);
  line-height: 1.15;
  max-width: 22ch;          /* punchy, but consistent across sections */
  margin: 16px 0 24px;
  letter-spacing: -0.025em;
}
.section__body {
  max-width: 60ch;          /* comfortable reading measure */
  color: var(--ink-2);
  font-size: 1.0625rem;
  line-height: 1.75;
  margin-bottom: 56px;
}
.section__body p + p { margin-top: 1em; }

/* When a section title/body lives inside a column layout (.split__text),
   the column already constrains them — drop the per-element max-widths so
   they fill the column instead of getting double-clipped. */
.split__text .section__title,
.split__text .section__body { max-width: none; }

/* Eyebrow label — quiet, no border or chip bg. Just a small caps lockup
   in the accent color. The shape was making it look like a status pill
   from a SaaS dashboard, which isn't the editorial register we want. */
.eyebrow {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  padding: 0;
  margin-bottom: 4px;
}

/* Solid accent color (kept as utility — used in .who__shared em).
   The hero phrase highlight is now done via .hero__title-em (weight + italic). */
.accent {
  color: var(--accent);
}
.hero__title-em {
  font-style: italic;
  font-weight: 700;          /* same weight as title — italic alone carries the highlight */
  color: var(--ink);          /* same color — italic + serif-feel does the work */
}

/* ---------- Buttons ------------------------------------------ */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 20px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
  border: 1px solid transparent;
  cursor: pointer;
  /* Snappier curve on press feedback (200ms) than on hover lift (250ms) */
  transition:
    transform   .2s  var(--ease-out-quint),
    filter      .25s var(--ease-out-quart),
    box-shadow  .25s var(--ease-out-quart),
    background  .25s var(--ease-out-quart);
  user-select: none;
}
.btn:focus-visible {
  outline: 2px solid var(--accent-deep);
  outline-offset: 3px;
}
.btn--primary {
  background: var(--grad-accent);
  color: var(--btn-primary-ink);
  box-shadow: var(--shadow-lift);
}
.btn--primary:hover {
  /* Lift + brightness, no shadow swap. */
  transform: translateY(-2px);
  filter: brightness(1.06);
}
.btn--primary:active {
  /* Tactile press — quick scale-down. Tells the finger "I felt that." */
  transform: translateY(0) scale(0.98);
  transition-duration: .08s;
  filter: brightness(0.96);
}
.btn--primary:hover .btn__arrow { transform: translateX(4px); }
.btn--primary:active .btn__arrow { transform: translateX(0); }
.btn__arrow { transition: transform .25s var(--ease-out-expo); }
.btn--lg {
  padding: 16px 28px;
  font-size: 1rem;
}

/* ---------- NAV ---------------------------------------------- */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  border-bottom: 1px solid transparent;
  /* Smooth crossfade when scroll state flips, not a hard switch */
  transition:
    background-color .3s var(--ease-out-quart),
    border-color     .3s var(--ease-out-quart);
}
.nav.is-scrolled {
  /* Solid scrolled background — replaces the glassmorphism blur.
     Calmer, less GPU work, and reads as "anchored navigation"
     rather than "decorative glass panel". */
  background: var(--bg);
  border-bottom-color: var(--line);
}
.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: var(--nav-h);
}
.nav__brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  transition: opacity .25s var(--ease);
}
.nav__brand:hover { opacity: 0.85; }
.nav__mark {
  display: inline-flex;
  width: 28px; height: 30px;
  filter: var(--logo-glow);
}
.nav__mark svg { width: 100%; height: 100%; }
.nav__brand-name {
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}
.nav__links {
  display: none;
  align-items: center;
  gap: 28px;
}
.nav__links a {
  color: var(--ink-2);
  font-size: 0.9375rem;
  font-weight: 500;
  transition: color .2s var(--ease);
  position: relative;
}
.nav__links a:hover { color: var(--ink); }
.nav__links a::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: -6px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .3s var(--ease);
}
.nav__links a:hover::after { transform: scaleX(1); }
.nav__actions {
  display: none;
  align-items: center;
  gap: 18px;
}
.nav__cta { padding: 10px 18px; font-size: 0.875rem; }

@media (min-width: 900px) {
  .nav__links, .nav__actions { display: inline-flex; }
}

/* Mobile toggle — visible 44×44 (was 40×40), meets WCAG 2.5.5 directly */
.nav__toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  background: var(--hover-tint);
  border-radius: 10px;
  cursor: pointer;
  padding: 0;
}
.nav__toggle span {
  display: block; width: 18px; height: 1.5px;
  background: var(--ink); margin: 0 auto;
  transition: transform .3s var(--ease), opacity .2s var(--ease);
}
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

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

/* Mobile panel — solid bg matches the scrolled nav (no glass effect) */
.nav.is-open {
  background: var(--bg);
  border-bottom-color: var(--line);
}
.nav.is-open .nav__links,
.nav.is-open .nav__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
  width: 100%;
}
.nav.is-open .nav__inner {
  flex-wrap: wrap;
  height: auto;
  padding-top: 18px;
  padding-bottom: 28px;
  gap: 20px;
}
.nav.is-open .nav__links,
.nav.is-open .nav__actions {
  order: 3;
  flex-basis: 100%;
}
.nav.is-open .nav__cta { width: 100%; text-align: center; }

/* Language toggle.
   Visible chrome stays compact; ::after extends each button's hit area
   to ≥ 44×44 so mobile taps land cleanly (WCAG 2.5.5). */
.lang {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
}
.lang__btn {
  position: relative;
  padding: 6px 8px;
  background: none;
  border: none;
  color: var(--ink-3);
  cursor: pointer;
  transition: color .2s var(--ease);
  font-family: inherit;
  /* Minimum visible target ~ 28px wide; ::after pads to 44 below */
  min-width: 28px;
  min-height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.lang__btn::after {
  /* Invisible hit-area extension so tap zone reaches 44×44 */
  content: "";
  position: absolute;
  inset: -10px -6px;   /* expand vertically + a little horizontally */
  min-width: 44px;
  min-height: 44px;
}
.lang__btn:hover { color: var(--ink); }
.lang__btn[aria-pressed="true"] { color: var(--accent); }
.lang__sep { color: var(--ink-4); pointer-events: none; }

/* Theme toggle (sun/moon) — visible 38px circle, 44×44 tap target via ::after */
.theme-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-2);
  cursor: pointer;
  padding: 0;
  transition: color .25s var(--ease), border-color .25s var(--ease), background .25s var(--ease), transform .25s var(--ease);
}
.theme-toggle::after {
  content: "";
  position: absolute;
  inset: -3px;
  min-width: 44px;
  min-height: 44px;
  border-radius: inherit;
}
.theme-toggle:hover {
  color: var(--accent);
  border-color: var(--accent-soft);
  transform: rotate(-12deg);
}
.theme-toggle__icon { width: 18px; height: 18px; }
/* Show moon in light mode (click → switch to dark), sun in dark mode (click → switch to light) */
.theme-toggle__icon--moon { display: none; }
.theme-toggle__icon--sun  { display: block; }
:root[data-theme="light"] .theme-toggle__icon--moon { display: block; }
:root[data-theme="light"] .theme-toggle__icon--sun  { display: none; }
/* Footer toggle uses the same 44×44 extension */
.theme-toggle--footer { width: 34px; height: 34px; }
.theme-toggle--footer::after { inset: -5px; }

/* ---------- HERO --------------------------------------------- */
.hero {
  position: relative;
  padding: calc(var(--nav-h) + 64px) 0 96px;
  min-height: 88vh;
  display: flex;
  align-items: center;
  overflow: hidden;
}
@media (min-width: 1024px) {
  .hero { padding: calc(var(--nav-h) + 120px) 0 140px; min-height: 92vh; }
}
/* Short viewports (landscape phones, foldables, side-by-side windows) —
   88vh becomes ~280-400px, way too cramped for the hero content.
   Drop min-height and tighten padding so content fits without overflow. */
@media (max-height: 600px) {
  .hero {
    min-height: 0;
    padding: calc(var(--nav-h) + 32px) 0 64px;
  }
}
.hero__bg {
  position: absolute; inset: 0;
  z-index: 0;
  pointer-events: none;
}
.hero__grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--grid-color) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
  background-size: 40px 40px;
  background-position: -1px -1px;
}
.hero__fade {
  position: absolute;
  inset: 0;
  background: var(--hero-fade);
  pointer-events: none;
}
/* Static atmospheric blooms — no animation. They were drifting on a
   loop, which created a constant subtle motion that felt restless.
   Static, lower-opacity, larger-blur reads as "atmosphere" not "effect". */
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(120px);
}
.orb--blue {
  width: 480px; height: 480px;
  background: radial-gradient(circle at 30% 30%, oklch(66% 0.130 235), transparent 60%);
  top: -160px; right: -140px;
  opacity: var(--orb-1-opa);
}
.orb--blue-deep {
  width: 380px; height: 380px;
  background: radial-gradient(circle at 40% 40%, oklch(48% 0.160 250), transparent 60%);
  bottom: -180px; left: -140px;
  opacity: var(--orb-2-opa);
}

.hero__inner { position: relative; z-index: 1; max-width: 980px; }
.hero__title {
  font-size: clamp(2.2rem, 1.3rem + 4vw, 3.75rem);
  line-height: 1.05;
  letter-spacing: -0.035em;
  margin: 20px 0 28px;
  font-weight: 800;
}
.hero__sub {
  font-size: clamp(1.05rem, 0.95rem + 0.4vw, 1.25rem);
  color: var(--ink-2);
  max-width: 58ch;
  margin-bottom: 40px;
  line-height: 1.65;
}
.hero__cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
  margin-bottom: 64px;
}
.hero__micro {
  font-size: 0.875rem;
  color: var(--ink-3);
  margin: 0;
}

/* The gilded ::before "centerline" between sections was decorative
   chrome — removed for editorial calm. Sections breathe via padding
   and the natural change of content rhythm, not via tiny accent rules. */

/* ---------- Split layout (text + media side-by-side) --------- */
.split {
  display: grid;
  gap: 48px;
  grid-template-columns: 1fr;
  align-items: center;
  margin-bottom: 72px;
}
@media (min-width: 960px) {
  .split { grid-template-columns: 1.1fr 1fr; gap: 80px; }
}
.split__text { min-width: 0; }   /* allow grid child to shrink below content */
.split__text .section__title { margin-top: 16px; }
.split__text .section__body  { margin-bottom: 0; }

/* ---------- Generic media slot (SVG illustration or photo) --- */
.media,
.split__media {
  position: relative;
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background:
    radial-gradient(circle at 20% 20%, var(--accent-soft), transparent 55%),
    linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 100%);
  border: 1px solid var(--line);
  aspect-ratio: 600 / 420;
  /* No shadow — the border + tinted gradient is enough separation.
     Reserves shadow for genuinely elevated UI (form, avatar). */
}
.media--full {
  max-width: var(--content);
  margin: 16px 0 56px;
}
.media__svg,
.split__media .media__svg {
  width: 100%; height: 100%;
  display: block;
  object-fit: contain;
  padding: 24px;
  position: relative;
  z-index: 1;
}
.media__photo {
  display: none;
  position: absolute; inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  z-index: 2;
}
/* When a real image is available, add `has-image` to the figure and
   a matching file in /assets — the SVG hides and the photo takes over. */
.media.has-image .media__photo,
.split__media.has-image .media__photo { display: block; }
.media.has-image .media__svg,
.split__media.has-image .media__svg { display: none; }
/* Map each figure's data-media to the matching asset file */
.media[data-media="curriculum"].has-image .media__photo,
.split__media[data-media="curriculum"].has-image .media__photo {
  background-image: url("assets/curriculum.jpg");
}
.split__media[data-media="problem"].has-image .media__photo {
  background-image: url("assets/problem.jpg");
}

/* ---------- Problem ------------------------------------------ */
/* Problem cards fill the full container width with equal columns.
   auto-fit + minmax keeps them flowing 1→2→3 at narrow viewports. */
.problem__cards {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.problem__cards .card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 32px 28px 28px;
}

/* Card title — fewer competing weights/sizes per the distill principles */
.card__title {
  font-size: 1.0625rem;
  margin-bottom: 12px;
  letter-spacing: -0.015em;
}
.card__body {
  color: var(--ink-2);
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.65;
}

/* ---------- Solution pillars (3-up card grid) ---------------
   Consistent with the Problem section above. Fills the container
   with equal columns; flows 1→2→3 at narrow viewports. */
.pillars {
  list-style: none;
  padding: 0;
  margin: 32px 0 0;
  display: grid;
  gap: 24px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.pillar {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 28px 28px 26px;
  min-width: 0;
}
.pillar__num {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  color: var(--accent);
  margin-bottom: 14px;
}
.pillar__title {
  font-size: 1.0625rem;
  margin: 0 0 10px;
  letter-spacing: -0.015em;
}
.pillar__body {
  color: var(--ink-2);
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.65;
}

.quote {
  font-style: italic;
  color: var(--ink);
  padding: 18px 0 18px 20px;
  border-left: 2px solid var(--accent);
  margin: 20px 0 0;
  font-size: 1.125rem;
}

/* ---------- Who: flat editorial 3-up ------------------------
   No cards, no glyphs. Each persona is just a small accent rule
   above its title — minimal chrome, maximum reading. */
/* Personas — 2x3 card grid, consistent with Problem and Pillars cards.
   Fills the full container; auto-fit reflows to fewer columns on narrow
   viewports. */
.personas {
  list-style: none;
  padding: 0;
  margin: 32px 0 0;
  display: grid;
  gap: 24px;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.persona {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 28px 28px 26px;
  min-width: 0;
}
/* Static accent rule on each card, integrated into the card frame */
.persona::before {
  content: "";
  position: absolute;
  top: -1px; left: 28px;
  width: 32px; height: 2px;
  background: var(--accent);
}
.persona__title {
  font-size: 1.0625rem;
  margin: 0 0 10px;
  letter-spacing: -0.015em;
}
.persona__body {
  color: var(--ink-2);
  font-size: 0.9375rem;
  line-height: 1.65;
  margin: 0;
}
.persona__body a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.persona__body a:hover { color: var(--accent-bright); }

.who__shared {
  margin: 48px 0 0;
  font-size: 1.125rem;
  color: var(--ink);
  max-width: var(--content);
  line-height: 1.6;
}
.who__shared em { color: var(--accent); font-style: italic; }

/* "Not for" — typographic treatment with a brand-color left rule.
   Was a dashed bordered box; now reads as a quiet sidebar quote. */
.who__not {
  margin: 56px 0 0;
  padding: 4px 0 4px 24px;
  border-left: 2px solid var(--accent);
  max-width: var(--content);
}
.who__not h3 {
  font-size: 0.75rem;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-family: var(--font-mono);
  font-weight: 400;
  margin-bottom: 10px;
}
.who__not h3 em { font-style: normal; }
.who__not p { color: var(--ink-2); margin: 0; font-size: 0.9375rem; line-height: 1.7; }

/* ---------- Curriculum --------------------------------------- */
.weeks {
  list-style: none;
  padding: 0;
  margin: 16px 0 0;
  max-width: var(--content);
  border-top: 1px solid var(--line);
}
.week {
  border-bottom: 1px solid var(--line);
  transition: background .3s var(--ease);
}
.week:hover { background: var(--hover-tint-soft); }
.week__btn {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 24px;
  width: 100%;
  padding: 26px 4px;
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  color: var(--ink);
}
.week__num {
  font-family: var(--font-mono);
  font-size: 0.9rem;
  color: var(--accent);
  letter-spacing: 0.12em;
  min-width: 42px;
}
.week__label {
  /* min-width:0 lets long BG titles wrap inside the 1fr grid track instead
     of pushing the chev off-screen. */
  min-width: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.4;
  color: var(--ink);
}
.week__chev {
  position: relative;
  width: 16px; height: 16px;
}
.week__chev::before,
.week__chev::after {
  content: "";
  position: absolute;
  background: var(--accent);
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  transition: transform .3s var(--ease), opacity .3s var(--ease);
}
.week__chev::before { width: 14px; height: 1.5px; }
.week__chev::after  { width: 1.5px; height: 14px; }
.week__btn[aria-expanded="true"] .week__chev::after { transform: translate(-50%, -50%) rotate(90deg); opacity: 0; }

/* Accordion via animated grid-template-rows. The body sits in a single
   grid track that interpolates from 0fr (collapsed) to 1fr (open) — the
   rendered height is the natural content height, no arbitrary max cap.
   Long BG translations no longer risk clipping. Animates only the grid
   row size (a layout property the browser can interpolate cheaply),
   not the height of arbitrary content. */
.week__body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .4s var(--ease-out);
}
.week__body > * {
  min-height: 0;       /* required so the grid child can shrink to 0 */
  overflow: hidden;
}
.week__body p {
  padding: 0 4px 0 66px;
  margin: 0;
  color: var(--ink-2);
  font-size: 0.9375rem;
  line-height: 1.7;
  max-width: 72ch;
}
.week.is-open .week__body {
  grid-template-rows: 1fr;
}
.week.is-open .week__body p {
  padding-bottom: 26px;
  transition: padding-bottom .25s var(--ease-out) .15s;
}

/* ---------- Outcomes: counter-styled numbered list ---------
   The browser-rendered `<ol>` counter, sized like a display
   numeral, becomes the visual rhythm — no dots, no cards, no
   shadows. Reads like a manifesto. */
.outcomes {
  counter-reset: outcome;
  list-style: none;
  padding: 0;
  margin: 32px 0 0;
  display: grid;
  gap: 32px 56px;
  grid-template-columns: 1fr;
  max-width: var(--content);
}
@media (min-width: 720px) {
  .outcomes { grid-template-columns: 1fr 1fr; }
}
.outcome {
  counter-increment: outcome;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 18px;
  align-items: baseline;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--line);
  min-width: 0;
}
.outcome::before {
  content: counter(outcome, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: 0.875rem;
  letter-spacing: 0.16em;
  color: var(--accent);
  /* Numeral leads the prose into view — appears first, then ~80ms later
     the text follows. The per-row --reveal-delay below stacks on top. */
  opacity: 0;
  transform: translateX(-6px);
  transition:
    opacity   .5s var(--ease-out-expo) var(--reveal-delay, 0ms),
    transform .5s var(--ease-out-expo) var(--reveal-delay, 0ms);
}
.outcome.is-visible::before { opacity: 1; transform: translateX(0); }
.outcome p {
  margin: 0;
  color: var(--ink);
  font-size: 1.0625rem;
  line-height: 1.6;
  opacity: 0;
  transform: translateY(6px);
  transition:
    opacity   .5s var(--ease-out-expo) calc(var(--reveal-delay, 0ms) + 80ms),
    transform .5s var(--ease-out-expo) calc(var(--reveal-delay, 0ms) + 80ms);
}
.outcome.is-visible p { opacity: 1; transform: translateY(0); }
/* Stagger the 6 outcomes by 60ms each — reads as a controlled cascade,
   not 6 things appearing at once */
.outcome:nth-child(1) { --reveal-delay:   0ms; }
.outcome:nth-child(2) { --reveal-delay:  60ms; }
.outcome:nth-child(3) { --reveal-delay: 120ms; }
.outcome:nth-child(4) { --reveal-delay: 180ms; }
.outcome:nth-child(5) { --reveal-delay: 240ms; }
.outcome:nth-child(6) { --reveal-delay: 300ms; }

/* ---------- Instructor --------------------------------------- */
.instructor {
  display: grid;
  gap: 48px;
  grid-template-columns: 1fr;
  align-items: center;
  /* No max-width — uses the standard container so its left edge lines up
     with every other section. */
}
@media (min-width: 900px) {
  .instructor { grid-template-columns: 280px minmax(0, 1fr); gap: 72px; }
}
.instructor__text {
  max-width: var(--content);
  min-width: 0;     /* allow grid child to shrink; long bios still wrap */
}
/* ------------------- Avatar (monogram + photo slot) --------- */
.avatar {
  position: relative;
  width: 260px; height: 260px;
  margin: 0 auto;
  display: flex; align-items: center; justify-content: center;
  isolation: isolate;
}
/* Static halo — no spin, no conic. A simple radial bloom in the brand
   accent. The avatar is the focal point; the halo just lifts it off the
   page, it doesn't perform. */
.avatar__ring {
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 35%, var(--accent-soft), transparent 70%);
  z-index: -1;
}
.avatar__frame {
  position: relative;
  width: 220px; height: 220px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-elevated), inset 0 0 0 1px oklch(96% 0.012 95 / 0.04);
  display: flex; align-items: center; justify-content: center;
}
.avatar__monogram {
  width: 100%; height: 100%;
  position: absolute; inset: 0;
}
.avatar__monogram text {
  filter: drop-shadow(0 8px 24px oklch(66% 0.130 235 / 0.35));
}
/* Flat-illustration avatar fills the round frame fully */
.avatar__illus {
  display: block;
}
/* Photo layer — hidden by default to avoid a 404. To use a real portrait:
   1. Save the image as `avatar.jpg` in the project root (any size ≥ 440×440).
   2. Add the class `has-photo` to the `.avatar` element in index.html. */
.avatar__photo {
  display: none;
  position: absolute; inset: 0;
  background-size: cover;
  background-position: center 20%;
  background-repeat: no-repeat;
}
.avatar.has-photo .avatar__photo {
  display: block;
  background-image: url("avatar.jpg");
}
.avatar.has-photo .avatar__monogram { display: none; }
/* Small TechVector badge pinned to the bottom-right of the avatar */
.avatar__badge {
  position: absolute;
  right: 4px; bottom: 4px;
  width: 44px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  padding: 6px;
  box-shadow: var(--shadow-lift);
  z-index: 1;
}
.avatar__badge svg { width: 22px; height: auto; filter: var(--logo-glow); }
.instructor__role {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: -12px 0 28px;
}
.instructor__bio p {
  color: var(--ink-2);
  font-size: 1.0625rem;
  line-height: 1.75;
}
.instructor__marks {
  list-style: none;
  padding: 0;
  margin: 28px 0 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.instructor__marks li {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ink-2);
  font-size: 0.9375rem;
}
.instructor__marks li::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
}

/* ---------- FAQ ---------------------------------------------- */
/* Use the standard container; the list itself shares --content with weeks. */
.faq__list {
  max-width: var(--content);
  border-top: 1px solid var(--line);
  margin-top: 16px;
}
.faq__item {
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.faq__item summary {
  list-style: none;
  cursor: pointer;
  padding: 26px 0;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  position: relative;
  padding-right: 48px;
  transition: color .25s var(--ease);
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: "+";
  position: absolute;
  right: 8px; top: 50%;
  transform: translateY(-50%);
  color: var(--accent);
  font-size: 1.5rem;
  font-weight: 400;
  transition: transform .3s var(--ease);
}
.faq__item[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.faq__item summary:hover { color: var(--accent-bright); }
.faq__body {
  padding: 0 0 28px 0;
  color: var(--ink-2);
  font-size: 0.9375rem;
  line-height: 1.75;
  max-width: 72ch;
}
.faq__body p { margin: 0; }

/* ---------- Waitlist ----------------------------------------- */
.section--waitlist {
  padding-top: 80px;
  padding-bottom: 96px;
  position: relative;
  overflow: hidden;
}
.section--waitlist::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(600px 400px at 50% 0%, var(--body-bloom-1), transparent 60%),
    radial-gradient(500px 400px at 80% 100%, var(--body-bloom-2), transparent 60%);
  pointer-events: none;
}
.waitlist {
  position: relative;
  max-width: 640px;
  margin-inline: auto;
  text-align: center;
}
.waitlist .eyebrow,
.waitlist .section__title,
.waitlist .section__body {
  margin-left: auto;
  margin-right: auto;
}
.waitlist .section__title { max-width: 18ch; }
.waitlist .section__body  { max-width: 50ch; }

/* Price lockup — sits between the intro copy and the form */
.price {
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 18px auto 4px;
  font-family: var(--font-mono);
  color: var(--ink-2);
}
.price__amount {
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.price__period { font-size: 0.9375rem; }
.price__sep    { margin: 0 4px; color: var(--ink-4); }
.price__note {
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.waitlist__bg {
  position: absolute;
  inset: -100px;
  pointer-events: none;
  z-index: 0;
}

.form {
  position: relative;
  z-index: 1;
  background: linear-gradient(180deg, var(--surface) 0%, var(--bg-2) 100%);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  padding: 36px 28px;
  text-align: left;
  box-shadow: var(--shadow-elevated);
}
@media (min-width: 720px) {
  .form { padding: 44px 44px; }
}
.form__row {
  display: grid;
  gap: 18px;
  margin-bottom: 18px;
}
@media (min-width: 620px) {
  .form__row { grid-template-columns: 1fr 1fr; }
}
.field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.field__label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink-2);
  letter-spacing: 0.02em;
  transition: color .25s var(--ease-out-quart);
}
/* When the field is focused, the label leans into the accent — the
   whole field "package" reads as active, not just the input border. */
.field:focus-within .field__label { color: var(--accent); }
.field:focus-within .field__req   { color: var(--accent); }
.field__req {
  color: var(--accent);
  font-weight: 700;
  line-height: 1;
}
.field__error {
  display: none;
  margin-top: 4px;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: oklch(58% 0.18 25);   /* warm coral, AA on both surfaces */
}
:root[data-theme="light"] .field__error { color: oklch(46% 0.20 25); }
.field.has-error .field__error { display: block; }
.field.has-error .field__label { color: oklch(58% 0.18 25); }
.field input,
.field select {
  background: var(--field-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  color: var(--ink);
  font-size: 0.9375rem;
  transition: border-color .25s var(--ease), background .25s var(--ease), box-shadow .25s var(--ease);
}
.field input::placeholder { color: var(--ink-4); }
.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
  background: var(--field-bg-focus);
}
.field select {
  appearance: none;
  -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--accent) 50%),
    linear-gradient(135deg, var(--accent) 50%, transparent 50%);
  background-position:
    calc(100% - 20px) 50%,
    calc(100% - 14px) 50%;
  background-size: 6px 6px;
  background-repeat: no-repeat;
  padding-right: 38px;
}
.field select option { background: var(--surface); color: var(--ink); }
.form__submit { width: 100%; margin-top: 12px; }
.form__submit:disabled,
.form[aria-busy="true"] .form__submit {
  opacity: 0.65;
  cursor: progress;
  filter: none;
  transform: none;
}
.form__submit:disabled:hover { transform: none; filter: none; }
.form__micro-sep { margin: 0 6px; color: var(--ink-4); }
.form__req-note { color: var(--accent); }
.form__micro {
  font-size: 0.8125rem;
  color: var(--ink-3);
  text-align: center;
  margin: 14px 0 0;
}
/* GDPR consent checkbox — affirmative opt-in required before submit */
.field--consent { margin-top: 16px; }
.consent {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-2);
}
.consent input {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}
.consent__box {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  margin-top: 1px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--field-bg);
  color: transparent;
  transition: background .2s var(--ease-out-quart), border-color .2s var(--ease-out-quart), color .2s var(--ease-out-quart), box-shadow .2s var(--ease-out-quart);
}
.consent:hover .consent__box { border-color: var(--accent); }
.consent input:focus-visible + .consent__box {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.consent input:checked + .consent__box {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.field.has-error .consent__box { border-color: oklch(58% 0.18 25); }
.consent__text a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.consent__text a:hover { color: var(--accent-bright); }
.form:not([aria-busy="true"]) .form__submit:disabled { cursor: not-allowed; opacity: 0.55; }
.form__status {
  margin: 12px 0 0;
  font-size: 0.875rem;
  color: var(--accent-bright);
  text-align: center;
  min-height: 1.4em;
}
.form__status.is-error { color: oklch(70% 0.18 25); }
:root[data-theme="light"] .form__status.is-error { color: oklch(46% 0.20 25); }

/* Field error border + soft glow ring (mirrors focus ring affordance) */
.field.has-error input,
.field.has-error select {
  border-color: oklch(58% 0.18 25);
  box-shadow: 0 0 0 3px oklch(58% 0.18 25 / 0.16);
}

/* ---------- Footer ------------------------------------------- */
.footer {
  border-top: 1px solid var(--line);
  padding: 48px 0 56px;
  background: var(--bg-2);
}
.footer__inner {
  display: grid;
  gap: 36px;
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 900px) {
  .footer__inner {
    grid-template-columns: auto 1fr auto;
    gap: 48px;
  }
}
.footer__brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.footer__mark {
  width: 24px; height: 26px;
}
.footer__name {
  font-weight: 700;
  font-size: 0.9375rem;
}
.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
}
.footer__links a {
  color: var(--ink-3);
  font-size: 0.875rem;
  transition: color .25s var(--ease);
}
.footer__links a:hover { color: var(--ink); }
.footer__meta {
  display: flex;
  align-items: center;
  gap: 20px;
  justify-content: space-between;
  flex-wrap: wrap;
}
.footer__copy {
  margin: 0;
  color: var(--ink-3);
  font-size: 0.8125rem;
}
.footer__controls {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.lang--footer { padding: 4px 8px; }

/* ---------- Scroll reveal ------------------------------------
   Default reveal: 12px rise + fade, ~600ms with exponential easing.
   Per-element customization via --reveal-delay (CSS custom prop) and
   --reveal-duration. Used by the hero choreography below. */
.reveal {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity   var(--reveal-duration, .6s) var(--ease-out-expo) var(--reveal-delay, 0ms),
    transform var(--reveal-duration, .6s) var(--ease-out-expo) var(--reveal-delay, 0ms);
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Hero choreography — staggered, with the title getting more time + a
   slightly larger lift so it lands with weight. Each element waits for
   the previous to settle before starting. */
.hero .eyebrow.reveal       { --reveal-delay:   0ms; --reveal-duration: .5s; }
.hero .hero__title.reveal   { --reveal-delay:  90ms; --reveal-duration: .9s; transform: translateY(20px); }
.hero .hero__sub.reveal     { --reveal-delay: 280ms; --reveal-duration: .6s; }
.hero .hero__cta.reveal     { --reveal-delay: 420ms; --reveal-duration: .6s; }

/* Reduced motion — animations collapse to instant, but content must
   still be visible. Each pseudo-element introduced for choreography
   needs an explicit override to land in its "open" state. */
@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;
  }
  .reveal { opacity: 1; transform: none; }
  /* Outcome numerals + prose: shown directly, no lead-and-follow */
  .outcome::before,
  .outcome p { opacity: 1; transform: none; }
}

/* ---------- Print stylesheet --------------------------------
   For students printing the curriculum or pinning the outcomes
   to a board. Strips chrome, expands the accordion, switches to
   black ink on white. Section breaks follow chapter boundaries. */
@media print {
  :root, :root[data-theme="light"], :root[data-theme="dark"] {
    --bg:        #fff;
    --bg-2:      #fff;
    --surface:   #fff;
    --surface-2: #fff;
    --ink:       #000;
    --ink-2:     #222;
    --ink-3:     #444;
    --ink-4:     #666;
    --line:      #ccc;
    --line-strong: #999;
    --accent:    #000;
    --accent-deep: #000;
    --shadow-lift:     none;
    --shadow-elevated: none;
  }
  body {
    background: #fff !important;
    background-image: none !important;
    color: #000;
    font-size: 11pt;
  }
  /* Hide chrome that doesn't belong on paper */
  .nav, .footer, .hero__bg, .orb,
  .skip-link, .form, .form__status,
  .theme-toggle, .lang, .nav__toggle,
  .avatar__ring, .avatar__badge,
  .media, .split__media,
  .section--waitlist {
    display: none !important;
  }
  /* Reset content-visibility so print engines see the whole page */
  .section--solution, .section--who, .section--curriculum,
  .section--outcomes, .section--instructor, .section--faq, .section--waitlist {
    content-visibility: visible !important;
    contain-intrinsic-size: none !important;
  }
  /* Tighten section padding for paper */
  .section { padding: 24pt 0 !important; }
  /* Section breaks after major content blocks */
  .section--solution, .section--curriculum, .section--instructor {
    page-break-before: auto;
  }
  .section--curriculum, .section--outcomes {
    page-break-after: auto;
  }
  /* Expand all accordion bodies — collapsed weeks would print blank */
  .week__body { display: block !important; grid-template-rows: none !important; }
  .week__body > * { overflow: visible !important; }
  .week__body p { padding: 0 0 12pt 60pt !important; }
  .week__chev { display: none !important; }
  .week { page-break-inside: avoid; }
  /* Open every <details> (FAQ) for print */
  details[open], details { /* both states */ }
  .faq__item summary::after { display: none; }
  .faq__body { display: block !important; padding: 0 0 12pt !important; }
  /* Print-friendly headings */
  h1, h2, h3 { color: #000; page-break-after: avoid; }
  .section__title { font-size: 18pt; }
  .hero__title { font-size: 18pt; }
  .pillar__title, .persona__title, .card__title { font-size: 13pt; }
  .reveal { opacity: 1 !important; transform: none !important; }
  /* Show URLs after links for offline reference */
  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    color: #555;
  }
}

/* ---------- Selection ---------------------------------------- */
::selection { background: var(--accent); color: #FFFFFF; }

/* ---------- Focus ring --------------------------------------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent-bright);
  outline-offset: 3px;
  border-radius: 6px;
}
