/* ============================================================
   SpeakEase — design system
   Drop-in replacement for styles.css. No markup changes required:
   every selector below maps to a class already emitted by app.js.
   ============================================================ */

/* ---- 1. Tokens -------------------------------------------- */

:root {
  color-scheme: dark;

  /* Surfaces, darkest to lightest. Four steps, used as a ladder:
     canvas < sunken < raised < overlay. Elevation is the ONLY
     signal of hierarchy, so it must stay ordered. */
  --canvas: #06101c;
  --sunken: #081726;
  --raised: #0b2032;
  --overlay: #0e2a40;

  --line: rgba(122, 197, 236, 0.12);
  --line-mid: rgba(122, 197, 236, 0.22);
  --line-strong: rgba(83, 205, 236, 0.42);

  /* Text: 3 steps. More than 3 and hierarchy stops reading. */
  --text: #eaf4f9;
  --text-dim: #a3b7c4;
  /* 4.5:1 against every surface above, including --overlay, where the
     previous #6f8595 fell to 3.84:1 and failed WCAG AA. */
  --text-faint: #879dad;

  /* Brand */
  --cyan: #35cbe4;
  --cyan-bright: #7ee3f6;
  --teal: #16a5ba;

  /* Category accents — one hue per practice domain, used
     consistently across cards, progress bars and pills. */
  --articulation: #38bdf8;
  --fluency: #34d399;
  --language: #fbbf24;
  --voice: #fb7185;

  /* Spacing: 4px base. Every margin/padding/gap in this file is
     one of these. Nothing else is allowed. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 20px;
  --s6: 24px;
  --s7: 32px;
  --s8: 40px;
  --s9: 56px;

  /* Type scale: 1.2 ratio, 7 steps. */
  --t-xs: 11px;
  --t-sm: 12.5px;
  --t-base: 14px;
  --t-md: 16px;
  --t-lg: 19px;
  --t-xl: 23px;
  --t-2xl: 28px;
  --t-3xl: 34px;

  --radius-sm: 10px;
  --radius: 14px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  /* Elevation ladder — matches the surface ladder above. */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.28);
  --shadow-3: 0 18px 48px rgba(0, 0, 0, 0.42);

  --ease: cubic-bezier(0.22, 0.68, 0.36, 1);
  --fast: 140ms;
  --med: 220ms;

  /* System stack, deliberately. The old file asked for Inter but
     never loaded it, so all the 7xx weights silently collapsed.
     Shipping the platform UI font costs zero bytes and zero
     layout shift; swap in a self-hosted woff2 if you want Inter
     for real. */
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, sans-serif;
  font-synthesis-weight: none;
}

* { box-sizing: border-box; }

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

body {
  min-width: 320px;
  margin: 0;
  color: var(--text);
  font-size: var(--t-base);
  line-height: 1.55;
  letter-spacing: -0.006em;
  background:
    radial-gradient(ellipse 60rem 40rem at 78% -8%, rgba(21, 165, 186, 0.13), transparent 70%),
    radial-gradient(ellipse 50rem 36rem at 12% 104%, rgba(42, 107, 176, 0.1), transparent 70%),
    var(--canvas);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button, select, input { font: inherit; color: inherit; }
button { border: 0; background: none; cursor: pointer; }

/* Default size for every icon. app.js injects raw ${icons.x} markup
   into several buttons with no wrapper class, so without a global
   default those SVGs expand to fill their button. Component rules
   below override it where a different size is wanted. */
svg { width: 18px; height: 18px; flex: 0 0 auto; }

/* One focus treatment everywhere, including the elements the old
   file missed (collapsible triggers, cards, footer links). */
:where(button, select, a, [tabindex]):focus-visible {
  outline: 2px solid var(--cyan-bright);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Shared micro-typography helpers ---------------------------- */
.reminder-label,
.result-stat span,
.completion-exercise small,
.brand-subtitle {
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* ---- 2. App shell ----------------------------------------- */

.app-shell { min-height: 100vh; min-height: 100dvh; }

.app-bar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 64px;
  padding: var(--s2) var(--s6);
  border-bottom: 1px solid var(--line);
  background: rgba(6, 16, 28, 0.82);
  backdrop-filter: blur(20px) saturate(160%);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-width: 0;
  padding: var(--s1);
  margin: calc(var(--s1) * -1);
  border-radius: var(--radius-sm);
  text-align: left;
  transition: background var(--fast) var(--ease);
}
.brand:hover { background: rgba(122, 197, 236, 0.06); }

.brand-mark,
.hero-mark {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  color: #d7f6ff;
  background: linear-gradient(150deg, var(--cyan) 0%, var(--teal) 100%);
  box-shadow: 0 6px 20px rgba(27, 186, 212, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.brand-mark { width: 34px; height: 34px; border-radius: var(--radius-sm); }
.brand-mark svg { width: 20px; height: 20px; }

.brand-copy { display: grid; gap: 1px; min-width: 0; }
.brand-name {
  font-size: var(--t-md);
  font-weight: 700;
  letter-spacing: -0.022em;
  line-height: 1.2;
}
.brand-subtitle { letter-spacing: 0.06em; }

.bar-spacer { flex: 1; }
.top-actions { display: flex; align-items: center; gap: var(--s2); }

.icon-button,
.passkey-button,
.back-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--raised);
  color: var(--cyan-bright);
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.icon-button:hover,
.passkey-button:hover,
.back-button:hover {
  background: var(--overlay);
  border-color: var(--line-strong);
}
.icon-button:active,
.passkey-button:active,
.back-button:active { transform: translateY(1px); }

/* 40px minimum on every tap target (was 38). flex-shrink is needed too:
   in the app bar at 390px the buttons were being squeezed to 38px wide. */
.icon-button { width: 40px; height: 40px; flex: 0 0 auto; }
.passkey-button, .back-button { flex: 0 0 auto; }
.icon-button svg { width: 18px; height: 18px; }
.passkey-button {
  min-height: 40px;
  padding: 0 var(--s4);
  font-size: var(--t-sm);
  font-weight: 600;
}
.back-button {
  width: 40px;
  height: 40px;
  color: var(--text-dim);
  background: var(--sunken);
}

.app-main {
  width: min(100%, 940px);
  margin: 0 auto;
  padding: var(--s7) var(--s5) var(--s9);
}

/* ---- 3. Surfaces ------------------------------------------
   Three tiers. The old file gave all eight card types the same
   gradient + shadow, which is why nothing stood out.
   ----------------------------------------------------------- */

/* Tier 3 — flat, recedes. Lists and repeated items. */
.game-card,
.plan-card,
.exercise-card,
.footer-link {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--sunken);
  box-shadow: none;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease),
    transform var(--fast) var(--ease);
}

/* Tier 2 — raised. Grouping containers. */
.panel-card,
.how-it-works-card,
.collapsible-card,
.streak-card,
.settings-card,
.category-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--raised);
  box-shadow: var(--shadow-1);
}

/* Tier 1 — the only things that get real elevation: things
   demanding a decision, and the live practice surface. */
.hero-card,
.notice-card,
.reminder-card,
.discovery,
.exercise-panel,
.result-card {
  border: 1px solid var(--line-mid);
  border-radius: var(--radius-lg);
  background: linear-gradient(155deg, var(--overlay), var(--raised));
  box-shadow: var(--shadow-2);
}

.game-card:hover,
.plan-card:hover,
.exercise-card:hover,
.category-card:hover,
.footer-link:hover {
  border-color: var(--line-mid);
  background: var(--raised);
  transform: translateY(-1px);
}
.category-card:hover { background: var(--overlay); }

/* ---- 4. Section headings ---------------------------------- */

.section-icon,
.notice-icon,
.reminder-icon,
.category-figure {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  color: var(--cyan-bright);
  background: rgba(53, 203, 228, 0.12);
  border: 1px solid rgba(53, 203, 228, 0.16);
}
.section-icon svg,
.notice-icon svg,
.reminder-icon svg,
.category-figure svg { width: 18px; height: 18px; }

.section-heading {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: var(--s7) 0 var(--s4);
}
/* A heading that opens a card shouldn't push off the card's own padding. */
.panel-card > .section-heading:first-child { margin-top: 0; }

/* Standalone panels and flush copy, replacing the inline styles that
   app.js used to emit. */
.panel-card { margin-top: var(--s6); padding: var(--s5); }
.copy-flush { margin: 0; }
.panel-actions { display: flex; justify-content: flex-end; margin-top: var(--s3); }
.section-heading h2 {
  margin: 0;
  font-size: var(--t-lg);
  font-weight: 650;
  letter-spacing: -0.024em;
}
.section-heading .section-icon { width: 32px; height: 32px; }
.section-heading .section-icon svg { width: 16px; height: 16px; }

.page-title {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-bottom: var(--s6);
}
.page-title h1 {
  margin: 0;
  font-size: var(--t-xl);
  font-weight: 680;
  letter-spacing: -0.03em;
  line-height: 1.2;
}
.page-title p { margin: var(--s1) 0 0; color: var(--text-dim); font-size: var(--t-sm); }

/* ---- 5. Hero ---------------------------------------------- */

.hero-intro { padding: var(--s8) 0 var(--s6); text-align: center; }
.hero-mark {
  width: 76px;
  height: 76px;
  margin: 0 auto var(--s5);
  border-radius: 24px;
  background: linear-gradient(150deg, rgba(53, 203, 228, 0.28), rgba(13, 77, 109, 0.85));
  border: 1px solid rgba(126, 227, 246, 0.22);
}
.hero-mark svg { width: 38px; height: 38px; }
.hero-intro h1 {
  margin: 0;
  font-size: clamp(var(--t-2xl), 5.5vw, var(--t-3xl));
  font-weight: 700;
  letter-spacing: -0.038em;
  line-height: 1.1;
}
.hero-intro p {
  max-width: 44ch;
  margin: var(--s4) auto 0;
  color: var(--text-dim);
  font-size: var(--t-md);
  line-height: 1.6;
}

/* ---- 6. Notices, reminders, how-it-works ------------------- */

.notice-card { padding: var(--s5); }
.notice-head { display: flex; align-items: flex-start; gap: var(--s3); }
.notice-title { margin: 0 0 2px; font-size: var(--t-md); font-weight: 650; }
.notice-kicker { margin: 0; color: var(--text-dim); font-size: var(--t-sm); }
.notice-copy {
  margin: var(--s4) 0;
  max-width: 64ch;
  color: var(--text-dim);
  font-size: var(--t-sm);
  line-height: 1.7;
}
.notice-actions { display: grid; grid-template-columns: 1fr auto; gap: var(--s2); }

.how-it-works-card { margin-top: var(--s6); padding: var(--s5); }
.how-it-works-card h2 {
  margin: 0 0 var(--s4);
  font-size: var(--t-md);
  font-weight: 650;
  letter-spacing: -0.02em;
}
.how-step { display: flex; align-items: flex-start; gap: var(--s3); padding: var(--s2) 0; }
.how-number {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  margin-top: 1px;
  border-radius: var(--radius-pill);
  color: var(--cyan-bright);
  background: rgba(53, 203, 228, 0.14);
  border: 1px solid rgba(53, 203, 228, 0.2);
  font-size: var(--t-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.how-step strong { display: block; font-size: var(--t-sm); font-weight: 650; }
.how-step p {
  margin: 2px 0 0;
  max-width: 62ch;
  color: var(--text-dim);
  font-size: var(--t-sm);
  line-height: 1.55;
}

.reminder-card {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s6);
  padding: var(--s4) var(--s5);
}
.reminder-card p { margin: 2px 0 0; color: var(--text); font-size: var(--t-sm); }
.reminder-dismiss {
  align-self: flex-start;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  margin: -6px -6px 0 auto;
  border-radius: var(--radius-sm);
  color: var(--text-faint);
  font-size: var(--t-lg);
  line-height: 1;
  transition: color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.reminder-dismiss:hover { color: var(--text); background: rgba(255, 255, 255, 0.07); }

/* ---- 7. Collapsibles -------------------------------------- */

.collapsible-card { margin-top: var(--s6); overflow: hidden; }
.collapsible-trigger {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  min-height: 64px;
  padding: var(--s3) var(--s5);
  color: var(--text);
  text-align: left;
  transition: background var(--fast) var(--ease);
}
.collapsible-trigger:hover { background: rgba(122, 197, 236, 0.05); }
.collapsible-trigger .section-icon { width: 32px; height: 32px; }
.collapsible-trigger .section-icon svg { width: 16px; height: 16px; }
.collapsible-trigger strong { font-size: var(--t-base); font-weight: 620; }

.collapsible-trigger .discovery-badge,
.achievement-badge { margin-left: auto; }

.discovery-badge,
.achievement-badge {
  padding: 4px var(--s2);
  border-radius: var(--radius-pill);
  font-size: var(--t-xs);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--cyan-bright);
  background: rgba(53, 203, 228, 0.14);
  border: 1px solid rgba(53, 203, 228, 0.22);
}
.achievement-badge {
  color: #f7d86b;
  background: rgba(251, 191, 36, 0.13);
  border-color: rgba(251, 191, 36, 0.24);
}
.achievement-icon {
  color: #f7d86b;
  background: rgba(251, 191, 36, 0.12);
  border-color: rgba(251, 191, 36, 0.2);
}

.collapse-chevron,
.discovery-chevron {
  display: grid;
  place-items: center;
  margin-left: var(--s1);
  color: var(--text-faint);
  transition: transform var(--med) var(--ease), color var(--fast) var(--ease);
}
.collapse-chevron svg,
.discovery-chevron svg { width: 18px; height: 18px; }
.collapse-chevron.open,
.discovery-chevron.open { transform: rotate(180deg); color: var(--text-dim); }

.collapsible-body {
  padding: var(--s5);
  border-top: 1px solid var(--line);
  animation: reveal var(--med) var(--ease);
}
.collapsible-body .result-grid { margin-bottom: 0; }

@keyframes reveal {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}

/* ---- 8. Progress & completion ----------------------------- */

.completion-progress {
  height: 6px;
  margin: var(--s4) 0;
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.07);
}
.completion-progress > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--articulation), var(--fluency));
  transition: width 500ms var(--ease);
}

.completion-rows { display: grid; gap: var(--s3); }
.completion-row-head {
  display: flex;
  justify-content: space-between;
  gap: var(--s3);
  color: var(--text-faint);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
}
.completion-row-label { font-weight: 650; }
.completion-row-track {
  height: 5px;
  margin-top: var(--s1);
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.06);
}
.completion-row-track > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  transition: width 500ms var(--ease);
}

/* One accent per category, applied to both the bar and its label.
   The old file set a `color` on the bar (unused) and needed four
   extra override rules to undo the background on labels. */
.completion-articulation { background: var(--articulation); }
.completion-fluency { background: var(--fluency); }
.completion-language { background: var(--language); }
.completion-voice { background: var(--voice); }

.completion-row-label.completion-articulation { background: none; color: var(--articulation); }
.completion-row-label.completion-fluency { background: none; color: var(--fluency); }
.completion-row-label.completion-language { background: none; color: var(--language); }
.completion-row-label.completion-voice { background: none; color: var(--voice); }

.completion-exercises {
  display: grid;
  margin-top: var(--s4);
  padding-top: var(--s2);
  border-top: 1px solid var(--line);
}
.completion-exercise {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-width: 0;
  padding: var(--s2) 0;
  color: var(--text-dim);
  font-size: var(--t-sm);
}
.completion-exercise > span:not(.empty-check) {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.completion-exercise svg {
  width: 16px;
  height: 16px;
  color: rgba(255, 255, 255, 0.18);
  transition: color var(--med) var(--ease);
}
.completion-exercise.complete { color: var(--text); }
.completion-exercise.complete svg { color: var(--fluency); }
.completion-exercise small { margin-left: auto; }

.empty-check {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  border: 1.5px solid rgba(255, 255, 255, 0.18);
  border-radius: 5px;
}

.achievement-list { padding-bottom: 0; }
.achievement-row {
  display: flex;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s3) 0;
  border-top: 1px solid var(--line);
  font-size: var(--t-sm);
}
.achievement-row:first-child { border-top: 0; padding-top: 0; }
.achievement-row small { display: block; margin-top: 2px; color: var(--text-dim); font-size: var(--t-xs); }
.achievement-row > span:first-child { display: flex; align-items: baseline; gap: var(--s2); flex-wrap: wrap; }
.achievement-row.earned { color: #f7d86b; }
.achievement-row.earned svg { width: 15px; height: 15px; align-self: center; }
.achievement-row.earned .progress-pill {
  color: #f7d86b;
  background: rgba(251, 191, 36, 0.13);
  border-color: rgba(251, 191, 36, 0.26);
}

/* ---- 9. Buttons ------------------------------------------- */

.primary-button,
.secondary-button,
.filter-button,
.preview-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease),
    transform var(--fast) var(--ease);
}
.primary-button svg,
.secondary-button svg,
.preview-button svg { width: 17px; height: 17px; }

.primary-button {
  min-height: 42px;
  padding: 0 var(--s5);
  color: #04222f;
  background: linear-gradient(150deg, var(--cyan-bright), var(--cyan));
  font-size: var(--t-base);
  font-weight: 650;
  box-shadow: 0 4px 14px rgba(53, 203, 228, 0.22);
}
.primary-button:hover {
  background: linear-gradient(150deg, #99ebfa, #4bd6ec);
  box-shadow: 0 6px 20px rgba(53, 203, 228, 0.32);
}
.primary-button:active { transform: translateY(1px); box-shadow: none; }

.secondary-button {
  min-height: 42px;
  padding: 0 var(--s4);
  color: var(--text-dim);
  background: var(--raised);
  border-color: var(--line);
  font-size: var(--t-sm);
  font-weight: 600;
}
.secondary-button:hover { color: var(--text); background: var(--overlay); border-color: var(--line-mid); }

.preview-button {
  min-height: 40px;
  padding: 0 var(--s3);
  color: var(--cyan-bright);
  background: rgba(53, 203, 228, 0.1);
  border-color: rgba(53, 203, 228, 0.22);
  font-size: var(--t-sm);
  font-weight: 600;
}
.preview-button:hover { background: rgba(53, 203, 228, 0.18); border-color: var(--line-strong); }

/* ---- 10. Streak ------------------------------------------- */

.streak-card { padding: var(--s5); }
.streak-label {
  display: flex;
  align-items: center;
  gap: var(--s2);
  color: var(--text-dim);
  font-size: var(--t-sm);
  font-weight: 650;
}
.streak-label svg { width: 17px; height: 17px; color: var(--language); }
.streak-body {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s5);
  margin-top: var(--s4);
}
.streak-number {
  font-size: 44px;
  font-weight: 700;
  line-height: 0.85;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(150deg, var(--cyan-bright), var(--teal));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.streak-unit { color: var(--text-faint); font-size: var(--t-sm); }
.streak-best { display: grid; gap: 2px; text-align: right; color: var(--text-faint); font-size: var(--t-xs); }
.streak-best strong {
  color: var(--text);
  font-size: var(--t-xl);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.week { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--s2); margin-top: var(--s5); }
.week-day { display: grid; justify-items: center; gap: var(--s2); color: var(--text-faint); font-size: var(--t-xs); }
.week-dot {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--radius-pill);
  color: var(--text-dim);
  background: var(--sunken);
  border: 1px solid var(--line);
}
.week-dot svg { width: 14px; height: 14px; }
/* A practised day is filled; today is ringed. Both can apply at once. */
.week-dot.done {
  color: #04222f;
  background: linear-gradient(150deg, var(--cyan-bright), var(--cyan));
  border-color: transparent;
  font-weight: 650;
}
.week-dot.today { box-shadow: 0 0 0 2px var(--cyan-bright); border-color: transparent; }
.week-dot.today:not(.done) { color: var(--cyan-bright); }

/* ---- 11. Discovery & games -------------------------------- */

.discovery { margin-top: var(--s6); padding: var(--s5); }
.discovery-head { display: flex; align-items: center; gap: var(--s3); }
.discovery-toggle { width: 100%; padding: 0; text-align: left; }
.discovery-head h2 { margin: 0; font-size: var(--t-md); font-weight: 650; letter-spacing: -0.02em; }
.discovery-head p { margin: 2px 0 0; color: var(--text-dim); font-size: var(--t-sm); }
.discovery .section-icon {
  color: #cbb0ff;
  background: rgba(139, 92, 246, 0.16);
  border-color: rgba(139, 92, 246, 0.26);
}
.discovery .discovery-badge {
  color: #cbb0ff;
  background: rgba(139, 92, 246, 0.14);
  border-color: rgba(139, 92, 246, 0.28);
}
.discovery-copy {
  margin: var(--s4) 0;
  max-width: 64ch;
  color: var(--text-dim);
  font-size: var(--t-sm);
  line-height: 1.65;
}

.game-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--s3); margin-top: var(--s4); }
.game-card { display: grid; gap: var(--s3); padding: var(--s4); align-content: start; }
.game-card-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s3);
  font-size: var(--t-base);
  font-weight: 650;
}
.game-card-copy { color: var(--text-dim); font-size: var(--t-sm); line-height: 1.55; }

.chips { display: flex; flex-wrap: wrap; gap: var(--s2); }
.chip,
.level-pill,
.category-pill,
.progress-pill {
  display: inline-flex;
  align-items: center;
  width: max-content;
  padding: 4px var(--s2);
  border-radius: var(--radius-pill);
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--cyan-bright);
  background: rgba(53, 203, 228, 0.12);
  border: 1px solid rgba(53, 203, 228, 0.2);
}
.category-pill {
  color: var(--language);
  background: rgba(251, 191, 36, 0.12);
  border-color: rgba(251, 191, 36, 0.22);
}
.progress-pill {
  flex: 0 0 auto;
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.05);
  border-color: var(--line);
  font-variant-numeric: tabular-nums;
}

/* ---- 12. Plans, categories, exercise list ------------------ */

.plan-grid { display: grid; gap: var(--s3); }
.category-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--s3); }

.plan-card { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); padding: var(--s4); }
.plan-card h3,
.category-card h3,
.exercise-card h3 { margin: 0; font-size: var(--t-base); font-weight: 650; letter-spacing: -0.014em; }
.plan-card p,
.category-card p,
.exercise-card p {
  margin: var(--s1) 0 0;
  max-width: 56ch;
  color: var(--text-dim);
  font-size: var(--t-sm);
  line-height: 1.55;
}

.category-card {
  position: relative;
  min-height: 132px;
  padding: var(--s5);
  overflow: hidden;
  isolation: isolate;
}
.category-card::after {
  position: absolute;
  right: -28px;
  bottom: -40px;
  z-index: -1;
  width: 116px;
  height: 116px;
  border-radius: var(--radius-pill);
  background: var(--cat, var(--cyan));
  opacity: 0.14;
  filter: blur(6px);
  transition: opacity var(--med) var(--ease), transform var(--med) var(--ease);
  content: "";
}
.category-card:hover::after { opacity: 0.24; transform: scale(1.12); }

.category-card[data-category="Articulation"] { --cat: var(--articulation); }
.category-card[data-category="Fluency"] { --cat: var(--fluency); }
.category-card[data-category="Language"] { --cat: var(--language); }
.category-card[data-category="Voice"] { --cat: var(--voice); }

.category-figure {
  width: 34px;
  height: 34px;
  margin-bottom: var(--s3);
  color: var(--cat, var(--cyan));
  background: color-mix(in srgb, var(--cat, var(--cyan)) 14%, transparent);
  border-color: color-mix(in srgb, var(--cat, var(--cyan)) 24%, transparent);
}

.filter-row { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s5); }
.filter-button {
  min-height: 36px;
  padding: 0 var(--s3);
  color: var(--text-dim);
  background: var(--sunken);
  border-color: var(--line);
  font-size: var(--t-sm);
  font-weight: 600;
}
.filter-button:hover { color: var(--text); background: var(--raised); border-color: var(--line-mid); }
.filter-button.active {
  color: #04222f;
  background: var(--cyan-bright);
  border-color: transparent;
}

.exercise-list { display: grid; gap: var(--s3); }
.exercise-card { display: grid; gap: var(--s3); padding: var(--s4); }
.exercise-meta { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2); }
.exercise-words { display: flex; flex-wrap: wrap; gap: var(--s2); }
.exercise-words span {
  padding: 4px var(--s2);
  border-radius: var(--radius-pill);
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.05);
  font-size: var(--t-xs);
}

/* ---- 13. Practice panel -----------------------------------
   The live exercise. This is the product; it gets the strongest
   surface, the largest type and the only motion in the app.
   ----------------------------------------------------------- */

.exercise-panel { padding: var(--s6); }
.exercise-panel > p {
  max-width: 62ch;
  color: var(--text-dim);
  font-size: var(--t-base);
  line-height: 1.65;
}

/* The task text is what the user actually has to read aloud, and
   what the scorer grades — so it is the largest, highest-contrast
   text on the screen, not 13px body copy. */
.task-box {
  padding: var(--s5);
  border-radius: var(--radius);
  background: rgba(3, 14, 24, 0.6);
  border: 1px solid var(--line);
  border-left: 3px solid var(--cyan);
}
.task-label {
  margin: 0 0 var(--s2);
  color: var(--cyan-bright);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
/* :not(.task-label) matters — the label is itself a <p>, so a bare
   `.task-box p` rule outranks `.task-label` on specificity. */
.task-box p:not(.task-label) {
  margin: 0;
  max-width: 46ch;
  color: var(--text);
  font-size: var(--t-lg);
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: -0.016em;
  text-wrap: balance;
}

.exercise-word-row { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s4); }
.exercise-word-row span {
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-pill);
  color: var(--cyan-bright);
  background: rgba(53, 203, 228, 0.13);
  border: 1px solid rgba(53, 203, 228, 0.2);
  font-size: var(--t-base);
  font-weight: 500;
}

.tip-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  margin-top: var(--s5);
  padding: var(--s1) 0;
  color: var(--language);
  font-size: var(--t-sm);
  font-weight: 600;
}
.tip-toggle svg { width: 16px; height: 16px; }
.tip-toggle:hover { color: #fcd34d; }

.tip-box {
  display: grid;
  gap: var(--s3);
  margin-top: var(--s3);
  padding: var(--s4);
  border: 1px solid rgba(251, 191, 36, 0.22);
  border-radius: var(--radius);
  background: rgba(251, 191, 36, 0.07);
  animation: reveal var(--med) var(--ease);
}
.tip-box p { margin: 0; max-width: 62ch; color: var(--text-dim); font-size: var(--t-sm); line-height: 1.65; }
.tip-box button {
  justify-self: start;
  min-height: 34px;
  padding: 0 var(--s3);
  border: 1px solid rgba(251, 191, 36, 0.28);
  border-radius: var(--radius-sm);
  color: var(--language);
  background: rgba(251, 191, 36, 0.1);
  font-size: var(--t-sm);
  font-weight: 600;
}
.tip-box button:hover { background: rgba(251, 191, 36, 0.18); }

/* Controls dock to the bottom of the panel. The old rule used
   `min-height: 270px` to fake this, which left a dead gap on
   short exercises and clipped long ones. */
.exercise-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s5);
  margin-top: var(--s7);
  padding-top: var(--s6);
  border-top: 1px solid var(--line);
}
.drag-hint {
  flex: 1;
  color: var(--text-faint);
  font-size: var(--t-xs);
}
.practice-controls { display: flex; align-items: center; gap: var(--s5); }

.round-button {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  color: var(--text-dim);
  background: var(--raised);
  transition: color var(--fast) var(--ease), background var(--fast) var(--ease),
    border-color var(--fast) var(--ease);
}
.round-button svg { width: 20px; height: 20px; }
.round-button:hover { color: var(--text); background: var(--overlay); border-color: var(--line-mid); }

/* Primary action: bigger, and it now says something while live. */
.mic-orb {
  position: relative;
  display: grid;
  place-items: center;
  width: 80px;
  height: 80px;
  border-radius: var(--radius-pill);
  color: #04222f;
  background: linear-gradient(150deg, var(--cyan-bright), var(--teal));
  box-shadow: 0 10px 30px rgba(29, 190, 214, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.28);
  transition: transform var(--med) var(--ease), box-shadow var(--med) var(--ease),
    background var(--med) var(--ease);
}
.mic-orb svg { width: 32px; height: 32px; }
.mic-orb:hover { transform: scale(1.04); box-shadow: 0 14px 38px rgba(29, 190, 214, 0.42); }
.mic-orb:active { transform: scale(0.98); }

.mic-orb.recording {
  color: #fff;
  background: linear-gradient(150deg, #ff8a80, #d63a4e);
  box-shadow: 0 12px 34px rgba(214, 58, 78, 0.4);
}
/* Expanding ring — the app had no recording feedback at all, so
   there was nothing on screen confirming the mic was live. */
.mic-orb.recording::before,
.mic-orb.recording::after {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid rgba(255, 138, 128, 0.55);
  animation: pulse-ring 1.9s var(--ease) infinite;
  content: "";
}
.mic-orb.recording::after { animation-delay: 0.95s; }

@keyframes pulse-ring {
  from { opacity: 0.8; transform: scale(1); }
  to { opacity: 0; transform: scale(1.7); }
}

/* ---- 14. Results ------------------------------------------ */

.result-card { margin-top: var(--s5); padding: var(--s5); animation: reveal 300ms var(--ease); }
.result-top { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); }
.result-top h2 { margin: 0; font-size: var(--t-md); font-weight: 650; }
.score {
  font-size: var(--t-3xl);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(150deg, var(--cyan-bright), var(--fluency));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.result-card p {
  margin: var(--s3) 0 0;
  max-width: 62ch;
  color: var(--text-dim);
  font-size: var(--t-sm);
  line-height: 1.65;
}
.result-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s2);
  margin: var(--s4) 0;
}
.result-stat {
  padding: var(--s3);
  border-radius: var(--radius-sm);
  background: rgba(3, 14, 24, 0.5);
  border: 1px solid var(--line);
  text-align: center;
}
.result-stat strong {
  display: block;
  margin-bottom: 2px;
  font-size: var(--t-lg);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

/* Evidence for the score: what was asked vs what was heard. */
.transcript-compare {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s3);
  margin-top: var(--s4);
}
.transcript-compare > div {
  padding: var(--s3);
  border-radius: var(--radius-sm);
  background: rgba(3, 14, 24, 0.5);
  border: 1px solid var(--line);
}
.transcript-compare p {
  margin: var(--s1) 0 0;
  color: var(--text);
  font-size: var(--t-sm);
  line-height: 1.5;
}
.transcript-label {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.score-empty {
  color: var(--text-faint);
  font-size: var(--t-sm);
  font-weight: 600;
}

/* ---- 15. Settings ----------------------------------------- */

.settings-card { display: grid; gap: var(--s5); padding: var(--s5); }
.setting-row {
  display: grid;
  grid-template-columns: 1fr minmax(0, 260px);
  align-items: center;
  gap: var(--s4);
}
.setting-row label { color: var(--text); font-size: var(--t-base); font-weight: 550; }
.setting-row small { display: block; margin-top: 2px; max-width: 52ch; color: var(--text-dim); font-size: var(--t-sm); }
.setting-control { display: flex; align-items: center; gap: var(--s2); min-width: 0; }
.setting-control select { min-width: 0; flex: 1; }

select {
  min-height: 40px;
  padding: 0 var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  background: var(--sunken);
  font-size: var(--t-sm);
  transition: border-color var(--fast) var(--ease);
}
select:hover { border-color: var(--line-mid); }

/* ---- 16. Footer, empty states ----------------------------- */

.footer-links { display: grid; gap: var(--s2); margin-top: var(--s7); }
.footer-link {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 48px;
  padding: 0 var(--s4);
  color: var(--text-dim);
  font-size: var(--t-sm);
}
.footer-link svg { width: 17px; height: 17px; }
.footer-link:hover { color: var(--text); }

.empty-state {
  padding: var(--s8) var(--s5);
  border: 1px dashed var(--line-mid);
  border-radius: var(--radius-lg);
  color: var(--text-dim);
  text-align: center;
  font-size: var(--t-base);
}

/* ---- 17. Modal & toast ------------------------------------ */

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: grid;
  place-items: center;
  padding: var(--s5);
  background: rgba(2, 8, 16, 0.7);
  backdrop-filter: blur(10px);
  animation: reveal 180ms var(--ease);
}
.modal {
  width: min(100%, 440px);
  padding: var(--s6);
  border: 1px solid var(--line-mid);
  border-radius: var(--radius-lg);
  background: var(--raised);
  box-shadow: var(--shadow-3);
  animation: modal-in var(--med) var(--ease);
}
@keyframes modal-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
.modal h2 { margin: 0 0 var(--s3); font-size: var(--t-lg); font-weight: 680; letter-spacing: -0.026em; }
.modal p { margin: 0; color: var(--text-dim); font-size: var(--t-sm); line-height: 1.65; }
.modal-actions { display: flex; justify-content: flex-end; gap: var(--s2); margin-top: var(--s5); }

.passkey {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin: var(--s4) 0;
  padding: var(--s3) var(--s4);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-sm);
  color: var(--cyan-bright);
  background: rgba(53, 203, 228, 0.08);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--t-base);
  letter-spacing: 0.04em;
  word-break: break-all;
}
.passkey button {
  flex: 0 0 auto;
  padding: var(--s1) var(--s2);
  border: 1px solid var(--line-mid);
  border-radius: 7px;
  color: var(--cyan-bright);
  background: var(--raised);
  font: inherit;
  font-size: var(--t-xs);
}
.passkey button:hover { background: var(--overlay); }

#toast {
  position: fixed;
  right: var(--s5);
  bottom: var(--s5);
  z-index: 30;
  max-width: min(380px, calc(100vw - var(--s8)));
  padding: var(--s3) var(--s4);
  border: 1px solid var(--line-mid);
  border-radius: var(--radius-sm);
  color: var(--text);
  background: var(--overlay);
  box-shadow: var(--shadow-3);
  font-size: var(--t-sm);
  transform: translateY(12px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--med) var(--ease), transform var(--med) var(--ease);
}
#toast.show { transform: none; opacity: 1; }

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

/* ---- 18. Responsive --------------------------------------- */

@media (max-width: 720px) {
  .app-bar { padding: var(--s2) var(--s4); }
  .app-main { padding: var(--s5) var(--s4) var(--s8); }
  .brand-subtitle { display: none; }
  .hero-intro { padding: var(--s6) 0 var(--s5); }
  .hero-mark { width: 64px; height: 64px; }
  .hero-mark svg { width: 32px; height: 32px; }
  .exercise-panel { padding: var(--s5) var(--s4); }
  .task-box p { font-size: var(--t-md); }
  .setting-row { grid-template-columns: 1fr; gap: var(--s2); }
  .notice-actions { grid-template-columns: 1fr; }
  .result-grid { grid-template-columns: repeat(3, 1fr); gap: var(--s1); }
  .result-stat { padding: var(--s2); }
  .exercise-footer { flex-direction: column; gap: var(--s4); }
  .drag-hint { flex: none; text-align: center; }
  #toast { right: var(--s4); left: var(--s4); bottom: var(--s4); max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ============================================================
   19. Landing page
   Marketing entry point (index.html). Shares every token above so
   the site and the app read as one product.
   ============================================================ */

.skip-link {
  position: absolute;
  left: -9999px;
  top: var(--s2);
  padding: var(--s2) var(--s4);
  border-radius: var(--radius-sm);
  background: var(--overlay);
  color: var(--text);
  z-index: 40;
}
.skip-link:focus { left: var(--s4); }

.landing { color: var(--text); }
.landing a { color: inherit; text-decoration: none; }

.landing-nav { display: flex; align-items: center; gap: var(--s5); }
.landing-nav a { color: var(--text-dim); font-size: var(--t-sm); font-weight: 550; transition: color var(--fast) var(--ease); }
.landing-nav a:hover { color: var(--text); }
.landing-nav .primary-button { color: #04222f; }

.landing main { width: min(100%, 1000px); margin: 0 auto; padding: 0 var(--s5); }

/* Hero ------------------------------------------------------- */
.lp-hero { padding: var(--s9) 0 var(--s8); text-align: center; }
.lp-eyebrow {
  display: inline-block;
  margin: 0 0 var(--s5);
  padding: var(--s1) var(--s3);
  border-radius: var(--radius-pill);
  border: 1px solid rgba(53, 203, 228, 0.22);
  background: rgba(53, 203, 228, 0.1);
  color: var(--cyan-bright);
  font-size: var(--t-xs);
  font-weight: 650;
  letter-spacing: 0.04em;
}
.lp-hero h1 {
  max-width: 17ch;
  margin: 0 auto;
  font-size: clamp(34px, 6.4vw, 60px);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.042em;
  text-wrap: balance;
}
.lp-lede {
  max-width: 56ch;
  margin: var(--s5) auto 0;
  color: var(--text-dim);
  font-size: clamp(var(--t-md), 2.2vw, var(--t-lg));
  line-height: 1.6;
  text-wrap: pretty;
}
.lp-cta { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s3); margin-top: var(--s7); }
.lp-cta-main { min-height: 52px; padding: 0 var(--s7); font-size: var(--t-md); }
.lp-cta .secondary-button { min-height: 52px; padding: 0 var(--s5); font-size: var(--t-base); }
.lp-microcopy { margin: var(--s4) 0 0; color: var(--text-faint); font-size: var(--t-sm); }

/* Stat strip ------------------------------------------------- */
.lp-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--s3);
  padding: var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--sunken);
}
.lp-strip > div { display: grid; gap: var(--s1); justify-items: center; text-align: center; }
.lp-strip strong {
  font-size: var(--t-2xl);
  font-weight: 700;
  letter-spacing: -0.035em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(150deg, var(--cyan-bright), var(--teal));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.lp-strip span { color: var(--text-faint); font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }

/* Sections --------------------------------------------------- */
.lp-section { padding: var(--s9) 0 0; }
.lp-section > h2 {
  margin: 0;
  font-size: clamp(var(--t-xl), 3.6vw, var(--t-3xl));
  font-weight: 680;
  letter-spacing: -0.032em;
  line-height: 1.15;
  text-wrap: balance;
}
.lp-section-lede {
  max-width: 62ch;
  margin: var(--s3) 0 var(--s6);
  color: var(--text-dim);
  font-size: var(--t-md);
  line-height: 1.6;
}
.lp-section .category-card { cursor: default; }
.lp-section .category-card:hover { transform: none; }
.lp-section .category-card .progress-pill { margin-top: var(--s3); }

/* Scoring demo ----------------------------------------------- */
.lp-split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s6); align-items: start; }
.lp-demo {
  padding: var(--s5);
  border: 1px solid var(--line-mid);
  border-radius: var(--radius-lg);
  background: linear-gradient(155deg, var(--overlay), var(--raised));
  box-shadow: var(--shadow-2);
}
.lp-demo h3 { margin: 0; font-size: var(--t-md); font-weight: 650; }
.lp-demo .transcript-compare { grid-template-columns: 1fr 1fr; }
.lp-points { display: grid; gap: var(--s4); margin: 0; padding: 0; list-style: none; }
.lp-points li {
  padding-left: var(--s5);
  border-left: 2px solid var(--line-mid);
  color: var(--text-dim);
  font-size: var(--t-sm);
  line-height: 1.6;
}
.lp-points strong { display: block; color: var(--text); font-size: var(--t-base); font-weight: 620; margin-bottom: 2px; }

/* Privacy ---------------------------------------------------- */
.lp-privacy {
  margin-top: var(--s9);
  padding: var(--s7) var(--s6);
  border: 1px solid var(--line-mid);
  border-radius: var(--radius-lg);
  background: linear-gradient(155deg, var(--overlay), var(--raised));
  text-align: center;
}
.lp-privacy .notice-icon { margin: 0 auto var(--s4); width: 44px; height: 44px; }
.lp-privacy .notice-icon svg { width: 22px; height: 22px; }
.lp-privacy h2 { margin: 0; }
.lp-privacy p { max-width: 62ch; margin: var(--s4) auto 0; color: var(--text-dim); font-size: var(--t-base); line-height: 1.65; }

/* FAQ -------------------------------------------------------- */
.lp-faq { display: grid; gap: var(--s2); }
.lp-faq details {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--sunken);
  transition: border-color var(--fast) var(--ease);
}
.lp-faq details[open] { border-color: var(--line-mid); background: var(--raised); }
.lp-faq summary {
  padding: var(--s4) var(--s5);
  cursor: pointer;
  font-size: var(--t-base);
  font-weight: 600;
  list-style: none;
}
.lp-faq summary::-webkit-details-marker { display: none; }
.lp-faq summary::after { content: "+"; float: right; color: var(--text-faint); font-weight: 400; }
.lp-faq details[open] summary::after { content: "−"; }
.lp-faq p { margin: 0; padding: 0 var(--s5) var(--s5); max-width: 68ch; color: var(--text-dim); font-size: var(--t-sm); line-height: 1.65; }

/* Closing CTA + footer --------------------------------------- */
.lp-final { padding: var(--s9) 0; text-align: center; }
.lp-final h2 { margin: 0; font-size: clamp(var(--t-xl), 4vw, var(--t-3xl)); font-weight: 700; letter-spacing: -0.035em; }
.lp-final p { margin: var(--s3) 0 var(--s6); color: var(--text-dim); font-size: var(--t-md); }

.lp-footer {
  width: min(100%, 1000px);
  margin: 0 auto;
  padding: var(--s6) var(--s5) var(--s8);
  border-top: 1px solid var(--line);
  color: var(--text-faint);
  font-size: var(--t-sm);
}
.lp-disclaimer { max-width: 72ch; margin: 0 0 var(--s4); line-height: 1.6; }
.lp-disclaimer strong { color: var(--text-dim); }
.lp-footer a { color: var(--cyan-bright); }

@media (max-width: 780px) {
  .landing-nav a:not(.primary-button) { display: none; }
  .lp-hero { padding: var(--s8) 0 var(--s7); }
  .lp-section { padding-top: var(--s8); }
  .lp-split { grid-template-columns: 1fr; gap: var(--s5); }
  .lp-cta { flex-direction: column; }
  .lp-cta a { width: 100%; }
}

/* ---- 20. Generated exercise pages -------------------------- */

.lp-crumbs { padding: var(--s6) 0 var(--s4); color: var(--text-faint); font-size: var(--t-sm); }
.lp-crumbs a { color: var(--text-dim); }
.lp-crumbs a:hover { color: var(--text); }

.lp-article { max-width: 68ch; padding-bottom: var(--s8); }
.lp-article h1 {
  margin: var(--s4) 0 0;
  font-size: clamp(var(--t-2xl), 5vw, 44px);
  font-weight: 700;
  letter-spacing: -0.036em;
  line-height: 1.1;
  text-wrap: balance;
}
.lp-article h2 {
  margin: var(--s8) 0 var(--s4);
  font-size: var(--t-lg);
  font-weight: 650;
  letter-spacing: -0.022em;
}
.lp-lede-left { margin-left: 0; margin-right: 0; text-align: left; }
.lp-article .task-box p:not(.task-label) { font-size: var(--t-md); }
.lp-article .tip-box { background: rgba(251, 191, 36, 0.07); }

.lp-inline-cta {
  margin-top: var(--s8);
  padding: var(--s6);
  border: 1px solid var(--line-mid);
  border-radius: var(--radius-lg);
  background: linear-gradient(155deg, var(--overlay), var(--raised));
  text-align: center;
}
.lp-inline-cta .lp-microcopy { margin-top: var(--s3); }

.lp-links { display: grid; gap: var(--s1); margin: 0; padding: 0; list-style: none; }
.lp-links li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s3) var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--sunken);
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.lp-links li:hover { background: var(--raised); border-color: var(--line-mid); }
.lp-links a { font-size: var(--t-base); font-weight: 550; }
.lp-links span { flex: 0 0 auto; color: var(--text-faint); font-size: var(--t-xs); text-transform: uppercase; letter-spacing: 0.06em; }

.lp-hero-compact { padding: var(--s7) 0 var(--s5); text-align: left; }
.lp-hero-compact .lp-lede { margin-left: 0; }

/* Progress transfer modal */
.transfer-label { margin: var(--s5) 0 var(--s2); color: var(--text-dim); font-size: var(--t-sm); font-weight: 600; }
.passkey input {
  flex: 1;
  min-width: 0;
  padding: var(--s2);
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--sunken);
  color: var(--text);
  font: inherit;
  font-size: var(--t-sm);
}
.passkey input::placeholder { color: var(--text-faint); }
.passkey span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- 21. Legal pages --------------------------------------- */

.lp-legal { max-width: 74ch; }
.lp-legal-date { margin: var(--s3) 0 var(--s7); color: var(--text-faint); font-size: var(--t-sm); }
.lp-legal h2 { font-size: var(--t-md); margin-top: var(--s7); }
.lp-legal p, .lp-legal li { color: var(--text-dim); font-size: var(--t-base); line-height: 1.7; }
.lp-legal p { margin: 0 0 var(--s4); }
.lp-legal ul { margin: 0 0 var(--s4); padding-left: var(--s5); display: grid; gap: var(--s2); }
.lp-legal a { color: var(--cyan-bright); text-decoration: underline; text-underline-offset: 2px; }
.lp-legal strong { color: var(--text); }

.lp-summary {
  padding: var(--s5);
  border: 1px solid var(--line-mid);
  border-radius: var(--radius-lg);
  background: linear-gradient(155deg, var(--overlay), var(--raised));
}
.lp-summary h2 { margin: 0 0 var(--s3); font-size: var(--t-base); text-transform: uppercase; letter-spacing: 0.08em; color: var(--cyan-bright); }
.lp-summary ul { margin: 0; }
.lp-summary p:last-child { margin-bottom: 0; }
.lp-summary-warn { border-color: rgba(251, 191, 36, 0.3); background: rgba(251, 191, 36, 0.07); }
.lp-summary-warn h2 { color: var(--language); }

.lp-privacy-note {
  max-width: 62ch;
  margin: var(--s4) auto 0;
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
  color: var(--text-faint);
  font-size: var(--t-sm);
  line-height: 1.6;
}
.lp-privacy-note a { color: var(--cyan-bright); text-decoration: underline; text-underline-offset: 2px; }

.modal-link { color: var(--cyan-bright); text-decoration: underline; text-underline-offset: 2px; font-weight: 600; }

/* ---- 22. Word accuracy heatmap ----------------------------- */

.heatmap { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s4); }
.heat {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: var(--t-sm);
  font-weight: 550;
}
.heat small { font-size: var(--t-xs); font-variant-numeric: tabular-nums; opacity: 0.75; }
.heat-good { color: #86efac; background: rgba(52, 211, 153, 0.14); border-color: rgba(52, 211, 153, 0.28); }
.heat-mid  { color: #fcd34d; background: rgba(251, 191, 36, 0.14); border-color: rgba(251, 191, 36, 0.28); }
.heat-poor { color: #fda4af; background: rgba(251, 113, 133, 0.14); border-color: rgba(251, 113, 133, 0.3); }

.heat-legend {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
  color: var(--text-faint);
  font-size: var(--t-xs);
}
.heat-legend .heat { width: 14px; height: 14px; padding: 0; border-radius: 4px; }
.heat-legend .heat:not(:first-child) { margin-left: var(--s3); }

.plan-card.complete { border-color: rgba(52, 211, 153, 0.32); }
.plan-card.complete .progress-pill { color: #86efac; background: rgba(52, 211, 153, 0.14); border-color: rgba(52, 211, 153, 0.28); }

.modal .task-box { margin: var(--s4) 0; }
.modal .chips { margin-top: var(--s3); }
.modal .completion-progress { margin: var(--s4) 0 var(--s3); }
.modal .primary-button { width: 100%; margin-top: var(--s2); }
