/* ============================================================
   Homeschool — single stylesheet (v2).
   §-refs: foundation-design-system.md §4–§6,
           foundation-aesthetic-v2.md §2–§6,
           foundation-app-shell.md §5–§6,
           student-dashboard.md §5–§6,
           trophy-room.md §5–§6,
           lesson.md §5–§6,
           quiz-card.md §5–§6.
   ============================================================ */

/* ============================================================
   TOKENS — §4 / §5
   Theme-independent constants (spacing, type, containers, fonts,
   icon scale, aside widths). Per-theme value sets follow below.
   ============================================================ */
:root {
  /* Families — v2 §4g */
  --font-body: 'Plus Jakarta Sans', system-ui, -apple-system, sans-serif;
  --font-headline: 'Epilogue', Georgia, serif;
  /* Back-compat alias for any V1 references that linger one cycle */
  --font-sans: var(--font-body);

  /* Spacing */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; --space-7: 48px; --space-8: 64px;

  /* Type scale */
  --text-xs: 12px; --text-sm: 14px; --text-base: 16px; --text-lg: 18px;
  --text-xl: 20px; --text-2xl: 28px; --text-3xl: 32px; --text-display: 40px;

  /* Weights — v2 adds 300 (script-accent) + 600 (medium) */
  --weight-light: 300; --weight-regular: 400; --weight-medium: 600; --weight-bold: 700;

  /* Containers — V1 holdovers */
  --container-narrow: 520px; --container-base: 720px; --container-wide: 1080px;

  /* Containers — v2 §4k additions */
  --content-max-width: 1280px;
  --prose-max-width: 65ch;
  --aside-collapsed-width: 64px;
  --aside-open-width: 360px;
  --nav-width: 180px;

  /* Icon size scale — v2 §4l (Material Symbols Outlined) */
  --icon-size-sm: 16px;
  --icon-size-md: 20px;
  --icon-size-lg: 24px;
  --icon-size-xl: 32px;
  --icon-size-hero: 64px;

  /* Radius — cross-theme constants */
  --radius-sm: 8px; --radius-md: 14px; --radius-lg: 24px; --radius-pill: 9999px;

  /* Motion — cross-theme constants */
  --duration-fast: 180ms;
  --duration-base: 260ms;
  --duration-slow: 400ms;
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);

  /* Semantic — cross-theme constants per v2 §2.3d */
  --success: #4FB58A;
  --warning: #E8A23A;
  --info: #7B9BC9;
  --gold: #E8A23A;
  --warning-strong: #C77400;

  /* School-phase avatar rings (§4d-i). CATEGORICAL, not semantic — which phase
     a child is in, never how they are doing. Warm→cool tracks younger→older so
     the progression needs no legend. Values here are the dark-glass (Spark)
     tier; Bloom overrides to the darker, more saturated variants below, because
     these hues wash out on its light glass. No red (never-red rule), and kept
     clear of --success/--warning/--info, which own green/amber/blue. */
  --phase-early-el: #F472B6;   /* K-2   pink   */
  --phase-upper-el: #FACC15;   /* 3-5   gold   */
  --phase-middle:   #2DD4BF;   /* 6-8   teal   */
  --phase-high:     #C084FC;   /* 9-12  violet */
}

/* §5a Spring–Spark v2 (sky / cloud) — default :root */
:root {
  /* Substrate */
  --bg-base: #020617;
  --bg-elevated: #FFFFFF;
  --bg-gradient-stop-1: #020617;
  --bg-gradient-stop-2: #1e3a8a;
  --bg-gradient-stop-3: #bfdbfe;
  --bg-gradient-angle: 170deg;
  --bokeh-tint-1: transparent;
  --bokeh-tint-2: transparent;
  --bokeh-tint-3: transparent;
  --ambient-particle-color-far: rgba(255, 255, 255, 0.30);
  --ambient-particle-color-mid: rgba(255, 255, 255, 0.45);
  --ambient-particle-color-near: rgba(255, 255, 255, 0.60);
  /* Deprecated v2 — replaced by --bg-gradient-* + --bokeh-tint-*.
     Kept as transparent for one cycle so any stragglers no-op. */
  --bg-wash: none;

  /* Glass */
  --surface-glass: rgba(255, 255, 255, 0.45);
  --surface-glass-strong: rgba(255, 255, 255, 0.65);
  --surface-glass-chrome: rgba(255, 255, 255, 0.55);
  --border-glass: rgba(255, 255, 255, 0.40);
  --border-focus: #2563EB;
  --glass-blur: 16px;
  --glass-border-width: 1px;
  --glass-inner-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85);

  /* Text — light-glass on bright sky substrate: dark text reads cleanly. */
  --text-primary: #001D33;
  --text-secondary: #3D4B5A;
  --text-muted: #7589A0;
  --text-on-accent: #FFFFFF;

  /* Accents */
  --accent-primary: #2563EB;
  --accent-secondary: #60A5FA;
  --accent-highlight: #A7D6F4;
  /* Emphasis halo (Track Diff §12.1). White by default; Bloom overrides to the
     rose accent below since a white glow vanishes on its light glass. */
  --glow-emphasis: #FFFFFF;
}

/* §5a-dark Spring–Spark v2 — Dark Glass variant (PL#16).
   Activated automatically on Spark (the default `:root`); Bloom keeps
   light glass. The substrate stays sky/cloud; only the glass tier
   values + text family invert toward dark-panel-with-light-text.
   We target body:not(.theme-bloom) so inline variables defined on body are correctly resolved. */
body:not(.theme-bloom) {
  --surface-glass:        rgba(var(--glass-shade, 15), var(--glass-shade, 23), var(--glass-shade, 42), var(--glass-opacity, 0.55));   /* deep slate, mid opacity */
  --surface-glass-strong: rgba(var(--glass-shade, 15), var(--glass-shade, 23), var(--glass-shade, 42), calc(var(--glass-opacity, 0.55) + 0.17));
  --surface-glass-chrome: rgba(var(--glass-shade, 15), var(--glass-shade, 23), var(--glass-shade, 42), calc(var(--glass-opacity, 0.55) + 0.23));   /* densest for nav legibility */
  --border-glass: rgba(255, 255, 255, 0.18);
  --glass-inner-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10);


  --text-primary: #F0F9FF;
  --text-secondary: #B8C5D6;
  --text-muted: #9DB1C7;

  /* Accent re-tuning so they pop against dark glass instead of light. */
  --accent-primary: #60A5FA;     /* lighter sky-blue for high contrast */
  --accent-secondary: #A7D6F4;
  --accent-highlight: #BFCBF0;
  /* Bright near-white halo — reads as white against the dark glass. */
  --glow-emphasis: #F0F9FF;

  /* Shadow softens against dark slate. */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.18);
  --shadow-md: 0 8px 22px rgba(0, 0, 0, 0.28), 0 2px 6px rgba(0, 0, 0, 0.18);
  --shadow-lg: 0 22px 48px rgba(0, 0, 0, 0.36), 0 4px 12px rgba(0, 0, 0, 0.20);
  --shadow-glow: 0 0 24px rgba(96, 165, 250, 0.55);



  /* Shadow */
  --shadow-sm: 0 1px 2px rgba(0, 29, 51, 0.06);
  --shadow-md: 0 8px 22px rgba(0, 29, 51, 0.08), 0 2px 6px rgba(0, 29, 51, 0.05);
  --shadow-lg: 0 22px 48px rgba(0, 29, 51, 0.14), 0 4px 12px rgba(0, 29, 51, 0.07);
  --shadow-glow: 0 0 24px rgba(37, 99, 235, 0.40);



  --track-eyebrow: 0.06em;
  --track-display: -0.02em;
}

/* §5b Spring–Bloom v2 (rosy) — body.theme-bloom */
body.theme-bloom {
  /* Substrate */
  --bg-base: #FFF7F9;
  --bg-elevated: #FFFFFF;
  --bg-gradient-stop-1: #FFD1E8;
  --bg-gradient-stop-2: #FBA6C9;
  --bg-gradient-stop-3: #FFF0F5;
  --bg-gradient-angle: 135deg;
  --bokeh-tint-1: rgba(255, 209, 232, 0.55);
  --bokeh-tint-2: rgba(251, 166, 201, 0.50);
  --bokeh-tint-3: rgba(255, 233, 168, 0.40);
  --ambient-particle-color-far: rgba(255, 255, 255, 0.30);
  --ambient-particle-color-mid: rgba(255, 255, 255, 0.45);
  --ambient-particle-color-near: rgba(255, 233, 168, 0.55);
  --bg-wash: none;

  --surface-glass: rgba(255, 255, 255, var(--glass-opacity, 0.18));
  --surface-glass-strong: rgba(255, 255, 255, calc(var(--glass-opacity, 0.18) + 0.22));
  --surface-glass-chrome: rgba(255, 255, 255, calc(var(--glass-opacity, 0.18) + 0.07));
  --border-glass: rgba(255, 255, 255, 0.15);

  --border-focus: #C2185B;
  --glass-blur: 20px;
  --glass-border-width: 1px;
  --glass-inner-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15);

  /* Text */
  --text-primary: #2A1F2D;
  --text-secondary: #5E4F5F;
  --text-muted: #8E7E8E;
  --text-on-accent: #FFFFFF;

  /* Accents */
  --accent-primary: #C2185B;
  --accent-secondary: #F08A8A;
  --accent-highlight: #FFE9A8;
  /* Light glass — a white halo would vanish, so the emphasis glow rides the
     rose accent here instead of white. */
  --glow-emphasis: var(--accent-primary);

  /* School-phase rings (§4d-i) — darker, more saturated than the Spark tier.
     The light-tier hues are chosen for contrast against light glass; the bright
     variants used on dark glass go muddy here. */
  --phase-early-el: #EC4899;
  --phase-upper-el: #CA8A04;
  --phase-middle:   #0D9488;
  --phase-high:     #9333EA;

  /* Shadow */
  --shadow-sm: 0 1px 2px rgba(80, 40, 60, 0.06);
  --shadow-md: 0 8px 22px rgba(80, 40, 60, 0.10), 0 2px 6px rgba(80, 40, 60, 0.06);
  --shadow-lg: 0 22px 48px rgba(80, 40, 60, 0.16), 0 4px 12px rgba(80, 40, 60, 0.08);
  --shadow-glow: 0 0 28px rgba(194, 24, 91, 0.40);

  --track-eyebrow: 0.08em;
  --track-display: -0.005em;
}

/* ============================================================
   BASE — resets + body binding (design system §6)
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
/* 100dvh (dynamic viewport height) tracks the *visible* area as iPad Safari's
   toolbars show/hide. With a plain 100vh + overflow:hidden shell, the browser
   sizes to the toolbar-retracted height, so the bottom of the fixed shell hides
   behind the toolbar and can't be scrolled to. 100vh stays as the fallback. */
html { -webkit-text-size-adjust: 100%; height: 100vh; height: 100dvh; overflow: hidden; }
body {
  margin: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  background-color: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-regular);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Headings auto-bind to the headline family per design-system §4g */
h1, h2, h3 { font-family: var(--font-headline); font-weight: var(--weight-medium); letter-spacing: -0.01em; }
h1 { font-size: var(--text-3xl); line-height: 1.2; }
h2 { font-size: var(--text-2xl); line-height: 1.3; }
h3 { font-size: var(--text-xl); line-height: 1.4; }

/* Material Symbols base — sized via icon tokens; color inherits */
.material-symbols-outlined {
  font-family: 'Material Symbols Outlined';
  font-weight: normal;
  font-style: normal;
  display: inline-block;
  line-height: 1;
  text-transform: none;
  letter-spacing: normal;
  word-wrap: normal;
  white-space: nowrap;
  direction: ltr;
  -webkit-font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
  font-size: var(--icon-size-md);
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}

/* a11y helper */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}

/* PL#4 — thin, theme-tinted scrollbars across all scrollable surfaces. */
* { scrollbar-width: thin; scrollbar-color: var(--text-muted) transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--text-muted) 60%, transparent);
  border-radius: var(--radius-pill);
}
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* ============================================================
   GLASS RECIPE (design system §6 — v2)
   Content/card tier = --surface-glass / --surface-glass-strong
   Chrome tier       = --surface-glass-chrome (highest opacity for nav)
   ============================================================ */
.subject-card,
.trophy-room__hero, .trophy-room__momentum, .trophy-room__next,
.trophy-card,
.lesson__summary,
.quiz-card,
.quiz-summary__hero, .quiz-summary__delta, .quiz-summary__trophies,
.dashboard-hero, .dashboard-momentum,
.choice-card,
.dashboard-growth,
.trophy-strip,
.up-next-card,
.today-plan {
  background: var(--surface-glass);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: var(--glass-border-width) solid var(--border-glass);
  box-shadow: var(--shadow-md), var(--glass-inner-shadow);
}

/* Chrome tier — nav surfaces */
.shell__topbar, .shell__nav, .shell__tutor {
  background: var(--surface-glass-chrome);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  box-shadow: var(--shadow-md), var(--glass-inner-shadow);
}
.shell__topbar {
  border-bottom: var(--glass-border-width) solid var(--border-glass);
}
.shell__nav {
  border-right: var(--glass-border-width) solid var(--border-glass);
}

/* ============================================================
   SUBSTRATE — v2 §2.2 (5-layer ambient theme background)
   Layer 1: gradient · 2: bokeh underglow · 3: pattern (optional)
   Layer 4: animated particles · Layer 5 = the glass surfaces above
   ============================================================ */
.shell__substrate {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.shell__substrate-gradient {
  position: absolute; inset: 0;
  background: linear-gradient(
    var(--bg-gradient-angle),
    var(--bg-gradient-stop-1),
    var(--bg-gradient-stop-2) 55%,
    var(--bg-gradient-stop-3)
  );
  /* Dialed back for V1 ship; iterate on per-theme intensity later. */
  opacity: 0.55;
}
body:not(.theme-bloom) .shell__substrate-gradient {
  opacity: 1.0;
}

.shell__substrate-bokeh {
  position: absolute; inset: 0;
  background:
    radial-gradient(circle 360px at 18% 22%, var(--bokeh-tint-1), transparent 70%),
    radial-gradient(circle 460px at 78% 60%, var(--bokeh-tint-2), transparent 70%),
    radial-gradient(circle 280px at 40% 88%, var(--bokeh-tint-3), transparent 70%);
  filter: blur(60px);
  opacity: 0.35;
}

.shell__substrate-pattern {
  position: absolute; inset: 0;
  background-image:
    repeating-linear-gradient(45deg, rgba(255,255,255,0.02) 0 2px, transparent 2px 6px);
  opacity: 0.4;
  mix-blend-mode: soft-light;
}

.shell__substrate-particles {
  position: absolute; inset: 0;
}
.shell__substrate-particles .motes-svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  overflow: visible;
}

/* Bloom — rising motes (slow drift up + sideways meander).
   Each particle reads its own --mote-delay / --mote-dur / --mote-sway-mid
   / --mote-sway-end / --mote-rot from inline style, with tier-default
   fallbacks here. Different durations PER particle (not just delays)
   means no two particles share a phase relationship for long, which
   breaks the lock-step cluster. ease-in-out keyframe gives the motion
   a gust-like feel instead of a linear conveyor. */
.shell__substrate-particles .mote {
  transform-origin: center;
  animation: mote-rise calc(var(--mote-dur, 28s) / var(--particle-speed-mult, 1)) ease-in-out var(--mote-delay, 0s) infinite;
  opacity: var(--particle-opacity, 0.55);
}
.shell__substrate-particles .mote--mid {
  animation-duration: calc(var(--mote-dur, 36s) / var(--particle-speed-mult, 1));
  opacity: calc(var(--particle-opacity, 0.55) + 0.10);
}
.shell__substrate-particles .mote--near {
  /* Fireflies: rise + blink. Two parallel animations — `mote-rise` for
     the slow vertical drift, `firefly-pulse` for the fast on/off blink.
     The later animation wins for `opacity` per CSS animation cascade,
     so the pulse fully controls when each firefly is visible. */
  animation: mote-rise calc(var(--mote-dur, 22s) / var(--particle-speed-mult, 1)) ease-in-out var(--mote-delay, 0s) infinite,
             firefly-pulse calc(var(--firefly-dur, 2.4s) / var(--firefly-speed-mult, 1)) ease-in-out var(--firefly-delay, 0s) infinite;
  opacity: calc(var(--particle-opacity, 0.55) + 0.20);
}
@keyframes mote-rise {
  0%   { transform: translate(0, 8vh) rotate(0deg) scale(0.9); opacity: 0; }
  10%  { opacity: var(--particle-opacity, 0.55); }
  50%  { transform: translate(var(--mote-sway-mid, 40px), -40vh) rotate(calc(var(--mote-rot, 0deg) * 0.5)) scale(1.05); }
  90%  { opacity: calc(var(--particle-opacity, 0.55) * 0.8); }
  100% { transform: translate(var(--mote-sway-end, -20px), -90vh) rotate(var(--mote-rot, 0deg)) scale(0.95); opacity: 0; }
}
/* Firefly blink — sharp ramp to bright, hold, fade back to near-dark.
   Per-particle --firefly-delay scatters the blinks so the cluster
   doesn't pulse in unison. */
@keyframes firefly-pulse {
  0%, 100% { opacity: 0.08; }
  40%, 55% { opacity: 1; }
}

/* Theme-scoped particle sprite selection */
.shell__substrate-particles .particles--bloom { display: none; }
.shell__substrate-particles .particles--spark { display: none; }
body.theme-bloom:not(.focus-mode) .shell__substrate-particles .particles--bloom { display: block; }
body:not(.theme-bloom):not(.focus-mode) .shell__substrate-particles .particles--spark { display: block; }


@media (prefers-reduced-motion: reduce) {
  .shell__substrate-particles * { animation: none !important; }
}

/* ============================================================
   APP SHELL — foundation-app-shell.md §6
   ============================================================ */
.shell {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: var(--nav-width) 1fr;
  grid-template-rows: auto 1fr;
  height: 100vh;
  height: 100dvh;          /* iPad Safari toolbar-safe (see html/body note) */
  max-height: 100vh;
  max-height: 100dvh;
  overflow: hidden;
}
.shell__topbar {
  grid-column: 1 / -1;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4);
  padding: 5px var(--space-6);
  max-height: 62px;
  /* z-index must stay above .shell__tutor (z=20) so the slide-out
     doesn't sweep over the topbar controls during expand. */
  position: sticky; top: 0; z-index: 30;
}
.shell__topbar-left {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
.shell__topbar-divider {
  width: 1px;
  height: 20px;
  background: var(--border-glass);
  opacity: 0.6;
}
.shell__identity { display: flex; align-items: center; gap: var(--space-3); }
.shell__avatar {
  width: var(--space-7); height: var(--space-7);
  border-radius: var(--radius-pill); object-fit: cover;
  border: var(--glass-border-width) solid var(--border-glass);
}
.shell__identity-meta { display: flex; flex-direction: column; gap: var(--space-1); align-items: flex-start; }
.shell__student-name { font-size: var(--text-base); font-weight: var(--weight-bold); color: var(--text-primary); }
.shell__grade-badge {
  background: var(--accent-secondary); color: var(--text-on-accent);
  border-radius: var(--radius-pill); font-size: var(--text-xs);
  font-weight: var(--weight-medium); padding: var(--space-1) var(--space-3);
}

.shell__progress {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: var(--space-2);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: 4px var(--space-4);
}
.shell__xp-meta { display: flex; align-items: center; gap: var(--space-3); }
.shell__level-chip {
  background: var(--accent-primary); color: var(--text-on-accent);
  border-radius: var(--radius-pill); font-size: var(--text-xs);
  font-weight: var(--weight-bold); padding: var(--space-1) var(--space-3);
}
.shell__xp-value { font-size: var(--text-xs); color: var(--text-secondary); }
.shell__xp-bar {
  width: 200px; height: var(--space-2);
  background: var(--surface-glass-strong);
  border-radius: var(--radius-pill); overflow: hidden;
}
.shell__xp-fill {
  height: 100%; width: var(--xp-pct, 0%);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent-secondary), var(--accent-highlight));
  transition: width var(--duration-slow) var(--ease-out);
}

.shell__topbar-actions { display: flex; align-items: center; gap: var(--space-3); }
.shell__streak-chip {
  display: flex; align-items: center; gap: var(--space-2);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill); padding: var(--space-1) var(--space-3);
}
.shell__streak-icon { color: var(--warning); line-height: 1; font-size: var(--icon-size-md); }
.shell__streak-value { font-size: var(--text-sm); font-weight: var(--weight-bold); color: var(--text-primary); }
.shell__icon-btn {
  display: grid; place-items: center;
  /* 44px min hit area — icon-only chrome controls (notifications, tutor,
     logout) were 20-38px, below the touch-target floor on iPad. */
  min-width: 44px; min-height: 44px;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill); padding: var(--space-2);
  color: var(--text-secondary); cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out),
              color var(--duration-base) var(--ease-out);
}
.shell__icon-btn:hover { box-shadow: var(--shadow-glow); color: var(--text-primary); }
.shell__icon-btn .material-symbols-outlined { font-size: var(--icon-size-md); }
.shell__icon { line-height: 1; font-size: var(--text-base); }

@media (max-width: 1100px) {
  .shell__progress { flex-direction: row; align-items: center; gap: var(--space-3); }
  .shell__xp-bar { width: 120px; }
  .shell__xp-value { display: none; }
}
@media (max-width: 820px) {
  /* Wrap to a second row on narrow viewports; lift the height cap so
     the wrapped row isn't clipped. */
  .shell__topbar { flex-wrap: wrap; row-gap: var(--space-2); max-height: none; }
  .shell__progress { order: 3; flex-basis: 100%; justify-content: center; }
}

.shell__nav {
  grid-row: 2; grid-column: 1;
  width: var(--nav-width);              /* 180px */
  display: flex; flex-direction: column; gap: var(--space-5);
  /* 12.5px inline padding centers a 155px-wide nav link inside the 180px rail. */
  padding: var(--space-5) 12.5px;
  overflow-y: auto;
  overflow-x: hidden;
}
.shell__nav-brand {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2);
  font-family: var(--font-headline);
  font-size: var(--text-lg); font-weight: var(--weight-bold);
  color: var(--text-primary); text-decoration: none;
}
.shell__nav-mark { color: var(--accent-primary); font-size: var(--icon-size-lg); }
.shell__nav-wordmark { letter-spacing: -0.01em; }
.shell__nav-identity {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
}
.shell__nav-avatar {
  width: var(--space-7); height: var(--space-7);
  border-radius: var(--radius-pill); object-fit: cover;
}
.shell__nav-identity-meta { display: flex; flex-direction: column; gap: 2px; }
.shell__nav-student-name { font-size: var(--text-sm); font-weight: var(--weight-bold); color: var(--text-primary); }
.shell__nav-rank-label { font-size: var(--text-xs); color: var(--text-secondary); }
.shell__nav-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); flex: 1; }
.shell__nav-footer { margin-top: auto; }
.shell__nav-link {
  display: flex; align-items: center;
  /* 20px icon + 8px gap + 89px (longest label "Trophy Room") = 117px
     content. With 12px left + 6px right padding inside a 155px link,
     content area = 137px — comfortable fit. */
  gap: 8px; width: 100%;
  padding: var(--space-3) 6px var(--space-3) 12px;
  border: none; background: transparent;
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--text-secondary); text-decoration: none; text-align: left; cursor: pointer;
  transition: background var(--duration-base) var(--ease-out),
              color var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
.shell__nav-link:hover { background: var(--surface-glass-strong); color: var(--text-primary); }
.shell__nav-link[data-state="active"] {
  background: var(--accent-primary); color: var(--text-on-accent);
  box-shadow: inset 0 0 0 1px var(--border-glass),
              0 0 15px color-mix(in srgb, var(--accent-primary) 40%, transparent);
}
.shell__nav-icon { font-size: var(--icon-size-md); color: currentColor; }
.shell__nav-link[data-state="active"] .shell__nav-icon {
  font-variation-settings: 'FILL' 1, 'wght' 600;
}
.shell__nav-label { font-family: inherit; }

.shell__main {
  /* The container fills the grid column so the scrollbar tracks the
     viewport's right edge; content is centered via padding-inline:max(...)
     instead of max-width + margin-inline:auto, which used to anchor the
     scrollbar to a 1280px centered box and "drift" inward on wide windows. */
  grid-row: 2; grid-column: 2;
  padding: var(--space-7) max(var(--space-7), calc((100% - var(--content-max-width)) / 2));
  overflow-y: auto;
}
.shell__main:has(> .settings) { padding-top: 35px; }
.shell__main:has(.parent) { padding-top: var(--space-3); }
/* Family Setup's <main> isn't tagged `.parent`, so it fell back to the 48px
   default and stacked with shell__surface (16px) + family-setup (12px) into a
   dead band below the topper (S10). Scope it down like the other parent
   surfaces. */
.shell__main:has(.family-setup) { padding-top: var(--space-3); }
/* The parent chrome lays out its own full-bleed surface under a sticky topper,
   so it opts out of shell__main's centering padding instead of double-indenting.
   Was two inline styles on the element (tokens-only rule, CLAUDE.md). */
.shell__main--flush { padding-left: 0; width: 100%; }
.shell__surface--parent { padding-top: var(--space-4); width: 100%; }
/* The logout control sits inside a <form>, which would otherwise break the
   icon row's flex line, and it wants the 44px hit area from .shell__icon-btn
   WITHOUT the glass chrome — the row already has one glass button beside it and
   two read as a pair of unrelated controls. Was four inline styles. */
.shell__logout-form {
  display: inline-flex; align-items: center; margin-left: var(--space-1);
}
.shell__icon-btn--bare {
  background: none; border: none; color: inherit; padding: 0;
}
.shell__breadcrumbs {
  font-size: var(--text-xs); color: var(--text-secondary);
  display: flex; align-items: center; gap: var(--space-2);
}
.shell__breadcrumbs a { color: inherit; text-decoration: none; }
.shell__breadcrumbs a:hover { color: var(--text-primary); }
.shell__crumb-current { color: var(--text-primary); font-weight: var(--weight-medium); }

/* AI Tutor aside — v2 §2.7c + PL#3.
   Default <1200px: fixed-position slide-out OVER content (overlay).
   The panel keeps its full width at all times and is translated off
   the right edge of the viewport when collapsed; transitioning on
   `transform` makes it slide IN from the right rather than expanding
   from 0-width (which looked like content materializing left-to-right).
   >=1200px: when expanded, the shell grid grows a 3rd column and the
   main pane shrinks so tutor + lesson sit side-by-side, no overlap. */
.shell__tutor {
  position: fixed; top: 0; right: 0; height: 100vh; height: 100dvh;
  width: var(--aside-open-width);
  transform: translateX(100%);
  z-index: 20;
  /* Flex column so a long transcript scrolls inside the panel instead of
     spilling off the bottom (the body flex-fills; the transcript scrolls). */
  display: flex; flex-direction: column;
  overflow: hidden;
  background: var(--surface-glass-chrome);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border-left: var(--glass-border-width) solid var(--border-glass);
  box-shadow: var(--shadow-md), var(--glass-inner-shadow);
  transition: transform var(--duration-slow) var(--ease-out);
}
.shell__tutor[data-state="expanded"] {
  transform: translateX(0);
}

@media (min-width: 1200px) {
  /* On wide viewports, give the aside its own grid track so it doesn't overlap. */
  .shell:has(.shell__tutor[data-state="expanded"]) {
    grid-template-columns: var(--nav-width) 1fr var(--aside-open-width);
    padding-right: 0;
  }
  .shell:has(.shell__tutor[data-state="expanded"]) .shell__tutor {
    position: relative; height: auto;
    grid-row: 2; grid-column: 3;
    z-index: 1;
    transform: none;
  }
}

/* Tablet / iPad (both orientations) — below 1200px the tutor is a fixed
   overlay: it starts at top:0 *behind* the topbar (which wraps to 2–3 rows at
   these widths — up to ~160px on a lesson — hiding the top of the panel and its
   reply box), and it covers the very lesson/question it's helping with. Give it
   its own grid column instead (as we do ≥1200px) so it sits BELOW the topbar and
   BESIDE the content, and collapse the left nav to an icon rail to buy the room.
   Nav stays reachable — icons only, labels return when the tutor closes. */
@media (min-width: 600px) and (max-width: 1199px) {
  .shell:has(.shell__tutor[data-state="expanded"]) {
    /* 60px icon rail · content (1fr) · tutor (shrinks to 320 before content does) */
    grid-template-columns: 60px 1fr minmax(320px, var(--aside-open-width));
    padding-right: 0;
  }
  .shell:has(.shell__tutor[data-state="expanded"]) .shell__tutor {
    position: relative; height: auto;
    grid-row: 2; grid-column: 3;
    z-index: 1; transform: none;
    width: auto;
  }
  /* Left nav → icon rail: narrow the track, drop every text label, center icons. */
  .shell:has(.shell__tutor[data-state="expanded"]) .shell__nav {
    width: 60px; padding-left: 0; padding-right: 0; align-items: center;
  }
  .shell:has(.shell__tutor[data-state="expanded"]) .shell__nav-wordmark,
  .shell:has(.shell__tutor[data-state="expanded"]) .shell__nav-label {
    display: none;
  }
  .shell:has(.shell__tutor[data-state="expanded"]) .shell__nav-brand,
  .shell:has(.shell__tutor[data-state="expanded"]) .shell__nav-link {
    justify-content: center; padding-left: 0; padding-right: 0; width: 44px;
  }
}
.shell__tutor-toggle[aria-expanded="true"] {
  background: var(--accent-primary);
  color: var(--text-on-accent);
  border-color: transparent;
}
/* Body stays rendered; the parent .shell__tutor is translated off-screen
   when collapsed, so visibility is controlled by transform, not display.
   This keeps the content sliding IN and OUT with the panel rather than
   flashing into existence mid-animation. */
.shell__tutor-body {
  padding: var(--space-6); max-width: var(--aside-open-width);
  /* Flex-fill the panel and become the scroll container's frame: the transcript
     scrolls, the reply box stays pinned at the bottom. min-height:0 lets a flex
     child actually shrink so overflow engages instead of pushing content off. */
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column; overflow: hidden;
}

/* Tutor response fragment — rendered by /tutor/open via HTMX swap. */
.tutor-response { display: flex; flex-direction: column; gap: var(--space-4); }
.tutor-response__loading { opacity: 0.6; font-style: italic; }
/* Optimistic entry thinking-state: shown the instant an entry button opens the
   panel, replaced by the real turn when it arrives. Gentle pulse so the wait
   reads as "thinking", not "stuck" (never-red). Reuses the reply-path keyframes. */
.tutor-response--pending { animation: tutor-pending-pulse 1.4s ease-in-out infinite; }
.tutor-response__caption { font-size: 0.78rem; letter-spacing: 0.04em;
  text-transform: uppercase; opacity: 0.55; margin: 0; }
.tutor-response__body { font-size: 1rem; line-height: 1.5; margin: 0; }
.tutor-response__chips { list-style: none; padding: 0; margin: 0;
  flex: none;   /* pinned below the scrolling transcript */
  display: flex; flex-direction: column; gap: var(--space-2); }
.tutor-response__chips form { margin: 0; }
.tutor-response__chip {
  width: 100%; text-align: left; padding: var(--space-2) var(--space-3);
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: inherit;
  font: inherit; cursor: pointer;
}
.tutor-response__chip:hover { background: var(--surface-glass-strong); }
.tutor-response--error .tutor-response__body { opacity: 0.7; font-style: italic; }

/* Conversation transcript + reply (WS5 Phase 2). */
.tutor-transcript {
  display: flex; flex-direction: column; gap: var(--space-3);
  margin-bottom: var(--space-4);
  /* Scroll the transcript within the panel; the reply/chips stay pinned below.
     min-height:0 is what lets this flex child shrink so the scrollbar appears. */
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
}
.tutor-msg { padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); max-width: 90%; }
.tutor-msg__body { margin: 0; font-size: 0.95rem; line-height: 1.5; }
.tutor-msg--tutor   { background: var(--surface-glass); align-self: flex-start; }
.tutor-msg--student { background: var(--surface-glass-strong); align-self: flex-end; }
.tutor-msg--system  { opacity: 0.6; font-style: italic; align-self: center; }
.tutor-reply { display: flex; gap: var(--space-2); margin-top: var(--space-3); flex: none; }
.tutor-reply__input {
  flex: 1; min-width: 0; padding: var(--space-2) var(--space-3);
  background: var(--surface-glass-strong); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: var(--text-primary); font: inherit;
}
.tutor-reply__send {
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: inherit; font: inherit; cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.tutor-reply__send:hover { background: var(--surface-glass-strong); }
/* Instant press feedback — the click paints on mouse-down, not after the
   round-trip, so the button never feels dead on click. */
.tutor-reply__send:active { transform: scale(0.94); background: var(--surface-glass-strong); }
.tutor-reply__send[aria-busy="true"] { opacity: 0.6; cursor: default; }

/* Clean exit from the tutor — leave without re-prompting the model (6d polish). */
.tutor-reply__done {
  margin-top: var(--space-2); align-self: center;
  background: none; border: none; color: var(--text-secondary);
  font: inherit; font-size: 0.85rem; cursor: pointer;
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm);
  transition: color var(--duration-fast) var(--ease-out),
              background var(--duration-fast) var(--ease-out);
}
.tutor-reply__done:hover { color: var(--text-primary); background: var(--surface-glass); }
/* Wrap-up chips read as actions (leave / try again), accented with --info. */
.tutor-response__chip--exit { border-color: var(--info); color: var(--text-primary); }

/* Optimistic "Thinking…" turn shown while the model round-trips (never-red). */
.tutor-msg--pending { opacity: 0.75; animation: tutor-pending-pulse 1.4s ease-in-out infinite; }
.tutor-msg__dots { animation: tutor-pending-dots 1.4s steps(1, end) infinite; }
@keyframes tutor-pending-pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.85; } }
@keyframes tutor-pending-dots {
  0% { opacity: 0.2; } 30% { opacity: 0.6; } 60%, 100% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .tutor-msg--pending, .tutor-msg__dots, .tutor-response--pending { animation: none; }
}

/* Flipped-classroom explain-back (WS5 Phase 3, G4) — never-red: partial = amber. */
.explain-back-offer {
  margin: var(--space-4) 0; padding: var(--space-3);
  border: 1px solid var(--border-glass); border-radius: var(--radius-sm);
  background: var(--surface-glass);
}
.explain-back-offer > summary { cursor: pointer; font-weight: 600; }
.explain-back-offer__intro { margin: var(--space-2) 0; color: var(--text-secondary); font-size: var(--text-sm); }
.explain-back__input {
  width: 100%; box-sizing: border-box; padding: var(--space-2) var(--space-3);
  background: var(--surface-glass-strong); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: var(--text-primary); font: inherit; resize: vertical;
}
.explain-back__send {
  margin-top: var(--space-2); padding: var(--space-2) var(--space-3);
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: inherit; font: inherit; cursor: pointer;
}
.explain-back__send:hover { background: var(--surface-glass-strong); }
.explain-back { margin-top: var(--space-3); padding: var(--space-3);
  border-radius: var(--radius-sm); border: 1px solid var(--border-glass); }
.explain-back__note { margin: 0; color: var(--text-secondary); font-size: var(--text-sm); }
.explain-back__verdict { margin: 0 0 var(--space-2); font-weight: 600; }
.explain-back__followup { margin: 0 0 var(--space-2); color: var(--text-secondary); }
.explain-back--pass { border-color: var(--success); }
.explain-back--pass .explain-back__verdict { color: var(--success); }
.explain-back--partial { border-color: var(--warning); }
.explain-back--partial .explain-back__verdict { color: var(--warning); }
.explain-back__retry { margin-top: var(--space-2); }

/* ============================================================
   DASHBOARD v2 — student-dashboard.md §6
   Composition: hero + Up Next + momentum row + display case
   ============================================================ */
.dashboard {
  max-width: var(--content-max-width);
  margin: 0 auto;
  display: flex; flex-direction: column; gap: var(--space-7);
}

.dashboard__top-grid {
  display: grid; grid-template-columns: 2fr 1fr; gap: var(--space-5);
}
@media (max-width: 1024px) {
  .dashboard__top-grid { grid-template-columns: 1fr; }
}

/* Hero card */
.dashboard-hero {
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-4);
}
.dashboard-hero__eyebrow {
  font-family: var(--font-headline); font-style: italic; font-weight: var(--weight-light);
  font-size: var(--text-lg); color: var(--text-secondary);
}
.dashboard-hero__title {
  margin: 0; font-size: var(--text-3xl); font-weight: var(--weight-bold);
  color: var(--text-primary); letter-spacing: var(--track-display);
}
.dashboard-hero__tagline { margin: 0; font-size: var(--text-base); color: var(--text-secondary); max-width: 60ch; }
.dashboard-hero__xp { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-3); }
.dashboard-hero__xp-meta { display: flex; align-items: baseline; justify-content: space-between; }
.dashboard-hero__xp-label { font-size: var(--text-xs); color: var(--text-secondary); text-transform: uppercase; letter-spacing: var(--track-eyebrow); }
.dashboard-hero__xp-value {
  font-size: var(--text-sm); font-weight: var(--weight-bold); color: var(--text-primary);
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.dashboard-hero__xp-bar {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill); height: var(--space-3); overflow: hidden;
}
.dashboard-hero__xp-fill {
  height: 100%; width: var(--xp-pct, 0%);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent-secondary), var(--accent-highlight));
  transition: width var(--duration-slow) var(--ease-out);
}

/* Momentum stack — PL#1: vertical column in the 1/3 sidebar slot */
.dashboard-momentum {
  display: flex; flex-direction: column; gap: var(--space-3);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.dashboard-momentum__stat {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
}
.dashboard-momentum__icon {
  font-size: var(--icon-size-lg);
  color: var(--accent-secondary);
}
.dashboard-momentum__icon--flame { color: var(--warning); }
.dashboard-momentum__value {
  font-family: var(--font-headline); font-size: var(--text-2xl); font-weight: var(--weight-bold);
  color: var(--text-primary); font-feature-settings: "tnum" 1, "lnum" 1; line-height: 1;
  text-align: right;
}
.dashboard-momentum__label {
  font-size: var(--text-xs); color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: var(--track-eyebrow);
}

/* How you're growing — student self-referenced trajectory (never peer, never red) */
.dashboard-growth {
  display: flex; flex-direction: column; gap: var(--space-4);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-top: var(--space-6);
}
.dashboard-growth__header { display: flex; flex-direction: column; gap: var(--space-1); }
.dashboard-growth__title {
  margin: 0; font-family: var(--font-headline);
  font-size: var(--text-xl); font-weight: var(--weight-bold); color: var(--text-primary);
}
.dashboard-growth__hint { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }
.dashboard-growth__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--space-2);
}
.dashboard-growth__row {
  display: grid;
  grid-template-columns: minmax(8rem, auto) 1fr auto minmax(5rem, auto);
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
}
.dashboard-growth__label {
  font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-primary);
}
.dashboard-growth__spark { width: 100%; height: var(--space-6); color: var(--info); }
.dashboard-growth__row[data-tone="grew"] .dashboard-growth__spark { color: var(--success); }
.dashboard-growth__now {
  font-family: var(--font-headline); font-size: var(--text-lg); font-weight: var(--weight-bold);
  color: var(--text-primary); font-feature-settings: "tnum" 1, "lnum" 1; text-align: right;
}
.dashboard-growth__delta {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  justify-self: end;
}
.dashboard-growth__delta .material-symbols-outlined { font-size: var(--icon-size-md); }
.dashboard-growth__delta[data-tone="grew"]     { color: var(--success); }
.dashboard-growth__delta[data-tone="building"] { color: var(--text-secondary); }
@media (max-width: 720px) {
  .dashboard-growth__row {
    grid-template-columns: 1fr auto auto;
    grid-template-areas:
      "label label label"
      "spark now   delta";
  }
  .dashboard-growth__label { grid-area: label; }
  .dashboard-growth__spark { grid-area: spark; }
  .dashboard-growth__now   { grid-area: now; }
  .dashboard-growth__delta { grid-area: delta; }
}

/* Choose Your Practice — PL#2: 3 distinct-source action cards */
.dashboard-choices { display: flex; flex-direction: column; gap: var(--space-4); margin-top: var(--space-6); }
.dashboard-choices__header { display: flex; flex-direction: column; gap: var(--space-1); }
.dashboard-choices__title {
  margin: 0; font-family: var(--font-headline);
  font-size: var(--text-xl); font-weight: var(--weight-bold); color: var(--text-primary);
}
.dashboard-choices__hint { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }
.dashboard-choices__list {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
}
@media (max-width: 960px) {
  .dashboard-choices__list { grid-template-columns: 1fr; }
}
.choice-card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  border-top: var(--space-1) solid transparent;
  transition: transform var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
/* Practice job accents (Student-Surface-Practice.md §10). Never --error. */
.choice-card[data-kind="review"]      { border-top-color: var(--warning); }
.choice-card[data-kind="redeem"]      { border-top-color: var(--info); }
.choice-card[data-kind="stretch"]     { border-top-color: var(--accent-primary); }
.choice-card[data-kind="boss"]        { border-top-color: var(--accent-secondary); }
.choice-card[data-kind="explore"]     { border-top-color: var(--info); }
.choice-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md), var(--shadow-glow); }
.choice-card__eyebrow {
  font-size: var(--text-xs); color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: var(--track-eyebrow); font-weight: var(--weight-medium);
}
.choice-card__icon {
  font-size: var(--icon-size-xl);
  color: var(--accent-secondary);
  font-variation-settings: 'FILL' 1, 'wght' 600;
}
.choice-card__title { margin: 0; font-size: var(--text-lg); font-weight: var(--weight-bold); color: var(--text-primary); }
.choice-card__hint { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); flex: 1; }
.choice-card__cta {
  margin-top: var(--space-3); align-self: flex-start;
  background: var(--accent-primary); color: var(--text-on-accent);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  font-weight: var(--weight-bold); text-decoration: none;
  transition: box-shadow var(--duration-base) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.choice-card__cta:hover { box-shadow: var(--shadow-glow); }
.choice-card__cta:active { transform: scale(0.98); }
/* Practice job cards: [icon + card-type tag] → skill chips → CTA. */
.choice-card__tag {
  display: inline-flex; align-items: center; gap: var(--space-1); align-self: flex-start;
  font-size: var(--text-xs); font-weight: var(--weight-medium);
  text-transform: uppercase; letter-spacing: var(--track-eyebrow);
  color: var(--text-secondary);
  background: var(--surface-glass-strong); border: 1px solid var(--border-glass);
  border-radius: var(--radius-pill); padding: var(--space-1) var(--space-3);
}
.choice-card__tag-icon { font-size: var(--icon-size-sm); }
.choice-card[data-kind="redeem"]  .choice-card__tag { color: var(--info); }
.choice-card[data-kind="stretch"] .choice-card__tag { color: var(--accent-primary); }
.choice-card[data-kind="boss"]    .choice-card__tag { color: var(--accent-secondary); }
.choice-card[data-kind="review"]  .choice-card__tag { color: var(--warning); }
.choice-card__skills { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); flex: 1; align-content: flex-start; }
.choice-card__skills-chip {
  font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-primary);
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-md); padding: var(--space-1) var(--space-2);
}
.choice-card__skills-more { font-size: var(--text-xs); color: var(--text-secondary); align-self: center; }
.choice-card__cta--off {
  background: transparent; color: var(--text-secondary);
  border: 1px solid var(--border-glass); cursor: default; box-shadow: none;
}
.choice-card[data-empty="true"] { opacity: 0.72; }

/* Practice hero — boss carries a skill roster + an interleave-motif emblem. */
.up-next-card__body { display: flex; flex-direction: column; gap: var(--space-3); flex: 1; min-width: 0; }
/* Higher specificity so it wins over the base .up-next-card (defined later). */
.up-next-card.up-next-card--boss { flex-direction: row; align-items: center; gap: var(--space-5); overflow: hidden; }
.up-next-card__art { flex: 0 0 auto; width: 140px; height: 140px; display: flex; align-items: center; justify-content: center; }
.up-next-card__art-svg { width: 100%; height: 100%; opacity: 0.9; }
.up-next-card__skills { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.up-next-card__skills-chip {
  font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-primary);
  background: var(--surface-glass-strong); border: 1px solid var(--border-glass);
  border-radius: var(--radius-md); padding: var(--space-1) var(--space-3);
}
.up-next-card__skills-more { font-size: var(--text-xs); color: var(--text-secondary); align-self: center; }
@media (max-width: 720px) {
  .up-next-card.up-next-card--boss { flex-direction: column; align-items: stretch; }
  .up-next-card__art { align-self: center; }
}

/* --- Practice activity history (Student-Surface-Practice.md §10) -----------
   Read-only "Recent practice" footer — the surface's lowest-priority zone.
   Tokens only; result chips never use --error. */
.practice-history {
  display: flex; flex-direction: column; gap: var(--space-3);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-glass);
}
.practice-history__head {
  display: flex; justify-content: space-between; align-items: baseline;
  flex-wrap: wrap; gap: var(--space-2);
}
.practice-history__title { margin: 0; font-size: var(--text-base); font-weight: var(--weight-bold); color: var(--text-primary); }
.practice-history__summary {
  margin: 0; font-size: var(--text-xs); color: var(--text-secondary);
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.practice-history__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.practice-history__row {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
}
.practice-history__icon { font-size: var(--icon-size-sm); color: var(--text-secondary); }
.practice-history__row-skills {
  font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-primary);
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.practice-history__row-mode {
  font-size: var(--text-xs); font-weight: var(--weight-medium);
  color: var(--text-secondary); white-space: nowrap;
  background: var(--surface-glass-strong); border: 1px solid var(--border-glass);
  border-radius: var(--radius-pill); padding: 0 var(--space-2);
}
.practice-history__row-mode[data-kind="redeem"]  { color: var(--info); }
.practice-history__row-mode[data-kind="stretch"] { color: var(--accent-primary); }
.practice-history__row-mode[data-kind="boss"]    { color: var(--accent-secondary); }
.practice-history__row-mode[data-kind="review"]  { color: var(--warning); }
.practice-history__row-time { font-size: var(--text-xs); color: var(--text-secondary); white-space: nowrap; }
.practice-history__row-result {
  font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--text-primary);
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.practice-history__empty { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }

.trophy-strip {
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-3);
}
.trophy-strip__header { display: flex; align-items: center; justify-content: space-between; }
.trophy-strip__title { margin: 0; font-size: var(--text-base); font-weight: var(--weight-bold); color: var(--text-primary); }
.trophy-strip__link {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--text-sm); color: var(--accent-primary);
  font-weight: var(--weight-medium); text-decoration: none;
}
.trophy-strip__link:hover { text-decoration: underline; }
.trophy-strip__link .material-symbols-outlined { font-size: var(--icon-size-sm); }
.trophy-strip__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: var(--space-3);
}
.trophy-strip__list .trophy-card {
  padding: var(--space-4);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  text-align: center;
}
.trophy-strip__empty {
  grid-column: 1 / -1;
  padding: var(--space-4) 0;
  font-size: var(--text-sm); color: var(--text-secondary);
  text-align: center;
}

/* ============================================================
   MY PATH — Student surface `/` (Student-Surface-MyPath.md §8)
   Plan-driven daily driver. Tokens only; catch-up muted = --warning
   (never --error). Continue reuses the .up-next-card pinned recipe.
   ============================================================ */

/* ② Continue — pinned-affordance card (parent student-dashboard §6). */
.up-next-card {
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-3);
  border-left: var(--space-1) solid var(--accent-primary);
}
.up-next-card__eyebrow {
  font-size: var(--text-xs); color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: var(--track-eyebrow); font-weight: var(--weight-medium);
}
.up-next-card__title { margin: 0; font-size: var(--text-xl); font-weight: var(--weight-bold); color: var(--text-primary); }
.up-next-card__hint { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }
.up-next-card__chip-row { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.up-next-card__chip {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs); color: var(--text-secondary);
}
.up-next-card__cta {
  align-self: flex-start; margin-top: var(--space-1);
  background: var(--accent-primary); color: var(--text-on-accent);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-5);
  font-weight: var(--weight-bold); text-decoration: none; text-align: center;
  transition: box-shadow var(--duration-base) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.up-next-card__cta:hover { box-shadow: var(--shadow-glow); }
.up-next-card__cta:active { transform: scale(0.98); }

/* ① Today's wins — inline in the hero header. */
.today-wins {
  list-style: none; margin: var(--space-2) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-4);
}
.today-wins__stat { display: flex; align-items: baseline; gap: var(--space-2); }
.today-wins__icon {
  font-size: var(--icon-size-sm); color: var(--accent-secondary);
  font-variation-settings: 'FILL' 1;
}
.today-wins__value {
  font-size: var(--text-lg); font-weight: var(--weight-bold); color: var(--text-primary);
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.today-wins__label { font-size: var(--text-xs); color: var(--text-secondary); text-transform: uppercase; letter-spacing: var(--track-eyebrow); }

/* ③ Today's plan — read-only checklist + catch-up subgroup. */
.today-plan {
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-3);
}
.today-plan__title { margin: 0; font-size: var(--text-base); font-weight: var(--weight-bold); color: var(--text-primary); }
.today-plan__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.today-plan__item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
}
.today-plan__item[data-state="done"] .today-plan__item-title { color: var(--text-secondary); text-decoration: line-through; }
.today-plan__item[data-state="done"] .today-plan__icon { color: var(--success); }
.today-plan__item[data-state="now"] {
  background: var(--surface-glass-strong);
  border-left: var(--space-1) solid var(--accent-primary);
}
.today-plan__item[data-state="now"] .today-plan__icon { color: var(--accent-primary); }
.today-plan__item[data-state="next"] .today-plan__icon { color: var(--text-secondary); }
.today-plan__icon { font-size: var(--icon-size-md); font-variation-settings: 'FILL' 1; }
.today-plan__item-title { flex: 1; font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-primary); text-decoration: none; }
a.today-plan__item-title:hover { text-decoration: underline; }
.today-plan__item-subject { font-size: var(--text-xs); color: var(--text-secondary); text-transform: uppercase; letter-spacing: var(--track-eyebrow); }

.today-plan__catchup {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: var(--glass-border-width) solid var(--border-glass);
}
.today-plan__catchup-label { font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--warning); text-transform: uppercase; letter-spacing: var(--track-eyebrow); }
.today-plan__catchup-more {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--text-sm); color: var(--accent-primary); text-decoration: none;
}
.today-plan__catchup-more:hover { text-decoration: underline; }
.today-plan__catchup-more .material-symbols-outlined { font-size: var(--icon-size-sm); }

/* ④ Warm-ups — demoted due-review chip strip. */
.today-warmups { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3); padding: var(--space-3) 0; }
.today-warmups__label { font-size: var(--text-xs); color: var(--text-secondary); text-transform: uppercase; letter-spacing: var(--track-eyebrow); font-weight: var(--weight-medium); }
.today-warmups__list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.today-warmups__chip {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
}
.today-warmups__chip a { color: var(--text-secondary); text-decoration: none; }
.today-warmups__chip a:hover { color: var(--text-primary); }

/* ---- Fit-to-screen layout (desktop + tablet landscape) --------------------
   All zones on ONE screen, no page scroll, at ≥900px landscape (desktop / iPad
   landscape). Narrow + portrait keep the single-column stack: the
   body/main/aside wrappers are display:contents there, so the surface is a
   plain vertical flow and mobile scrolls as usual. */
.dashboard__body, .dashboard__main, .dashboard__aside { display: contents; }

@media (min-width: 900px) {
  /* Reclaim the surface's generous 48px chrome padding for THIS surface only
     (scoped via :has, so other pages keep their breathing room), and pin the
     surface to the viewport so the PAGE never scrolls — an over-full column
     scrolls inside itself instead. */
  .shell__main:has(.dashboard) {
    padding-top: var(--space-5); padding-bottom: var(--space-5);
    overflow: hidden;
  }
  .shell__main:has(.dashboard) > .shell__surface { height: 100%; min-height: 0; }

  .dashboard { gap: var(--space-3); height: 100%; min-height: 0; }
  .dashboard__top-grid { flex: 0 0 auto; }

  /* Keep hero | momentum side-by-side (override the ≤1024 stack) + compact. */
  .dashboard__top-grid { grid-template-columns: 2fr 1fr; gap: var(--space-3); align-items: stretch; }
  .dashboard-hero { padding: var(--space-4) var(--space-5); gap: var(--space-2); }
  .dashboard-hero__title { font-size: var(--text-2xl); }
  .dashboard-hero__tagline { display: none; }
  .dashboard-hero__xp { margin-top: var(--space-1); }
  .dashboard-momentum { padding: var(--space-3); gap: var(--space-2); justify-content: center; }
  .dashboard-momentum__stat { padding: var(--space-2) var(--space-3); }

  /* Two-column body: primary (Continue + plan) | context (warm-ups, growth,
     extra-practice, trophies). Wrappers become real flex columns here. */
  .dashboard__body {
    display: grid; grid-template-columns: 1.5fr 1fr;
    grid-template-rows: minmax(0, 1fr);   /* one row, pinned to the body height */
    gap: var(--space-3);
    flex: 1 1 auto; min-height: 0;         /* fill remaining height under the header */
  }
  .dashboard__main, .dashboard__aside {
    display: flex; flex-direction: column; gap: var(--space-3);
    min-width: 0; min-height: 0; overflow-y: auto;   /* over-full column scrolls itself */
  }

  /* Density: trim card padding + the tall zones so the columns fit one screen. */
  .up-next-card, .today-plan, .dashboard-growth, .trophy-strip { padding: var(--space-4); }
  .up-next-card { gap: var(--space-2); }
  .dashboard-growth { margin-top: 0; gap: var(--space-2); }
  /* Fit the row to the narrow context column: shrinkable label (ellipsis),
     compact sparkline, then now% + delta — the wide 4-col grid overflowed here. */
  .dashboard-growth__row {
    grid-template-columns: minmax(0, 1fr) 3rem auto auto;
    gap: var(--space-2); padding: var(--space-1) var(--space-3);
  }
  .dashboard-growth__label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .today-plan { gap: var(--space-2); }
  .today-plan__list { gap: var(--space-1); }
  .today-plan__item { padding: var(--space-1) var(--space-2); }
  .today-plan__icon { font-size: var(--icon-size-sm); }
  /* One line per item — truncate long lesson titles so 6+ fit without wrap. */
  .today-plan__item-title { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* An over-long plan scrolls inside its own card, never the page. */
  .today-plan__list { min-height: 0; max-height: 42vh; overflow-y: auto; }

  /* Continue: the chip just repeats the title here — drop it to save height. */
  .up-next-card__chip-row { display: none; }

  /* Growth: drop the explanatory hint (the title carries it) in the dense view. */
  .dashboard-growth__hint { display: none; }
  .dashboard-growth__spark { height: var(--space-5); }

  .trophy-strip__list .trophy-card { padding: var(--space-3); }
}

/* ============================================================
   TROPHY ROOM — trophy-room.md §6
   ============================================================ */
.trophy-room {
  max-width: var(--content-max-width);
  margin: 0 auto;
  display: flex; flex-direction: column; gap: var(--space-6);
}

.trophy-room__hero {
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: grid; grid-template-columns: 1fr auto; gap: var(--space-6);
  align-items: center;
}
.trophy-room__hero-meta { display: flex; flex-direction: column; gap: var(--space-2); }
.trophy-room__eyebrow {
  font-size: var(--text-xs); color: var(--text-secondary);
  font-weight: var(--weight-medium);
  text-transform: uppercase; letter-spacing: var(--track-eyebrow);
}
.trophy-room__level {
  margin: 0;
  font-size: var(--text-3xl); font-weight: var(--weight-bold);
  color: var(--text-primary); letter-spacing: var(--track-display);
}
.trophy-room__tagline { margin: 0; font-size: var(--text-base); color: var(--text-secondary); }
.trophy-room__hero-progress { display: flex; flex-direction: column; gap: var(--space-2); min-width: 240px; }
.trophy-room__xp-meta { display: flex; justify-content: space-between; gap: var(--space-3); }
.trophy-room__xp-label { font-size: var(--text-xs); color: var(--text-secondary); text-transform: uppercase; letter-spacing: var(--track-eyebrow); }
.trophy-room__xp-value { font-size: var(--text-sm); color: var(--text-primary); font-weight: var(--weight-medium); }
.trophy-room__xp-bar {
  height: var(--space-3);
  background: var(--surface-glass-strong);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.trophy-room__xp-fill {
  height: 100%; width: var(--xp-pct, 0%);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent-secondary), var(--accent-highlight));
  transition: width var(--duration-slow) var(--ease-out);
}

.trophy-room__row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }

.trophy-room__momentum, .trophy-room__next {
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-4);
}
.trophy-room__panel-title { margin: 0; font-size: var(--text-xl); font-weight: var(--weight-bold); color: var(--text-primary); }

.trophy-room__stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
.trophy-room__stat {
  background: var(--surface-glass-strong);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  text-align: center;
}
.trophy-room__stat-icon { font-size: var(--icon-size-xl); line-height: 1; color: var(--accent-secondary); }
.trophy-room__stat-icon--flame { color: var(--warning); }
.trophy-room__stat-value { font-size: var(--text-2xl); font-weight: var(--weight-bold); color: var(--text-primary); }
.trophy-room__stat-label { font-size: var(--text-xs); color: var(--text-secondary); text-transform: uppercase; letter-spacing: var(--track-eyebrow); }
.trophy-room__stat-hint { margin: 0; font-size: var(--text-sm); color: var(--text-muted); }

.trophy-room__next-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-4); }

.trophy-room__case-header {
  display: grid; grid-template-columns: 1fr auto;
  grid-template-areas: "title filter" "subtitle filter";
  column-gap: var(--space-4); row-gap: var(--space-1);
  align-items: center;
  margin-bottom: var(--space-4);
}
.trophy-room__case-header .trophy-room__panel-title { grid-area: title; }
.trophy-room__case-subtitle { grid-area: subtitle; margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }
.trophy-room__case-filter { grid-area: filter; display: flex; gap: var(--space-2); align-self: center; }
.trophy-room__filter {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-family: inherit; font-size: var(--text-xs);
  color: var(--text-secondary); cursor: pointer;
  transition: background var(--duration-base) var(--ease-out), color var(--duration-base) var(--ease-out);
}
.trophy-room__filter[data-state="active"] { background: var(--accent-primary); color: var(--text-on-accent); }

.trophy-room__case-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: var(--space-4);
}
/* PL#8 — filter tabs hide locked cards when Unlocked is active. */
.trophy-room__case-grid[data-filter="unlocked"] .trophy-card[data-state="locked"] { display: none; }

.trophy-card {
  position: relative;
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  text-align: center;
  transition: transform var(--duration-base) var(--ease-out), box-shadow var(--duration-base) var(--ease-out);
}
.trophy-card[data-state="earned"] { opacity: 1; }
.trophy-card[data-state="earned"]:hover { transform: translateY(-2px); box-shadow: var(--shadow-glow), var(--shadow-md), var(--glass-inner-shadow); }
.trophy-card[data-state="locked"] { opacity: 0.55; cursor: default; }
.trophy-card[data-state="featured"]::before {
  content: "";
  position: absolute; inset: calc(-1 * var(--space-4));
  border-radius: inherit; z-index: -1;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent-primary) 35%, transparent), transparent 70%);
}
/* Trophy card icon — direct Material Symbol usage in dashboard trophy strip
   and quiz summary banner. The trophy-room display case uses the richer
   .trophy-badge component instead. */
.trophy-card__icon {
  font-size: var(--icon-size-xl); line-height: 1;
  color: var(--accent-secondary);
  font-variation-settings: 'FILL' 1, 'wght' 600;
}
.trophy-card[data-state="locked"] .trophy-card__icon,
.trophy-card__icon--locked {
  color: var(--text-muted);
  font-variation-settings: 'FILL' 0, 'wght' 400;
}

/* ============================================================
   TROPHY BADGE v2 — partials/trophy_badge.html
   Material Symbol inside a per-tier frame + theme glow halo.
   Sizing scales with .trophy-card padding; the badge itself
   defaults to --icon-size-hero with a frame ring at 1.5x.
   ============================================================ */
.trophy-badge {
  position: relative;
  display: inline-grid; place-items: center;
  width: calc(var(--icon-size-hero) * 1.5);
  height: calc(var(--icon-size-hero) * 1.5);
  isolation: isolate;
  transition: transform var(--duration-base) var(--ease-out);
}
.trophy-card[data-state="earned"]:hover .trophy-badge { transform: translateY(-2px) scale(1.05); }

/* Frame — the per-tier shape language. Sits behind the glyph. */
.trophy-badge__frame {
  position: absolute; inset: 0;
  z-index: 1;
  background: linear-gradient(135deg, var(--accent-secondary), var(--accent-highlight));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45);
  border: 1px solid var(--border-glass);
}
/* Tier-specific shapes */
.trophy-badge[data-tier="initiation"]      .trophy-badge__frame { border-radius: var(--radius-pill); }
.trophy-badge[data-tier="streak"]          .trophy-badge__frame {
  clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%); /* flame-ish pentagon */
  border-radius: var(--radius-sm);
}
.trophy-badge[data-tier="subject_mastery"] .trophy-badge__frame {
  clip-path: polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%); /* hex */
}
.trophy-badge[data-tier="collection"]      .trophy-badge__frame {
  border-radius: var(--radius-md);
  /* ribbon notch via clip-path */
  clip-path: polygon(0 0, 100% 0, 100% 80%, 50% 100%, 0 80%);
}

/* Halo — sits behind the frame; softens out into the substrate */
.trophy-badge__halo {
  position: absolute; inset: -25%;
  z-index: 0;
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--accent-primary) 35%, transparent),
    transparent 65%);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-out);
}
.trophy-badge[data-state="earned"] .trophy-badge__halo { opacity: 1; }
.trophy-card[data-state="featured"] .trophy-badge__halo {
  opacity: 1;
  animation: trophy-halo-pulse 3.2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .trophy-card[data-state="featured"] .trophy-badge__halo { animation: none; }
}
@keyframes trophy-halo-pulse {
  0%, 100% { transform: scale(1); opacity: 0.85; }
  50%      { transform: scale(1.12); opacity: 1; }
}

/* Glyph — the Material Symbol itself */
.trophy-badge__glyph {
  position: relative; z-index: 2;
  font-size: var(--icon-size-hero);
  color: var(--text-on-accent);
  font-variation-settings: 'FILL' 1, 'wght' 600;
  /* Slight inner shadow on the glyph to lift it off the frame gradient */
  filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.15));
}

/* Locked state — desaturated, no halo, outline-weight glyph */
.trophy-badge[data-state="locked"] .trophy-badge__frame {
  background: var(--surface-glass-strong);
  border-color: var(--border-glass);
  box-shadow: none;
}
.trophy-badge[data-state="locked"] .trophy-badge__halo { opacity: 0; }
.trophy-badge[data-state="locked"] .trophy-badge__glyph {
  color: var(--text-muted);
  font-variation-settings: 'FILL' 0, 'wght' 400;
  filter: none;
}

/* Compact size when the badge appears in the trophy-toast or the dashboard
   "Recent trophies" strip — context can override --icon-size-hero. */
.trophy-toast .trophy-badge,
.trophy-strip__list .trophy-badge {
  width: calc(var(--icon-size-xl) * 1.5);
  height: calc(var(--icon-size-xl) * 1.5);
}
.trophy-toast .trophy-badge__glyph,
.trophy-strip__list .trophy-badge__glyph { font-size: var(--icon-size-xl); }
.trophy-card__name { margin: 0; font-size: var(--text-base); font-weight: var(--weight-bold); color: var(--text-primary); }
.trophy-card[data-state="locked"] .trophy-card__name { color: var(--text-muted); }
.trophy-card__milestone, .trophy-card__requirement { font-size: var(--text-xs); color: var(--text-secondary); }
.trophy-card__earned-on { font-size: var(--text-xs); color: var(--text-muted); }
.trophy-card__progress {
  width: 100%; height: var(--space-2);
  background: var(--surface-glass-strong);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.trophy-card__progress-fill {
  height: 100%; width: var(--pct, 0%);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent-primary), var(--accent-highlight));
  transition: width var(--duration-slow) var(--ease-out);
}
.trophy-card__progress-label { font-size: var(--text-xs); color: var(--text-secondary); }

@media (max-width: 720px) {
  .trophy-room__row { grid-template-columns: 1fr; }
  .trophy-room__hero { grid-template-columns: 1fr; }
}

/* ============================================================
   LESSON — lesson.md §6
   ============================================================ */
.lesson {
  max-width: var(--content-max-width);
  margin-inline: auto;
  color: var(--text-primary);
}
.lesson__breadcrumbs { margin-bottom: var(--space-4); font-size: var(--text-xs); color: var(--text-secondary); }
.lesson__crumbs { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.lesson__crumb { display: inline-flex; align-items: center; gap: var(--space-2); }
.lesson__crumb-link { color: var(--text-secondary); text-decoration: none; }
.lesson__crumb-link:hover { color: var(--text-primary); }
.lesson__crumb-sep { color: var(--text-muted); }
.lesson__crumb-current { color: var(--text-primary); font-weight: var(--weight-medium); }

.lesson__title { margin: 0; font-size: var(--text-3xl); font-weight: var(--weight-bold); color: var(--text-primary); line-height: 1.2; letter-spacing: var(--track-display); }
.lesson__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-top: var(--space-4); margin-bottom: var(--space-5); }
.lesson__skill-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.lesson__skill-chip {
  display: inline-flex; align-items: center;
  padding: var(--space-1) var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs); color: var(--text-secondary);
}
.lesson__grade-badge {
  display: inline-flex; align-items: center;
  padding: var(--space-1) var(--space-3);
  background: var(--accent-secondary); color: var(--text-on-accent);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs); font-weight: var(--weight-bold);
}
.lesson__read-aloud {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin-left: auto;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  font-family: inherit; font-size: var(--text-sm); color: var(--text-primary);
  cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out);
}
.lesson__read-aloud:hover { box-shadow: var(--shadow-glow); }
.lesson__read-aloud-icon { color: var(--accent-primary); font-size: var(--icon-size-md); }

/* Early-reader delivery — read-aloud control on a question card. Same shape as
   .lesson__read-aloud so the two surfaces read as one affordance. Only rendered
   when the student has read_aloud on. */
.quiz-card__read-aloud {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin-left: auto;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  font-family: inherit; font-size: var(--text-sm); color: var(--text-primary);
  cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out);
}
.quiz-card__read-aloud:hover { box-shadow: var(--shadow-glow); }
.quiz-card__read-aloud-icon { color: var(--accent-primary); font-size: var(--icon-size-md); }

.lesson__grid {
  display: grid;
  grid-template-columns: minmax(0, var(--prose-max-width)) 320px;
  column-gap: var(--space-7);
  align-items: start;
}
.lesson__body { max-width: var(--prose-max-width); margin-inline: auto; font-size: var(--text-lg); line-height: 1.6; color: var(--text-primary); }
.lesson__body-end { height: var(--space-1); }
.lesson__body h2 { margin-top: var(--space-6); margin-bottom: var(--space-3); font-size: var(--text-2xl); font-weight: var(--weight-bold); color: var(--text-primary); line-height: 1.25; }
.lesson__body h3 { margin-top: var(--space-5); margin-bottom: var(--space-3); font-size: var(--text-xl); font-weight: var(--weight-bold); color: var(--text-primary); }
.lesson__body p { margin-top: 0; margin-bottom: var(--space-4); }
.lesson__body a { color: var(--accent-primary); text-decoration: underline; }
.lesson__body ul, .lesson__body ol { margin-top: 0; margin-bottom: var(--space-4); padding-left: var(--space-6); }
.lesson__body li { margin-bottom: var(--space-2); }
.lesson__body code {
  padding: var(--space-1) var(--space-2);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-sm); font-size: var(--text-sm);
  /* Inline equation chips (e.g. `2 × 1000 = 2000`) shouldn't push past
     the column edge when the body is narrow. `anywhere` lets the
     browser break inside the chip if the whole token won't fit. */
  overflow-wrap: anywhere;
}
.lesson__body pre {
  margin-top: 0; margin-bottom: var(--space-4);
  padding: var(--space-4);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  font-size: var(--text-sm); line-height: 1.5; overflow-x: auto;
}
.lesson__body pre code { padding: 0; background: transparent; border: 0; border-radius: 0; color: var(--text-primary); }
.lesson__body blockquote { margin: 0 0 var(--space-4); padding-left: var(--space-4); border-left: var(--space-1) solid var(--accent-primary); color: var(--text-secondary); font-style: italic; }
.lesson__body img, .lesson__body iframe { max-width: 100%; border: var(--glass-border-width) solid var(--border-glass); border-radius: var(--radius-md); }

.lesson__panel { position: sticky; top: var(--space-5); display: flex; flex-direction: column; gap: var(--space-4); }
.lesson__summary { border-radius: var(--radius-lg); padding: var(--space-5); }
.lesson__summary-title { margin: 0 0 var(--space-3); font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary); text-transform: uppercase; letter-spacing: var(--track-eyebrow); }
.lesson__summary-list { list-style: none; margin: 0; padding: 0; }
.lesson__summary-item { position: relative; margin-bottom: var(--space-2); padding-left: var(--space-4); font-size: var(--text-base); color: var(--text-primary); }
.lesson__summary-item::before {
  content: ""; position: absolute; left: 0; top: 0.6em;
  width: var(--space-1); height: var(--space-1);
  border-radius: var(--radius-pill); background: var(--accent-highlight);
}
.lesson__tutor-hook {
  padding: var(--space-3) var(--space-5);
  background: var(--accent-secondary); color: var(--text-on-accent);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  font-family: inherit; font-size: var(--text-base); font-weight: var(--weight-bold);
  text-align: center; cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.lesson__tutor-hook:hover { box-shadow: var(--shadow-glow); }
/* Instant press feedback — paints on mouse-down / Enter-Space, so the click
   registers visually before the (several-second) model round-trip. Matches the
   reply Send button's :active pattern. */
.lesson__tutor-hook:active { transform: translateY(1px) scale(0.97); }
.lesson__proceed {
  display: block;
  padding: var(--space-3) var(--space-5);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  font-size: var(--text-base); font-weight: var(--weight-bold);
  text-align: center; text-decoration: none;
  transition: background-color var(--duration-base) var(--ease-out),
              color var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
.lesson__proceed[data-state="locked"] { background: var(--surface-glass-strong); color: var(--text-muted); cursor: not-allowed; pointer-events: none; }
.lesson__proceed[data-state="unlocked"] { background: var(--accent-primary); color: var(--text-on-accent); box-shadow: var(--shadow-glow); cursor: pointer; }
/* Stack the lesson panel under the body, with the action button first,
   whenever the two-column lesson layout would be too tight. Two triggers:
   (a) narrow viewport (≤1180px), and (b) AI tutor expanded — its grid
   column eats enough horizontal room that the lesson grid can no longer
   hold body + 320px panel without them overlapping. Same stacked layout
   either way; same reorder so Proceed appears right under the body
   instead of buried below the summary + tutor hook. */
@media (max-width: 1180px) {
  .lesson__grid { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-6); }
  .lesson__panel { position: static; }
  .lesson__proceed    { order: 1; }
  .lesson__tutor-hook { order: 2; }
  .lesson__summary    { order: 3; }
}
.shell:has(.shell__tutor[data-state="expanded"]) .lesson__grid {
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--space-6);
}
.shell:has(.shell__tutor[data-state="expanded"]) .lesson__panel    { position: static; }
.shell:has(.shell__tutor[data-state="expanded"]) .lesson__proceed    { order: 1; }
.shell:has(.shell__tutor[data-state="expanded"]) .lesson__tutor-hook { order: 2; }
.shell:has(.shell__tutor[data-state="expanded"]) .lesson__summary    { order: 3; }

/* ============================================================
   QUIZ PROGRESS — PL#12 (slim animated bar above the quiz card)
   ============================================================ */
.quiz-progress {
  position: relative;
  width: 100%; max-width: var(--container-base);
  margin: 0 auto var(--space-5);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  height: var(--space-3); overflow: hidden;
}
.quiz-progress__fill {
  position: absolute; inset: 0 auto 0 0;
  width: var(--pct, 0%);
  background: linear-gradient(90deg, var(--accent-secondary), var(--accent-highlight));
  border-radius: var(--radius-pill);
  transition: width var(--duration-slow) var(--ease-out);
}
.quiz-progress__label {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  font-size: var(--text-xs); font-weight: var(--weight-medium);
  color: var(--text-primary);
  pointer-events: none; white-space: nowrap;
  mix-blend-mode: difference;
}

/* ============================================================
   QUIZ CARD — quiz-card.md §6
   ============================================================ */
.quiz-card {
  display: flex; flex-direction: column; gap: var(--space-5);
  width: 100%; max-width: 520px; margin-inline: auto;
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  transition: border-color var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
.quiz-card[data-state="success"] {
  border-color: var(--success);
  box-shadow: var(--glass-inner-shadow),
    0 0 0 var(--glass-border-width) var(--success),
    0 0 var(--space-6) color-mix(in srgb, var(--success) 45%, transparent);
}
.quiz-card[data-state="retry"] {
  border-color: var(--warning);
  box-shadow: var(--glass-inner-shadow),
    0 0 0 var(--glass-border-width) var(--warning),
    0 0 var(--space-6) color-mix(in srgb, var(--warning) 45%, transparent);
}

.quiz-card__header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.quiz-card__eyebrow {
  flex: none; white-space: nowrap;
  font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: var(--track-eyebrow);
}
.quiz-card__skill-badge {
  flex: 0 1 auto; min-width: 0;
  padding: var(--space-1) var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: inline-flex; align-items: center; gap: var(--space-1);
}
/* Way B: per-question chip variants — visual cue that this slot is
   reinforcing a prereq or reviewing a previously-attempted skill, not the
   primary practice target. Color comes from the accent palette so the
   chip reads at-a-glance without crowding the badge text. */
.quiz-card__skill-badge--prereq {
  border-color: color-mix(in srgb, var(--accent-secondary) 60%, transparent);
  color: var(--text-primary);
}
.quiz-card__skill-badge--review {
  border-color: color-mix(in srgb, var(--warning) 60%, transparent);
  color: var(--text-primary);
}
.quiz-card__skill-badge-kind {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: var(--track-eyebrow);
  padding: 0 var(--space-1); border-radius: var(--radius-pill);
  background: color-mix(in srgb, currentColor 12%, transparent);
}

/* Way C: multi-step renderer chrome. The scenario sits above the step
   progress + active form so the student sees the shared context while
   they work through each sub-question. */
.quiz-card__scenario {
  margin: 0 0 var(--space-3) 0;
  padding: var(--space-3); border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-glass-strong) 60%, transparent);
  font-size: var(--text-base); color: var(--text-secondary);
  line-height: 1.45;
}
.quiz-step__progress {
  display: inline-flex; gap: var(--space-1); margin-bottom: var(--space-2);
}
.quiz-step__dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
}
.quiz-step__dot--done    { background: var(--accent-secondary); }
.quiz-step__dot--active  { background: var(--accent-primary); box-shadow: var(--shadow-glow); }
.quiz-step__dot--pending { background: transparent; }
.quiz-step__subhead {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--track-eyebrow); color: var(--text-secondary);
  margin-bottom: var(--space-2);
}
.quiz-step__skill {
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-pill);
  background: var(--surface-glass-strong); color: var(--text-primary);
  font-weight: var(--weight-medium); letter-spacing: 0; text-transform: none;
}
.quiz-card__prompt { margin: 0; font-size: var(--text-2xl); font-weight: var(--weight-bold); line-height: 1.25; color: var(--text-primary); }

.quiz-card__options { display: flex; flex-direction: column; gap: var(--space-3); margin: 0; }
.quiz-card__option {
  display: flex; align-items: center; gap: var(--space-3);
  width: 100%; padding: var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-family: inherit; font-size: var(--text-base); font-weight: var(--weight-medium);
  text-align: left; cursor: pointer;
  transition: box-shadow var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
}
.quiz-card__option:hover { box-shadow: var(--shadow-glow); border-color: var(--accent-primary); transform: translateY(-1px); }
/* PL#10 — radio is visually hidden but reachable by keyboard; the label
   carries the visible affordance and :has() lifts the option when selected. */
.quiz-card__option-radio,
.quiz-card__option-checkbox {
  position: absolute; opacity: 0;
  width: 1px; height: 1px; margin: -1px; overflow: hidden;
}
.quiz-card__option:has(.quiz-card__option-radio:checked),
.quiz-card__option:has(.quiz-card__option-checkbox:checked) {
  border-color: var(--accent-primary);
  box-shadow: var(--shadow-glow), inset 0 0 0 1px var(--accent-primary);
  background: color-mix(in srgb, var(--accent-primary) 12%, var(--surface-glass-strong));
}
.quiz-card__option:has(.quiz-card__option-radio:focus-visible),
.quiz-card__option:has(.quiz-card__option-checkbox:focus-visible) {
  outline: 2px solid var(--border-focus); outline-offset: 2px;
}
.quiz-card__option-letter {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--space-6); height: var(--space-6);
  background: var(--accent-primary); color: var(--text-on-accent);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm); font-weight: var(--weight-bold);
}
.quiz-card__option-text { flex: 1; }

.quiz-card__entry { display: flex; flex-direction: column; gap: var(--space-3); margin: 0; }
.quiz-card__entry-label { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary); }
.quiz-card__entry-input {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  color: var(--text-primary); font-family: inherit; font-size: var(--text-lg);
}
.quiz-card__entry-input:focus { outline: none; border-color: var(--border-focus); box-shadow: var(--shadow-glow); }
.quiz-card__submit, .quiz-card__advance {
  align-self: flex-start;
  padding: var(--space-3) var(--space-5);
  background: var(--accent-primary); color: var(--text-on-accent);
  border: none; border-radius: var(--radius-md);
  font-family: inherit; font-size: var(--text-base); font-weight: var(--weight-bold);
  cursor: pointer;
  transition: box-shadow var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out),
              filter var(--duration-fast) var(--ease-out);
}
.quiz-card__submit:hover, .quiz-card__advance:hover {
  box-shadow: var(--shadow-md), var(--shadow-glow);
  transform: translateY(-2px); filter: brightness(1.08);
}
.quiz-card__submit:active, .quiz-card__advance:active {
  transform: translateY(0) scale(0.98); filter: brightness(1);
}

.quiz-card__footer { display: flex; flex-direction: column; gap: var(--space-3); }
.quiz-card[data-state="default"] .quiz-card__footer { display: none; }
.quiz-card__feedback--success, .quiz-card__advance { display: none; }
.quiz-card__feedback--retry, .quiz-card__retry-actions { display: none; }
.quiz-card[data-state="success"] .quiz-card__feedback--success { display: block; }
.quiz-card[data-state="success"] .quiz-card__advance { display: inline-flex; }
.quiz-card[data-state="retry"] .quiz-card__feedback--retry { display: block; }
.quiz-card[data-state="retry"] .quiz-card__retry-actions { display: flex; }
/* WS5 Phase 4 — deferred (rubric grader offline): saved-for-review, never
   scored. --info tone (calm, not amber-retry / not green-success). */
.quiz-card__feedback--deferred { display: none; }
.quiz-card[data-state="deferred"] .quiz-card__feedback--deferred { display: block; }
.quiz-card[data-state="deferred"] .quiz-card__advance { display: inline-flex; }
.quiz-card[data-state="deferred"] {
  border-color: var(--info);
  box-shadow: var(--glass-inner-shadow),
    0 0 0 var(--glass-border-width) var(--info),
    0 0 var(--space-6) color-mix(in srgb, var(--info) 45%, transparent);
}
.quiz-card__feedback { margin: 0; font-size: var(--text-base); font-weight: var(--weight-medium); line-height: 1.4; }
.quiz-card__feedback--success { color: var(--success); }
.quiz-card__feedback--retry { color: var(--warning); }
.quiz-card__feedback--deferred { color: var(--info); }

.quiz-card__retry-actions { flex-direction: row; gap: var(--space-3); }
.quiz-card__try-again, .quiz-card__stuck {
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  font-family: inherit; font-size: var(--text-base); font-weight: var(--weight-bold);
  cursor: pointer;
  transition: box-shadow var(--duration-fast) var(--ease-out);
}
.quiz-card__try-again {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  color: var(--text-primary);
}
.quiz-card__stuck { background: var(--accent-secondary); border: none; color: var(--text-on-accent); }
.quiz-card__try-again:hover, .quiz-card__stuck:hover { box-shadow: var(--shadow-glow); }

/* ============================================================
   PRODUCTIVE STRUGGLE LOOP — productive-struggle-loop.md §6
   Consumes §4 design tokens ONLY. No --error (red) anywhere:
   struggle is a signal, never a failure. The win (--success) is
   louder than the exit (--warning), by design (§7).
   ============================================================ */

/* Retry footer grows a wrapping row so the hint meter + lifelines fit. */
.quiz-card__retry-actions { flex-wrap: wrap; align-items: center; }

/* The two extra lifelines the live card historically lacked. "I'm stuck"
   (scaffold) is a glass secondary; "Ask a grown-up" is the quietest action —
   the parent is a last resort, never a first reflex (§7). */
.quiz-card__scaffold {
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  font-family: inherit; font-size: var(--text-base); font-weight: var(--weight-bold);
  cursor: pointer;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  color: var(--text-primary);
  transition: box-shadow var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.quiz-card__scaffold:hover { box-shadow: var(--shadow-glow); }
/* Instant press feedback (see .lesson__tutor-hook:active). */
.quiz-card__scaffold:active { transform: translateY(1px) scale(0.97); }
.quiz-card__ask-parent {
  padding: var(--space-2) var(--space-3);
  border: none; background: none;
  color: var(--text-muted);
  font-family: inherit; font-size: var(--text-sm);
  text-decoration: underline; cursor: pointer;
}
.quiz-card__ask-parent:hover { color: var(--text-secondary); }

/* Hint-token meter (§5a) — the weekly-pool affordance. */
.hint-meter { display: flex; align-items: center; gap: var(--space-2); }
.hint-meter__spend {
  display: flex; align-items: center; gap: var(--space-1);
  font-family: inherit; font-size: var(--text-sm);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  cursor: pointer;
  transition: box-shadow var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.hint-meter__spend:hover { box-shadow: var(--shadow-glow); transform: translateY(-1px); }
.hint-meter[data-state="empty"] .hint-meter__spend { opacity: 0.5; cursor: not-allowed; }
.hint-meter[data-state="empty"] .hint-meter__spend:hover { transform: none; box-shadow: none; }
.hint-meter__icon { font-size: var(--text-sm); }
.hint-meter__label { font-size: var(--text-sm); color: var(--text-secondary); }
.hint-meter__count { font-size: var(--text-xs); font-weight: var(--weight-bold); }
.hint-meter__count[data-pace="on"] { color: var(--text-secondary); }
.hint-meter__count[data-pace="ahead"] { color: var(--warning); }
.hint-meter__count[data-pace="last"] { color: var(--warning-strong); }
.hint-meter__empty-note {
  font-size: var(--text-xs); color: var(--text-muted); margin-top: var(--space-1);
}
/* Below 720px the meter collapses to a 💡{count} chip (§4). */
@media (max-width: 720px) { .hint-meter__label { display: none; } }

/* Self-reliance affirmation (§5b) — the loudest state: --success + glow. */
.struggle-affirm {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--space-2); padding: var(--space-4);
  background: var(--surface-glass);
  border-radius: var(--radius-lg);
  border: 1px solid var(--success);
  box-shadow: var(--shadow-glow);
}
.quiz-card[data-state="affirmation"] .quiz-card__advance { display: inline-flex; }
.struggle-affirm__line {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-lg); font-weight: var(--weight-bold); color: var(--text-primary);
}
.struggle-affirm__glyph { font-size: var(--text-xl); }
.struggle-affirm__sub { font-size: var(--text-sm); color: var(--text-secondary); }

/* Graceful escalation hand-off (§5c) — the quietest state: --warning, soft. */
.struggle-exit {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--space-3); padding: var(--space-5);
  background: var(--surface-glass);
  border-radius: var(--radius-lg);
  border: 1px solid var(--warning);
}
.struggle-exit__glyph { font-size: var(--text-2xl); }
.struggle-exit__title {
  font-size: var(--text-lg); font-weight: var(--weight-bold);
  color: var(--text-primary); text-align: center;
}
.struggle-exit__body {
  font-size: var(--text-sm); color: var(--text-secondary);
  text-align: center; max-width: var(--container-narrow);
}
.struggle-exit__break { font-size: var(--text-xs); color: var(--text-muted); text-align: center; }
.struggle-exit__resume {
  background: var(--accent-primary); color: var(--text-on-accent);
  border: none; border-radius: var(--radius-md);
  font-family: inherit; font-weight: var(--weight-bold);
  padding: var(--space-2) var(--space-4);
  text-decoration: none; cursor: pointer;
}

/* ============================================================
   QUIZ SUMMARY — quiz-summary.md §6
   ============================================================ */
.quiz-summary {
  max-width: var(--container-base);
  margin: 0 auto;
  padding: var(--space-5) 0;
  display: flex; flex-direction: column; gap: var(--space-5);
}
.quiz-summary__hero {
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.quiz-summary__eyebrow {
  font-size: var(--text-xs); color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: var(--track-eyebrow);
  font-weight: var(--weight-medium);
}
.quiz-summary__score {
  margin: 0; font-size: var(--text-2xl); font-weight: var(--weight-bold);
  color: var(--text-primary); line-height: 1.25;
  letter-spacing: var(--track-display);
}
.quiz-summary__score strong { color: var(--accent-primary); }
.quiz-summary__tagline { margin: 0; font-size: var(--text-base); color: var(--text-secondary); }
.quiz-summary__scorenote { margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--text-muted); }
.quiz-summary__panel-note { margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--text-muted); }

.quiz-summary__dots {
  display: flex; gap: var(--space-2); justify-content: center;
  padding: var(--space-3) 0;
}
.quiz-summary__dot {
  width: var(--space-4); height: var(--space-4);
  border-radius: var(--radius-pill);
  border: var(--glass-border-width) solid var(--border-glass);
  background: var(--surface-glass-strong);
}
.quiz-summary__dot[data-state="correct"] { background: var(--success); border-color: var(--success); }
.quiz-summary__dot[data-state="retry"] {
  background: linear-gradient(90deg, var(--success) 0 50%, var(--info) 50% 100%);
  border-color: var(--info);
}
.quiz-summary__dot[data-state="wrong"] { background: var(--warning); border-color: var(--warning); }

.quiz-summary__delta, .quiz-summary__trophies {
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-3);
}
.quiz-summary__panel-title { margin: 0; font-size: var(--text-xl); font-weight: var(--weight-bold); color: var(--text-primary); }

.quiz-summary__delta-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.quiz-summary__delta-row {
  display: grid; grid-template-columns: 1fr auto auto;
  align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
}
.quiz-summary__delta-skill { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-primary); }
/* PL#13 — visual delta bars: overlayed track + before + after. */
.quiz-summary__delta-bars {
  position: relative;
  display: block;
  width: 180px; height: var(--space-5);
  flex-shrink: 0;
}
.quiz-summary__delta-track,
.quiz-summary__delta-before,
.quiz-summary__delta-after {
  position: absolute; inset: 0 auto 0 0;
  border-radius: var(--radius-pill);
}
.quiz-summary__delta-track {
  width: 100%;
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
}
.quiz-summary__delta-before {
  width: var(--pct, 0%);
  background: color-mix(in srgb, var(--text-muted) 55%, transparent);
}
.quiz-summary__delta-after {
  width: var(--pct, 0%);
  /* color depends on sign — see row[data-sign] below */
  transition: width var(--duration-slow) var(--ease-out);
}
.quiz-summary__delta-row[data-sign="up"]   .quiz-summary__delta-after { background: var(--success); }
.quiz-summary__delta-row[data-sign="flat"] .quiz-summary__delta-after { background: var(--info); }
.quiz-summary__delta-row[data-sign="down"] .quiz-summary__delta-after { background: var(--warning); }
.quiz-summary__delta-text {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center; gap: var(--space-2);
  height: 100%;
  font-size: var(--text-xs); color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  /* Text-shadow gives a stable dark halo so the numbers stay legible
     whether the segment behind them is the muted-gray "before" bar,
     the colored "after" bar, or the translucent glass track.
     `mix-blend-mode: difference` used to do this but landed in a
     low-contrast zone over warning-yellow + muted-gray overlap. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
  pointer-events: none;
}
.quiz-summary__delta-pct { font-weight: var(--weight-bold); }
.quiz-summary__delta-arrow { color: var(--text-secondary); }
.quiz-summary__delta-change {
  font-size: var(--text-sm); font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  min-width: var(--space-7); text-align: right;
}
.quiz-summary__delta-change[data-sign="up"]   { color: var(--success); }
.quiz-summary__delta-change[data-sign="flat"] { color: var(--text-muted); }
.quiz-summary__delta-change[data-sign="down"] { color: var(--warning); }

.quiz-summary__trophy-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: var(--space-4);
}

.quiz-summary__actions { display: flex; gap: var(--space-3); justify-content: flex-end; }
.quiz-summary__back, .quiz-summary__again {
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  font-size: var(--text-base); font-weight: var(--weight-bold);
  text-decoration: none; cursor: pointer;
  transition: box-shadow var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              filter var(--duration-fast) var(--ease-out);
}
.quiz-summary__back {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  color: var(--text-primary);
}
.quiz-summary__again { background: var(--accent-primary); color: var(--text-on-accent); }
.quiz-summary__back:hover, .quiz-summary__again:hover {
  box-shadow: var(--shadow-md), var(--shadow-glow);
  transform: translateY(-2px);
}
.quiz-summary__back:hover { border-color: var(--accent-primary); }
.quiz-summary__again:hover { filter: brightness(1.08); }
.quiz-summary__back:active, .quiz-summary__again:active { transform: translateY(0) scale(0.98); }

/* ============================================================
   Trophy toast (dashboard) — appears top-right above content.
   ============================================================ */
.trophy-toast-stack {
  position: fixed;
  top: var(--space-5);
  right: var(--space-5);
  display: flex; flex-direction: column;
  gap: var(--space-3);
  z-index: 50;
  max-width: 360px;
}
.trophy-toast {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-glow);
  transition: opacity var(--duration-base) var(--ease-out),
              transform var(--duration-base) var(--ease-out);
}
/* PL#14 — fade-out class applied by JS on dismiss; transitionend triggers removal. */
.trophy-toast--fade {
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
}
.trophy-toast__icon { font-size: var(--text-2xl); display: flex; align-items: center; justify-content: center; }
.trophy-toast .trophy-badge { max-width: 44px; }
.trophy-toast__body { display: flex; flex-direction: column; gap: 2px; }
.trophy-toast__eyebrow {
  font-size: var(--text-xs); color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.06em;
  font-weight: var(--weight-medium);
}
.trophy-toast__name {
  font-size: var(--text-base); font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.trophy-toast__milestone { font-size: var(--text-sm); color: var(--text-secondary); }
.trophy-toast__close {
  background: transparent; border: 0; cursor: pointer;
  color: var(--text-muted); font-size: var(--text-xl);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
}
.trophy-toast__close:hover { color: var(--text-primary); background: var(--surface-glass); }

/* ============================================================
   Settings (`settings.html`) — per docs/ui-specs/settings-notifications.md §6.
   Token-only; the three --swatch-* custom props on .settings__theme-swatch
   are the only allowed inline declarations.
   ============================================================ */
.settings {
  max-width: var(--container-narrow);
  margin: 0 auto;
  padding: var(--space-7) 0;
  display: flex; flex-direction: column;
  gap: var(--space-6);
}
.settings__header {
  display: flex; flex-direction: column; gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.settings__eyebrow {
  font-size: var(--text-xs); color: var(--text-secondary);
  font-weight: var(--weight-medium); text-transform: uppercase;
  letter-spacing: 0.08em;
}
.settings__title {
  font-size: var(--text-3xl); font-weight: var(--weight-bold);
  color: var(--text-primary); margin: 0;
}
.settings__tagline {
  font-size: var(--text-base); color: var(--text-secondary); margin: 0;
}

.settings__card {
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex; flex-direction: column; gap: var(--space-5);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  box-shadow: var(--shadow-md), var(--glass-inner-shadow);
}
.settings__card--placeholder { opacity: 0.75; box-shadow: none; }

.settings__parent-console {
  margin-bottom: var(--space-5);
  border-style: dashed;
  background: var(--surface-glass-strong);
  gap: var(--space-2);
}
.settings__parent-console-title {
  font-size: var(--text-sm);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.settings__parent-console-icon {
  font-size: var(--icon-size-md);
}
.settings__parent-console-cta {
  background: var(--accent-primary);
  color: var(--text-on-accent);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-decoration: none;
  border-radius: var(--radius-md);
}
.settings__parent-console-hint {
  font-size: var(--text-xs);
  line-height: 1.4;
}

.settings__card-header {
  display: flex; flex-direction: row; justify-content: space-between;
  align-items: center; gap: var(--space-3);
}
.settings__card-title {
  font-size: var(--text-xl); font-weight: var(--weight-bold);
  color: var(--text-primary); margin: 0;
}
.settings__card-hint {
  font-size: var(--text-sm); color: var(--text-secondary); margin: 0;
}

.settings__legend {
  font-size: var(--text-xs); color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.06em;
  font-weight: var(--weight-medium);
  margin-bottom: var(--space-2);
}
.settings__theme-grid {
  border: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3);
}
.settings__theme-option {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  display: flex; flex-direction: column; gap: var(--space-2);
  cursor: pointer;
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  box-shadow: var(--shadow-sm), var(--glass-inner-shadow);
  transition: box-shadow var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out);
}
.settings__theme-option[data-state="active"] {
  border-color: var(--accent-primary);
  box-shadow: var(--shadow-glow), var(--shadow-sm), var(--glass-inner-shadow);
}
.settings__theme-option input[type="radio"] {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}
.settings__theme-swatch {
  display: block;
  height: var(--space-7);
  border-radius: var(--radius-md);
  background: linear-gradient(135deg,
    var(--swatch-primary) 0%,
    var(--swatch-accent) 70%,
    var(--swatch-bg) 100%);
}
.settings__theme-name {
  font-size: var(--text-base); font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.settings__theme-desc { font-size: var(--text-xs); color: var(--text-secondary); }

.settings__divider {
  height: 1px; background: var(--border-glass); opacity: 0.5;
}

.settings__tuner-grid {
  display: flex; flex-direction: column;
  gap: var(--space-4);
  border: none; padding: 0; margin: 0;
}
.settings__legend--tuner { margin-bottom: var(--space-2); }
.settings__tuner-row {
  display: flex; flex-direction: column;
  gap: var(--space-1);
}
.settings__tuner-row-head {
  display: flex; justify-content: space-between;
  font-size: var(--text-sm);
}
.settings__tuner-slider {
  width: 100%;
  height: 6px;
  border-radius: var(--radius-pill);
}
.settings__tuner-slider--spark { accent-color: var(--accent-primary); }
.settings__tuner-slider--bloom { accent-color: var(--accent-secondary); }

.settings__toggle-row {
  display: flex; flex-direction: row; align-items: center;
  justify-content: space-between; gap: var(--space-4); cursor: pointer;
}
.settings__toggle-text { display: flex; flex-direction: column; gap: var(--space-1); }
.settings__toggle-name {
  font-size: var(--text-base); font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.settings__toggle-desc { font-size: var(--text-sm); color: var(--text-secondary); }

.settings__toggle {
  position: relative; display: inline-block;
  width: calc(var(--space-7) * 2); height: var(--space-6);
}
.settings__toggle input {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}
.settings__toggle-track {
  position: absolute; inset: 0;
  background: var(--surface-glass-strong);
  border-radius: var(--radius-pill);
  transition: background var(--duration-base) var(--ease-out);
}
.settings__toggle-track::before {
  content: ""; position: absolute;
  top: 2px; left: 2px;
  width: calc(var(--space-6) - 4px); height: calc(var(--space-6) - 4px);
  background: var(--accent-secondary);
  border-radius: var(--radius-pill);
  transition: transform var(--duration-base) var(--ease-out);
}
.settings__toggle[data-state="on"] .settings__toggle-track { background: var(--accent-primary); }
.settings__toggle[data-state="on"] .settings__toggle-track::before {
  transform: translateX(calc(var(--space-7) - 4px));
}

.settings__placeholder-list {
  display: flex; flex-direction: column; gap: var(--space-4);
}
.settings__chip[data-state="future"] {
  background: var(--surface-glass-strong);
  color: var(--text-muted);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
}

/* Focus Mode — additive body class per design system §5f.
   PL#15: target decorations only — never the body text. Hide ambient
   particles, mute the gradient + bokeh underglow, leave text + accent
   buttons at full contrast. Animations also stilled. */
body.focus-mode .shell__substrate-particles { display: none; }
body.focus-mode .shell__substrate-gradient { opacity: 0.18; }
body.focus-mode .shell__substrate-bokeh    { opacity: 0.10; }
body.focus-mode * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }

/* ============================================================
   Schedule (`schedule.html`) — placeholder surface for the V2
   calendar planner. Token-only.
   ============================================================ */
.schedule {
  max-width: var(--content-max-width);
  margin: 0 auto;
  display: flex; flex-direction: column;
  gap: var(--space-6);
}
.schedule__eyebrow {
  font-size: var(--text-xs); color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
  font-weight: var(--weight-medium);
}
.schedule__title {
  margin: 0;
  font-size: var(--text-3xl); font-weight: var(--weight-bold);
  color: var(--text-primary);
  letter-spacing: var(--track-display);
}
.schedule__tagline {
  margin-top: var(--space-2);
  font-size: var(--text-base); color: var(--text-secondary);
}
.schedule__placeholder {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: var(--space-8);
  text-align: center;
  border-radius: var(--radius-lg);
  margin-top: var(--space-4);
}
.schedule__placeholder-icon {
  font-size: var(--icon-size-hero);
  color: var(--accent-primary);
  margin-bottom: var(--space-4);
}
.schedule__card-title {
  margin: 0;
  font-size: var(--text-2xl); font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.schedule__chip {
  display: inline-block;
  margin-top: var(--space-3);
  background: var(--accent-secondary);
  color: var(--text-on-accent);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
}
.schedule__card-hint {
  margin-top: var(--space-4);
  font-size: var(--text-sm); color: var(--text-secondary);
  max-width: 45ch;
  line-height: 1.6;
}

/* ============================================================
   Library (`library.html`) — per docs/ui-specs/library.md §6.
   Token-only; the --pct prop on .library-card__heatbar-fill is the
   only allowed inline declaration.
   ============================================================ */
.library {
  max-width: var(--content-max-width);
  margin: 0 auto;
  display: flex; flex-direction: column;
  gap: var(--space-7);
}
.library__header {
  display: flex; flex-direction: column; gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.library__eyebrow {
  font-size: var(--text-xs); color: var(--text-secondary);
  font-weight: var(--weight-medium); text-transform: uppercase;
  letter-spacing: 0.08em;
}
.library__title {
  font-size: var(--text-3xl); font-weight: var(--weight-bold);
  color: var(--text-primary); margin: 0;
}
.library__tagline {
  font-size: var(--text-base); color: var(--text-secondary); margin: 0;
}

/* Two groups: "Your path" (parent-enabled subjects) vs "Explore more"
   (in-grade, not on the plan). Explore is visually separated + gently
   de-emphasized so unselected subjects never read as skipped assigned
   work — awareness, not a to-do. Muted, never red. */
.library__group {
  display: flex; flex-direction: column; gap: var(--space-3);
}
.library__group-header {
  display: flex; flex-direction: column; gap: var(--space-1);
  margin-bottom: var(--space-2);
}
.library__group-title {
  font-size: var(--text-2xl); font-weight: var(--weight-bold);
  color: var(--text-primary); margin: 0;
}
.library__group-subtitle {
  font-size: var(--text-sm); color: var(--text-secondary); margin: 0;
}
.library__group[data-group="explore"] {
  padding-top: var(--space-6);
  border-top: var(--glass-border-width) solid var(--border-glass);
}
.library__group[data-group="explore"] .library__subject { opacity: 0.82; }

/* Subject = a native <details> accordion, closed by default. Expanded, the
   14 subjects of a real grade-5 map stack ~1,750 lesson cards down one page
   and the student scrolls past whole subjects to reach theirs; closed, every
   subject is one row and the map is legible again. The row is a card so a
   closed subject still reads as a place to go, not a bare heading. */
.library__subject {
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  background: var(--surface-glass);
  padding: var(--space-3) var(--space-4);
}
.library__subject[open] { padding-bottom: var(--space-5); }
.library__subject-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); flex-wrap: wrap;
  cursor: pointer;
  list-style: none;                 /* hide the default disclosure triangle; */
}                                   /* the chevron below is the affordance.  */
.library__subject-header::-webkit-details-marker { display: none; }
.library__subject-header:hover .library__subject-title,
.library__subject-header:focus-visible .library__subject-title {
  color: var(--accent-primary);
}
.library__subject-heading {
  display: flex; flex-direction: column; gap: var(--space-1);
}
.library__subject-title {
  font-size: var(--text-xl); font-weight: var(--weight-bold);
  color: var(--text-primary); margin: 0;
  transition: color var(--duration-fast) var(--ease-out);
}
.library__subject-subtitle {
  font-size: var(--text-sm); color: var(--text-secondary); margin: 0;
}
/* Closed, the count is the only hint of what is inside — without it the row
   says nothing about whether the subject holds 4 lessons or 212. */
.library__subject-meta {
  display: inline-flex; align-items: center; gap: var(--space-2);
}
.library__subject-count {
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--text-muted);
  font-size: var(--text-xs); font-weight: var(--weight-medium);
  white-space: nowrap;
}
.library__subject-chevron {
  color: var(--text-muted);
  transition: transform var(--duration-base) var(--ease-out);
}
.library__subject[open] .library__subject-chevron { transform: rotate(180deg); }
.library__subject > .library__ask { margin-top: var(--space-4); }

/* "Ask to add" — the student's voice on an Explore-more subject. Inviting
   (accent, not red); confirmed state reads as a gentle success. The parent
   still gates what counts — this only records the request. */
.library__ask { display: flex; align-items: center; }
.library__ask-btn {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--accent-primary);
  color: var(--accent-primary);
  font-size: var(--text-sm); font-weight: var(--weight-bold);
  cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out);
}
.library__ask-btn:hover { box-shadow: var(--shadow-glow); }
.library__ask-done {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--success);
}
.library__ask-done .material-symbols-outlined { font-size: var(--text-base); }

.library__lesson-grid {
  list-style: none; padding: 0; margin: var(--space-4) 0 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-4);
}

.library-card {
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-3);
  backdrop-filter: blur(12px);
  transition: box-shadow var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out),
              transform var(--duration-base) var(--ease-out);
}
.library-card[data-state="mastered"]    { border-color: var(--success); }
.library-card[data-state="in_progress"] { border-color: var(--accent-secondary); }
.library-card[data-state="unlocked"]    { border-color: var(--accent-primary); }
.library-card[data-state="locked"]      { opacity: 0.85; }
.library-card[data-state="mastered"]:hover,
.library-card[data-state="in_progress"]:hover,
.library-card[data-state="unlocked"]:hover {
  box-shadow: var(--shadow-glow);
  transform: translateY(-2px);
}
.library-card--placeholder {
  opacity: 0.6; box-shadow: none; text-align: center;
  align-items: center; justify-content: center;
}

.library-card__header {
  display: flex; flex-direction: row; justify-content: space-between;
  align-items: center; gap: var(--space-2);
}
.library-card__grade-chip {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs); color: var(--text-secondary);
}
.library-card__state-chip {
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs); font-weight: var(--weight-medium);
}
.library-card__state-chip[data-state="mastered"]    { background: var(--success); color: var(--text-on-accent); }
.library-card__state-chip[data-state="in_progress"] { background: var(--accent-secondary); color: var(--text-on-accent); }
.library-card__state-chip[data-state="unlocked"]    { background: var(--accent-primary); color: var(--text-on-accent); }
.library-card__state-chip[data-state="locked"]      { background: var(--surface-glass-strong); color: var(--text-muted); }

.library-card__title {
  font-size: var(--text-lg); font-weight: var(--weight-bold);
  color: var(--text-primary); margin: 0;
}
/* Skills a lesson teaches — labelled so the card reads unmistakably as a
   *lesson* (the heading) that teaches *skills* (these), not two restatements. */
.library-card__teaches {
  display: flex; flex-direction: column; gap: var(--space-1);
}
.library-card__teaches-label {
  font-size: var(--text-xs); color: var(--text-muted);
  font-weight: var(--weight-medium); text-transform: uppercase;
  letter-spacing: 0.06em;
}
.library-card__skill-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: var(--space-1);
}
.library-card__skill { font-size: var(--text-sm); color: var(--text-secondary); }

.library-card__heatbar {
  background: var(--surface-glass-strong);
  border-radius: var(--radius-pill);
  height: var(--space-2); overflow: hidden;
}
.library-card__heatbar-fill {
  height: 100%;
  width: var(--pct, 0%);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg,
    var(--warning) 0%, var(--info) 50%, var(--success) 100%);
  transition: width var(--duration-slow) var(--ease-out);
}

.library-card__prereqs {
  display: flex; flex-direction: column; gap: var(--space-2);
  font-size: var(--text-sm);
}
.library-card__prereq-label {
  font-size: var(--text-xs); color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.library-card__prereq-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: row; flex-wrap: wrap; gap: var(--space-2);
}
.library-card__prereq-chip {
  /* inline-block keeps the chip as ONE box when its text wraps — without
     this the default `display: inline` paints background + border per
     line-box, so a chip whose label spans two lines renders as two
     stacked pill fragments. max-width:100% caps it to the parent so a
     long single chip doesn't blow out the card. overflow-wrap:anywhere
     lets long single tokens break inside the chip. */
  display: inline-block;
  max-width: 100%;
  overflow-wrap: anywhere;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs); color: var(--text-primary);
  text-decoration: none;
  transition: box-shadow var(--duration-base) var(--ease-out);
}
.library-card__prereq-chip:hover { box-shadow: var(--shadow-glow); }
.library-card__prereq-chip[data-state="orphan"] { color: var(--text-muted); cursor: default; }

/* Advisory cross-grade foundation flag — "review suggested". This is NOT a lock
   and NOT an error: it uses --info (informational), never --error, per the
   never-red rule. The lesson stays fully available; a returning student proceeds. */
.library-card__foundations {
  display: flex; flex-direction: column; gap: var(--space-2);
  font-size: var(--text-sm);
  border-left: 2px solid var(--info);
  padding-left: var(--space-3);
}
.library-card__foundation-label {
  font-size: var(--text-xs); color: var(--info);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.library-card__foundation-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: row; flex-wrap: wrap; gap: var(--space-2);
}
.library-card__foundation-chip {
  display: inline-block; max-width: 100%; overflow-wrap: anywhere;
  background: color-mix(in srgb, var(--info) 14%, transparent);
  border: var(--glass-border-width) solid color-mix(in srgb, var(--info) 40%, transparent);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs); color: var(--text-primary);
  text-decoration: none;
  transition: box-shadow var(--duration-base) var(--ease-out);
}
.library-card__foundation-chip:hover { box-shadow: var(--shadow-glow); }

/* Schedule surface — the same advisory foundation flag, compact inline row. */
.schedule-card__foundations {
  display: flex; flex-direction: row; flex-wrap: wrap; align-items: center;
  gap: var(--space-2); margin-top: var(--space-2);
  font-size: var(--text-xs); color: var(--info);
}
.schedule-card__foundations-icon { font-size: var(--icon-size-sm); }
.schedule-card__foundations-label {
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--info);
}
.schedule-card__foundation-chip {
  display: inline-block; max-width: 100%; overflow-wrap: anywhere;
  background: color-mix(in srgb, var(--info) 14%, transparent);
  border: var(--glass-border-width) solid color-mix(in srgb, var(--info) 40%, transparent);
  border-radius: var(--radius-pill);
  padding: 2px var(--space-2);
  color: var(--text-primary); text-decoration: none;
}
.schedule-card__foundation-chip:hover { box-shadow: var(--shadow-glow); }

/* Parent Schedule — "Foundations to review" card (advisory, --info; never-red). */
.psched-foundations__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--space-2);
}
.psched-foundations__item {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--info);
  background: color-mix(in srgb, var(--info) 8%, transparent);
  border-radius: var(--radius-sm);
}
.psched-foundations__skill { font-weight: var(--weight-medium); color: var(--text-primary); }
.psched-foundations__meta { font-size: var(--text-xs); color: var(--text-muted); }
.psched-foundations__link {
  margin-left: auto; font-size: var(--text-xs); color: var(--info);
  text-decoration: none; display: inline-flex; align-items: center; gap: var(--space-1);
}
.psched-foundations__link:hover { text-decoration: underline; }

.library-card__cta {
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  font-size: var(--text-base); font-weight: var(--weight-bold);
  text-decoration: none; text-align: center;
  transition: box-shadow var(--duration-base) var(--ease-out);
}
.library-card__cta:hover { box-shadow: var(--shadow-glow); }
.library-card__cta[data-state="mastered"] {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  color: var(--text-primary);
}
.library-card__cta[data-state="in_progress"] { background: var(--accent-secondary); color: var(--text-on-accent); }
.library-card__cta[data-state="unlocked"]    { background: var(--accent-primary); color: var(--text-on-accent); }
/* Explore-more "Preview" — quiet/neutral, distinct from the committal
   Start/Resume path CTAs (this subject isn't assigned; reading it earns no
   mastery). Never red. */
.library-card__cta[data-variant="preview"] {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  color: var(--text-primary);
}

.library-card__icon { font-size: var(--icon-size-xl); color: var(--accent-secondary); }
.library-card__hint { font-size: var(--text-sm); color: var(--text-secondary); margin: 0; }

/* Subject card — review state additions (per spaced-repetition queue). */
.subject-card__caught-up {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
  padding: var(--space-3) 0;
}
.subject-card[data-state="review_due"] { border-color: var(--accent-secondary); }
.subject-card[data-state="all_caught_up"] { opacity: 0.78; }

/* ============================================================
   ORGANIC SUBSTRATE ELEMENTS (Spark Stars/Clouds & Bloom Dandelions)
   ============================================================ */

/* --- Spark: Star Twinkle layers --- */
.shell__substrate-stars {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 33vh;
  pointer-events: none;
  display: none;
  z-index: 1;
}
body:not(.theme-bloom):not(.focus-mode) .shell__substrate-stars {
  display: block;
}
.stars-layer-1 {
  background-image: 
    radial-gradient(1px 1px at 45px 10px, white, transparent),
    radial-gradient(1.5px 1.5px at 180px 40px, rgba(255,255,255,0.8), transparent),
    radial-gradient(2px 2px at 90px 75px, white, transparent);
  background-size: 300px 150px;
  animation: star-twinkle calc(4s / var(--twinkle-speed-mult, 1.0)) ease-in-out infinite;
}
.stars-layer-2 {
  background-image: 
    radial-gradient(1px 1px at 150px 45px, white, transparent),
    radial-gradient(2px 2px at 300px 90px, rgba(255,255,255,0.7), transparent);
  background-size: 400px 200px;
  animation: star-twinkle calc(6s / var(--twinkle-speed-mult, 1.0)) ease-in-out infinite;
  animation-delay: -3s;
}
@keyframes star-twinkle {
  0%, 100% { opacity: 0.1; }
  50%      { opacity: 0.8; }
}

/* --- Spark: Shooting Stars --- */
.shell__substrate-shooting-stars {
  position: absolute;
  inset: 0;
  pointer-events: none;
  display: none;
  z-index: 2;
}
body:not(.theme-bloom):not(.focus-mode) .shell__substrate-shooting-stars {
  display: block;
}
.star-wrapper {
  position: absolute;
  transform: rotate(145deg);
}
.shooting-star {
  width: 0px;
  height: 3px;
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,1));
  border-radius: 999px;
  box-shadow: 0 0 12px 2px rgba(255, 255, 255, 0.8);
  animation: shoot-star calc(var(--star-base-dur, 10s) / var(--star-speed-mult, 1.0)) ease-in-out infinite;
  animation-delay: inherit;
}
@keyframes shoot-star {
  0% { transform: translateX(0); width: 0; opacity: 1; }
  5% { width: 150px; opacity: 1; }
  15% { transform: translateX(900px); width: 0; opacity: 0; }
  100% { transform: translateX(900px); width: 0; opacity: 0; }
}

/* --- Spark: Organic Drifting Clouds --- */
.drift-cloud {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0) 70%);
  filter: blur(30px);
  animation: cloud-drift-sky calc(var(--cloud-base-dur) / var(--cloud-speed-mult, 1.0)) linear infinite;
  opacity: 0.28;
  pointer-events: none;
  z-index: 1;
}
@keyframes cloud-drift-sky {
  0%   { transform: translateX(-60vw); }
  100% { transform: translateX(120vw); }
}

/* --- Bloom: Dandelions --- */
.dandelion {
  position: absolute;
  transform: scale(var(--dandelion-scale, 1));
  pointer-events: none;
  transform-origin: 50% 140px;
  z-index: 2;
}
.dandelion__float {
  animation: dandelion-float calc(var(--dandelion-float-dur) / var(--dandelion-speed-mult, 1.0)) ease-in-out infinite;
}
.dandelion__sway {
  animation: dandelion-sway calc(var(--dandelion-sway-dur) / var(--dandelion-speed-mult, 1.0)) ease-in-out infinite;
  transform-origin: 50% 140px;
}
.dandelion__glow-element {
  animation: dandelion-glow 4s ease-in-out infinite;
}
@keyframes dandelion-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-40px); }
}
@keyframes dandelion-sway {
  0%, 100% { transform: rotate(-8deg); }
  50%      { transform: rotate(8deg); }
}
@keyframes dandelion-glow {
  0%, 100% { opacity: 0.6; }
  50%      { opacity: 0.2; }
}

/* --- Premium custom range sliders --- */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255, 255, 255, 0.15);
  border: none;
  cursor: pointer;
  outline: none;
  overflow: hidden;
}
body.theme-bloom input[type="range"] {
  background: rgba(0, 0, 0, 0.08);
}

/* Chrome/Safari/Edge WebKit thumb styling */
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent-primary, #60A5FA);
  border: 1px solid rgba(255, 255, 255, 0.4);
  box-shadow: -407px 0 0 400px var(--accent-primary, #60A5FA);
  transition: transform var(--duration-fast) var(--ease-out);
}
body.theme-bloom input[type="range"]::-webkit-slider-thumb {
  background: var(--accent-secondary, #F08A8A);
  box-shadow: -407px 0 0 400px var(--accent-secondary, #F08A8A);
}
input[type="range"]::-webkit-slider-thumb:hover {
  transform: scale(1.15);
}

/* Firefox thumb styling */
input[type="range"]::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent-primary, #60A5FA);
  border: 1px solid rgba(255, 255, 255, 0.4);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-out);
}
body.theme-bloom input[type="range"]::-moz-range-thumb {
  background: var(--accent-secondary, #F08A8A);
}
input[type="range"]::-moz-range-thumb:hover {
  transform: scale(1.15);
}

/* Firefox native progress fill styling */
input[type="range"]::-moz-range-progress {
  background-color: var(--accent-primary, #60A5FA);
  height: 6px;
  border-radius: var(--radius-pill);
}
body.theme-bloom input[type="range"]::-moz-range-progress {
  background-color: var(--accent-secondary, #F08A8A);
}

/* ============================================================
   SCRATCH BLOCKS CUSTOM STYLING (Block 13 CS)
   ============================================================ */
.scratch-block {
    display: inline-block;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 0.85rem;
    font-weight: bold;
    color: #ffffff;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    margin: 0.1rem 0.2rem;
    vertical-align: middle;
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.15);
}
    background-color: #2ca5e2;
    border: 1px solid #1c7ba8;
}

/* Add Focus Mode Semantic overrides */
body.focus-mode {
  --gold: #FFFFFF;
  --warning-strong: #D8C29F;
  --success: #9FD8A6;
  --warning: #D8C29F;
  --info: #BFBFBF;
}

/* ============================================================
   PARENT CONSOLE & SCHEDULE STYLING OVERRIDES (V1.1)
   ============================================================ */

/* Parent Top Bar */
.pbar {
  /* Parent chrome lives inside .shell (which is a 2-col grid for the
     student app's left nav). Parent surfaces have no left nav, so the
     pbar must span both columns to use the full viewport width. */
  grid-column: 1 / -1;
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-5);
  /* See .pbar__right — the bar reflows at any width rather than clipping. */
  flex-wrap: wrap;
  row-gap: var(--space-3);
  padding: var(--space-3) var(--space-6);
  background: var(--surface-glass-chrome);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border-bottom: var(--glass-border-width) solid var(--border-glass);
  flex-wrap: nowrap;
}
.pbar__who {
  white-space: nowrap;
}
.pbar__name {
  white-space: nowrap;
}
/* Sibling: when .shell wraps a parent surface (no .shell__nav), make main span both cols too */
.shell:has(.pbar) > .shell__main {
  grid-column: 1 / -1;
}
.pbar__left {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
.pbar__brand {
  font-family: var(--font-headline);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.pbar__mark {
  color: var(--accent-primary);
  display: flex;
  align-items: center;
}
.pbar__divider {
  width: 1px;
  height: var(--space-6);
  background: var(--border-glass);
}
.pbar__who {
  display: flex;
  flex-direction: column;
}
.pbar__eyebrow {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  font-weight: var(--weight-medium);
}
.pbar__name {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
/* `.pbar__student-picker*` lived here and was deleted: a student selector is a
   content control, and the top bar is the parent's menu. Its replacement is
   `.student-lens`, defined with the other in-surface controls — see
   `partials/student_lens.html`. Do not reintroduce a student control into
   `.pbar`; that placement is what made a surface able to mix a family-wide
   grid with a single-child panel (`docs/ideation/parent-workflow.md` §6 D-4). */
/* --- Exit-link student chooser -----------------------------------------
   A <summary> styled as an icon button. `list-style: none` + the ::-webkit
   pseudo kill the disclosure triangle in both engines; without both, Safari
   still draws it and the icon sits off-centre. */
.pbar__student-jump { position: relative; }
.pbar__student-jump > summary {
  list-style: none;
  cursor: pointer;
}
.pbar__student-jump > summary::-webkit-details-marker { display: none; }
.pbar__student-jump-menu {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 120;            /* above .pbar's own z-index: 100 */
  min-width: 180px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2);
  background: var(--surface-glass-chrome);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-glow);
}
.pbar__student-jump-head {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: var(--space-1) var(--space-2);
}
.pbar__student-jump-item {
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  text-decoration: none;
}
.pbar__student-jump-item:hover {
  background: var(--surface-glass-strong);
  color: var(--text-primary);
}
.pbar__student-jump-item--current { color: var(--text-primary); font-weight: var(--weight-bold); }

.pbar__right {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  /* Wrap at EVERY width, not just under the 820px step. Above that step the
     bar had no reflow at all, so between ~821px and whatever width happened to
     fit, it silently overflowed and clipped the logout control off-screen — a
     control disappearing, not merely a cramped row. It went unnoticed because
     the row was short enough to fit at most sizes; naming the child on the
     Digest link put the width back and re-opened the gap that the retired
     ≤1024 step used to cover.

     Wrapping unconditionally fixes it structurally rather than by tuning a
     breakpoint, which matters because the row's width now depends on a child's
     NAME — there is no single number that is right for both "Bo" and
     "Alexandra". `margin-left: auto` keeps the group right-aligned once it
     drops to its own line (space-between alone would flush it left). */
  flex-wrap: wrap;
  justify-content: flex-end;
  margin-left: auto;
  row-gap: var(--space-2);
}
/* Icon-only chrome controls at the end of the nav row. The form wrapper exists
   only because logout is a POST; it must not introduce its own box. */
.pbar__logout-form { display: inline-flex; }
.pbar__icon-link { text-decoration: none; }
.pbar__nav-link {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-weight: var(--weight-medium);
  text-decoration: none;
  /* Nav labels never wrap. Every label was a single word until "Digest" began
     naming the selected child, and a two-word label broke across lines at
     narrow widths — "Digest" over "· Becca", with the active underline
     splitting across both. The row already wraps as a whole at 820px; it is
     the individual link that must stay intact. */
  white-space: nowrap;
  transition: color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
}
.pbar__nav-link:hover {
  color: var(--text-primary);
}
.pbar__nav-link--active {
  color: var(--accent-primary);
  border-bottom-color: var(--accent-primary);
}
/* Legacy single-student links demoted — smaller + muted. Stay
   clickable so old bookmarks still resolve. */
.pbar__nav-link--legacy {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-weight: var(--weight-regular);
}
.pbar__nav-link--legacy:hover {
  color: var(--text-secondary);
}
.pbar__nav-link--legacy.pbar__nav-link--active {
  /* Even when active, legacy stays muted-accent — visual cue that
     this is a sidetrack, not the primary surface set */
  color: var(--accent-primary);
  border-bottom-color: color-mix(in srgb, var(--accent-primary) 50%, transparent);
}
.pbar__nav-divider {
  display: inline-block;
  width: 1px;
  height: var(--space-4);
  background: var(--border-glass);
  margin: 0 var(--space-2);
}
/* `.pbar__exit` (the accent-filled "Student app" / "Logout" pill) was removed
   with its last markup: both are icon-only `.shell__icon-btn`s now. */

/* Tablet / iPad — the parent chrome is a single nowrap row that overflows
   below desktop width, clipping Setup / Student app / Logout off the right edge
   (unreachable in both iPad orientations).
   The ≤1024 step used to hide the "Unlocked on this device" chip to recover
   ~200px. That chip is gone entirely now, and Student app / Logout became
   icon-only, so the row is far shorter at every width and the step is no longer
   needed. */
/* ≤820 (iPad portrait & below): the nav still can't share the row with the
   brand block — drop it to its own full-width row.
   Mirrors the student topbar's wrap pattern at this width (see @820px above). */
@media (max-width: 820px) {
  /* Wrap itself is now unconditional (see .pbar / .pbar__right). What survives
     here is the part that is genuinely width-specific: FORCING the nav to its
     own full row even when it would still squeeze onto the first one, and
     tightening the gap once it gets there. */
  .pbar__right {
    flex-basis: 100%;
    gap: var(--space-4);
  }
}

/* Parent Workspace Layout */
.parent {
  max-width: var(--container-wide);
  margin: 0 auto;
  padding: var(--space-2) var(--space-5) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Horizon Alert Banner */
.horizon-alert {
  border-left: var(--space-1) solid var(--accent-secondary);
  padding: var(--space-5);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
}
.horizon-alert__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.horizon-alert__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-top: var(--space-1);
}
.horizon-alert__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.horizon-alert__options {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.horizon-alert__radio {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-primary);
  cursor: pointer;
}
.horizon-alert__btn {
  background: var(--accent-primary);
  color: var(--text-on-accent);
  border: none;
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  cursor: pointer;
}

/* Weekly Digest */
.digest {
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.digest__top {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.digest__eyebrow {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  font-weight: var(--weight-bold);
}
.digest__pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}
.digest__pill[data-status="success"] {
  background: rgba(79, 181, 138, 0.15);
  color: var(--success);
}
.digest__pill[data-status="attention"] {
  background: rgba(232, 162, 58, 0.15);
  color: var(--warning);
}
.digest__headline {
  font-family: var(--font-headline);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.digest__facts {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
  list-style: none;
  padding: 0;
  margin: 0;
}
@media (max-width: 720px) {
  .digest__facts {
    grid-template-columns: repeat(2, 1fr);
  }
}
.fact {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  position: relative;
}
.fact__icon {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  color: var(--accent-secondary);
}
.fact[data-flag="hurdle"] .fact__icon {
  color: var(--warning);
}
.fact__value {
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.fact__label {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  margin-top: var(--space-1);
}
.digest__actions {
  margin-top: var(--space-3);
}
.digest__cta {
  background: var(--accent-primary);
  color: var(--text-on-accent);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-5);
  font-weight: var(--weight-bold);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  transition: opacity var(--duration-fast);
}
.digest__cta:hover {
  opacity: 0.9;
}
.digest__cta-badge {
  background: rgba(255, 255, 255, 0.2);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  padding: 1px var(--space-2);
}

/* Mastery pride strip */
.mastery__pride-strip {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: var(--glass-border-width) solid var(--border-glass);
  margin-bottom: var(--space-4);
}
.mastery__shields-label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
}
.mastery__shields {
  display: flex;
  gap: var(--space-1);
}
.mastery__shield {
  color: var(--gold);
  display: flex;
  align-items: center;
}
.mastery__shields-empty {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.mastery__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.mastery__legend-item {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: var(--space-1);
}
.mastery__dot {
  width: var(--space-2);
  height: var(--space-2);
  border-radius: var(--radius-pill);
}
.mastery__dot[data-zone="warning"] { background: var(--warning); }
.mastery__dot[data-zone="info"]    { background: var(--info); }
.mastery__dot[data-zone="success"] { background: var(--success); }
.mastery__dot[data-zone="gold"]    { background: var(--gold); }

.mastery__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.subject {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.subject__row {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-sm);
}
.subject__name {
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}
.subject__pct {
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
}
.heatbar {
  height: var(--space-2);
  background: var(--surface-glass-strong);
  border-radius: var(--radius-pill);
  overflow: hidden;
  position: relative;
}
.heatbar__thumb {
  display: block;
  height: 100%;
  width: var(--mastery);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--warning), var(--info), var(--success));
}

/* Intervention Settings */
.setting {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.setting__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.setting__help {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.setting__alert-consequence {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: var(--space-1);
}

/* Stepper */
.stepper {
  display: inline-flex;
  align-items: center;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-1);
  gap: var(--space-3);
}
.stepper__btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-1);
  border-radius: var(--radius-sm);
  transition: background var(--duration-fast);
}
.stepper__btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.1);
}
.stepper__btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}
.stepper__value {
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
  color: var(--text-primary);
  min-width: 20px;
  text-align: center;
}
.stepper__unit {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-left: var(--space-2);
}

/* Segmented Buttons */
.segmented-control {
  display: flex;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-1);
}
.segmented-control__option {
  flex: 1;
  text-align: center;
  cursor: pointer;
  position: relative;
}
.segmented-control__option input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
}
.segmented-control__option span {
  display: block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  transition: all var(--duration-fast);
}
.segmented-control__option input:checked + span {
  background: var(--bg-elevated);
  color: var(--text-primary);
  font-weight: var(--weight-bold);
  box-shadow: var(--shadow-sm);
}

/* Horizon Slider */
.horizon-setting__readout {
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
  margin-bottom: var(--space-1);
}
.horizon-setting__value {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.horizon-setting__unit {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.horizon-setting__slider {
  width: 100%;
  height: var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  outline: none;
  cursor: pointer;
}
.horizon-setting__scale {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: var(--space-1);
}

/* Hurdles list */
.hurdle-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.hurdle {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-left: 3px solid var(--warning);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  align-items: center;
}
.hurdle__icon {
  color: var(--warning);
  display: flex;
  align-items: center;
  background: rgba(232, 162, 58, 0.1);
  padding: var(--space-2);
  border-radius: var(--radius-pill);
}
.hurdle__body {
  display: flex;
  flex-direction: column;
}
.hurdle__skill {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.hurdle__meta {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  margin-top: 1px;
}
.hurdle__note {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  margin-top: var(--space-2);
  line-height: 1.4;
}
.hurdle__note span {
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.hurdle__link {
  font-size: var(--text-xs);
  color: var(--accent-primary);
  font-weight: var(--weight-bold);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
.hurdle__empty {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  text-align: center;
  padding: var(--space-4) 0;
}
.hurdle-strip {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--success) 8%, transparent);
  border: var(--glass-border-width) solid color-mix(in srgb, var(--success) 28%, transparent);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.hurdle-strip__icon {
  width: 16px;
  height: 16px;
  color: var(--success);
  flex-shrink: 0;
}
.hurdle-strip__text {
  font-weight: var(--weight-medium);
}
.intervention-card--compact .setting__consequence {
  display: none;
}
.intervention-card--compact .setting__help {
  font-size: var(--text-xs);
  margin-bottom: var(--space-1);
}
.intervention-card--compact .setting {
  gap: var(--space-1);
}
.intervention-card--compact > .setting + .setting {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: var(--glass-border-width) solid var(--border-glass);
}
.parent__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding: var(--space-2) 0 0 0;
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.parent__footer-note {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.parent__footer-icon {
  width: 14px;
  height: 14px;
}
.parent__footer-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--accent-primary);
  text-decoration: none;
  font-weight: var(--weight-medium);
}
.parent__footer-link:hover {
  text-decoration: underline;
}
.parent__footer-link svg {
  width: 14px;
  height: 14px;
}
.settings__local-data-hint {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-2);
}
.settings__local-data-icon {
  color: var(--success);
  font-size: 18px;
  flex-shrink: 0;
  line-height: 1;
  margin-top: 1px;
}
.settings__local-data-cta .material-symbols-outlined {
  font-size: 16px;
  vertical-align: middle;
  margin-right: var(--space-1);
}

/* AI Insights */
.insight {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
.insight__tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--accent-secondary);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  margin-bottom: var(--space-1);
}
.insight__text {
  display: block;
  font-size: var(--text-sm);
  color: var(--text-primary);
  line-height: 1.5;
}
.insight__foot {
  font-size: var(--text-xs);
  color: var(--text-muted);
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  line-height: 1.4;
}
.insight__foot-icon {
  color: var(--info);
  margin-top: 1px;
}

/* Backup Export */
.export {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.export__text {
  display: flex;
  flex-direction: column;
}
.export__title {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.export__line {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-1);
}
.export__line-icon {
  color: var(--success);
}
.export__btn {
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--accent-secondary);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  transition: background var(--duration-fast);
}
.export__btn:hover {
  background: rgba(255, 255, 255, 0.1);
}

/* Presets Panel */
.presets-panel {
  padding: var(--space-5);
}
.presets-form {
  margin-top: var(--space-4);
}
.presets-selectors {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-4);
}
@media (max-width: 768px) {
  .presets-selectors {
    grid-template-columns: repeat(2, 1fr);
  }
}
.preset-selector {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.preset-selector__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
}
.presets-btn {
  background: var(--accent-primary);
  color: var(--text-on-accent);
  border: none;
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-5);
  font-weight: var(--weight-bold);
  cursor: pointer;
  transition: opacity var(--duration-fast);
}
.presets-btn:hover {
  opacity: 0.9;
}
.presets-btn--secondary {
  background: var(--surface-glass);
  color: var(--text-primary);
  border: var(--glass-border-width) solid var(--border-glass);
}

.syllabus-select {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-primary);
  outline: none;
}

/* Modals */
.modal-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0, 10, 20, 0.6);
  backdrop-filter: blur(8px);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
}
.modal {
  max-width: 480px;
  width: 100%;
  padding: var(--space-6);
  position: relative;
}
.modal__title {
  font-family: var(--font-headline);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin-bottom: var(--space-4);
}
.modal__summary {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.modal__summary ul {
  margin: var(--space-3) 0;
  padding-left: var(--space-5);
}
.modal__summary li {
  margin-top: var(--space-1);
}
.modal__warning {
  background: rgba(232, 162, 58, 0.1);
  border: 1px solid var(--warning);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
  color: var(--text-primary);
}
.modal__warning-checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
}
.modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* Student Schedule Status Strip */
.schedule-view__status-strip {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.status-stat {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}
.status-stat__icon { font-size: var(--icon-size-sm); flex-shrink: 0; }
.status-stat--streak {
  background: rgba(232, 162, 58, 0.15);
  color: var(--warning);
}
.status-stat--freeze {
  background: rgba(123, 155, 201, 0.15);
  color: var(--info);
}
.status-stat--freeze[data-state="used"] {
  opacity: 0.5;
}
.status-stat--shield {
  background: rgba(232, 162, 58, 0.15);
  color: var(--gold);
}

/* Schedule Layout */
.schedule-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--space-5);
}
@media (max-width: 1024px) {
  .schedule-layout {
    grid-template-columns: 1fr;
  }
}

/* Schedule Card */
.schedule-card {
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  position: relative;
  transition: all var(--duration-base) var(--ease-out);
}
.schedule-card:hover {
  background: var(--surface-glass-strong);
  box-shadow: var(--shadow-md);
}
.schedule-card--pinned {
  border: 2px solid var(--accent-highlight);
  box-shadow: var(--shadow-glow);
}
.schedule-card__badge {
  background: rgba(37, 99, 235, 0.15);
  color: var(--accent-primary);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  padding: 1px var(--space-2);
  display: inline-block;
}
.subtask-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  color: var(--text-primary);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-decoration: none;
  flex: 1;
  text-align: center;
  justify-content: center;
  transition: background var(--duration-fast);
}
.subtask-btn:hover {
  background: rgba(255, 255, 255, 0.15);
}
.subtask-btn__status {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--text-muted);
  display: inline-block;
}
.subtask-btn[data-state="completed"] {
  background: var(--success);
  color: var(--text-on-accent);
}
.subtask-btn[data-state="completed"] .subtask-btn__status {
  background: var(--text-on-accent);
}
.subtask-btn[data-state="locked"] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* Week View Grid */
.week-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--space-3);
  align-items: start;
}
@media (max-width: 1200px) {
  .week-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (max-width: 768px) {
  .week-grid {
    grid-template-columns: 1fr;
  }
}
.day-column {
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.day-column--off-day {
  background: rgba(0, 0, 0, 0.08);
  opacity: 0.8;
}

/* Capacity bar */
.capacity-bar {
  height: var(--space-2);
  background: var(--surface-glass-strong);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.capacity-bar__fill {
  height: 100%;
  width: var(--load-pct);
  border-radius: var(--radius-pill);
  background: var(--accent-secondary);
}
.capacity-bar__fill[data-load-state="warning"] {
  background: var(--warning);
}
.capacity-bar__fill[data-load-state="normal"] {
  background: var(--accent-secondary);
}
.capacity-bar__fill[data-load-state="success"] {
  background: var(--success);
}

/* --- Schedule orientation reshape: trail · today · year zoom · behind ------ */

/* Completion trail (how much of the week is done) */
.completion-trail {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.completion-trail__label {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  white-space: nowrap;
}
.completion-trail__count {
  color: var(--text-primary);
  font-weight: var(--weight-bold);
}
.completion-trail__bar { flex: 1; }

/* Today's column — orientation ("where does today sit?") */
.day-column--today {
  border-color: var(--accent-primary);
  box-shadow: var(--shadow-glow);
}
.day-column__today-badge {
  display: inline-block;
  margin-top: var(--space-1);
  padding: 1px var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--accent-primary);
  color: var(--text-on-accent);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

/* Card: single tap-through title + done-state */
.schedule-card__title-link {
  text-decoration: none;
  color: inherit;
}
.schedule-card__title-link:hover .schedule-card__title { color: var(--accent-primary); }
.schedule-card--done { opacity: 0.62; }
.schedule-card__done-tag {
  color: var(--success);
  font-weight: var(--weight-bold);
}

/* Card outcome — how a finished lesson WENT, shown beside "Done", never
   instead of it. Completion records the work; this records the proficiency.
   Mastered is --success. Revisit is --warning (amber) and never --error: she
   finished the lesson, it needs another pass, and telling a struggling learner
   in red that her completed work is a failure is the opposite of the job. */
.card-outcome {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-glass-strong);
  font-size: var(--text-xs);
  line-height: 1.3;
  align-self: flex-start;
}
.card-outcome__icon { font-size: var(--icon-size-sm); flex-shrink: 0; }
.card-outcome__label { font-weight: var(--weight-bold); }
.card-outcome__pct { color: var(--text-muted); }
.card-outcome[data-outcome="mastered"] { color: var(--success); }
.card-outcome[data-outcome="revisit"] { color: var(--warning); }

/* Behind-awareness — the map SHOWS the debt, My Path does the catch-up.
   Amber (never red), per the locked never-red rule. */
.schedule-behind {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: var(--glass-border-width) solid var(--warning);
  background: var(--surface-glass);
  color: var(--text-primary);
  text-decoration: none;
  font-size: var(--text-sm);
  transition: background var(--duration-fast);
}
.schedule-behind:hover { background: var(--surface-glass-strong); }
.schedule-behind__icon { color: var(--warning); font-size: var(--icon-size-sm); flex-shrink: 0; }
.schedule-behind__text { flex: 1; }
.schedule-behind__arrow { font-size: var(--icon-size-sm); color: var(--text-muted); flex-shrink: 0; }

/* Working ahead — the mirror of .schedule-behind, deliberately in --info and
   not --warning: ranging past next week is a good outcome, not a debt. */
.schedule-ahead {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: var(--glass-border-width) solid var(--info);
  background: var(--surface-glass);
  color: var(--text-primary);
  font-size: var(--text-sm);
}
.schedule-ahead__icon { color: var(--info); font-size: var(--icon-size-sm); flex-shrink: 0; }
.schedule-ahead__text { flex: 1; }
.schedule-ahead__back {
  color: var(--accent-primary);
  text-decoration: none;
  font-weight: var(--weight-bold);
  white-space: nowrap;
}
.schedule-ahead__back:hover { text-decoration: underline; }

/* Real empty-state — never a blank grid */
.schedule-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-8) var(--space-4);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
}
.schedule-empty-state__icon { font-size: var(--icon-size-xl); color: var(--accent-secondary); }
.schedule-empty-state__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.schedule-empty-state__hint {
  max-width: 42ch;
  color: var(--text-secondary);
}

/* Year zoom — the far horizon: weeks across the year, today marked, filled by
   completion. The heatbar stays warning-free: future=info, done=success. */
.year-zoom {
  margin-top: var(--space-6);
  padding: var(--space-4);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
}
.year-zoom__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: var(--space-3);
}
.year-zoom__eyebrow {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.year-zoom__meta { font-size: var(--text-sm); color: var(--text-secondary); }
.year-zoom__track {
  display: flex;
  gap: 3px;
  align-items: flex-end;
  height: 40px;
}
.year-zoom__week {
  flex: 1;
  min-width: 3px;
  height: 100%;
  border-radius: var(--radius-sm);
  background: var(--surface-glass-strong);
  position: relative;
  overflow: hidden;
}
.year-zoom__fill {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--pct);
  background: var(--success);
}
.year-zoom__week[data-state="future"] .year-zoom__fill { background: var(--info); }
.year-zoom__week[data-state="viewing"] .year-zoom__fill { background: var(--info); }
/* Two distinct marks: where TODAY is (secondary, always shown) and which week
   is on screen (primary). They coincide on the default view; they separate the
   moment a student ranges ahead, which is exactly when the difference matters. */
.year-zoom__week[data-state="current"] {
  outline: 2px solid var(--accent-secondary);
  outline-offset: 1px;
}
.year-zoom__week[data-state="viewing"] {
  outline: 2px solid var(--accent-primary);
  outline-offset: 1px;
}
a.year-zoom__week {
  display: block;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--duration-fast);
}
a.year-zoom__week:hover { background: var(--accent-highlight); }
a.year-zoom__week:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 1px;
}

/* Sidebar Queues */
.schedule-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.sidebar-section {
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.sidebar-section__title {
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.sidebar-section__help {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 2px;
  margin-bottom: var(--space-3);
}
.pool-badge {
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  padding: 1px var(--space-2);
}
.pool-badge[data-pool-state="normal"]  { background: var(--surface-glass-strong); color: var(--text-muted); }
.pool-badge[data-pool-state="caution"] { background: var(--warning); color: var(--text-primary); }
.pool-badge[data-pool-state="urgent"]  { background: var(--warning-strong); color: var(--text-on-accent); }

.pool-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}
.pool-item__launch {
  text-decoration: none;
  flex-grow: 1;
}
.pool-item__content {
  display: flex;
  align-items: center;
}
.pool-item__pin-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-muted);
  display: flex;
  align-items: center;
}
.pool-item__pin-btn:hover {
  color: var(--accent-primary);
}
.pool-item__pin-btn--active {
  color: var(--accent-primary);
  transform: rotate(45deg);
}

.remediation-card {
  display: flex;
  align-items: center;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  text-decoration: none;
  color: var(--text-primary);
}

/* ============================================================
   Canonical glass card recipe (Claude)
   The .card glass recipe used by every card surface.
   Tokens only (foundation-design-system.md §4). No hardcoded
   colors, sizes, radii, or shadows.
   ============================================================ */

/* === Canonical glass card recipe — used by every .card surface === */
.card {
  background: var(--surface-glass);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md), var(--glass-inner-shadow);
  padding: var(--space-6);
}

.card__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.card__title {
  font-family: var(--font-headline);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
  line-height: 1.2;
}

.card__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: var(--space-1) 0 0 0;
  max-width: 60ch;
}

.card__icon {
  display: inline-flex;
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  color: var(--accent-primary);
  flex-shrink: 0;
}
.card__icon svg {
  width: 18px;
  height: 18px;
}

/* === Presets panel — tighten the form === */
.presets-panel {
  padding: var(--space-6);
}
.presets-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: 0;
}
.preset-selector__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.presets-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  align-self: flex-start;
  transition: box-shadow var(--duration-fast), opacity var(--duration-fast), transform var(--duration-fast);
}
.presets-btn:hover {
  box-shadow: var(--shadow-glow);
  opacity: 1;
  transform: translateY(-1px);
}
.presets-btn svg {
  width: 16px;
  height: 16px;
}

/* === Polished native-select wrap with custom chevron === */
.syllabus-select-wrap {
  position: relative;
  display: block;
}
.syllabus-select-wrap__chevron {
  position: absolute;
  right: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--text-muted);
  display: inline-flex;
}
.syllabus-select-wrap__chevron .material-symbols-outlined {
  font-size: var(--icon-size-sm);
}

/* Override the bare-select default to allow our custom chevron */
.syllabus-select {
  -webkit-appearance: none;
  appearance: none;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  /* Right padding reserves room for the absolute-positioned chevron (16px icon + 12px gap from edge + 8px breathing) */
  padding: var(--space-2) calc(var(--space-5) + var(--space-3)) var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  cursor: pointer;
  width: 100%;
  transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
  line-height: 1.4;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.syllabus-select:hover {
  border-color: color-mix(in srgb, var(--accent-primary) 40%, var(--border-glass));
}
.syllabus-select:focus {
  outline: none;
  border-color: var(--accent-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-primary) 22%, transparent);
}

/* === Modal polish (preset preview) === */
.modal__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.modal__title {
  font-family: var(--font-headline);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
  line-height: 1.2;
}
.modal__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-md);
  border: var(--glass-border-width) solid var(--border-glass);
  background: var(--surface-glass-strong);
  color: var(--text-secondary);
  cursor: pointer;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.modal__close:hover {
  background: var(--surface-glass);
  color: var(--text-primary);
}
.modal__close svg {
  width: 16px;
  height: 16px;
}

.modal__summary {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.modal__summary-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.modal__summary-list li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--text-primary);
  font-size: var(--text-sm);
}
.modal__summary-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  border: var(--glass-border-width) solid var(--border-glass);
}
.modal__summary-pill--add {
  background: color-mix(in srgb, var(--success) 16%, transparent);
  color: var(--success);
}
.modal__summary-pill--remove {
  background: color-mix(in srgb, var(--warning) 16%, transparent);
  color: var(--warning);
}
.modal__footnote {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0;
}
.modal__footnote-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--success);
}

/* Override the existing hardcoded warning panel — token-only */
.modal__warning {
  background: color-mix(in srgb, var(--warning) 10%, transparent);
  border: var(--glass-border-width) solid var(--warning);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
}
.modal__warning-head {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--warning-strong);
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
}
.modal__warning-icon {
  width: 16px;
  height: 16px;
}
.modal__warning-title {
  font-weight: var(--weight-bold);
}
.modal__warning-body {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}
.modal__warning-checkbox {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  margin-top: var(--space-1);
}

/* ============================================================
   ROUND 2 — Parent Dashboard + Schedule polish (Claude)
   Adds hero treatment, status pills, subject dots, gradient
   capacity bars, polished settings, schedule sidebar. Tokens
   only.
   ============================================================ */

/* === Insight Hero (parent dashboard top) === */
.insight-hero {
  position: relative;
  overflow: hidden;
  padding-top: var(--space-4);
  padding-bottom: var(--space-4);
}
.insight-hero__top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}
.insight-hero__top-actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.insight-hero__cta {
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
}
.insight-hero__eyebrow {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
}
.insight-hero__headline {
  font-family: var(--font-headline);
  font-size: var(--text-3xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
  line-height: 1.1;
  letter-spacing: -0.01em;
}
.insight-hero__lede {
  font-size: var(--text-base);
  color: var(--text-secondary);
  margin: 0 0 var(--space-3) 0;
  max-width: 64ch;
  line-height: 1.45;
}
.insight-hero__facts {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-3);
}
.insight-hero__facts .fact {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  position: relative;
}
.insight-hero__facts .fact[data-flag] {
  border-color: color-mix(in srgb, var(--warning) 60%, var(--border-glass));
}
.insight-hero__facts .fact__icon {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  color: var(--text-muted);
  display: inline-flex;
}
.insight-hero__facts .fact__icon svg {
  width: 16px;
  height: 16px;
}
.insight-hero__facts .fact[data-flag] .fact__icon {
  color: var(--warning);
}
.insight-hero__facts .fact__value {
  font-family: var(--font-headline);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  line-height: 1;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.insight-hero__facts .fact__label {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--weight-medium);
}
.insight-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* === Status pill (success/warning/info/muted) === */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  border: var(--glass-border-width) solid var(--border-glass);
  background: var(--surface-glass-strong);
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.status-pill[data-status="success"] {
  background: color-mix(in srgb, var(--success) 14%, transparent);
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 50%, transparent);
}
.status-pill[data-status="warning"] {
  background: color-mix(in srgb, var(--warning) 14%, transparent);
  color: var(--warning);
  border-color: color-mix(in srgb, var(--warning) 50%, transparent);
}
.status-pill[data-status="info"] {
  background: color-mix(in srgb, var(--info) 14%, transparent);
  color: var(--info);
  border-color: color-mix(in srgb, var(--info) 50%, transparent);
}
.status-pill__icon {
  width: 14px;
  height: 14px;
}

/* presets-btn embellishments (badge + icon support, reused on dashboard) */
.presets-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.presets-btn svg {
  width: 16px;
  height: 16px;
}
.presets-btn__badge {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--text-on-accent) 22%, transparent);
  color: var(--text-on-accent);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  margin-left: var(--space-1);
}

/* === Subject color dot (small color-coded chip) === */
.subject-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: var(--radius-pill);
  background: var(--text-muted);
  flex-shrink: 0;
}
.subject-dot[data-subject="math"]              { background: var(--accent-primary); }
.subject-dot[data-subject="ela"]               { background: var(--info); }
.subject-dot[data-subject="science"]           { background: var(--success); }
.subject-dot[data-subject="cs"]                { background: var(--accent-secondary); }
.subject-dot[data-subject="social_studies"]    { background: var(--warning); }
.subject-dot[data-subject="design_innovation"] { background: var(--gold); }
.subject-dot[data-subject="practical_economics"]{ background: var(--accent-highlight); }
/* Remaining V1 subjects — distinct hues via color-mix on existing tokens */
.subject-dot[data-subject="logic_inquiry"]     { background: color-mix(in srgb, var(--accent-secondary) 60%, var(--accent-primary) 40%); }
.subject-dot[data-subject="music"]             { background: var(--warning-strong); }
.subject-dot[data-subject="pe_health"]         { background: color-mix(in srgb, var(--success) 70%, var(--info) 30%); }
.subject-dot[data-subject="sel"]               { background: color-mix(in srgb, var(--accent-secondary) 50%, var(--warning) 50%); }
.subject-dot[data-subject="self_mastery"]      { background: color-mix(in srgb, var(--gold) 60%, var(--accent-primary) 40%); }
.subject-dot[data-subject="visual_art"]        { background: color-mix(in srgb, var(--accent-primary) 50%, var(--warning) 50%); }
.subject-dot[data-subject="world_language"]    { background: color-mix(in srgb, var(--info) 60%, var(--success) 40%); }

/* === Horizon alert head — eyebrow + title structure === */
.horizon-alert {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.horizon-alert__eyebrow {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: var(--weight-bold);
  color: var(--warning);
}
.horizon-alert__title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-headline);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: var(--space-1) 0 0 0;
  line-height: 1.2;
}
.horizon-alert__icon {
  width: 20px;
  height: 20px;
  color: var(--warning);
  flex-shrink: 0;
}
.horizon-alert__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
  max-width: 60ch;
}
.horizon-alert__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.horizon-alert__options {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.horizon-alert__radio {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-primary);
  cursor: pointer;
}

/* === Mastery overview — bold % + gradient bar === */
.mastery__pride-strip {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-4);
  border-bottom: var(--glass-border-width) solid var(--border-glass);
}
.mastery__shields-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
}
.mastery__shields {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.mastery__shield {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--gold) 18%, transparent);
  color: var(--gold);
  border: var(--glass-border-width) solid color-mix(in srgb, var(--gold) 40%, transparent);
}
.mastery__shield-icon {
  width: 14px;
  height: 14px;
}
.mastery__shields-empty {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
}
.mastery__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.mastery__legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--weight-medium);
}
.mastery__dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
}
.mastery__dot[data-zone="warning"] { background: var(--warning); }
.mastery__dot[data-zone="info"]    { background: var(--info); }
.mastery__dot[data-zone="success"] { background: var(--success); }
.mastery__dot[data-zone="gold"]    { background: var(--gold); }
.mastery__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.mastery__group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.mastery__group + .mastery__group {
  padding-top: var(--space-2);
  border-top: var(--glass-border-width) solid var(--border-glass);
}
.mastery__group-label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-1);
}
.subject {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(120px, 1fr) auto;
  gap: var(--space-3);
  align-items: center;
}
.subject--link {
  color: inherit;
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  margin: 0 calc(var(--space-2) * -1);
  border-radius: var(--radius-sm);
  transition: background 120ms ease;
}
.subject--link:hover,
.subject--link:focus-visible {
  background: var(--surface-glass-strong);
  outline: none;
}
.subject__name {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.subject__pct {
  font-family: var(--font-headline);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  font-feature-settings: "tnum" 1, "lnum" 1;
  line-height: 1;
  min-width: 2.5rem;
  text-align: right;
}
.heatbar {
  position: relative;
  width: 100%;
  height: var(--space-2);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.heatbar__thumb {
  display: block;
  height: 100%;
  width: var(--mastery, 0%);
  background: linear-gradient(
    90deg,
    var(--warning) 0%,
    var(--info) 40%,
    var(--success) 75%,
    var(--gold) 100%
  );
  border-radius: var(--radius-pill);
  transition: width var(--duration-slow, 400ms) var(--ease-out, ease-out);
}

/* === Hurdle list polish === */
.hurdle-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.hurdle {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-left: 3px solid var(--warning);
}
.hurdle__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--warning) 16%, transparent);
  color: var(--warning);
  flex-shrink: 0;
}
.hurdle__icon svg {
  width: 16px;
  height: 16px;
}
.hurdle__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.hurdle__skill {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.hurdle__meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.hurdle__note {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: var(--space-1) 0 0 0;
}
.hurdle__note-label {
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  margin-right: var(--space-1);
}
.hurdle__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  transition: background var(--duration-fast);
}
.hurdle__link:hover {
  background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
}
.hurdle__link svg {
  width: 14px;
  height: 14px;
}
.hurdle__empty {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-muted);
  text-align: center;
  justify-content: center;
}
.hurdle__empty-icon {
  width: 18px;
  height: 18px;
  color: var(--success);
}

/* === Intervention settings — value pills + cleaner stepper === */
.intervention-card .setting + .setting {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: var(--glass-border-width) solid var(--border-glass);
}
.setting__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-1);
}
.setting__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.setting__value-pill {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--accent-primary);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  font-feature-settings: "tnum" 1, "lnum" 1;
  border: var(--glass-border-width) solid color-mix(in srgb, var(--accent-primary) 45%, transparent);
}
.setting__value-pill--relaxed {
  color: var(--info);
  border-color: color-mix(in srgb, var(--info) 45%, transparent);
}
.setting__value-pill--standard {
  color: var(--accent-primary);
  border-color: color-mix(in srgb, var(--accent-primary) 45%, transparent);
}
.setting__value-pill--push {
  color: var(--warning);
  border-color: color-mix(in srgb, var(--warning) 45%, transparent);
}
.setting__help {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  margin: 0 0 var(--space-2) 0;
  line-height: 1.45;
}
.setting__control {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
}
.stepper {
  display: inline-flex;
  align-items: center;
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  overflow: hidden;
}
.stepper__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: none;
  background: transparent;
  color: var(--text-primary);
  cursor: pointer;
  transition: background var(--duration-fast);
}
.stepper__btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent-primary) 14%, transparent);
  color: var(--accent-primary);
}
.stepper__btn:disabled {
  color: var(--text-muted);
  cursor: not-allowed;
  opacity: 0.4;
}
.stepper__btn svg {
  width: 16px;
  height: 16px;
}
.stepper__value {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 36px;
  font-family: var(--font-headline);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  font-feature-settings: "tnum" 1, "lnum" 1;
  border-left: var(--glass-border-width) solid var(--border-glass);
  border-right: var(--glass-border-width) solid var(--border-glass);
}
.stepper__unit {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.setting__consequence {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  padding: 0;
  margin: var(--space-2) 0 0 0;
  background: transparent;
  border: none;
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: 1.45;
}
.setting__consequence-icon {
  width: 14px;
  height: 14px;
  color: var(--info);
  flex-shrink: 0;
  margin-top: 1px;
}

/* segmented control polish */
.segmented-control {
  display: flex;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-1);
  gap: 2px;
}
.segmented-control__option {
  flex: 1;
  text-align: center;
  cursor: pointer;
  position: relative;
}
.segmented-control__option input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  border: 0;
}
.segmented-control__option span {
  display: block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-weight: var(--weight-medium);
  transition: background var(--duration-fast), color var(--duration-fast);
}
.segmented-control__option:hover span {
  color: var(--text-primary);
}
.segmented-control__option input:checked + span {
  background: var(--accent-primary);
  color: var(--text-on-accent);
  font-weight: var(--weight-bold);
}

/* === Plan horizon slider === */
.horizon-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  outline: none;
  cursor: pointer;
}
.horizon-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-pill);
  background: var(--accent-primary);
  border: 2px solid var(--text-on-accent);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform var(--duration-fast);
}
.horizon-slider::-webkit-slider-thumb:hover {
  transform: scale(1.15);
}
.horizon-slider::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: var(--radius-pill);
  background: var(--accent-primary);
  border: 2px solid var(--text-on-accent);
  cursor: pointer;
}
.horizon-slider__scale {
  display: flex;
  justify-content: space-between;
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--weight-medium);
}

/* === Insight section === */
.insight__rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.insight {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
}
.insight__tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--weight-bold);
}
.insight__tag svg {
  width: 14px;
  height: 14px;
}
.insight__text {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.5;
}
.insight__text strong {
  color: var(--text-primary);
}
.insight__foot {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
  margin: var(--space-2) 0 0 0;
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--accent-highlight) 10%, transparent);
}
.insight__foot-icon {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--accent-primary);
  margin-top: 2px;
}
.insight__foot-icon svg {
  width: 14px;
  height: 14px;
}

/* === Export card === */
.export-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
}
.export-card__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.export-card__title {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.export-card__line {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.export-card__line-icon {
  width: 14px;
  height: 14px;
  color: var(--success);
}

/* ============================================================
   SCHEDULE SURFACE polish
   ============================================================ */

.schedule-view__header {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}
.schedule-view__meta {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.schedule-view__eyebrow {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
}
.schedule-view__title {
  font-family: var(--font-headline);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
  line-height: 1.1;
}
.schedule-view__controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.view-toggle {
  display: inline-flex;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: 3px;
  gap: 2px;
}
.view-toggle__btn {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
  text-decoration: none;
  transition: background var(--duration-fast), color var(--duration-fast);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.view-toggle__btn:hover {
  color: var(--text-primary);
}
.view-toggle__btn--active {
  background: var(--accent-primary);
  color: var(--text-on-accent);
}

/* --- Records: attendance table -----------------------------------------
   A roster read at a filing deadline, so it optimizes for scanning one column
   (days, or hours) down seven children rather than reading one row across. */
.records-table { display: flex; flex-direction: column; gap: var(--space-1); }
.records-table__row {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 2fr 1fr;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass);
  border-radius: var(--radius-sm);
}
.records-table__row--head {
  background: none;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.records-table__name { font-weight: var(--weight-medium); color: var(--text-primary); }
/* Tabular figures so the columns line up digit-for-digit down the roster. */
.records-table__num {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.records-table__span { font-size: var(--text-xs); color: var(--text-secondary); }
.records-table__link { font-size: var(--text-xs); }
/* This stylesheet has no global `a` rule — every link is styled by its own
   class — so an unclassed anchor renders in the BROWSER's default #0000EE,
   which on a dark navy row is very nearly unreadable. That is what both of
   these were doing: the roster's log link, and the state-source links the rule
   pack has been shipping since #261 (the compliance surface's one "verify this
   yourself" affordance, in invisible ink). One rule, both fixed. */
.records-table__link a,
.records-rules a,
.parent-portfolio .parent-schedule__eyebrow a,
.parent-standards .parent-schedule__eyebrow a {
  color: var(--accent-primary);
  text-decoration: none;
}
.records-table__link a:hover,
.records-rules a:hover,
.parent-portfolio .parent-schedule__eyebrow a:hover,
.parent-standards .parent-schedule__eyebrow a:hover { text-decoration: underline; }
.records-caveats { border-left: 2px solid var(--info); }

/* --- Portfolio log (docs/systems/portfolio-record.md) --------------------
   The log half of a portfolio, per student. Reuses the Records print theme
   wholesale (the template carries `.parent-records`), so nothing here restates
   a print rule — only the log's own two blocks need shape. */
/* The half-a-portfolio notice. Amber, because nothing is WRONG — the parent
   simply has a second half to keep. --error appears nowhere (locked rule). */
.portfolio-scope { border-left: 2px solid var(--warning); }
.portfolio-scope__body,
.portfolio-scope__state {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
}
.portfolio-scope__state { margin-top: var(--space-2); color: var(--text-muted); }

.portfolio-subjects {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.portfolio-subject {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}
.portfolio-subject__name { color: var(--text-primary); font-weight: var(--weight-medium); }
.portfolio-subject__count {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
}
.portfolio-subject__hours { font-size: var(--text-xs); color: var(--text-muted); }

.portfolio-table { display: flex; flex-direction: column; gap: var(--space-1); }
.portfolio-table__row {
  /* Date narrow and fixed, activity greedy — the activity title is the column
     a superintendent actually reads, so it gets the room. */
  display: grid;
  grid-template-columns: 7rem 9rem 1fr;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}
.portfolio-table__row--head {
  background: none;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.portfolio-table__date {
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.portfolio-table__subject { color: var(--text-secondary); }
.portfolio-table__title { color: var(--text-primary); }
.portfolio-table__note { font-size: var(--text-xs); color: var(--text-muted); }

.portfolio-range__form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
}
.portfolio-range__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.records-caveats__list {
  margin: 0; padding-left: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-2);
  font-size: var(--text-sm); color: var(--text-secondary);
}
.records-caveats__list strong { color: var(--text-primary); }

/* --- Standards coverage (docs/systems/standards-coverage.md) -------------
   One student against one state framework at their grade. Carries
   `.parent-records`, so the whole print theme is inherited; only the status
   vocabulary and the standard list need shape here. */

/* "This is a curriculum match, not a compliance check." Amber, because nothing
   is WRONG — the parent simply must not read a percentage as a verdict. Same
   register as the portfolio log's half-a-portfolio notice. --error appears
   nowhere (locked rule). */
.standards-scope { border-left: 2px solid var(--warning); }
.standards-scope__body {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
}

/* THE FOUR STATUSES ARE CATEGORICAL, NOT A SCALE. They are deliberately not a
   green→amber ramp: "not in this curriculum" is not a worse "covered", it is a
   statement about the MATERIAL, so it gets amber (the repo's "look at this"
   colour) while "not started here" — genuinely just an absence of evidence —
   stays muted and quiet. Colour is never the only carrier: every chip is
   labelled in words. */
.standards-chip {
  display: inline-block;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  border: 1px solid var(--border-glass);
  color: var(--text-secondary);
}
.standards-chip--covered     { color: var(--success); border-color: var(--success); }
.standards-chip--in_progress { color: var(--info);    border-color: var(--info); }
.standards-chip--not_started { color: var(--text-muted); }
.standards-chip--not_taught  { color: var(--warning); border-color: var(--warning); }

.standards-legend {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.standards-legend__row {
  display: grid;
  grid-template-columns: 14rem 1fr;
  gap: var(--space-3);
  align-items: baseline;
}
.standards-legend__term {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0;
}
.standards-legend__count {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.standards-legend__desc {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
}

.standards-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.standards-item {
  padding: var(--space-3);
  background: var(--surface-glass);
  border-radius: var(--radius-sm);
  /* The left rule repeats the chip's colour so the list is scannable at
     arm's length without reading every chip. Redundant encoding, not the
     only encoding. */
  border-left: 2px solid var(--border-glass);
}
.standards-item--covered     { border-left-color: var(--success); }
.standards-item--in_progress { border-left-color: var(--info); }
.standards-item--not_taught  { border-left-color: var(--warning); }
.standards-item__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}
.standards-item__code {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  font-size: var(--text-sm);
}
.standards-item__desc {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
}
.standards-item__gap {
  margin: var(--space-2) 0 0;
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.standards-skills {
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.standards-skills__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.standards-skills__name { color: var(--text-secondary); }
.standards-skills__score {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media (max-width: 720px) {
  .standards-legend__row { grid-template-columns: 1fr; gap: var(--space-1); }
}

/* --- Horizon close guard + result -------------------------------------
   The destructive branch of the horizon decision. Amber, never red: being at
   a horizon end is a normal event, and --error is barred from family-facing
   flows. The weight comes from the itemised blast radius and the typed
   confirmation, not from colour. */
.horizon-close { border-left: 2px solid var(--warning); }
.horizon-close__blast { font-size: var(--text-sm); color: var(--text-primary); margin: 0; }
.horizon-close__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-2);
}
.horizon-close__list li {
  display: inline-flex; align-items: baseline; gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  background: color-mix(in srgb, var(--warning) 8%, transparent);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
}
.horizon-close__subject { color: var(--text-primary); }
.horizon-close__n { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.horizon-close__kept { font-size: var(--text-sm); color: var(--text-secondary); margin: 0; }
.horizon-close__error {
  font-size: var(--text-sm); color: var(--warning-strong); margin: 0;
  font-weight: var(--weight-medium);
}
.horizon-close__form {
  display: flex; flex-direction: column; gap: var(--space-2);
  align-items: flex-start;
}
.horizon-close__label { font-size: var(--text-sm); color: var(--text-secondary); }
.horizon-close__input {
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
  font-family: inherit; font-size: var(--text-sm); color: var(--text-primary);
  min-width: 220px;
}
.horizon-close__input:focus-visible {
  outline: 2px solid var(--accent-primary); outline-offset: 1px;
}

.horizon-result { border-left: 2px solid var(--success); }
.horizon-result__title {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--text-base); font-weight: var(--weight-bold);
  color: var(--success); margin: 0;
}
.horizon-result__body { font-size: var(--text-sm); color: var(--text-secondary); margin: 0; }

/* The radio labels carry a second line explaining the action. */
.horizon-alert__radio small {
  display: block; font-size: var(--text-xs); color: var(--text-muted);
  margin-top: 2px;
}

/* --- Day timeline: who is needed ---------------------------------------
   TWO marks, never merged. `planned` is --info: the lesson was always going
   to need an adult, it is a calendar fact, and it should read as neutral
   information. `asked` is --warning: a child is stuck and waiting, which is
   an interrupt. One shared colour would leave a parent unable to tell "I am
   teaching this at 10" from "Maya is waiting for me right now". Never
   --error; a child asking for help is healthy. */
.day-timeline__entry-mark {
  margin-left: auto;
  flex-shrink: 0;
  width: 14px;
  height: 14px;
}
.day-timeline__entry-mark--planned { color: var(--info); }
.day-timeline__entry-mark--asked   { color: var(--warning-strong); }
/* A block that needs an adult carries a quiet left edge as well as the icon,
   so it is findable when scanning a column rather than only on inspection. */
.day-timeline__entry[data-needs="you"] {
  border-left: 2px solid var(--info);
  padding-left: var(--space-2);
}

.day-timeline__popover-need {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  line-height: 1.4;
  margin-top: 2px;
}
.day-timeline__popover-need svg { width: 13px; height: 13px; flex-shrink: 0; }
.day-timeline__popover-need[data-kind="planned"] { color: var(--info); }
.day-timeline__popover-need[data-kind="asked"]   { color: var(--warning-strong); }

/* --- Signal inbox: requests from the children ---------------------------
   Amber, never red. A child asking for help is a normal, healthy event — the
   urgency is that it went UNANSWERED, not that anything is wrong. */
.signal-inbox {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-left: 2px solid var(--warning);
  border-radius: var(--radius-lg);
}
.signal-inbox__head { display: flex; flex-direction: column; gap: 2px; }
.signal-inbox__eyebrow {
  font-size: var(--text-xs); color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.04em;
  font-weight: var(--weight-medium);
}
.signal-inbox__title {
  font-size: var(--text-lg); font-weight: var(--weight-bold);
  color: var(--text-primary); margin: 0;
}
.signal-inbox__list { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--space-2); }
.signal-inbox__item {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--space-3);
  padding: var(--space-3);
  background: var(--surface-glass-strong);
  border-radius: var(--radius-md);
}
.signal-inbox__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.signal-inbox__who { font-weight: var(--weight-bold); color: var(--text-primary); }
.signal-inbox__what { font-size: var(--text-sm); color: var(--text-secondary); }
.signal-inbox__when { font-size: var(--text-xs); color: var(--text-muted); }
.signal-inbox__actions { display: flex; align-items: center; gap: var(--space-2); }
.signal-inbox__cta {
  display: inline-flex; align-items: center;
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--accent-primary); color: var(--text-on-accent);
  font-size: var(--text-xs); font-weight: var(--weight-bold);
  text-decoration: none; border: none; cursor: pointer;
  font-family: inherit;
}
/* The two HELP-row verbs. They replace a single button labelled "Sorted" that
   wrote outcome='dismissed'. (`.signal-inbox__dismiss` itself survives — the
   subject-request row still uses it for "Not now", which is a genuine decline.)

   Both are quiet outline pills, deliberately: the loud action on this row is
   "Help <child>", which opens the coaching overlay. Defer and Complete are the
   shortcuts for a parent who has already dealt with it, not the primary path,
   and styling them to compete would invite closing requests without reading
   them. */
.signal-inbox__defer,
.signal-inbox__complete,
.signal-inbox__dismiss {          /* still used by the subject-request "Not now" */
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: none; border: 1px solid var(--border-glass);
  color: var(--text-secondary); font-size: var(--text-xs);
  cursor: pointer; font-family: inherit;
}
.signal-inbox__defer:hover,
.signal-inbox__complete:hover,
.signal-inbox__dismiss:hover { color: var(--text-primary); background: var(--surface-glass); }
/* Complete is the one that ENDS the thread, so it earns the success tint on
   hover — enough to tell the two apart under a fast cursor, not enough to make
   it louder than the coaching CTA at rest. */
.signal-inbox__complete:hover { border-color: var(--success); color: var(--success); }
/* Amber, never red: a request coming back is a loose end, not a failure. */
.signal-inbox__returned { color: var(--warning); }
/* A child who paged before trying the hints is a different conversation from
   one who worked the scaffolds first — worth seeing at a glance. */
.signal-inbox__item[data-kind="subject"] { border-left: 2px solid var(--info); }

/* --- Student lens ------------------------------------------------------
   The in-surface "which child am I looking at" control, replacing the chrome
   `<select>` (`.pbar__student-picker`, deleted). Borrows the segmented-control
   vocabulary above deliberately: it is the same KIND of thing as the Week/Year
   zoom — a control that re-scopes the surface it sits on — and reading as its
   sibling is the point. It carries no tokens of its own.

   `flex-wrap` rather than a scroller: the column axis here is family size,
   which is unbounded. Seven first-name pills run ~665px inside a ~1250px
   content width, so the Rivera demo family fits one line and a larger family
   wraps instead of scrolling something that looks unscrollable. */
.student-lens {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.student-lens__label {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  font-weight: var(--weight-medium);
  letter-spacing: 0.04em;
}
.student-lens__opts {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: 3px;
}
.student-lens__opt {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
  text-decoration: none;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.student-lens__opt:hover { color: var(--text-primary); }
.student-lens__opt--active {
  background: var(--accent-primary);
  color: var(--text-on-accent);
}
.student-lens__opt:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: 1px;
}

/* --- Progress: the term-read's actionable half -------------------------
   Mirrors `.psched-review`'s separator treatment, because it is the same
   content — the blocks absorbed from Schedule. A rule above it marks the
   surface's turn from evidence to decision. */
.progress-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: var(--glass-border-width) solid var(--border-glass);
}
.progress-actions__head { display: flex; flex-direction: column; gap: var(--space-1); }
.progress-actions__eyebrow {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  font-weight: var(--weight-medium);
  letter-spacing: 0.04em;
}
/* Recovery proposal. Amber, never red — being behind is information, not a
   failure state, and the copy guard forbids --error in family-facing flows. */
.recovery { border-left: 2px solid var(--warning); }
.recovery__options {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.recovery__option {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3);
  background: var(--surface-glass);
  border-radius: var(--radius-md);
}
/* The first option is the recommended one — ranking is the product here, so it
   has to be visible without reading all three. */
.recovery__option:first-child {
  background: color-mix(in srgb, var(--warning) 8%, transparent);
}
.recovery__option-label {
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.recovery__option-detail {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.recovery__option-cta {
  align-self: flex-start;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--info);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.recovery__option-cta:hover { text-decoration: underline; }

.progress-actions__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}

.week-tabs {
  display: inline-flex;
  gap: var(--space-3);
  align-items: center;
}
/* Steppers: how a student moves past "next week" one week at a time. Inert at
   the ends of the materialized range — shown, dimmed, not a dead link. */
.week-tabs__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  text-decoration: none;
  transition: color var(--duration-fast), background var(--duration-fast);
}
.week-tabs__step-icon { font-size: var(--icon-size-md); }
.week-tabs__step:hover {
  color: var(--accent-primary);
  background: var(--surface-glass-strong);
}
.week-tabs__step--off { opacity: 0.3; pointer-events: none; }
.week-tabs__tab {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  border-bottom: 2px solid transparent;
  transition: color var(--duration-fast), border-color var(--duration-fast);
}
.week-tabs__tab:hover {
  color: var(--text-secondary);
}
.week-tabs__tab--active {
  color: var(--accent-primary);
  border-bottom-color: var(--accent-primary);
}
.schedule-view__status-strip {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* status-stat (streak/freeze/shield) styling reuses what's already in styles.css §schedule status strip */

.schedule-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: var(--space-5);
}
@media (max-width: 1024px) {
  .schedule-layout {
    grid-template-columns: 1fr;
  }
}

/* === Today workspace === */
.today-workspace {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.today-capacity {
  padding: var(--space-5);
  background: var(--surface-glass);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md), var(--glass-inner-shadow);
}
.today-capacity__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--space-3);
}
.today-capacity__label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
}
.today-capacity__readout {
  font-family: var(--font-headline);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.today-capacity__readout-unit {
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-weight: var(--weight-medium);
}
.today-capacity__readout[data-load-state="warning"] {
  color: var(--warning);
}
.today-capacity__readout[data-load-state="overloaded"] {
  color: var(--warning-strong);
}

/* === Capacity bar (used on today + week) === */
.capacity-bar {
  width: 100%;
  height: 6px;
  background: var(--surface-glass-strong);
  border-radius: var(--radius-pill);
  overflow: hidden;
  border: var(--glass-border-width) solid var(--border-glass);
}
.capacity-bar--lg {
  height: 10px;
}
.capacity-bar__fill {
  height: 100%;
  width: var(--load-pct, 0%);
  background: linear-gradient(
    90deg,
    var(--accent-secondary) 0%,
    var(--accent-primary) 100%
  );
  border-radius: var(--radius-pill);
  transition: width var(--duration-slow, 400ms) var(--ease-out, ease-out);
}
.capacity-bar__fill[data-load-state="normal"] {
  background: linear-gradient(90deg, var(--accent-secondary), var(--accent-primary));
}
.capacity-bar__fill[data-load-state="warning"] {
  background: linear-gradient(90deg, var(--accent-primary), var(--warning));
}
.capacity-bar__fill[data-load-state="overloaded"] {
  background: linear-gradient(90deg, var(--warning), var(--warning-strong));
}

/* === Today focus section === */
.today-focus-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.today-focus-section__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
}
.today-focus-section__pin-icon {
  width: 14px;
  height: 14px;
}

/* === Today tasks section === */
.today-tasks-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.today-tasks-section__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding-bottom: var(--space-2);
  border-bottom: var(--glass-border-width) solid var(--border-glass);
}
.today-tasks-section__title {
  font-family: var(--font-headline);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.today-tasks-section__count {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--weight-bold);
}
.today-tasks-section__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* === Schedule card === */
.schedule-card {
  position: relative;
  padding: var(--space-4);
  background: var(--surface-glass);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm), var(--glass-inner-shadow);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  transition: transform var(--duration-fast), box-shadow var(--duration-fast);
}
.schedule-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md), var(--glass-inner-shadow);
}
.schedule-card--compact {
  padding: var(--space-3);
  gap: var(--space-2);
}
.schedule-card--pinned {
  border-left: 3px solid var(--accent-primary);
  background: color-mix(in srgb, var(--accent-primary) 6%, var(--surface-glass));
}
.schedule-card__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.schedule-card__badge {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--accent-primary) 14%, transparent);
  color: var(--accent-primary);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border: var(--glass-border-width) solid color-mix(in srgb, var(--accent-primary) 30%, transparent);
}
.schedule-card__icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background var(--duration-fast), color var(--duration-fast);
}
.schedule-card__icon-btn:hover {
  background: color-mix(in srgb, var(--text-primary) 8%, transparent);
  color: var(--text-primary);
}
.schedule-card__icon-btn svg {
  width: 14px;
  height: 14px;
}
.schedule-card__meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.schedule-card__title {
  font-family: var(--font-headline);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
  line-height: 1.3;
}
.schedule-card--compact .schedule-card__title {
  font-size: var(--text-sm);
}
.schedule-card__time {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--weight-bold);
}
.schedule-card__time-icon {
  font-size: var(--icon-size-sm);
}
.schedule-card__subtasks {
  display: flex;
  gap: var(--space-2);
}
.subtask-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  flex: 1;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  color: var(--text-primary);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.subtask-btn:hover {
  background: var(--surface-glass);
  color: var(--accent-primary);
}
.subtask-btn--sm {
  padding: var(--space-1) var(--space-2);
}
.subtask-btn__icon {
  width: 12px;
  height: 12px;
}
.subtask-btn[data-state="completed"] {
  background: color-mix(in srgb, var(--success) 18%, transparent);
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 40%, transparent);
}
.subtask-btn[data-state="locked"] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}
.schedule-card__reschedule {
  margin-top: var(--space-1);
}
.syllabus-select--sm {
  padding: 4px calc(var(--space-4) + var(--space-3)) 4px var(--space-2);
  font-size: var(--text-xs);
}

/* === Schedule empty state === */
.schedule-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-8) var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  gap: var(--space-2);
}
.schedule-empty__icon {
  width: 40px;
  height: 40px;
  color: var(--accent-primary);
  margin-bottom: var(--space-2);
}
.schedule-empty__title {
  font-family: var(--font-headline);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.schedule-empty__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}

/* === Week grid — fits all 6 day columns (Mon-Fri + Weekend) === */
.week-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--space-2);
  align-items: start;
}
@media (max-width: 960px) {
  .week-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (max-width: 540px) {
  .week-grid {
    grid-template-columns: 1fr;
  }
}
/* Compact day columns when packed into 6 columns */
.week-grid .day-column {
  padding: var(--space-3);
}
.week-grid .day-column__date {
  font-size: var(--text-xl);
}
.day-column {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface-glass);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm), var(--glass-inner-shadow);
}
.day-column--off {
  opacity: 0.7;
}
.day-column__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: var(--glass-border-width) solid var(--border-glass);
}
.day-column__title-block {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.day-column__day-name {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
}
.day-column__date {
  font-family: var(--font-headline);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  line-height: 1;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.day-column__capacity {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.day-column__capacity-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.day-column__load-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
}
.day-column__load-pct {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.day-column__load-pct[data-load-state="warning"]    { color: var(--warning); }
.day-column__load-pct[data-load-state="overloaded"] { color: var(--warning-strong); }
.day-column__off-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--weight-bold);
}
.day-column__off-icon {
  font-size: var(--icon-size-sm);
}
.day-column__cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 80px;
}
.day-column__off-state {
  padding: var(--space-4);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-style: italic;
}
.day-column__empty {
  text-align: center;
  font-size: var(--text-xs);
  color: var(--text-muted);
  padding: var(--space-4) 0;
  font-style: italic;
  margin: 0;
}

/* === Sidebar sections === */
.schedule-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.sidebar-section {
  padding: var(--space-5);
}
.sidebar-section__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-2);
}
.sidebar-section__title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-headline);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.sidebar-section__icon {
  width: 16px;
  height: 16px;
  color: var(--accent-primary);
}
.sidebar-section__help {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0 0 var(--space-3) 0;
  line-height: 1.5;
}
.pool-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  color: var(--text-primary);
}
.pool-badge[data-pool-state="caution"] {
  background: color-mix(in srgb, var(--warning) 18%, transparent);
  color: var(--warning);
  border-color: color-mix(in srgb, var(--warning) 40%, transparent);
}
.pool-badge[data-pool-state="urgent"] {
  background: color-mix(in srgb, var(--warning-strong) 22%, transparent);
  color: var(--warning-strong);
  border-color: color-mix(in srgb, var(--warning-strong) 40%, transparent);
}
.pool-list,
.remediation-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.pool-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  transition: background var(--duration-fast);
}
.pool-item:hover {
  background: var(--surface-glass);
}
.pool-item__launch {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 1;
  text-decoration: none;
  color: inherit;
}
.pool-item__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}
.pool-item__title {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pool-item__meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.pool-item__pin-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background var(--duration-fast), color var(--duration-fast);
  flex-shrink: 0;
}
.pool-item__pin-btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent-primary) 14%, transparent);
  color: var(--accent-primary);
}
.pool-item__pin-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}
.pool-item__pin-btn--active {
  color: var(--accent-primary);
  background: color-mix(in srgb, var(--accent-primary) 14%, transparent);
}
.pool-item__pin-btn svg {
  width: 14px;
  height: 14px;
}
.pool-list__empty,
.remediation-list__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-align: center;
  font-style: italic;
}
.pool-list__empty-icon {
  width: 14px;
  height: 14px;
  color: var(--success);
}
.remediation-card {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: inherit;
  transition: background var(--duration-fast), transform var(--duration-fast);
}
.remediation-card:hover {
  background: var(--surface-glass);
  transform: translateX(2px);
}
.remediation-card__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.remediation-card__title {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.remediation-card__meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.remediation-card__arrow {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
  flex-shrink: 0;
  transition: color var(--duration-fast);
}
.remediation-card:hover .remediation-card__arrow {
  color: var(--accent-primary);
}

/* Responsive — schedule header on narrow */
@media (max-width: 760px) {
  .schedule-view__header {
    grid-template-columns: 1fr;
  }
  .schedule-view__controls {
    width: 100%;
    justify-content: space-between;
  }
}

/* ============================================================
   PHASE 2 — Attempts surface (per-skill history)
   ============================================================ */

.attempts-view {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.attempts-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.attempts-header__back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  text-decoration: none;
  width: max-content;
  padding: var(--space-1) 0;
  margin-bottom: var(--space-2);
  transition: color var(--duration-fast);
}
.attempts-header__back:hover {
  color: var(--accent-primary);
}
.attempts-header__back-icon {
  width: 16px;
  height: 16px;
}
.attempts-header__eyebrow {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
}
.attempts-header__title {
  font-family: var(--font-headline);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
  line-height: 1.1;
}
.attempts-header__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: var(--space-1) 0 0 0;
}
/* Request state, above the history. Two states, and neither is red: an open
   request is a loose end (--warning) and an answered one is done (--success).
   A child asking for help is never an error condition. */
.attempts-signal {
  display: flex; align-items: center; gap: var(--space-2);
  margin: 0 0 var(--space-4);
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--info);
  border-radius: var(--radius-sm);
  background: var(--surface-glass);
  font-size: var(--text-sm); color: var(--text-secondary);
}
.attempts-signal[data-state="open"]     { border-left-color: var(--warning); }
.attempts-signal[data-state="answered"] { border-left-color: var(--success); }
.attempts-signal svg { width: var(--icon-size-sm); height: var(--icon-size-sm); flex-shrink: 0; }
.attempts-signal[data-state="answered"] svg { color: var(--success); }
.attempts-signal[data-state="open"] svg     { color: var(--warning); }

.attempts-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.attempt-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.attempt-card__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: var(--glass-border-width) solid var(--border-glass);
}
.attempt-card__meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.attempt-card__eyebrow {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
}
.attempt-card__title {
  font-family: var(--font-headline);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.attempt-score-badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-pill);
  font-family: var(--font-headline);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  font-feature-settings: "tnum" 1, "lnum" 1;
  border: var(--glass-border-width) solid var(--border-glass);
  background: var(--surface-glass-strong);
}
.attempt-score-badge[data-state="gold"] {
  background: color-mix(in srgb, var(--gold) 18%, transparent);
  color: var(--gold);
  border-color: color-mix(in srgb, var(--gold) 40%, transparent);
}
.attempt-score-badge[data-state="success"] {
  background: color-mix(in srgb, var(--success) 18%, transparent);
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 40%, transparent);
}
.attempt-score-badge[data-state="warning"] {
  background: color-mix(in srgb, var(--warning) 18%, transparent);
  color: var(--warning);
  border-color: color-mix(in srgb, var(--warning) 40%, transparent);
}

.attempt-questions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.attempt-question {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
}
.attempt-question[data-correct="false"] {
  border-left: 3px solid var(--warning);
}
.attempt-question[data-correct="true"] {
  border-left: 3px solid var(--success);
}
.attempt-question__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.attempt-question__index {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
}
.attempt-question__verdict {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
}
.attempt-question__verdict[data-state="correct"] {
  background: color-mix(in srgb, var(--success) 16%, transparent);
  color: var(--success);
}
.attempt-question__verdict[data-state="incorrect"] {
  background: color-mix(in srgb, var(--warning) 16%, transparent);
  color: var(--warning);
}
.attempt-question__verdict-icon {
  width: 12px;
  height: 12px;
}
.attempt-question__prompt {
  font-family: var(--font-headline);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  margin: 0;
  line-height: 1.4;
}
.attempt-question__diagnosis {
  margin-top: var(--space-2);
  padding: var(--space-3);
  background: var(--surface-glass);
  border-radius: var(--radius-sm);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.attempt-question__diag-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}
.attempt-question__diag-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  flex-shrink: 0;
  min-width: 100px;
}
.attempt-question__diag-value {
  font-size: var(--text-sm);
  color: var(--text-primary);
  font-weight: var(--weight-medium);
}
code.attempt-question__diag-value {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: 2px var(--space-2);
}
/* Misconception now reads as prose (the YAML `description`); the raw
   snake_case key is demoted to a small muted chip beneath it — kept for
   parents/authors who want the exact key, but no longer the headline. */
.attempt-question__diag-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  align-items: flex-start;
}
.attempt-question__diag-key {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: var(--text-xs);
  color: var(--text-muted);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: 1px var(--space-2);
}
.attempt-question__coaching {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: var(--space-1) 0 0 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--info) 8%, transparent);
  border: var(--glass-border-width) solid color-mix(in srgb, var(--info) 20%, transparent);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-style: italic;
  line-height: 1.5;
}
.attempt-question__coaching-icon {
  width: 14px;
  height: 14px;
  color: var(--info);
  flex-shrink: 0;
  margin-top: 2px;
}

.attempts-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-2);
  padding: var(--space-8);
}
.attempts-empty__icon {
  width: 40px;
  height: 40px;
  color: var(--text-muted);
  margin-bottom: var(--space-2);
}
.attempts-empty__title {
  font-family: var(--font-headline);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.attempts-empty__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
  max-width: 50ch;
}

/* ==========================================================================
   Family Setup (per docs/ui-specs/family-setup.md §6)
   Reuses: .pbar / .card / .stepper / .segmented-control from earlier
   blocks. Defines the .btn / .field / .chip foundation the four parent-
   cadence specs all reference. No new design tokens.
   ========================================================================== */

/* --- Shared form vocabulary (.btn / .field / .chip) ------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-5);
  font-family: inherit;
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  cursor: pointer;
  text-decoration: none;
  transition: filter 0.15s ease, transform 0.1s ease;
}
.btn:hover { filter: brightness(1.05); }
.btn:active { transform: translateY(1px); }

.btn--primary {
  background: var(--accent-primary);
  color: var(--text-on-accent);
  border-color: var(--accent-primary);
}
.btn--secondary {
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
  border-color: var(--accent-secondary);
}
.btn--text {
  background: transparent;
  color: var(--accent-primary);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.btn--text:hover {
  background: var(--surface-glass);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.field--inline {
  border: none;
  padding: 0;
  margin: 0;
}
.field__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.field__input {
  border: 1px solid var(--border-glass);
  background: var(--surface-glass-strong);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font: inherit;
  color: var(--text-primary);
}
.field__input:focus {
  outline: 2px solid var(--border-focus);
  outline-offset: 1px;
}
.field__hint {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0;
}

.chip-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.chip:hover { background: var(--surface-glass-chrome); }
.chip > input[type="radio"],
.chip > input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.chip:has(input:checked) {
  background: var(--accent-primary);
  color: var(--text-on-accent);
  border-color: var(--accent-primary);
}

/* --- Page shell -------------------------------------------------------- */

.family-setup {
  max-width: 1280px;
  margin: 0 auto;
  /* Tight top padding (S10): with the setup ribbon gone the family card is the
     first child, and the shell topper already provides the breathing room —
     a large top pad here left a dead band below the topper. */
  padding: var(--space-3) var(--space-5) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.family-setup--instant {
  max-width: 720px;
  padding-block: var(--space-7);
}

/* --- Setup ribbon ------------------------------------------------------ */

.setup-ribbon {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-6);
  border-radius: var(--radius-lg);
}
.setup-ribbon__headline {
  font-family: var(--font-headline, inherit);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0 0 var(--space-2);
}
.setup-ribbon__sub {
  font-size: var(--text-base);
  color: var(--text-secondary);
  margin: 0;
  max-width: 60ch;
  line-height: 1.5;
}

/* --- Instant Start form ----------------------------------------------- */

.instant-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  border-radius: var(--radius-lg);
}
.instant-form__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-5);
}
.instant-form__added {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.instant-form__added strong { color: var(--text-primary); }
.instant-form__added a { color: var(--accent-primary); }
.instant-form__added i {
  width: 18px;
  height: 18px;
  color: var(--success);
  flex-shrink: 0;
}

/* --- Family card (Full mode) ------------------------------------------ */

.family-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}
.family-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
}
.family-card__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.family-card__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.family-card__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}
.family-card__form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
}

/* --- Student cards grid ----------------------------------------------- */

.student-cards {
  display: grid;
  /* Multi-column by default — this is the FCC roster shape. Each card is ~573px
     tall, so a single column costs a full viewport per child: a 7-child family
     scrolled ~4,100px of roster to see everyone, with seven identical full-width
     "Open Schedule" buttons and no way to scan the family at a glance. Three
     columns at desktop width brings that to ~1,750px.

     `auto-fit` (not auto-fill) so a one- or two-child family still fills the
     row instead of leaving collapsed tracks. `min(340px, 100%)` keeps the track
     from exceeding a narrow viewport — a bare `minmax(340px, 1fr)` overflows
     horizontally below 340px. The Setup grid needs the opposite shape and
     overrides this below. */
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: var(--space-4);
}
/* Setup only — single column, full-width cards (S12). The multi-column shape
   above splits the width between the card and the add-student tile (a sibling
   grid item), so even on a wide window the card is capped at ~600px and its
   subject rows' grade·pacing·rhythm wrap. One column lets each card use the
   full width — rows fit on one line — and `student-add` stacks below as a
   full-width bar instead of stealing a column. The FCC roster has no such
   sibling and no subject rows, which is why it does not want this. */
.family-setup .student-cards {
  grid-template-columns: 1fr;
}
.student-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}
/* Setup cards only — the FCC roster shares `.student-card`/`.student-cards`, so
   the accordion changes MUST be scoped to `.family-setup` or they cramp the FCC
   card (its sections rely on the base card-level gap). On setup the card collapses
   to toggle + body (no card-level gap), runs tighter padding, and is a container
   for the subject-row width queries. */
.family-setup .student-card {
  gap: 0;
  padding: var(--space-4);
  container-type: inline-size;
  container-name: student-card;
}
/* --- Accordion (S16): the name row IS the collapsed header ------------- */
/* The toggle is now just the chevron button, inline in the name row next to the
   editable name; the whole row stays visible when collapsed. */
.student-card__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-1);
  margin-left: calc(-1 * var(--space-1));
  background: none;
  border: none;
  cursor: pointer;
  color: inherit;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}
.student-card__toggle:hover { background: var(--surface-glass-strong); }
.student-card__chev {
  display: inline-flex;
  color: var(--text-muted);
  transition: transform 280ms ease;
}
.student-card__chev svg { width: 18px; height: 18px; }
.student-card[data-open="true"] .student-card__chev { transform: rotate(90deg); }
.student-card__toggle-chip {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
/* Animate open/closed via grid-template-rows 0fr<->1fr (smooth, height-agnostic). */
.student-card__body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 300ms ease;
}
.student-card[data-open="true"] .student-card__body { grid-template-rows: 1fr; }
.student-card__body-inner {
  overflow: hidden;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
/* Separate the toggle from the content when open. A margin on the first child
   (not padding on body-inner) so it clips to nothing when the 0fr track collapses
   — padding would floor the collapsed height at ~12px. */
.student-card__body-inner > :first-child { margin-top: var(--space-3); }
.student-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}
.student-card__identity {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  flex: 1;
}
/* The name row is the accordion header (S16): chevron toggle + editable name +
   age, with the summary chip pushed to the right. */
.student-card__name-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.student-card__name {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  background: transparent;
  border: none;
  border-bottom: 1px solid transparent;
  padding: var(--space-1) 0;
  font-family: inherit;
}
/* Setup only (shared with the FCC name): the setup name is an inline-editable
   input that should hug its text so the age + chip sit next to it. Scoped so the
   FCC name — a display element — is untouched. Degrades to default width where
   field-sizing is unsupported. */
.family-setup .student-card__name {
  flex: 0 1 auto;
  field-sizing: content;
  min-width: 6ch;
  max-width: 100%;
}
.student-card__name:focus {
  outline: none;
  border-bottom-color: var(--border-focus);
}
.student-card__grade {
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-family: inherit;
  align-self: flex-start;
}
/* Setup-only: derived age shown above the birth-date + grade row. */
.student-card__age {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
  margin: 0;
  flex-shrink: 0;
  white-space: nowrap;
}
.student-card__grade-row {
  display: flex;
  gap: var(--space-3);
  align-items: flex-end;
  flex-wrap: wrap;
}
.student-card__birthdate,
.student-card__grade-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.student-card__birthdate-label {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-weight: var(--weight-medium);
}
.student-card__birthdate-input {
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-family: inherit;
}
.student-card__archive {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  /* Smaller, less prominent (S11): was min-height space-7 + sm text. */
  padding: var(--space-1) var(--space-2);
  background: transparent;
  border: 1px solid var(--border-glass);
  color: var(--text-muted);
  border-radius: var(--radius-pill);
  cursor: pointer;
  font-size: var(--text-xs);
  flex-shrink: 0;
}
.student-card__archive i,
.student-card__archive svg { width: 12px; height: 12px; }
.student-card__archive-label { line-height: 1; }
.student-card__archive:hover { color: var(--warning); border-color: var(--warning); }

/* Grade-content gap advisory — amber (never red): the pilot ships grade 5
   only, so an off-grade student gets no plan until that grade's curriculum
   lands. Honest signal, not an error state. */
.student-card__content-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: var(--space-3) 0 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid color-mix(in srgb, var(--warning) 55%, transparent);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.student-card__content-note i { color: var(--warning); flex-shrink: 0; }

/* --- Per-student card collapsible sections ---------------------------- */

.student-card__section {
  border-top: 1px solid var(--border-glass);
  padding-top: var(--space-2);
}
.student-card__section > summary {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
  cursor: pointer;
  padding: var(--space-1) 0;
  letter-spacing: 0.02em;
}
.student-card__section[open] > summary { color: var(--text-primary); }

/* --- Subject grid ------------------------------------------------------ */

.subject-grid {
  display: flex;
  flex-direction: column;
  /* Tight vertical rhythm (density pass) so more subjects fit in frame. */
  gap: var(--space-1);
  padding-top: var(--space-1);
}
.subject-row {
  display: flex;
  flex-wrap: wrap;
  /* Tight column gap so the 4 controls (esp. the wider 3-option emphasis) group
     on one line when they wrap under the subject name at iPad-portrait widths. */
  gap: var(--space-1) var(--space-2);
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
}
/* Keep the subject name+icon a stable width so the wider (3-option) emphasis
   control never collapses onto it. */
.subject-row > .subject-toggle { flex: 1 1 11rem; min-width: 10rem; }
/* Below ~950px of CARD width (e.g. iPad portrait, ~748px card) a single-line row
   can't hold the toggle + emphasis + 3 selects, so the last select wraps
   raggedly. Give the subject (icon + name) its own line and let ALL controls
   group cleanly on the next line. Keyed off the card, not the viewport, via the
   student-card container query — so it also fires when a card is otherwise
   narrow. iPad landscape (~1100px card) stays single-line. */
@container student-card (max-width: 950px) {
  .subject-row > .subject-toggle { flex-basis: 100%; }
}
/* Very narrow (phone, or a hard-squeezed card): the grouped controls no longer
   fit one line either — let each take the full width and stack. */
@container student-card (max-width: 480px) {
  .subject-row__emphasis,
  .subject-row__grade,
  .subject-row__policy { flex: 1 1 100%; }
}
.subject-row[data-state="off"] { opacity: 0.55; }
.subject-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--text-primary);
}
.subject-toggle__label { font-weight: var(--weight-medium); }
.subject-toggle__tag {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  border-radius: var(--radius-pill);
  padding: 1px var(--space-2);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.subject-toggle__tag[data-kind="core"] {
  background: var(--surface-glass-strong);
  color: var(--text-primary);
}
.subject-toggle__tag[data-kind="elective"] {
  background: var(--surface-glass);
  color: var(--text-secondary);
}

/* --- Track Differentiation §12: track picker + emphasis glow ------------- */
.track-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  padding: var(--space-1) var(--space-3);
  margin-bottom: var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
}
.track-picker__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}
.track-picker__help {
  flex-basis: 100%;
  margin: 0;
  font-size: var(--text-xs);
  color: var(--text-muted);
}
/* The icon IS the control (§12.1): a solid RING answers "is it in the plan?"
   (selection); the white GLOW answers "how much does it matter?" (emphasis).
   Glow is white — brightest for Focus — via `--glow-emphasis` (Bloom swaps it
   for the rose accent). Enrichment keeps the amber tint; an OFF elective is a
   dashed, dim, un-ringed icon with a `+` affordance. Never red. */
.subject-toggle__icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Density pass (S11), nudged to 18px per feedback — smaller than the S9 28px
     but comfortably legible; glyph tracks it (lucide default is 24px). */
  width: 18px;
  height: 18px;
  border-radius: var(--radius-pill);
  color: var(--glow-emphasis);
  transition: box-shadow 120ms ease, color 120ms ease, opacity 120ms ease;
}
/* Target svg too: lucide swaps the <i data-lucide> for an <svg>, so an `i`-only
   rule never binds and the glyph falls back to lucide's 24px default. */
.subject-toggle__icon i,
.subject-toggle__icon svg { width: 14px; height: 14px; }
/* Focus — permanent ring + brightest white halo (halo scaled to the icon). */
.subject-toggle__icon[data-emphasis="focus"] {
  box-shadow: 0 0 0 1.5px var(--glow-emphasis),
              0 0 11px 1px var(--glow-emphasis);
}
/* Standard — ring + a softer white halo. */
.subject-toggle__icon[data-emphasis="standard"] {
  box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--glow-emphasis) 80%, transparent),
              0 0 6px 0 color-mix(in srgb, var(--glow-emphasis) 50%, transparent);
}
/* Enrichment — in the plan (ring only, no halo), amber glyph as the lightest cue. */
.subject-toggle__icon[data-emphasis="enrichment"] {
  color: var(--warning);
  box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--glow-emphasis) 55%, transparent);
}
/* Off — NOT in the plan: no ring, dashed + dim, with a `+` add affordance.
   `outline` (not border/box-shadow) draws the dash without shifting layout. */
/* Off — NOT in the plan. The row already dims to 0.55 (below), so DON'T add a
   second opacity here or the icon compounds to ~0.30 and vanishes (feedback).
   Keep the glyph at full strength with a clear dashed ring so it stays legible. */
.subject-toggle__icon[data-emphasis="off"] {
  color: var(--text-secondary);
  box-shadow: none;
  outline: 1px dashed var(--text-muted);
  outline-offset: 2px;
}
.subject-toggle__icon[data-emphasis="off"]::after {
  content: "+";
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 11px;
  height: 11px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--text-primary);
  font-size: 9px;
  line-height: 1;
  font-weight: var(--weight-bold);
}
/* Core lock badge (§12.1) — a small corner indicator that core is permanently
   in the plan. Shrunk hard (S11) so it reads as a subtle badge on the smaller
   icon rather than overlapping the glyph. */
.subject-toggle__lock {
  position: absolute;
  right: -4px;
  bottom: -4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 1px;
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--text-secondary);
}
/* 11px glyph (nudged up again per feedback) — a legible corner badge, backed so
   it reads against the icon it overlaps. */
.subject-toggle__lock i,
.subject-toggle__lock svg { width: 11px; height: 11px; }
/* A locked (core) selector shows it can't be toggled off. */
.subject-toggle--locked { cursor: default; }
/* The icon IS the elective selector (§12.1) — hide the native checkbox but keep
   it operable + focusable; the keyboard focus ring lands on the icon instead. */
.subject-toggle input[type="checkbox"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.subject-toggle input[type="checkbox"]:focus-visible + .subject-toggle__icon {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}
/* Emphasis segmented control compacted to the same height as the row's selects
   (S12): its stock padding made it ~47px vs the selects' ~27px. Shrink the
   option padding + drop the control's vertical padding, then a shared min-height
   lines all three controls up on one baseline. */
.subject-row__emphasis {
  font-size: var(--text-xs);
  padding: 0 var(--space-1);
  min-height: var(--space-6);
  align-items: center;
}
.subject-row__emphasis .segmented-control__option span {
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-xs);
}
.subject-row__grade,
.subject-row__policy {
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
  min-height: var(--space-6);
  font-size: var(--text-xs);
  font-family: inherit;
  color: var(--text-secondary);
}
.intervention-row__select {
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  font-family: inherit;
  color: var(--text-secondary);
}
@media (max-width: 540px) {
  .subject-row { grid-template-columns: 1fr; gap: var(--space-2); }
}
/* Energy-allocation bar (§12 anatomy #2): a single stacked bar of weighted-load
   share by emphasis tier. Focus = brightest white, Standard = softer white,
   Enrichment = amber — mirrors the icon glow so the two read as one language. */
.energy-bar {
  margin: 0 0 var(--space-1);
}
.energy-bar__track {
  display: flex;
  height: 10px;
  border-radius: var(--radius-pill);
  overflow: hidden;
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
}
.energy-bar__seg {
  /* `--pct` is a documented dynamic custom property; a 0 tier collapses to
     nothing so the three always fill the track edge-to-edge. */
  flex-grow: var(--pct, 0);
  flex-basis: 0;
  min-width: 0;
  transition: flex-grow 160ms ease;
}
.energy-bar__seg[data-tier="focus"]      { background: var(--glow-emphasis); }
.energy-bar__seg[data-tier="standard"]   {
  background: color-mix(in srgb, var(--glow-emphasis) 55%, var(--surface-glass-strong));
}
.energy-bar__seg[data-tier="enrichment"] { background: var(--warning); }
.energy-bar__readout {
  margin: var(--space-1) 0 0;
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.energy-bar__readout strong { color: var(--text-primary); }
.load-estimate {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  /* Sits right under the energy bar now — no top gap, space before the grid. */
  margin: 0 0 var(--space-2);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-glass);
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.load-estimate__hours {
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
/* Over-selection cue: amber (`--warning`), never red — locked palette rule. */
.load-estimate[data-state="warning"] {
  background: var(--surface-glass-strong);
  border: 1px solid var(--warning);
  color: var(--warning);
}
.load-estimate[data-state="warning"] .load-estimate__hours { color: var(--warning); }

/* --- Intervention grid (three knobs + ratio slider + hint tokens) ---- */

.intervention-grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-top: var(--space-2);
}
.intervention-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.intervention-row__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.intervention-row__help {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0;
}

/* --- Diagnostic tier card -------------------------------------------- */

.diagnostic-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-top: var(--space-2);
}
.diagnostic-tier {
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.diagnostic-tier__badge {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.diagnostic-tier__current {
  font-size: var(--text-sm);
  color: var(--text-primary);
  margin: 0;
}
.diagnostic-tier__hint {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0;
  font-style: italic;
}
.diagnostic-tier__form { margin: 0; }

/* --- Methodology grid ------------------------------------------------- */

.methodology-grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-2);
  border: none;
  margin: 0;
}
.methodology-option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.methodology-option:has(input:checked) {
  background: color-mix(in srgb, var(--accent-primary) 8%, transparent);
}
.methodology-option[data-status="v2"] {
  opacity: 0.55;
  cursor: not-allowed;
}
.methodology-option__label {
  font-size: var(--text-sm);
  color: var(--text-primary);
  flex: 1;
}
.methodology-option__badge {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  background: var(--accent-secondary);
  color: var(--text-on-accent);
  border-radius: var(--radius-pill);
  padding: 1px var(--space-2);
}

/* --- Add-student affordance ------------------------------------------ */

.student-add {
  /* A full-width horizontal bar below the cards (S12): the card grid is now a
     single column, so a tall 200px tile no longer fits the layout. */
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  background: transparent;
  border: 1px dashed var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  color: var(--text-secondary);
  cursor: pointer;
  font: inherit;
  font-size: var(--text-sm);
  transition: border-color 0.15s ease, color 0.15s ease;
}
.student-add:hover {
  border-color: var(--border-focus);
  color: var(--accent-primary);
}
.student-add__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
}
.student-add__label { font-weight: var(--weight-medium); }

/* --- Archived students (WS6) ----------------------------------------- */
/* Collapsed by default: a rare, low-frequency section that must not add
   standing weight to the common zero-archived case. Scoped under
   .family-setup so .archived-* can't collide with other surfaces' chrome.
   Restore reads as the affirmative "bring them back" action (accent on
   hover), never red — consistent with the archive button's restorative tone. */
.family-setup .archived-students {
  margin-top: var(--space-5);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-glass);
}
.family-setup .archived-students__summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  list-style: none;
}
.family-setup .archived-students__summary::-webkit-details-marker { display: none; }
.family-setup .archived-students__summary i,
.family-setup .archived-students__summary svg { width: 14px; height: 14px; }
.family-setup .archived-students__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--space-5);
  height: var(--space-5);
  padding: 0 var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--text-muted);
  font-size: var(--text-xs);
}
.family-setup .archived-students__hint {
  margin: var(--space-3) 0 var(--space-2);
  color: var(--text-muted);
  font-size: var(--text-xs);
}
.family-setup .archived-students__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.family-setup .archived-student {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  background: transparent;
}
.family-setup .archived-student__identity {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.family-setup .archived-student__name {
  color: var(--text-primary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.family-setup .archived-student__meta {
  color: var(--text-muted);
  font-size: var(--text-xs);
}
.family-setup .archived-student__restore {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
  padding: var(--space-1) var(--space-3);
  background: transparent;
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  cursor: pointer;
  font: inherit;
  font-size: var(--text-xs);
}
.family-setup .archived-student__restore i,
.family-setup .archived-student__restore svg { width: 12px; height: 12px; }
.family-setup .archived-student__restore:hover {
  color: var(--accent-primary);
  border-color: var(--border-focus);
}

/* --- Commit footer --------------------------------------------------- */

.commit-footer {
  display: flex;
  justify-content: flex-end;
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-glass);
}

/* ==========================================================================
   Family Command Center (per docs/ui-specs/family-command-center.md §6)
   Reuses: .btn / .card / .field / .chip / .metric-tile / .student-cards /
   .student-card from session-8 + the parent_base.html .pbar chrome.
   Adds: headline ribbon (+ folded wins line), quiet alerts, per-card status
   variants, touchpoint timeline. Zero new tokens.
   ========================================================================== */

.family-command {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) var(--space-8);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* --- Dev-mode demo-data freshness hint ------------------------------- */

.demo-seed-hint {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface-glass);
  border: 1px dashed var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.demo-seed-hint__icon {
  display: inline-flex;
  width: 14px;
  height: 14px;
  color: var(--accent-secondary);
  flex-shrink: 0;
}
.demo-seed-hint__body { margin: 0; line-height: 1.5; }
.demo-seed-hint code {
  background: var(--surface-glass-strong);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-2);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.95em;
  color: var(--text-secondary);
}

/* --- Headline ribbon + Quiet Alert strip ----------------------------- */

.family-command__headline {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-5);
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  align-items: start;
}
@media (max-width: 720px) {
  .family-command__headline { grid-template-columns: 1fr; }
}
.family-command__headline-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.family-command__greeting {
  font-family: var(--font-headline, inherit);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.family-command__narrative {
  font-size: var(--text-base);
  color: var(--text-secondary);
  line-height: 1.6;
  margin: 0;
  max-width: 60ch;
}
.family-command__narrative .family-headline__name {
  color: var(--accent-primary);
  font-weight: var(--weight-bold);
}
.family-command__wins {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 0;
  max-width: 60ch;
}
.family-command__wins-icon {
  color: var(--success);
  display: inline-flex;
  flex-shrink: 0;
  transform: translateY(2px);
}
.family-command__wins-icon svg {
  width: 15px;
  height: 15px;
}
.family-command__wins strong {
  color: var(--success);
  font-weight: var(--weight-bold);
}
.family-command__focus {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 0;
}
.family-command__alert {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  justify-self: end;
  min-width: 280px;
}
@media (max-width: 720px) {
  .family-command__alert { justify-self: stretch; min-width: 0; }
}
.quiet-alert {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-3);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-left: var(--space-1) solid var(--warning);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}
.quiet-alert__icon {
  color: var(--warning);
  font-size: var(--text-lg);
  display: inline-flex;
}
.quiet-alert__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.quiet-alert__pill {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--warning-strong);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.quiet-alert__line {
  font-size: var(--text-sm);
  color: var(--text-primary);
  margin: 0;
}
.quiet-alert__cta {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
  text-decoration: none;
}
.quiet-alert__cta:hover { text-decoration: underline; }

/* --- Per-student card state variants -------------------------------- */
/* Reuses .student-cards / .student-card grid + card recipe from
   session-8. Adds status-conditional border-left + glow + status pill
   colors. */

.student-card[data-status="stuck"] {
  border-left: var(--space-1) solid var(--warning);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--warning) 20%, transparent),
              0 8px 24px color-mix(in srgb, var(--warning) 12%, transparent);
}
.student-card[data-status="finished"] {
  border-left: var(--space-1) solid var(--success);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--success) 20%, transparent),
              0 8px 24px color-mix(in srgb, var(--success) 10%, transparent);
}
/* on_track / coop_block / not_started use default card */

.student-card__name-block {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.student-card__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-pill);
  overflow: hidden;
  border: 1px solid var(--border-glass);
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
}
.student-card__avatar img { width: 100%; height: 100%; object-fit: cover; }

/* --- School-phase ring + family-unique glyph (§4d-i) ----------------------
   Two orthogonal encodings on one avatar: the RING is the school phase (grade-
   derived, and siblings legitimately share it); the GLYPH is which child this
   is (unique within the family). Keeping them separate is the point — grade
   cannot carry identity, because in the Rivera seed four of seven children are
   the same grade.
   The ring is a 2px border in the phase hue. `overflow: hidden` above clips a
   photo avatar to the circle, so the ring rides the existing border rather than
   an outline that the clip would eat. */
.student-card__avatar[data-phase],
.roll-student__avatar[data-phase] {
  border: 2px solid var(--border-glass);
}
.student-card__avatar[data-phase="early_el"],
.roll-student__avatar[data-phase="early_el"] { border-color: var(--phase-early-el); }
.student-card__avatar[data-phase="upper_el"],
.roll-student__avatar[data-phase="upper_el"] { border-color: var(--phase-upper-el); }
.student-card__avatar[data-phase="middle"],
.roll-student__avatar[data-phase="middle"]   { border-color: var(--phase-middle); }
.student-card__avatar[data-phase="high"],
.roll-student__avatar[data-phase="high"]     { border-color: var(--phase-high); }

/* The glyph grows to 2-3 characters when a family needs it to stay unique, so
   the type steps down rather than overflowing a fixed circle. */
.student-card__avatar[data-glyph-len="3"] { font-size: var(--text-sm); }
.roll-student__avatar[data-glyph-len="3"] { font-size: var(--text-xs); }
.student-card__avatar--initial { letter-spacing: 0.02em; }
.student-card__status-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
}
.student-card__status-pill[data-status="stuck"] {
  color: var(--warning-strong);
  background: color-mix(in srgb, var(--warning) 16%, transparent);
}
.student-card__status-pill[data-status="finished"] {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 12%, transparent);
}
.student-card__status-pill[data-status="on_track"] {
  color: var(--accent-primary);
  background: color-mix(in srgb, var(--accent-primary) 10%, transparent);
}
.student-card__status-pill[data-status="coop_block"] {
  color: var(--info);
  background: color-mix(in srgb, var(--info) 14%, transparent);
}
.student-card__status-pill[data-status="not_started"] {
  color: var(--text-muted);
  background: var(--surface-glass-strong);
}
.student-card__buffer-chip {
  font-size: var(--text-xs);
  color: var(--text-muted);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: 2px var(--space-2);
  align-self: flex-start;
  margin: 0;
}
.student-card__current {
  font-size: var(--text-base);
  font-style: italic;
  color: var(--text-primary);
  line-height: 1.55;
  padding: var(--space-3) 0;
  border-top: 1px solid var(--border-glass);
  border-bottom: 1px solid var(--border-glass);
  margin: 0;
}
.student-card__metrics {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}
.metric-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  text-align: center;
}
.metric-tile__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.metric-tile__value {
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  line-height: 1;
}
.metric-tile__unit {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.metric-tile--primary .metric-tile__value {
  color: var(--accent-primary);
}
.metric-tile[data-provisional="1"] .metric-tile__value {
  opacity: 0.6;
}
.student-card__tutor-line {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}
.student-card__tutor-line strong {
  color: var(--text-primary);
  font-weight: var(--weight-bold);
}
.student-card__tokens-line {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0;
}
.student-card__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: auto;
}
.btn--muted { color: var(--text-muted); font-size: var(--text-xs); }
.btn--muted:hover { color: var(--text-secondary); }

/* --- Touchpoint Timeline -------------------------------------------- */

.touchpoint-timeline {
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.touchpoint-timeline__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}
.touchpoint-timeline__title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.touchpoint-timeline__title i { color: var(--accent-primary); }
.touchpoint-timeline__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}
.touchpoint-list {
  list-style: none;
  padding: 0;
  margin: 0;
  position: relative;
}
.touchpoint-list::before {
  content: '';
  position: absolute;
  left: var(--space-4);
  top: var(--space-3);
  bottom: var(--space-3);
  width: 1px;
  background: var(--border-glass);
}
.touchpoint-row {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  gap: var(--space-3);
  align-items: start;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border-glass);
}
.touchpoint-row:last-child { border-bottom: 0; }
.touchpoint-row__time {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  min-width: 64px;
}
.touchpoint-row__dot {
  width: var(--space-2);
  height: var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--accent-primary);
  position: relative;
  margin-top: 6px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--surface-glass-strong) 80%, transparent);
}
.touchpoint-row__dot[data-status="completed"] { background: var(--success); }
.touchpoint-row__dot[data-status="skipped"]   { background: var(--text-muted); }
.touchpoint-row__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.touchpoint-row__headline {
  font-size: var(--text-sm);
  color: var(--text-primary);
  margin: 0;
}
.touchpoint-row__overlap {
  display: inline-flex;
  align-self: flex-start;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--warning-strong);
  background: color-mix(in srgb, var(--warning) 14%, transparent);
  border-radius: var(--radius-pill);
  padding: 2px var(--space-2);
}
.touchpoint-row__notes {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
  margin: 0;
}
.touchpoint-row__resolved {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.touchpoint-row__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  align-items: flex-end;
}
.touchpoint-timeline__empty {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-style: italic;
  text-align: center;
  padding: var(--space-5) 0;
  margin: 0;
}

/* ==========================================================================
   Family Day Timeline (Section D) — docs/ui-specs/family-command-center.md §5g
   Horizontal spine of TIME-BLOCK columns: one card per hourly slot, each
   listing the students with a learning block at that slot (student · lesson,
   tagged done / current / upcoming). A floating NOW marker (accent dashed
   line + pill) keys off the parent's local wall clock. Slot clock labels are
   a derived V1 cadence (schedule_item has no time-of-day). Never red: done →
   --success, current → --accent-primary, upcoming → neutral.
   ========================================================================== */
.day-timeline {
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.day-timeline__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}
.day-timeline__title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.day-timeline__title i { color: var(--accent-primary); }
/* `.day-timeline__hint` removed with the line it styled — the title now names
   the date and week, which is all that line carried worth keeping. */

/* Parent lane — sits ABOVE the children's spine, because it is the constraint
   the rest of the day has to fit inside, not another row of it. A quiet band,
   not a card: it must be readable at a glance and ignorable the rest of the
   time. Never a score, never a streak — this is the burnout guard. */
.parent-lane {
  display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap;
  margin: var(--space-3) 0 0;
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--info);
  border-radius: var(--radius-sm);
  background: var(--surface-glass);
}
/* Amber at a heavy day — never red (locked rule: --error appears nowhere in a
   family flow). Heavy is information, not a verdict on the parent. */
.parent-lane[data-heavy="true"] { border-left-color: var(--warning); }
.parent-lane__who {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--text-primary);
}
.parent-lane__mins { font-size: var(--text-sm); color: var(--text-secondary); }
.parent-lane[data-heavy="true"] .parent-lane__mins { color: var(--warning); }
.parent-lane__detail {
  font-size: var(--text-xs); color: var(--text-muted); margin-left: auto;
}

/* Spine — horizontal scroll region. The track grows to fit all slots so the
   connecting line (::before) spans the full run; cards alternate above/below
   a continuous centre line, dots pinned to it. */
.day-timeline__spine {
  overflow-x: auto;
  scrollbar-width: thin;
  padding: var(--space-2) 0;
}
.day-timeline__track {
  position: relative;
  display: inline-flex;
  align-items: stretch;
  gap: var(--space-4);
  min-width: 100%;
}
.day-timeline__track::before {          /* continuous centre timeline line */
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 2px;
  background: var(--border-glass);
  z-index: 0;
}

.day-timeline__slot {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  width: 220px;                         /* room for a 2-line lesson wrap (§5g a) */
  display: grid;
  grid-template-rows: 1fr 1fr;          /* above half | below half */
  row-gap: var(--space-5);              /* clearance around the centre line */
}
/* A hovered/focused slot lifts above its neighbours so its popover reads
   clearly over the adjacent cards (§5g d). */
.day-timeline__slot:hover,
.day-timeline__slot:focus-within {
  z-index: 4;
}
.day-timeline__dot {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 12px;
  height: 12px;
  border-radius: var(--radius-pill);
  background: var(--accent-primary);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--surface-glass-strong) 80%, transparent);
}
.day-timeline__slot[data-now="1"] .day-timeline__dot {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-primary) 22%, transparent);
}
.day-timeline__slot[data-pos="above"] .day-timeline__slot-card {
  grid-row: 1;
  align-self: end;
}
.day-timeline__slot[data-pos="below"] .day-timeline__slot-card {
  grid-row: 2;
  align-self: start;
}
.day-timeline__slot-card {
  position: relative;                    /* anchors the slot popover */
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass);
  background: var(--surface-glass-strong);
  transition: transform var(--duration-fast, 150ms) var(--ease-out, ease-out),
              box-shadow var(--duration-fast, 150ms) var(--ease-out, ease-out);
}
/* Hover / keyboard-focus affordance (§5g b) — a gentle lift signals the card
   is interactive (reveals the slot popover). Only cards with entries are
   focusable, so empty slots stay inert. */
.day-timeline__slot-card[tabindex]:hover,
.day-timeline__slot-card[tabindex]:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md, 0 6px 16px rgba(0, 0, 0, 0.28));
  outline: none;
}
.day-timeline__slot[data-now="1"] .day-timeline__slot-card {
  border-color: var(--accent-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-primary) 14%, transparent);
}
.day-timeline__slot-time {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 2px;
}
.day-timeline__slot[data-now="1"] .day-timeline__slot-time {
  color: var(--accent-primary);
}

/* Entry line — one student's block within a slot. Lesson wraps to 2 lines so
   long titles read fully instead of hard-truncating. */
.day-timeline__entry {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  margin: 0;
  font-size: var(--text-xs);
  line-height: 1.35;
  color: var(--text-secondary);
}
.day-timeline__entry-icon,
.day-timeline__entry-check {
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
  margin-top: 2px;
}
.day-timeline__entry-icon { color: var(--text-muted); }
.day-timeline__entry-check { color: var(--success); margin-left: auto; }
.day-timeline__entry-student {
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  flex: 0 0 auto;
}
.day-timeline__entry-lesson {
  min-width: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.day-timeline__entry[data-status="done"] {
  color: var(--text-muted);
}
.day-timeline__entry[data-status="done"] .day-timeline__entry-student {
  color: var(--text-muted);
  font-weight: var(--weight-medium);
}
.day-timeline__entry[data-status="current"] .day-timeline__entry-icon {
  color: var(--accent-primary);
}
.day-timeline__slot-empty {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-align: center;
}

/* Slot popover (§5g d) — full skill name + per-student mastery, revealed on
   hover / keyboard focus. Centred on the slot's vertical midpoint (the centre
   line) rather than offset above/below the card: the spine is a horizontal
   scroll region, so its overflow-y computes to `auto` and clips vertically —
   a card-offset popover gets cut off, but a slot-centred one stays inside the
   track's height. It overlays the card while open (opaque + lifted shadow). */
.day-timeline__popover {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.98);
  min-width: 100%;
  width: max-content;
  /* 260px could not hold a lesson title on one line, which is what forced the
     old row layout to wrap into columns. Wider is legible; much wider would
     start covering the neighbouring slots. */
  max-width: 320px;
  /* A slot holds one row per child with a block at that time, and each row is
     student + lesson title + mastery (+ the reason, when one needs an adult).
     At seven children the first slot renders ~657px tall inside a ~514px card
     and spills out of both ends. Cap it and let the list scroll: the alternative
     is truncating rows, which hides exactly the child a parent is looking for. */
  /* Cover the card COMPLETELY. The popover is centred on its slot and was
     capped shorter than the card it overlays, so the card's own entries showed
     below its bottom edge — which reads as the popover being cut off rather
     than scrollable. `min-height: 100%` pins it to the card's height (and wins
     over max-height per spec), so it always covers, and the list scrolls
     inside. */
  min-height: 100%;
  max-height: 340px;
  overflow-y: auto;
  overscroll-behavior: contain;
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-glass);
  /* Popover overlays the card, so — unlike the glass panels that float over the
     page gradient — it must be OPAQUE or the card text ghosts through. Composite
     the glass tint over the solid substrate: same frosted look, zero bleed,
     theme-adaptive (both tokens). */
  background:
    linear-gradient(var(--surface-glass-strong), var(--surface-glass-strong)),
    var(--bg-base);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--duration-fast, 150ms) var(--ease-out, ease-out),
              transform var(--duration-fast, 150ms) var(--ease-out, ease-out);
}
.day-timeline__slot:hover .day-timeline__popover,
.day-timeline__slot:focus-within .day-timeline__popover {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, -50%) scale(1);
  /* Re-enable the mouse. The resting state sets `pointer-events: none` so the
     hidden popover can't block the card beneath it — but this rule used to
     restore only opacity/visibility/transform, so the VISIBLE popover stayed
     transparent to input. Every wheel event fell through to the page, which is
     why a list that scrolls correctly scrolled the whole document instead.

     Safe against flicker: the popover is a CHILD of the slot, so the cursor
     sitting on it keeps `.day-timeline__slot:hover` true and the popover open. */
  pointer-events: auto;
}

/* EDGE CLAMP. The popover is centred on its slot, so up to half of it sits
   outside the slot's own box — and the spine is `overflow-x: auto`, which
   clips it. On the FIRST slot that meant the left edge of the popover was cut
   off ("9:00 AM" rendering as ":00 AM"); on the last, the right edge.
   (The original positioning comment solved the VERTICAL case only.)

   Anchor the outermost slots to their own edge instead of centring. Both the
   resting and hover transforms have to be overridden, or the popover jumps
   sideways as it fades in. */
.day-timeline__slot:first-child .day-timeline__popover {
  left: 0;
  transform: translate(0, -50%) scale(0.98);
}
.day-timeline__slot:first-child:hover .day-timeline__popover,
.day-timeline__slot:first-child:focus-within .day-timeline__popover {
  transform: translate(0, -50%) scale(1);
}
.day-timeline__slot:last-child .day-timeline__popover {
  left: auto;
  right: 0;
  transform: translate(0, -50%) scale(0.98);
}
.day-timeline__slot:last-child:hover .day-timeline__popover,
.day-timeline__slot:last-child:focus-within .day-timeline__popover {
  transform: translate(0, -50%) scale(1);
}
.day-timeline__popover-time {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent-primary);
  /* Sticky so the count — the only thing telling a parent the list is longer
     than the window — stays visible while they scroll it. */
  position: sticky;
  top: calc(var(--space-3) * -1);
  margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1) 0;
  padding: var(--space-3) var(--space-3) var(--space-2);
  background:
    linear-gradient(var(--surface-glass-strong), var(--surface-glass-strong)),
    var(--bg-base);
}
.day-timeline__popover-count {
  font-weight: var(--weight-regular);
  letter-spacing: normal;
  text-transform: none;
  color: var(--text-muted);
}
.day-timeline__popover-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
/* The head holds four things — icon, "Leo · PE & health", the lesson title, and
   the reason an adult is needed — and it used to lay them out as a flex ROW.
   Inside a ~255px popover that gave each span ~60px, so every one wrapped into
   a tall narrow column and the columns visually collided: at seven children the
   first slot generated 717px of content for 7 rows. The scroller was already
   here and working; it was scrolling badly-shaped content.

   A 2-column grid instead: the icon holds its own column, and the three text
   spans stack in the second. Rows become three short lines rather than three
   interleaved columns. */
.day-timeline__popover-head {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-1);
  row-gap: 2px;
  align-items: start;
  font-size: var(--text-xs);
  line-height: 1.35;
  color: var(--text-secondary);
  min-width: 0;
}
.day-timeline__popover-head > .day-timeline__entry-icon { grid-column: 1; grid-row: 1; }
.day-timeline__popover-student {
  grid-column: 2;
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
/* Every text span shares the second column, so they stack under one another
   and each gets the popover's full readable width. */
.day-timeline__popover-skill,
.day-timeline__popover-need { grid-column: 2; }
.day-timeline__popover-skill { min-width: 0; }
.day-timeline__popover-mastery {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-left: calc(13px + var(--space-1));  /* align under the skill text */
}
.day-timeline__meter {
  flex: 1 1 auto;
  height: var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  overflow: hidden;
}
.day-timeline__meter-fill {
  display: block;
  height: 100%;
  width: var(--mastery, 0%);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg,
    var(--warning) 0%, var(--info) 45%, var(--success) 100%);
}
.day-timeline__meter-pct {
  flex: 0 0 auto;
  font-size: 10px;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
}

/* NOW marker — floats between the current and upcoming slots. */
.day-timeline__now {
  position: relative;
  z-index: 2;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.day-timeline__now-pill {
  height: 18px;
  line-height: 18px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  font-size: 10px;
  font-weight: var(--weight-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-primary);
  background: color-mix(in srgb, var(--accent-primary) 16%, transparent);
  border: 1px solid var(--accent-primary);
}
.day-timeline__now-line {
  flex: 1;
  width: 0;
  margin-top: var(--space-1);
  border-left: 2px dashed var(--accent-primary);
}

.day-timeline__empty {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-style: italic;
  text-align: center;
  padding: var(--space-5) 0;
  margin: 0;
}
@media (max-width: 720px) {
  .day-timeline { padding: var(--space-4); }
  .day-timeline__slot { width: 196px; }
}

/* ==========================================================================
   Monthly Digest (per docs/ui-specs/monthly-digest.md §6)
   Reuses: .card / .btn / .field / .metric-tile from session-8 + the
   .pbar chrome. Adds the subject-row spine, sparkline cascade, momentum
   pills, 3-baseline tile-strip, engagement + tutor cards. Zero new tokens.
   ========================================================================== */

.monthly-digest {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) var(--space-8);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* --- Chrome strip (month picker + pacing pill) ---------------------- */

.digest-chrome {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.digest-month-picker {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
}
.digest-month-picker__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-6);
  height: var(--space-6);
  border: none;
  background: transparent;
  color: var(--accent-primary);
  cursor: pointer;
  border-radius: var(--radius-pill);
}
.digest-month-picker__step:hover:not(:disabled) {
  background: var(--surface-glass);
}
.digest-month-picker__step:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.digest-month-picker__current {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  min-width: 9ch;
  text-align: center;
}
.digest-pacing-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
}
/* Plan-vs-year overrun. Amber: running past the year is information, not a
   failure — the two horizons are allowed to differ, they just have to SAY so. */
.digest-overrun-pill {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--text-xs); font-weight: var(--weight-bold);
  letter-spacing: 0.05em; text-transform: uppercase;
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  border: 1px solid var(--border-glass);
  color: var(--warning-strong);
}
.digest-pacing-pill[data-status="on_pace"]    { color: var(--success); }
.digest-pacing-pill[data-status="ahead"]      { color: var(--accent-primary); }
.digest-pacing-pill[data-status="behind"]     { color: var(--warning-strong); }

/* --- A. Executive Summary ribbon ------------------------------------ */

.digest__summary {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-5);
  align-items: start;
  padding: var(--space-6);
  border-radius: var(--radius-lg);
}
.digest__summary-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-8);
  height: var(--space-8);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
  font-size: var(--text-xl);
}
.digest__summary-eyebrow {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin: 0 0 var(--space-2);
}
.digest__summary-prose {
  font-size: var(--text-base);
  color: var(--text-primary);
  line-height: 1.6;
  margin: 0;
  max-width: 70ch;
}
.digest__summary-trend   { color: var(--accent-primary); font-weight: var(--weight-bold); }
.digest__summary-improve { color: var(--success);        font-weight: var(--weight-bold); }
.digest__summary-stuck   { color: var(--text-secondary); font-weight: var(--weight-bold); }
.digest__summary-decay   { color: var(--warning-strong); font-weight: var(--weight-bold); }

/* --- B. Temporal Hurdles strip -------------------------------------- */

.digest__temporal {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}
@media (max-width: 720px) {
  .digest__temporal { grid-template-columns: 1fr; }
}
.digest__temporal-column {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.digest__temporal-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
}
.digest__temporal-eyebrow {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.digest__temporal-count {
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.digest__temporal-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.digest__temporal-hurdle {
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-left: 2px solid var(--warning);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}
.digest__temporal-hurdle a {
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.digest__temporal-hurdle-title {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.digest__temporal-hurdle-meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.digest__temporal-empty {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-style: italic;
  text-align: center;
  padding: var(--space-4) 0;
  margin: 0;
}

/* --- C. Subject row spine ------------------------------------------- */

.digest__subject-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.digest__subject-list-head {
  display: grid;
  grid-template-columns: 200px 1fr 140px 320px 40px;
  gap: var(--space-4);
  align-items: baseline;
  padding: 0 var(--space-4);
}
@media (max-width: 1024px) {
  .digest__subject-list-head { display: none; }
}
.digest__col {
  display: block;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.digest__subject-list-head .digest__col {
  /* header labels — keep the small caps treatment */
}
.digest-subject-row {
  display: grid;
  grid-template-columns: 200px 1fr 140px 320px 40px;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
}
@media (max-width: 1024px) {
  .digest-subject-row {
    grid-template-columns: 1fr;
    gap: var(--space-3);
  }
}
.digest-subject-row[data-bucket="decaying"] {
  border-left: var(--space-1) solid var(--warning);
}
.digest-subject-row[data-bucket="building"] {
  opacity: 0.75;
}
.digest-subject-row .digest__col {
  /* override header text styling for body cells — body cells host
     real content, not labels */
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
  letter-spacing: normal;
  text-transform: none;
}
.digest__col--subject {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.digest-subject-row__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
}
.digest-subject-row__identity {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.digest-subject-row__name {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.digest-subject-row__skill-count {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.digest__col--velocity {
  padding: 0 var(--space-4);
}
.digest-sparkline {
  width: 100%;
  height: var(--space-6);
  color: var(--text-muted);   /* default — overridden by data-bucket cascade */
}
.digest-subject-row[data-bucket="trending"]  .digest-sparkline { color: var(--accent-primary); }
.digest-subject-row[data-bucket="improving"] .digest-sparkline { color: var(--success); }
.digest-subject-row[data-bucket="stuck"]     .digest-sparkline { color: var(--text-muted); }
.digest-subject-row[data-bucket="decaying"]  .digest-sparkline { color: var(--warning); }
.digest-subject-row[data-bucket="building"]  .digest-sparkline { color: var(--text-muted); opacity: 0.6; }

.digest__col--momentum {
  display: inline-flex;
  justify-content: center;
}
.digest-momentum-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
}
.digest-momentum-pill[data-bucket="trending"] {
  color: var(--accent-primary);
  background: color-mix(in srgb, var(--accent-primary) 10%, transparent);
}
.digest-momentum-pill[data-bucket="improving"] {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 12%, transparent);
}
.digest-momentum-pill[data-bucket="stuck"] {
  color: var(--text-secondary);
  background: var(--surface-glass-strong);
}
.digest-momentum-pill[data-bucket="decaying"] {
  color: var(--warning-strong);
  background: color-mix(in srgb, var(--warning) 14%, transparent);
}
.digest-momentum-pill[data-bucket="building"] {
  color: var(--text-muted);
  background: var(--surface-glass-strong);
  opacity: 0.6;
}

.digest__col--baselines {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--space-2);
}
.digest-baseline-tile {
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  align-items: flex-start;
}
.digest-baseline-tile__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.digest-baseline-tile__value {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.digest-baseline-tile--self .digest-baseline-tile__value {
  color: var(--accent-primary);
}
.digest-baseline-tile__value--building {
  color: var(--text-muted);
  opacity: 0.6;
}
.digest-baseline-tile__source {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
}
.digest-baseline-tile__delta {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}
.digest-baseline-tile__delta[data-direction="up"]   { color: var(--success); }
.digest-baseline-tile__delta[data-direction="down"] { color: var(--warning-strong); }
.digest-baseline-tile__delta[data-direction="flat"] { color: var(--text-secondary); }
.digest-baseline-tile__delta--building {
  color: var(--text-muted);
  font-style: italic;
}
.digest-baseline-tile[data-status="building"] {
  opacity: 0.6;
}
.digest__col--drill {
  display: inline-flex;
  justify-content: center;
  color: var(--accent-primary);
  text-decoration: none;
  transition: transform 0.15s ease;
}
.digest__col--drill:hover {
  transform: translateX(var(--space-1));
}

/* --- D. Two-column secondary block ---------------------------------- */

.digest__secondary {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
}
@media (max-width: 720px) {
  .digest__secondary { grid-template-columns: 1fr; }
}

/* Engagement × Score signal lattice (§5h) — a 2×2 plane, one dot per subject
   plotted as a delta from its rolling baseline (centre = at baseline). Dots
   are placed via the documented dynamic props --lattice-x / --lattice-y.
   Never red: the at-risk quadrant (Stalling) uses --warning. */
.digest-lattice {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}
.digest-lattice__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
}
.digest-lattice__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0 0 var(--space-1);
}
.digest-lattice__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
  max-width: 52ch;
}
.digest-lattice__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
  flex: 0 0 auto;
}
.digest-lattice__frame {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "yaxis plane"
    ".     xaxis";
  gap: var(--space-2);
}
.digest-lattice__plane {
  grid-area: plane;
  position: relative;
  aspect-ratio: 16 / 10;
  min-height: 240px;
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  background: var(--surface-glass);
  overflow: hidden;
}
/* Centre cross — the baseline origin the dots are read against. */
.digest-lattice__plane::before,
.digest-lattice__plane::after {
  content: "";
  position: absolute;
  background: var(--border-glass);
  z-index: 0;
}
.digest-lattice__plane::before { left: 0; right: 0; top: 50%; height: 1px; }
.digest-lattice__plane::after  { top: 0; bottom: 0; left: 50%; width: 1px; }
.digest-lattice__quad {
  position: absolute;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  opacity: 0.72;
  padding: var(--space-2);
}
.digest-lattice__quad--coasting { top: 0; left: 0; }
.digest-lattice__quad--thriving { top: 0; right: 0; }
.digest-lattice__quad--grinding { bottom: 0; right: 0; }
.digest-lattice__quad--stalling { bottom: 0; left: 0; color: var(--warning); }
.digest-lattice__dot {
  position: absolute;
  left: var(--lattice-x, 50%);
  top: var(--lattice-y, 50%);
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  z-index: 1;
}
/* Right-half dots hang their label to the left of the mark so it never spills
   past the plane's clipped right edge. */
.digest-lattice__dot[data-side="left"] { flex-direction: row-reverse; }
.digest-lattice__dot-mark {
  width: 12px;
  height: 12px;
  border-radius: var(--radius-pill);
  background: var(--accent-primary);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--surface-glass-strong) 70%, transparent);
  flex: 0 0 auto;
}
.digest-lattice__dot-label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  white-space: nowrap;
}
.digest-lattice__dot[data-quadrant="thriving"] .digest-lattice__dot-mark { background: var(--success); }
.digest-lattice__dot[data-quadrant="coasting"] .digest-lattice__dot-mark { background: var(--info); }
.digest-lattice__dot[data-quadrant="grinding"] .digest-lattice__dot-mark { background: var(--accent-primary); }
.digest-lattice__dot[data-quadrant="stalling"] .digest-lattice__dot-mark { background: var(--warning); }
.digest-lattice__dot[data-quadrant="steady"] .digest-lattice__dot-mark,
.digest-lattice__dot[data-quadrant="forming"] .digest-lattice__dot-mark { background: var(--text-muted); }
.digest-lattice__axis {
  display: flex;
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.digest-lattice__axis--y {
  grid-area: yaxis;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-end;
  text-align: right;
}
.digest-lattice__axis--x {
  grid-area: xaxis;
  justify-content: space-between;
  align-items: center;
}
.digest-lattice__axis-name {
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.digest-lattice__empty {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-style: italic;
  text-align: center;
  padding: var(--space-5) 0;
  margin: 0;
}

/* --- Developmental-capacity trajectory (Digest §C3) ---------------------- */
.digest-trajectory {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}
.digest-trajectory__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
}
.digest-trajectory__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0 0 var(--space-1);
}
.digest-trajectory__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
  max-width: 52ch;
}
.digest-trajectory__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
  flex: 0 0 auto;
}
.digest-trajectory__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}
.digest-trajectory__row {
  display: grid;
  grid-template-columns: minmax(8rem, auto) 1fr auto minmax(5rem, auto);
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--border-glass);
}
.digest-trajectory__row:first-child { border-top: none; }
.digest-trajectory__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}
.digest-trajectory__spark {
  width: 100%;
  height: var(--space-6);
  color: var(--info);          /* default; direction overrides below (never red) */
}
.digest-trajectory__row[data-direction="up"]   .digest-trajectory__spark { color: var(--success); }
.digest-trajectory__row[data-direction="down"] .digest-trajectory__spark { color: var(--warning); }
.digest-trajectory__row[data-direction="flat"] .digest-trajectory__spark { color: var(--text-muted); }
.digest-trajectory__now {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.digest-trajectory__delta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-muted);
  justify-self: end;
}
.digest-trajectory__delta i { width: 1em; height: 1em; }
.digest-trajectory__delta[data-direction="up"]   { color: var(--success); }
.digest-trajectory__delta[data-direction="down"] { color: var(--warning); }
.digest-trajectory__foot {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0;
}
.digest-trajectory__empty {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-style: italic;
  text-align: center;
  padding: var(--space-5) 0;
  margin: 0;
}
@media (max-width: 720px) {
  .digest-trajectory__row {
    grid-template-columns: 1fr auto auto;
    grid-template-areas:
      "label label label"
      "spark now   delta";
  }
  .digest-trajectory__label { grid-area: label; }
  .digest-trajectory__spark { grid-area: spark; }
  .digest-trajectory__now   { grid-area: now; }
  .digest-trajectory__delta { grid-area: delta; }
}
@media (max-width: 720px) {
  /* Drop the wide aspect-ratio + min-height on narrow viewports: together
     they force a min WIDTH that overflows the column and pushes dots off the
     card. A square, width-constrained plane keeps every dot inside. */
  .digest-lattice__plane { aspect-ratio: 1; min-height: 0; }
}

.digest-engagement {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}
.digest-engagement__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
}
.digest-engagement__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0 0 var(--space-1);
}
.digest-engagement__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
  max-width: 40ch;
}
.digest-engagement__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
}
.digest-engagement__primary {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}
.digest-engagement__secondary {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-glass);
}
.digest-engagement__secondary-note {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin: 0;
}
.digest-engagement__secondary-tiles {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}
.metric-tile--muted { opacity: 0.65; }

.digest-tutor-effectiveness {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}
.digest-tutor-effectiveness__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
}
.digest-tutor-effectiveness__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0 0 var(--space-1);
}
.digest-tutor-effectiveness__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}
.digest-tutor-effectiveness__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
}
.digest-tutor-effectiveness__narrative {
  font-size: var(--text-base);
  color: var(--text-primary);
  line-height: 1.55;
  margin: 0;
}
.digest-tutor-effectiveness__metrics {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--space-3);
}
@media (max-width: 720px) {
  .digest-tutor-effectiveness__metrics { grid-template-columns: 1fr; }
}

/* --- E. Forward-declared placeholders ------------------------------- */

.digest__forward {
  display: flex;
  flex-direction: row;
  gap: var(--space-3);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-glass);
}
.btn--disabled {
  opacity: 0.5;
  cursor: not-allowed;
  position: relative;
}
.btn--disabled:hover { filter: none; }
.btn__chip {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  background: var(--accent-secondary);
  color: var(--text-on-accent);
  border-radius: var(--radius-pill);
  padding: 0 var(--space-2);
  margin-left: var(--space-2);
}

/* ==========================================================================
   Annual Replan Wizard (per docs/ui-specs/annual-replan-wizard.md §6)
   Two-pane workbench, desktop-only V1 (≥1280). Below 1280 renders the
   .replan-fallback empty-state. Reuses .btn / .card / .field / .chip /
   .metric-tile from sessions 8 + 9 + 11. Zero new design tokens.
   ========================================================================== */

.annual-replan {
  max-width: 1600px;
  margin: 0 auto;
  padding: var(--space-5);
}

/* --- Below-1280 fallback (the only thing visible below the breakpoint) -- */

.replan-fallback {
  max-width: 560px;
  margin: var(--space-7) auto;
  padding: var(--space-7);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-4);
  border-radius: var(--radius-lg);
}
.replan-fallback__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-8);
  height: var(--space-8);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
  font-size: var(--text-xl);
}
.replan-fallback__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.replan-fallback__body {
  font-size: var(--text-base);
  color: var(--text-secondary);
  line-height: 1.55;
  margin: 0;
  max-width: 50ch;
}
.replan-fallback__actions {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

/* --- Two-pane workbench (≥1280 only) -- */

.annual-replan__panes { display: none; }
@media (min-width: 1280px) {
  .replan-fallback     { display: none; }
  .annual-replan__panes {
    display: grid;
    grid-template-columns: minmax(420px, 40fr) minmax(640px, 60fr);
    gap: var(--space-5);
    align-items: start;
    min-height: calc(100vh - var(--space-8) * 3);
  }
}

/* --- Left pane: Retrospective ----------------------------------------- */

.replan-retrospective {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-5);
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg);
}
.replan-retro__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.replan-retro__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.replan-retro__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}
.replan-retro__eyebrow {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 var(--space-2);
}
.replan-year-picker {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  align-self: flex-start;
}
.replan-year-picker__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.replan-year-picker__select {
  background: transparent;
  border: none;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  font-family: inherit;
}

/* === v2 marker: replaces v1 mastery row + interest detection + */
/* === comparative baselines + move palette popover blocks.      */

/* --- Retrospective: section + subject card -------------------- */

.replan-retro-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.replan-retro-section__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--accent-secondary);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin: 0;
}
.replan-retro-subject-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
}
.replan-retro-subject-card__head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-3);
}
.replan-retro-subject-card__identity {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.replan-retro-subject-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-md);
  background: var(--surface-glass);
  color: var(--accent-primary);
}
.replan-retro-subject-icon i {
  width: 18px;
  height: 18px;
}
.replan-retro-subject-card__title {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.replan-retro-subject-card__strand {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0;
}
.replan-retro-subject-score {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.replan-retro-subject-card[data-mastery="strong"]     .replan-retro-subject-score { color: var(--success); }
.replan-retro-subject-card[data-mastery="solid"]      .replan-retro-subject-score { color: var(--accent-primary); }
.replan-retro-subject-card[data-mastery="developing"] .replan-retro-subject-score { color: var(--warning); }
.replan-retro-subject-card[data-mastery="emerging"]   .replan-retro-subject-score { color: var(--warning-strong); }

.replan-retro-subject-card__pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* --- Pills (shared mastery / growth / strength / focus) ---- */

.replan-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  color: var(--text-secondary);
}
.replan-pill i { width: 14px; height: 14px; }
.replan-pill--mastery[data-mastery="strong"]     { color: var(--success); }
.replan-pill--mastery[data-mastery="solid"]      { color: var(--accent-primary); }
.replan-pill--mastery[data-mastery="developing"] { color: var(--warning); }
.replan-pill--mastery[data-mastery="emerging"]   { color: var(--warning-strong); }
.replan-pill--growth[data-growth="up"]         { color: var(--success); }
.replan-pill--growth[data-growth="stable"]     { color: var(--text-secondary); }
.replan-pill--growth[data-growth="slipping"]   { color: var(--warning-strong); }
.replan-pill--growth[data-growth="first_year"] {
  color: var(--text-muted);
  font-style: italic;
}
.replan-pill--strength {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 14%, transparent);
  border-color: color-mix(in srgb, var(--success) 30%, transparent);
}
.replan-pill--focus-area {
  color: var(--warning-strong);
  background: color-mix(in srgb, var(--warning-strong) 14%, transparent);
  border-color: color-mix(in srgb, var(--warning-strong) 30%, transparent);
}

.replan-retro-subject-card__summary {
  font-size: var(--text-sm);
  color: var(--text-primary);
  line-height: 1.5;
  margin: 0;
}
.replan-retro-subject-card__summary strong {
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
}

.replan-retro-subject-card__skills > summary {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer;
  padding: var(--space-2) 0;
  list-style: none;
}
.replan-retro-subject-card__skills > summary::-webkit-details-marker { display: none; }
.replan-retro-subject-card__skills > summary::marker { display: none; }
.replan-retro-subject-card__skills ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.replan-retro-subject-card__skills li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
}
.replan-retro-subject-card__skills li:nth-child(odd) {
  background: color-mix(in srgb, var(--surface-glass) 70%, transparent);
}
.replan-retro-subject-card__skill-score {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}
.replan-retro-subject-card__skill-score[data-tone="strong"]     { color: var(--success); }
.replan-retro-subject-card__skill-score[data-tone="solid"]      { color: var(--accent-primary); }
.replan-retro-subject-card__skill-score[data-tone="developing"] { color: var(--warning); }
.replan-retro-subject-card__skill-score[data-tone="emerging"]   { color: var(--warning-strong); }

.replan-retro-subject-card__bottom-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-glass);
}

/* --- Diagnostic callout (top of retrospective pane) ----------- */

.replan-diagnostic-callout {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
}
.replan-diagnostic-callout__icon {
  display: inline-flex;
  align-items: flex-start;
  color: var(--accent-secondary);
  flex-shrink: 0;
}
.replan-diagnostic-callout__icon i { width: 18px; height: 18px; }
.replan-diagnostic-callout__body { display: flex; flex-direction: column; gap: var(--space-1); }
.replan-diagnostic-callout__eyebrow {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
}
.replan-diagnostic-callout__line {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 0;
}
.replan-diagnostic-callout__source { color: var(--text-muted); font-style: italic; }

/* --- Cohort strip (bottom of retrospective pane) ------------- */

.replan-cohort-strip {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
}
.replan-cohort-strip__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
}
.replan-cohort-strip__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.replan-cohort-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
  min-width: 96px;
}
.replan-cohort-chip__subject {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-secondary);
}
.replan-cohort-chip__delta {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.replan-cohort-chip__delta[data-direction="up"]   { color: var(--success); }
.replan-cohort-chip__delta[data-direction="down"] { color: var(--warning-strong); }
.replan-cohort-chip__delta[data-direction="flat"] { color: var(--text-secondary); }
.replan-cohort-chip__delta--building {
  color: var(--text-muted);
  font-style: italic;
}
.replan-cohort-strip__source {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
  margin: 0;
}

/* --- "How {first} learns" — evidence moved from the retired Syllabus.
   Observed patterns only; feeds next-year intent. ------------------- */
.replan-learning__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
}
.replan-learning__card--empty {
  color: var(--text-muted);
  font-style: italic;
}
.replan-learning__row {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.replan-learning__tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
}
.replan-learning__tag i {
  width: 14px;
  height: 14px;
}
.replan-learning__text {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.5;
}
.replan-learning__text strong {
  color: var(--text-primary);
}
.replan-learning__foot {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--info) 8%, transparent);
  border: var(--glass-border-width) solid color-mix(in srgb, var(--info) 20%, transparent);
  font-size: var(--text-sm);
  font-style: italic;
  color: var(--text-secondary);
  line-height: 1.5;
}
.replan-learning__foot-icon {
  color: var(--info);
  flex-shrink: 0;
  margin-top: 2px;
}
.replan-learning__foot-icon i { width: 14px; height: 14px; }

/* --- Right pane: Plan ---------------------------------------- */

.replan-plan {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-5);
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg);
}
.replan-plan__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.replan-plan__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.replan-plan__hint {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}
.replan-plan-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.replan-plan-section__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent-secondary);
  margin: 0;
}

/* --- Plan subject card (per-subject) ------------------------- */

.replan-plan-subject-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-left-width: var(--space-1);
  border-left-color: transparent;
}
.replan-plan-subject-card[data-level="advance"]  { border-left-color: var(--accent-primary); }
.replan-plan-subject-card[data-level="remedial"] { border-left-color: var(--warning); }
.replan-plan-subject-card__head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-3);
}
.replan-plan-subject-card__identity {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.replan-plan-subject-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-md);
  background: var(--surface-glass);
  color: var(--accent-primary);
}
.replan-plan-subject-icon i { width: 18px; height: 18px; }
.replan-plan-subject-card__title {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.replan-plan-subject-card__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-6);
  height: var(--space-6);
  border: none;
  background: transparent;
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.replan-plan-subject-card__remove:hover {
  color: var(--text-primary);
  background: var(--surface-glass-strong);
}
.replan-plan-subject-card__remove i { width: 16px; height: 16px; }

.replan-plan-subject-card__pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.replan-plan-subject-grade-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
}
.replan-plan-subject-grade-pill__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.replan-plan-subject-grade-pill__select {
  appearance: none;
  background: transparent;
  border: none;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
  cursor: pointer;
  padding-right: var(--space-3);
}
.replan-plan-subject-grade-pill__select:focus {
  outline: none;
}

.replan-plan-subject-level-pill {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: var(--radius-pill);
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
}
/* Level is a select now, shaped like the Grade pill beside it (the tri-state
   buttons were a second, bespoke segmented control doing the same job). The
   per-level colour the active button used to carry moves onto the pill, keyed
   off the CARD's data-level — so the chosen level still reads without opening
   the menu, which is the one thing a select would otherwise cost. */
.replan-plan-subject-level-pill__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.replan-plan-subject-level-pill__select {
  appearance: none;
  background: transparent;
  border: none;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  cursor: pointer;
  padding-right: var(--space-3);
}
.replan-plan-subject-level-pill__select:focus { outline: none; }
.replan-plan-subject-card[data-level="remedial"] .replan-plan-subject-level-pill {
  background: color-mix(in srgb, var(--warning) 22%, transparent);
}
.replan-plan-subject-card[data-level="remedial"] .replan-plan-subject-level-pill__select {
  color: var(--warning-strong);
}
.replan-plan-subject-card[data-level="standard"] .replan-plan-subject-level-pill {
  background: var(--surface-glass-strong);
}
.replan-plan-subject-card[data-level="advance"] .replan-plan-subject-level-pill {
  background: color-mix(in srgb, var(--accent-primary) 22%, transparent);
}
.replan-plan-subject-card[data-level="advance"] .replan-plan-subject-level-pill__select {
  color: var(--accent-primary);
}

.replan-plan-subject-card__work-summary {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 0;
}

/* --- Add-subject affordances --------------------------------- */

.replan-plan-add-subject-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 1px dashed var(--border-glass);
  border-radius: var(--radius-md);
  background: transparent;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  cursor: pointer;
  width: 100%;
}
.replan-plan-add-subject-btn:hover {
  color: var(--accent-primary);
  border-color: var(--accent-primary);
}
.replan-plan-add-subject-btn i { width: 14px; height: 14px; }

.replan-plan-add-subject-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
}
.replan-plan-add-subject-form__actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-2);
}

/* === end v2 marker — v1 .replan-retro-mastery / interests / */
/* === baselines / move-palette popover deleted (replaced by  */
/* === per-subject cards + cohort strip above).               */


/* --- Sticky commit ribbon ---------------------------------------- */

.replan-commit-ribbon {
  position: sticky;
  bottom: 0;
  z-index: 10;
  margin-top: var(--space-5);
  background: var(--surface-glass-strong);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-top: 1px solid var(--border-glass);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: var(--space-4) var(--space-5);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-5);
}
.replan-commit-ribbon__summary {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
.replan-commit-ribbon__divider {
  width: 1px;
  height: var(--space-7);
  background: var(--border-glass);
}
.replan-commit-ribbon__metric { display: flex; flex-direction: column; gap: 2px; }
.replan-commit-ribbon__metric--muted { opacity: 0.7; }
.replan-commit-ribbon__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.replan-commit-ribbon__value {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.replan-commit-ribbon__value[data-direction="up"]   { color: var(--warning-strong); }  /* more hours = load signal, not error */
.replan-commit-ribbon__value[data-direction="down"] { color: var(--success); }          /* fewer hours intentional too */
.replan-commit-ribbon__value[data-direction="flat"] { color: var(--text-primary); }
.replan-commit-ribbon__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* ==========================================================================
   Teleprompter Overlay (per docs/ui-specs/teleprompter-overlay.md §6)
   ONE responsive system, three breakpoint shapes per PICKS §4:
     ≥1280   — full-screen takeover centered in dim scrim
     768-1280 — side-panel right-45% (attempts page visible left)
     ≤768    — bottom-sheet with drag handle
   Reuses .btn / .card / .field foundation from sessions 8 / 9 / 11 / 12.
   Zero new design tokens.
   ========================================================================== */

/* --- Attempts page mount CTA ------------------------------------- */

/* Per-card "Help me explain this" — a quiet secondary button that sits
   inside an incorrect card's diagnosis (the CTA moved off the page header
   so it can carry THIS card's misconception into the Teleprompter). */
.attempt-question__explain-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  align-self: flex-start;
  margin-top: var(--space-1);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--accent-primary);
  background: color-mix(in srgb, var(--info) 8%, transparent);
  border: var(--glass-border-width) solid color-mix(in srgb, var(--info) 24%, transparent);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--duration-base) var(--ease-out);
}
.attempt-question__explain-cta:hover {
  background: color-mix(in srgb, var(--info) 16%, transparent);
}
.attempt-question__explain-cta i {
  width: 15px;
  height: 15px;
}

/* --- Scrim + shell ----------------------------------------------- */

.teleprompter-scrim {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: color-mix(in srgb, var(--text-primary) 20%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  padding: var(--space-5);
  /* Default = full-screen takeover (≥1280): center the card */
  justify-content: center;
  align-items: center;
}

.teleprompter {
  background: var(--surface-glass-strong);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border: 1px solid var(--border-glass);
  box-shadow: 0 20px 60px color-mix(in srgb, var(--text-primary) 30%, transparent);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Default (≥1280): rounded card */
  width: 100%;
  max-width: 1024px;
  max-height: calc(100vh - var(--space-8));
  border-radius: var(--radius-lg);
  animation: teleprompter-slide-up 0.4s cubic-bezier(0.33, 1, 0.68, 1);
}

@keyframes teleprompter-slide-up {
  from { opacity: 0; transform: translateY(var(--space-5)); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --- 768-1280 — side-panel right-45% --- */
@media (max-width: 1280px) and (min-width: 768px) {
  .teleprompter-scrim {
    justify-content: flex-end;
    align-items: stretch;
    padding: 0;
  }
  .teleprompter {
    width: 45%;
    max-width: none;
    height: 100vh;
    max-height: none;
    border-left: 1px solid var(--border-glass);
    border-radius: 0;
  }
}

/* --- ≤768 — bottom sheet --- */
@media (max-width: 768px) {
  .teleprompter-scrim {
    align-items: flex-end;
    justify-content: stretch;
    padding: 0;
  }
  .teleprompter {
    width: 100%;
    max-width: none;
    max-height: 90vh;
    border-top-left-radius: var(--radius-lg);
    border-top-right-radius: var(--radius-lg);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
  }
  /* Drag handle visual cue (pure CSS — no JS drag in V1) */
  .teleprompter::before {
    content: '';
    display: block;
    width: var(--space-7);
    height: 4px;
    background: var(--border-glass);
    border-radius: var(--radius-pill);
    margin: var(--space-2) auto 0;
    flex-shrink: 0;
  }
}

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

.teleprompter__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border-glass);
  background: color-mix(in srgb, var(--surface-glass-strong) 100%, white 4%);
}
.teleprompter__identity {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.teleprompter__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  border-radius: var(--radius-pill);
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  color: var(--accent-primary);
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  overflow: hidden;
}
.teleprompter__identity-block { display: flex; flex-direction: column; gap: 2px; }
.teleprompter__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
  margin: 0;
}
.teleprompter__hint {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0;
}
.teleprompter__pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  background: var(--surface-glass-strong);
}
.teleprompter__pill[data-state="in_session"]     { color: var(--warning-strong); }
.teleprompter__pill[data-state="self_initiated"] { color: var(--text-secondary); }
.teleprompter__pill-dot {
  width: var(--space-2);
  height: var(--space-2);
  border-radius: var(--radius-pill);
}
.teleprompter__pill[data-state="in_session"]     .teleprompter__pill-dot { background: var(--warning); }
.teleprompter__pill[data-state="self_initiated"] .teleprompter__pill-dot { background: var(--text-muted); }
.teleprompter__unit {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.teleprompter__dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-7);
  height: var(--space-7);
  background: transparent;
  border: none;
  color: var(--text-muted);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background 0.15s ease;
}
.teleprompter__dismiss:hover {
  background: var(--surface-glass-strong);
  color: var(--text-primary);
}

/* --- Body (scrollable) ------------------------------------------ */

.teleprompter__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-5);
  overflow-y: auto;
  flex: 1;
}
.teleprompter__split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
@media (max-width: 1024px) {
  .teleprompter__split { grid-template-columns: 1fr; }
}

/* --- Concept TL;DR --------------------------------------------- */

.teleprompter-concept {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-width: 70ch;
}
.teleprompter-concept__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.teleprompter-concept__icon {
  color: var(--accent-primary);
  font-size: var(--text-xl);
}
.teleprompter-concept__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.teleprompter-concept__body {
  font-size: var(--text-base);
  color: var(--text-secondary);
  line-height: 1.6;
  margin: 0;
}
.teleprompter-concept__keyword {
  color: var(--accent-primary);
  font-weight: var(--weight-bold);
}

/* --- Misconception card --------------------------------------- */

.teleprompter-misconception {
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
  border-left: var(--space-1) solid var(--warning);   /* warm-amber, NEVER red */
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.teleprompter-misconception[data-has-misconception="false"] {
  border-left-color: var(--text-muted);   /* calm muted edge when no misconception */
}
.teleprompter-misconception__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--warning-strong);
}
.teleprompter-misconception[data-has-misconception="false"] .teleprompter-misconception__head {
  color: var(--text-muted);
}
.teleprompter-misconception__icon { font-size: var(--text-base); }
.teleprompter-misconception__title {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin: 0;
}
.teleprompter-misconception__body {
  font-size: var(--text-base);
  color: var(--text-primary);
  line-height: 1.55;
  margin: 0;
}
.teleprompter-misconception__empty {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-style: italic;
  margin: 0;
}
.teleprompter-misconception__example {
  background: var(--surface-glass-strong);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: center;
  text-align: center;
  margin: 0;
}
.teleprompter-misconception__example-wrong {
  font-family: monospace;
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  text-decoration: line-through;
  text-decoration-thickness: 2px;
  opacity: 0.7;
}
.teleprompter-misconception__example-caption {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
}

/* --- Coaching Questions card --------------------------------- */

.teleprompter-coaching {
  background: var(--surface-glass);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.teleprompter-coaching__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--accent-primary);
}
.teleprompter-coaching__icon { font-size: var(--text-base); }
.teleprompter-coaching__title {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent-primary);
  margin: 0;
}
.teleprompter-coaching__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.teleprompter-coaching__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}
.teleprompter-coaching__index {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
  min-width: var(--space-5);
}
.teleprompter-coaching__prompt {
  font-size: var(--text-base);
  color: var(--text-primary);
  line-height: 1.5;
  margin: 0;
}

/* --- Session Timeline + Buffer indicator -------------------- */

.teleprompter-timeline {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.teleprompter-timeline__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text-secondary);
}
.teleprompter-timeline__icon { font-size: var(--text-base); }
.teleprompter-timeline__title {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin: 0;
}
.teleprompter-timeline__list {
  list-style: none;
  padding-left: var(--space-7);
  margin: 0;
  position: relative;
}
.teleprompter-timeline__list::before {
  content: '';
  position: absolute;
  left: calc(var(--space-3) + var(--space-base));
  top: var(--space-3);
  bottom: var(--space-3);
  width: 2px;
  background: var(--border-glass);
}
.teleprompter-timeline__event {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding-block: var(--space-3);
  position: relative;
}
.teleprompter-timeline__dot {
  position: absolute;
  left: calc((var(--space-base) * -1) - var(--space-5));
  top: calc(var(--space-3) + var(--space-1));
  width: var(--space-3);
  height: var(--space-3);
  border-radius: var(--radius-pill);
  box-shadow: 0 0 0 var(--space-base) var(--surface-glass-strong);
}
/* Per-event-type dot color cascade per §6. NO --error red anywhere
   — even wrong attempts pull warm-amber per the productive-struggle
   framing. */
.teleprompter-timeline__event[data-event-type="attempt_wrong"]            .teleprompter-timeline__dot { background: var(--warning-strong); }
.teleprompter-timeline__event[data-event-type="attempt_partial"]          .teleprompter-timeline__dot { background: var(--warning); }
.teleprompter-timeline__event[data-event-type="attempt_right"]            .teleprompter-timeline__dot { background: var(--success); }
.teleprompter-timeline__event[data-event-type="system_socratic_prompt"]   .teleprompter-timeline__dot { background: var(--info); }
.teleprompter-timeline__event[data-event-type="hint_token_spent"]         .teleprompter-timeline__dot { background: var(--warning); }
.teleprompter-timeline__event[data-event-type="buffer_exhausted_resolved"] .teleprompter-timeline__dot { background: var(--success); }
.teleprompter-timeline__event[data-event-type="escalated_to_parent"]      .teleprompter-timeline__dot { background: var(--accent-primary); }
.teleprompter-timeline__event-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
}
.teleprompter-timeline__event-label {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.teleprompter-timeline__event-label[data-event-type="attempt_wrong"]            { color: var(--warning-strong); }
.teleprompter-timeline__event-label[data-event-type="attempt_partial"]          { color: var(--warning-strong); }
.teleprompter-timeline__event-label[data-event-type="attempt_right"]            { color: var(--success); }
.teleprompter-timeline__event-label[data-event-type="system_socratic_prompt"]   { color: var(--info); }
.teleprompter-timeline__event-label[data-event-type="hint_token_spent"]         { color: var(--warning-strong); }
.teleprompter-timeline__event-label[data-event-type="buffer_exhausted_resolved"] { color: var(--success); }
.teleprompter-timeline__event-label[data-event-type="escalated_to_parent"]      { color: var(--accent-primary); }
.teleprompter-timeline__event-time {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.teleprompter-timeline__event-detail {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-style: italic;
  margin: 0;
  line-height: 1.5;
}
.teleprompter-timeline__inline-code {
  font-family: monospace;
  font-size: var(--text-sm);
  background: var(--surface-glass-strong);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
}
.teleprompter-timeline__event-chip {
  display: inline-flex;
  align-self: flex-start;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  border-radius: var(--radius-pill);
  padding: 2px var(--space-3);
}
.teleprompter-timeline__event-chip[data-event-type="hint_token_spent"] {
  color: var(--warning-strong);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--warning) 30%, transparent);
}
.teleprompter-timeline__empty {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-style: italic;
  text-align: center;
  padding: var(--space-5) 0;
  margin: 0;
}

.teleprompter-buffer {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-glass);
  font-size: var(--text-xs);
}
.teleprompter-buffer[data-state="respected_system_paged"]      { color: var(--text-secondary); }
.teleprompter-buffer[data-state="respected_system_paged"]      .teleprompter-buffer__icon { color: var(--success); }
.teleprompter-buffer[data-state="still_in_buffer_system_paged"] { color: var(--warning-strong); }
.teleprompter-buffer[data-state="still_in_buffer_system_paged"] .teleprompter-buffer__icon { color: var(--warning-strong); }
.teleprompter-buffer[data-state="self_initiated"]              { color: var(--text-muted); }
.teleprompter-buffer[data-state="self_initiated"]              .teleprompter-buffer__icon { color: var(--text-muted); }
.teleprompter-buffer[data-state="unknown_pre_agency_event"]    { color: var(--text-muted); }
.teleprompter-buffer[data-state="unknown_pre_agency_event"]    .teleprompter-buffer__icon { color: var(--info); }

/* --- Action footer ---------------------------------------------- */

.teleprompter-footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--border-glass);
  background: color-mix(in srgb, var(--surface-glass-strong) 100%, white 6%);
}
.teleprompter-footer__primary {
  display: flex;
  gap: var(--space-3);
}
@media (max-width: 768px) {
  .teleprompter-footer__primary {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}
.teleprompter-footer__mark-resolved { flex: 1; min-height: var(--space-7); }
.teleprompter-footer__log           { flex: 2; min-height: var(--space-7); }
.teleprompter-footer__escalate {
  display: inline-flex;
  align-self: center;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  text-decoration: none;
  padding: var(--space-2) var(--space-3);
  transition: color 0.15s ease;
}
.teleprompter-footer__escalate:hover {
  color: var(--accent-primary);
  text-decoration: underline;
}

/* --- Confirmation chip (after Log / Mark-resolved) ------------ */

.teleprompter-footer--confirmed {
  align-items: stretch;
}
.teleprompter-footer__confirmed {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  background: color-mix(in srgb, var(--success) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--success) 30%, transparent);
  border-radius: var(--radius-md);
}
.teleprompter-footer__confirmed-icon {
  color: var(--success);
  font-size: var(--text-xl);
}
.teleprompter-footer__confirmed-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.teleprompter-footer__confirmed-label {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--success);
}
.teleprompter-footer__confirmed-detail {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.5;
}

/* ==========================================================================
   Parent Schedule — Week view (parent-schedule.md §5d/§6, Phase 1)
   Tokens only. Year view + absence classes land with later phases.
   ========================================================================== */
.parent-schedule {
  max-width: var(--content-max-width); margin-inline: auto;
  padding-block: var(--space-5);
}
/* Per-student review panel — horizon / weekly-review / hurdles folded in
   from the retired Parent Dashboard. Sits below the family-wide grids,
   scoped to the VIEWING student; reuses .fact / .hurdle / .horizon-alert /
   .status-pill. */
.psched-review {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-glass);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.psched-review__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.psched-review__eyebrow {
  display: block;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--weight-bold);
  color: var(--text-muted);
}
.psched-review__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
  margin: 0;
}
.psched-review__facts { margin: 0; }
.parent-schedule__header {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: var(--space-4); margin-bottom: var(--space-4);
}
.parent-schedule__eyebrow {
  font-size: var(--text-xs); color: var(--text-muted);
  font-weight: var(--weight-medium); text-transform: uppercase;
  letter-spacing: var(--track-eyebrow);
}
.parent-schedule__title {
  margin: var(--space-1) 0 0; font-size: var(--text-xl);
  font-weight: var(--weight-bold); color: var(--text-primary);
}
.parent-schedule__subtitle {
  margin: var(--space-1) 0 0; font-size: var(--text-sm);
  color: var(--text-secondary); max-width: 60ch;
}

/* .view-toggle / __btn / --active reuse the shared toggle component
   (defined earlier). The Schedule toggle is a pure Week/Year zoom — the old
   Today handoff variant was removed when "today" consolidated onto the FCC. */
.view-toggle__btn--disabled { color: var(--text-muted); cursor: default; }

.week-view { display: flex; flex-direction: column; gap: var(--space-4); }

/* === Week flow: Reconcile → Set ===========================================
   The catch-up strip + its popover lived here and are retired with the split
   (see parent_schedule_week_grid.html for why the chips are not re-drawn on
   the planning screen). What follows is the two-step chrome and step 1.        */

/* The step rail. Numbered, not tabbed: these are ordered halves of one weekly
   job, and a segmented control would say they are interchangeable views. */
.week-steps {
  display: flex; gap: var(--space-2); list-style: none;
  margin: 0 0 var(--space-4); padding: 0;
}
.week-steps__step a {
  display: flex; align-items: baseline; gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border-glass); border-radius: var(--radius-md);
  background: var(--surface-glass); color: var(--text-secondary);
  font-size: var(--text-sm); text-decoration: none;
}
.week-steps__step a:hover { color: var(--text-primary); }
.week-steps__step--active a {
  background: var(--surface-glass-strong); color: var(--text-primary);
  border-color: var(--border-glass); font-weight: var(--weight-medium);
}
.week-steps__n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.4em; height: 1.4em; border-radius: var(--radius-pill);
  background: var(--surface-glass-strong); color: var(--text-secondary);
  font-size: var(--text-xs); font-weight: var(--weight-medium);
}
.week-steps__step--active .week-steps__n { background: var(--info); color: var(--text-on-accent); }
.week-steps__hint { font-size: var(--text-xs); color: var(--text-muted); }

/* Step 2's pointer back at step 1. Amber, never red — an undecided item is a
   loose end, not an error (locked rule: --error appears in no family flow). */
.week-view__unreconciled { margin: 0; }
.week-view__unreconciled a {
  display: inline-block; padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--warning); border-radius: var(--radius-sm);
  background: var(--surface-glass); color: var(--text-secondary);
  font-size: var(--text-sm); text-decoration: none;
}
.week-view__unreconciled a:hover { color: var(--text-primary); }

/* Step 1 — Reconcile. */
.reconcile { display: flex; flex-direction: column; gap: var(--space-4); }
.reconcile__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap;
}
.reconcile__title { margin: 0; font-size: var(--text-lg); color: var(--text-primary); }
.reconcile__sub { margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--text-secondary); }
.reconcile__count { margin: 0; font-size: var(--text-sm); color: var(--text-muted); }
.reconcile__count[data-open="true"] { color: var(--warning); }

.reconcile-student {
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg); padding: var(--space-4);
}
.reconcile-student__head {
  position: relative;
  display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
.reconcile-student__name { margin: 0; font-size: var(--text-base); color: var(--text-primary); }
.reconcile-student__tally { font-size: var(--text-sm); color: var(--text-secondary); }
.reconcile-student__absence {
  margin-left: auto; font-size: var(--text-xs); color: var(--text-muted);
}
.reconcile-student__absence:hover { color: var(--text-secondary); }
.reconcile-student__clear { margin: 0; font-size: var(--text-sm); color: var(--text-muted); }

.reconcile-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.reconcile-item {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-glass-strong); border-radius: var(--radius-md);
}
.reconcile-item__icon { font-size: var(--text-base); }
.reconcile-item__title { flex: 1 1 12rem; font-size: var(--text-sm); color: var(--text-primary); }
.reconcile-item__day { font-size: var(--text-xs); color: var(--text-muted); }
.reconcile-item__state { font-size: var(--text-xs); color: var(--text-secondary); }
/* Started = evidence exists (info); Not started = a loose end (warning). */
.reconcile-item[data-state="partial"] .reconcile-item__state { color: var(--info); }
.reconcile-item[data-state="not_started"] .reconcile-item__state { color: var(--warning); }
.reconcile-item__verbs { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.reconcile-verb { font-size: var(--text-xs); padding: var(--space-1) var(--space-3); }

.reconcile__seam {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap;
  padding-top: var(--space-4); border-top: 1px solid var(--border-glass);
}
.reconcile__seam-text { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }

/* The Week grid's COLUMN axis is family size, which is unbounded — the Rivera
   demo family is 7 children. With `width: 100%` the fixed table divided the
   viewport by student count, so each column collapsed to ~180px, every lesson
   title wrapped to three lines, and the grid ran 9,329px tall: 15 viewports to
   read one week. The height was a squeeze artifact, not a data problem — at a
   readable column width the same 148 items render in 5,869px.
   `parent-schedule.md` §2 already prescribed the fix ("scales 1-5 student
   columns gracefully and adds horizontal scroll above 5"); it was never built.
   This is that scroll: columns hold a readable floor and the grid grows
   sideways instead of downward. Trading vertical for horizontal is safe here
   precisely because the spec forbids cross-sibling comparison — every metric in
   the grid (capacity, hurdles, catch-up) is within-student, so no reading of
   this surface requires two children on screen at once.
   The wrapper is focusable (`tabindex="0"` + `role="region"`) so a keyboard-only
   parent can reach the horizontal scroll. */
.psched-week-scroll { overflow-x: auto; }
.psched-week-grid { min-width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: var(--space-1); }
/* Readable floor per student column. Titles run to a 43-char p90, so this keeps
   the common case at one or two lines; below ~200px it degrades to three. */
.psched-week-grid__student-th, .week-cell { min-width: 215px; }
.psched-week-grid__day-th { width: 96px; }
/* Once the grid scrolls sideways the day labels are the only thing anchoring a
   row, so they pin to the left edge instead of scrolling out of view. They take
   the chrome glass tier (not the plain one) for the same reason the nav does:
   cells slide underneath them, and mid-opacity glass let the passing lesson
   titles read straight through the day name. */
.psched-week-grid__day-th, .psched-week-grid__day-cell {
  position: sticky; left: 0; z-index: 1;
  /* The day rail needs to OCCLUDE (cells slide under it) without ADVANCING.
     It used --surface-glass-chrome, the densest tier, reserved for nav — so
     the axis label was the brightest thing on the page while the student
     columns, which are the actual content, sat on the plain tier and receded.
     That is the hierarchy backwards. `--surface-glass-strong` still occludes
     at 24px blur; the muted label colour below does the rest of the demotion. */
  background: var(--surface-glass-strong);
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
}
.psched-week-grid__day-th, .psched-week-grid__student-th {
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  padding: var(--space-2); text-align: left;
  vertical-align: bottom;
}
/* Axis label: recedes. */
.psched-week-grid__day-th { color: var(--text-muted); }
/* Column identity: advances, and PINS. The grid runs ~3,100px tall at seven
   children, so an unpinned header meant the student names scrolled away and
   every column below the fold was anonymous — you could read a cell without
   knowing whose week it was. Sticky on the other axis from the day rail, at a
   higher z-index so the two cross cleanly at the corner. */
.psched-week-grid__student-th {
  position: sticky; top: 0; z-index: 2;
  color: var(--text-secondary);
  background: var(--surface-glass-strong);
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.psched-week-grid__day-th { z-index: 3; }   /* the corner cell wins both axes */
.psched-week-grid__student-name { font-weight: var(--weight-bold); color: var(--text-primary); }

/* The parent column — a PEER of the children, so it inherits the sticky header
   and the column rhythm rather than sitting apart as a summary widget. It is
   set narrower than a student column and never carries lesson cards: it holds
   one modelled number, and giving it a child's width would imply a child's
   precision. */
.psched-week-grid__parent-th {
  position: sticky; top: 0; z-index: 2;
  min-width: 150px; text-align: left;
  color: var(--text-secondary);
  background: var(--surface-glass-strong);
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  border-left: 1px solid var(--border-glass);
}
.psched-week-grid__parent-total {
  display: block; font-size: var(--text-xs); color: var(--text-muted);
}
.psched-week-grid__parent-cell {
  min-width: 150px; vertical-align: top; padding: var(--space-2);
  text-align: left;
  border-left: 1px solid var(--border-glass);
}
.psched-week-grid__parent-mins {
  display: block; font-size: var(--text-sm); color: var(--text-secondary);
}
/* Heavy = amber, never red. A heavy day for the adult is a thing to SEE and
   rebalance, not a failure — same rule as the capacity bars (§Locked rules). */
.psched-week-grid__parent-cell[data-heavy="true"] .psched-week-grid__parent-mins {
  color: var(--warning);
}
.psched-week-grid__parent-mins--free { color: var(--text-muted); }
.psched-week-grid__parent-detail {
  display: block; font-size: var(--text-xs); color: var(--text-muted);
  margin-top: var(--space-1);
}
.psched-week-grid__parent-cell--foot { vertical-align: top; }
.psched-week-grid__day-cell {
  /* Background lives with the sticky rule above — it needs the chrome tier. */
  width: 96px; font-size: var(--text-sm);
  border-radius: var(--radius-md); padding: var(--space-2);
  vertical-align: top; text-align: left;
}
.psched-week-grid__day-name { font-weight: var(--weight-medium); color: var(--text-primary); }

.week-cell {
  background: var(--surface-glass); border-radius: var(--radius-md);
  padding: var(--space-2); vertical-align: top;
}
.week-cell__capacity { display: flex; flex-direction: column; gap: var(--space-1); margin-bottom: var(--space-2); }
.week-cell__capacity-text { font-size: var(--text-xs); color: var(--text-muted); }
.week-cell__capacity-text[data-load-state="warning"] { color: var(--warning); }
.week-cell__capacity-text[data-load-state="overload"] { color: var(--warning-strong); }
.week-cell__capacity-track {
  height: var(--space-1); background: var(--surface-glass-strong);
  border-radius: var(--radius-pill); overflow: hidden;
}
.week-cell__capacity-fill {
  height: 100%; width: var(--pct); max-width: 100%;
  background: var(--accent-secondary); border-radius: var(--radius-pill);
}
.week-cell__capacity-fill[data-load-state="warning"] { background: var(--warning); }
.week-cell__capacity-fill[data-load-state="overload"] { background: var(--warning-strong); }
.week-cell__items { display: flex; flex-direction: column; gap: var(--space-2); list-style: none; padding: 0; margin: 0; }
.week-cell__item {
  display: flex; gap: var(--space-1); align-items: center; flex-wrap: wrap;
  background: var(--surface-glass-strong); border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
}
.week-cell__item-title { font-size: var(--text-sm); color: var(--text-primary); flex-grow: 1; }
.week-cell__item-mins { font-size: var(--text-xs); color: var(--text-muted); }
.week-cell__move {
  font-size: var(--text-xs); background: var(--surface-glass-strong);
  color: var(--text-secondary); border-radius: var(--radius-sm);
  border: 1px solid var(--border-glass); padding: var(--space-1); flex-basis: 100%;
}
.week-cell__empty { font-size: var(--text-xs); color: var(--text-muted); list-style: none; }

.psched-week-grid__hurdle-cell { font-size: var(--text-xs); color: var(--text-secondary); vertical-align: top; padding: var(--space-2); }
.hurdle-tag {
  display: inline-flex; font-size: var(--text-xs);
  background: var(--surface-glass); border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-2); color: var(--warning-strong);
  text-decoration: none; margin: 0 var(--space-1) var(--space-1) 0;
}
.hurdle-tag:hover { box-shadow: var(--shadow-glow); }
.hurdle-tag--empty { color: var(--text-muted); }

/* The ribbon had no `z-index` while the sticky day column has `z-index: 1`,
   so the pinned day cells painted OVER it and clipped its left edge — the
   summary text read as truncated mid-sentence. It now adopts
   `.replan-commit-ribbon`'s treatment (z-index 10, top-rounded, margin-top),
   which is the established sticky-ribbon pattern on the sibling surfaces.

   `bottom` is negative on purpose. `.shell__main` is the scroll container and
   carries `padding: var(--space-7)`, and Chrome clamps a sticky element to the
   scrollport's CONTENT box — so `bottom: 0` docked it 48px above the viewport
   edge, floating over the grid instead of sitting on the bottom of the window.
   Cancelling the padding puts it flush. It is tied to `--space-7` by name so
   the two cannot drift. */
.commit-ribbon {
  position: sticky;
  bottom: calc(-1 * var(--space-7));
  z-index: 10;
  margin-top: var(--space-5);
  background: var(--surface-glass-chrome);
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  border-top: 1px solid var(--border-glass);
  /* Rounded on ALL FOUR corners, not just the top two.
     The ribbon has two states and they need different bottoms:
       stuck   — docked flush to the viewport (bottom: -48px cancels the
                 scroller's padding), so its lower 48px is below the scrollport
                 and the bottom corners are never seen.
       resting — scrolled to the end, it sits in normal flow with ~72px of page
                 below it, and the negative offset no longer applies.
     Top-only rounding was right for the first and made the second read as a
     torn edge — a square bottom with visible page beneath it looks clipped.
     Rounding all four is correct in both: invisible when docked, finished when
     at rest. */
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-5);
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-3);
}
.commit-ribbon form { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); width: 100%; }
.commit-ribbon__summary { font-size: var(--text-sm); color: var(--text-secondary); }

/* ==========================================================================
   Parent Schedule — Year view (parent-schedule.md §5b/§6, Phase 2)
   ========================================================================== */
.year-view { display: flex; flex-direction: column; gap: var(--space-4); }
.year-view__current { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--text-secondary); }
.year-view__current-week { font-weight: var(--weight-bold); color: var(--accent-primary); }

.year-strip {
  display: grid; grid-template-columns: repeat(40, minmax(0, 1fr));
  gap: var(--space-1); padding: var(--space-3) 0;
}
.year-cell {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-md); padding: var(--space-2) 2px;
  cursor: pointer; color: var(--text-secondary);
  transition: box-shadow var(--duration-fast), transform var(--duration-fast);
  min-height: var(--space-8);
}
.year-cell:hover { box-shadow: var(--shadow-glow); transform: translateY(-1px); }
.year-cell[data-kind="holiday"] { background: color-mix(in srgb, var(--text-muted) 14%, var(--surface-glass)); }
.year-cell[data-kind="sprint"] { background: color-mix(in srgb, var(--warning-strong) 20%, var(--surface-glass)); }
.year-cell[data-kind="family_event"] { background: color-mix(in srgb, var(--accent-secondary) 15%, var(--surface-glass)); }
.year-cell[data-current="true"] { border-bottom: 2px solid var(--accent-primary); }
.year-cell__num { font-size: var(--text-xs); color: var(--text-muted); font-weight: var(--weight-medium); }
.year-cell__kind-glyph { font-size: var(--text-sm); }
.year-cell__intensity { font-size: var(--text-xs); color: var(--warning-strong); font-weight: var(--weight-bold); }
.year-cell__overrides { display: flex; gap: 2px; }
.year-cell__dot { width: var(--space-1); height: var(--space-1); border-radius: var(--radius-pill); background: var(--accent-secondary); }
.year-cell__label { font-size: var(--text-xs); color: var(--text-secondary); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.year-view__range { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); font-size: var(--text-xs); color: var(--text-muted); }
.year-view__range-rule { flex: 1; height: 1px; background: var(--border-glass); }
.year-view__legend { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.legend-chip { font-size: var(--text-xs); background: var(--surface-glass-strong); border-radius: var(--radius-pill); padding: var(--space-1) var(--space-2); color: var(--text-secondary); }
.year-view__summary { font-size: var(--text-sm); color: var(--text-secondary); margin: 0; }

.year-cell-edit {
  display: block; margin: var(--space-3) 0; max-width: 480px;
  background: var(--surface-glass-strong); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg); padding: var(--space-4); box-shadow: var(--shadow-glow);
}
.year-cell-edit__title { font-size: var(--text-lg); font-weight: var(--weight-bold); color: var(--text-primary); margin: 0 0 var(--space-3); }
.year-cell-edit__kinds { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-2); border: 0; padding: 0; margin: 0 0 var(--space-3); }
.kind-radio { display: flex; align-items: center; gap: var(--space-2); background: var(--surface-glass); border: 1px solid var(--border-glass); border-radius: var(--radius-md); padding: var(--space-2); cursor: pointer; }
.kind-radio--selected { border-color: var(--accent-primary); background: var(--surface-glass-strong); }
.kind-radio__label { font-size: var(--text-sm); color: var(--text-primary); }
.year-cell-edit__label-row, .year-cell-edit__intensity-row { display: flex; flex-direction: column; gap: var(--space-1); margin-bottom: var(--space-3); font-size: var(--text-sm); color: var(--text-secondary); }
.year-cell-edit__label-row input[type="text"] { background: var(--surface-glass-strong); border: 1px solid var(--border-glass); border-radius: var(--radius-sm); padding: var(--space-2); color: var(--text-primary); }
.year-cell-edit__intensity-row output { font-size: var(--text-xs); color: var(--text-muted); }
.year-cell-edit__actions { display: flex; justify-content: flex-end; gap: var(--space-2); }

/* ==========================================================================
   Parent Schedule — per-student absence (parent-schedule.md §5g, Phase 3)
   ========================================================================== */
.psched-week-grid__log-absence {
  display: block; font-size: var(--text-xs); color: var(--text-muted);
  text-decoration: underline dotted; margin-top: var(--space-1);
}
.psched-week-grid__log-absence:hover { color: var(--accent-primary); }
.absence-popover-mount { position: relative; }
.absence-popover {
  position: absolute; z-index: 20; min-width: 240px; margin-top: var(--space-2);
  background: var(--surface-glass-strong); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg); padding: var(--space-4); box-shadow: var(--shadow-glow);
}
.absence-popover__title { font-size: var(--text-base); font-weight: var(--weight-bold); color: var(--text-primary); margin: 0 0 var(--space-3); }
.absence-popover__row { display: flex; flex-direction: column; gap: var(--space-1); margin-bottom: var(--space-2); font-size: var(--text-sm); color: var(--text-secondary); }
.absence-popover__row input {
  background: var(--surface-glass-strong); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); padding: var(--space-2); color: var(--text-primary);
}
.absence-popover__kinds { display: flex; flex-direction: column; gap: var(--space-1); border: 0; padding: 0; margin: 0 0 var(--space-2); font-size: var(--text-sm); color: var(--text-secondary); }
.absence-popover__actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }

.week-cell[data-state="absent"] { background: color-mix(in srgb, var(--text-muted) 14%, var(--surface-glass)); }
.week-cell__absence { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-2) 0; }
.week-cell__absence-label { font-size: var(--text-sm); color: var(--text-secondary); font-style: italic; }
.week-cell__absence-clear {
  background: var(--surface-glass-strong); border: 1px solid var(--border-glass);
  border-radius: var(--radius-pill); color: var(--text-secondary);
  width: var(--space-5); height: var(--space-5); line-height: 1; cursor: pointer; flex: 0 0 auto;
}
.week-cell__absence-clear:hover { color: var(--warning); }

/* Parent Schedule — Week navigation stepper (Phase 3 follow-up) */
.week-nav { display: flex; align-items: center; gap: var(--space-3); }
.week-nav__step {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--space-6); height: var(--space-6); flex: 0 0 auto;
  background: var(--surface-glass-strong); border: 1px solid var(--border-glass);
  border-radius: var(--radius-pill); color: var(--text-secondary);
  text-decoration: none; font-size: var(--text-lg); line-height: 1;
}
.week-nav__step:hover { color: var(--text-primary); box-shadow: var(--shadow-glow); }
.week-nav__step--disabled { color: var(--text-muted); cursor: default; box-shadow: none; }
.week-nav .parent-schedule__title { margin: 0; }

/* ============================================================
   WS3 Annual Rollover — FCC year-boundary band (Section E) +
   the /parent/next-year hub.
   Spec: docs/ui-specs/family-command-center.md §5h / §5i.
   Tokens only; the sole inline custom property is the documented
   dynamic --mastery on the remediation bars.
   ============================================================ */

/* Size modifier for .btn — the band's action is secondary to everything
   around it, so it reads one step down from a standard button. */
.btn--sm {
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
}

/* --- E. the band ------------------------------------------------------ */
.year-roll {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  position: relative;
  overflow: hidden;
  padding: var(--space-4) var(--space-5);
  margin-top: var(--space-4);
}
.year-roll::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--accent-primary);
}
/* Never red: a blocked roll is a not-yet, so it takes the gentle amber. */
.year-roll--blocked::before { background: var(--warning); }
.year-roll--nudge::before   { background: var(--info); }
.year-roll--rolled::before  { background: var(--success); }

.year-roll__icon {
  width: var(--space-6);
  height: var(--space-6);
  border-radius: var(--radius-pill);
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-glass-strong);
  color: var(--accent-primary);
}
.year-roll__icon i { width: var(--icon-size-md); height: var(--icon-size-md); }
.year-roll--blocked .year-roll__icon { color: var(--warning-strong); }
.year-roll--nudge .year-roll__icon   { color: var(--info); }
.year-roll--rolled .year-roll__icon  { color: var(--success); }

.year-roll__text { flex: 1 1 340px; min-width: 0; }
.year-roll__eyebrow {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 var(--space-1);
}
.year-roll__line {
  margin: 0;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: 1.45;
}
.year-roll__sub {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.year-roll__action { flex-shrink: 0; }
.year-roll__dismiss {
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  padding: var(--space-2) var(--space-3);
}
.year-roll__dismiss:hover { color: var(--text-secondary); }

/* --- the Next-Year hub -------------------------------------------- */
.next-year {
  max-width: var(--container-wide);
  margin: 0 auto;
  padding: var(--space-5) 0 var(--space-8);
}
.next-year__crumb { margin: 0 0 var(--space-4); font-size: var(--text-sm); }
.next-year__crumb a {
  color: var(--accent-primary);
  font-weight: var(--weight-medium);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.next-year__crumb i { width: var(--icon-size-sm); height: var(--icon-size-sm); }

.next-year__head { margin-bottom: var(--space-5); }
.next-year__title {
  font-family: var(--font-headline);
  font-size: var(--text-2xl);
  font-weight: var(--weight-medium);
  margin: 0 0 var(--space-2);
  line-height: 1.2;
}
.next-year__line {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--text-base);
  line-height: 1.6;
  max-width: var(--prose-max-width);
}

.next-year__calendar {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin: 0 0 var(--space-5);
  padding: var(--space-4) var(--space-5);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
}
.cal-leg { display: flex; flex-direction: column; gap: var(--space-1); }
.cal-leg__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.cal-leg__value { font-size: var(--text-lg); font-weight: var(--weight-medium); }
.cal-arrow { color: var(--accent-primary); display: inline-flex; }
.cal-arrow i { width: var(--icon-size-lg); height: var(--icon-size-lg); }
.cal-note {
  margin: 0 0 0 auto;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  max-width: 32ch;
}

.next-year__students { display: grid; gap: var(--space-3); margin-bottom: var(--space-5); }
.roll-student {
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
}
.roll-student__head {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.roll-student__avatar {
  width: var(--space-6);
  height: var(--space-6);
  border-radius: var(--radius-pill);
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-secondary);
  color: var(--text-on-accent);
  font-weight: var(--weight-bold);
}
.roll-student__name { font-size: var(--text-lg); font-weight: var(--weight-medium); }
.grade-move {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--accent-secondary);
  color: var(--accent-primary);
}
.grade-move__arrow { width: var(--icon-size-sm); height: var(--icon-size-sm); opacity: 0.7; }

.roll-student__subjects {
  margin-left: auto;
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.subj-pill {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  color: var(--text-secondary);
}
.subj-pill b { color: var(--text-primary); font-size: var(--text-sm); }
/* A subject held below the student's nominal next-year grade is a deliberate
   parent choice from the Replan wizard — amber says "notice this", not "wrong". */
.subj-pill--held { border-color: var(--warning); color: var(--warning-strong); }

.remediation { margin-top: var(--space-3); }
.remediation > summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--warning-strong);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--warning);
}
.remediation > summary::-webkit-details-marker { display: none; }
.remediation > summary::after { content: "\25BE"; opacity: 0.65; font-size: var(--text-xs); }
.remediation[open] > summary::after { content: "\25B4"; }
.remediation--clear {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--success);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--success);
}
/* Grouped by subject, core first. The flat list ran to 31 rows on the roll-ready
   seed — Music 11, PE 10, Design 6, Logic 3, Social Studies 1 — so the one row
   that gates grade-level work sat eleventh behind Music. Grouping makes the card
   scale with the number of SUBJECTS (5) rather than the catalog (31). */
.remediation__groups {
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-4);
}
.remediation__group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin: 0;
}
.remediation__group-count {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
/* Core carries the only obligation that gates grade-level work, so it reads
   first AND differently — without warm accent, which on this surface means
   "needs a decision" and these need none. */
.remediation__group[data-category="core"] .remediation__subject {
  color: var(--text-secondary);
}
.remediation__list {
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-1);
}
.remediation__item {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}
.remediation__item:nth-child(odd) { background: var(--surface-glass); }
.remediation__subject {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.remediation__score {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  justify-content: flex-end;
}
.remediation__pct {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  min-width: 9ch;
  text-align: right;
}
.mastery-bar {
  width: var(--space-8);
  height: var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  overflow: hidden;
}
.mastery-bar > i {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  width: var(--mastery);
  background: var(--warning);
}
.remediation__foot {
  margin: var(--space-3) 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  max-width: var(--prose-max-width);
}

.next-year__commit {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  flex-wrap: wrap;
  padding-top: var(--space-5);
  border-top: var(--glass-border-width) solid var(--border-glass);
}
.next-year__commit-summary {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  max-width: 56ch;
  line-height: 1.6;
}
.next-year__commit-summary b { color: var(--text-primary); }

/* --- blocked render --------------------------------------------------- */
.blockers {
  margin: 0 0 var(--space-5);
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-3);
}
.blocker {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  background: var(--surface-glass-strong);
  border: var(--glass-border-width) solid var(--border-glass);
  border-left: 3px solid var(--warning);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
}
.blocker__icon {
  width: var(--space-5);
  height: var(--space-5);
  border-radius: var(--radius-pill);
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-glass);
  color: var(--warning-strong);
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
}
.blocker__body { flex: 1; }
.blocker__text { margin: 0; font-size: var(--text-base); line-height: 1.55; }
.blocker__fix { margin: var(--space-2) 0 0; }
.blocker__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--accent-primary);
  text-decoration: none;
}
.blocker__cta i { width: var(--icon-size-sm); height: var(--icon-size-sm); }
.blocker__cta:hover { text-decoration: underline; }

.blocked-why {
  margin: 0;
  padding: var(--space-4) var(--space-5);
  background: var(--surface-glass);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.65;
  max-width: var(--prose-max-width);
}
.blocked-why b { color: var(--text-primary); }

@media (max-width: 720px) {
  .roll-student__subjects { margin-left: 0; width: 100%; }
  .cal-note { margin-left: 0; }
  /* `.remediation__item` is already 1fr auto, and the subject moved up to the
     group head — this used to drop a per-row subject column that no longer
     exists. */
  .mastery-bar { display: none; }
  .year-roll__action { flex: 1; }
}

/* --- Next-Year hub: per-child progress + the non-ready student states ----
   The count is load-bearing, not chrome: before the hub existed a parent of
   three had no way to see that two Replan wizards were still outstanding. */
.next-year__panel { padding: var(--space-6); }

.next-year__progress {
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.next-year__progress-count {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.next-year__meter {
  display: block;
  height: var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  overflow: hidden;
  margin-bottom: var(--space-5);
}
.next-year__meter > i {
  display: block;
  height: 100%;
  width: var(--pct);
  border-radius: var(--radius-pill);
  background: var(--success);
  transition: width var(--duration-base) var(--ease-out);
}
/* The once-only "what the wizard does" line, hoisted out of the rows. Sits
   below the meter as a header footnote — quieter than `.next-year__line`,
   because it is a standing explanation rather than this year's status. The
   meter's own margin-bottom supplies the gap above it. */
.next-year__hint {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
  max-width: var(--prose-max-width);
}

/* Three states, three accents — one per parent affordance, because the rail is
   what gets scanned once a family has more than three children.

   Amber = your move. Unplanned children sort first and carry the attention
   accent: they are the outstanding work, and the wizard clears them today.

   Info-blue = NOT your move. `unavailable` means the grade's curriculum isn't
   authored yet; no parent action fixes that. It shared the amber accent until
   this pass, which made the one row a parent cannot act on look identical to
   the rows that are pure to-do — the worst possible confusion on a page whose
   entire job is "what is still outstanding".

   Never red throughout: nothing here has gone wrong. */
.roll-student--unplanned { border-left: 3px solid var(--warning); }
.roll-student--unavailable { border-left: 3px solid var(--info); }
.roll-student--ready { border-left: 3px solid var(--success); }

.roll-student__state {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--warning);
  color: var(--warning-strong);
}
/* Matches the left rail above: the pill for a state the parent cannot act on
   must not wear the to-do colour either. Text drops to --text-secondary rather
   than --info because there is no --info-strong, and bare --info is too light
   to hold as pill text in the light theme (which is why --warning-strong
   exists). The border carries the distinction; the rail reinforces it. */
.roll-student--unavailable .roll-student__state {
  border-color: var(--info);
  color: var(--text-secondary);
}
.roll-student__blocker {
  margin: var(--space-3) 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.55;
  max-width: var(--prose-max-width);
}
.roll-student__fix { margin: var(--space-3) 0 0; }
.roll-student__fix .btn i {
  width: var(--icon-size-sm);
  height: var(--icon-size-sm);
}
.roll-student__edit { margin: var(--space-3) 0 0; }
.roll-student__edit a {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--accent-primary);
  text-decoration: none;
}
.roll-student__edit a:hover { text-decoration: underline; }

.next-year__commit { margin-top: var(--space-5); }

/* ===========================================================================
   WS4 content flagging — "Report a problem" (docs/systems/content-flagging.md)
   Never-red by design: a child reporting broken content is being HELPFUL, not
   making a mistake, so the whole control lives in --text-muted / --info and
   the amber --warning only marks the open disclosure. Deliberately the
   quietest affordance in its footer — it must not compete with Check / Try
   again / I'm stuck, or flagging becomes the path of least resistance and the
   signal dies (spec §4).
   =========================================================================== */
.content-flag { margin-top: var(--space-3); }
.content-flag__summary {
  cursor: pointer; font-size: var(--text-xs); color: var(--text-muted);
  list-style: none; display: inline-flex; align-items: center; gap: var(--space-1);
}
.content-flag__summary::-webkit-details-marker { display: none; }
.content-flag__summary::before { content: "⚑"; opacity: 0.6; }
.content-flag__summary:hover { color: var(--text-secondary); }
.content-flag[open] > .content-flag__summary { color: var(--warning); }
.content-flag__form {
  margin-top: var(--space-2); padding: var(--space-3);
  display: flex; flex-direction: column; gap: var(--space-2);
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm);
}
.content-flag__label { font-size: var(--text-xs); color: var(--text-secondary); }
.content-flag__optional { color: var(--text-muted); }
.content-flag__reason, .content-flag__note {
  width: 100%; box-sizing: border-box; padding: var(--space-2) var(--space-3);
  background: var(--surface-glass-strong); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: var(--text-primary); font: inherit;
}
.content-flag__note { resize: vertical; }
.content-flag__submit {
  align-self: flex-start; padding: var(--space-2) var(--space-3);
  background: var(--surface-glass); border: 1px solid var(--border-glass);
  border-radius: var(--radius-sm); color: inherit; font: inherit; cursor: pointer;
}
.content-flag__submit:hover { background: var(--surface-glass-strong); }
.content-flag__hint { margin: 0; font-size: var(--text-xs); color: var(--text-muted); }
/* The acknowledgment replaces the control outright, so the same card can't be
   double-reported. --info, not --success: we recorded it, we did not fix it. */
.content-flag--sent .content-flag__ack {
  margin: 0; padding: var(--space-2) var(--space-3);
  font-size: var(--text-xs); color: var(--info);
  border-left: 2px solid var(--info);
}

/* ===========================================================================
   WS4 Admin chrome — the THIRD <body> theme, alongside Spark/Bloom.
   docs/admin-console-ideation.md §8; mocked at
   docs/ui-specs/admin-console-mockup.html.

   Locked rule "one markup, theme by <body> class": `body.admin` overrides only
   the substrate/glass variables and adds admin-only components. It reuses the
   same §4 tokens — no new tokens, no forked design system.

   Deliberately cooler, flatter and denser than the family surfaces: no glass
   tuning, no substrate particles, monospace for every id and count. An
   operator should never be one glance away from thinking they are inside a
   family's app.

   On severity color: --error does NOT exist as a token (it appears elsewhere
   in this file only inside "never use this" comments and was never added to
   foundation-design-system.md §4). Severity here uses the existing
   --warning / --warning-strong pair AND is stated in text, because two ambers
   do not separate at a 3px bar and color must never be the sole carrier of
   meaning.
   =========================================================================== */
body.admin {
  --bg-base: #0B1220;
  --surface-panel: rgba(255, 255, 255, 0.035);
  --surface-panel-strong: rgba(255, 255, 255, 0.06);
  --border-panel: rgba(255, 255, 255, 0.10);
  --text-primary: #E6EDF6;
  --text-secondary: #A9B7C8;
  --text-muted: #6E7F94;
  --accent-primary: #5B8DD6;
  margin: 0; background: var(--bg-base); color: var(--text-primary);
}
/* The base rule pins html AND body to 100dvh/overflow:hidden. That is a FIXED
   FRAME around an inner scroller — right for the student shell, and originally
   wrong here only because the console had no inner scroller, so every surface
   was clipped at the viewport (the onboarding form lost its Create button, the
   family teardown form was unreachable entirely).

   #215 fixed that by letting the DOCUMENT scroll and sticking the chrome. It
   worked geometrically but bounced: a sticky header lives inside the scrolling
   document, so macOS rubber-band overscroll carries it along. The shell pattern
   does not have that failure mode, because there the chrome is a SIBLING of the
   scroller and cannot move by construction. So the console adopts it: body is
   the fixed frame, .admin-scroll is the only thing that scrolls. */
body.admin { display: flex; flex-direction: column; }
.admin-chrome { flex: none; }
.admin-scroll {
  flex: 1; min-height: 0; overflow-y: auto;
  /* Don't chain this scroller's overscroll to the document behind it. */
  overscroll-behavior: contain;
}
body.admin code, body.admin .mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.admin-bar {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  background: var(--surface-panel-strong);
  border-bottom: 1px solid var(--border-panel);
}
.admin-bar__mark { font-weight: 700; letter-spacing: 0.04em; font-size: var(--text-sm); }
/* Was an amber pill; see admin_base.html for why a permanent warning colour on
   an always-true state was the wrong signal. Now a plain scope label. */
.admin-bar__scope { font-size: var(--text-xs); color: var(--text-secondary); }
.admin-bar__spacer { flex: 1; }
/* --text-secondary, not --text-muted: muted (#6E7F94) on the admin substrate
   (#0B1220) is 4.6:1 — technically AA for body text, but these are 12px and it
   reads as greyed-out/disabled rather than quiet. --text-secondary is 9.3:1.
   Both are existing §4 tokens; no new ones. */
.admin-bar__who { font-size: var(--text-xs); color: var(--text-secondary); }
.admin-bar__out { margin: 0; }
.admin-bar__out button {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: var(--text-xs); color: var(--text-secondary);
}
.admin-bar__out button:hover { color: var(--text-primary); }

.admin-nav {
  display: flex; gap: var(--space-1); padding: 0 var(--space-5);
  border-bottom: 1px solid var(--border-panel);
}
/* Same contrast reason as .admin-bar__who: an unselected section is quiet, not
   disabled, and --text-muted read as the latter. */
.admin-nav a {
  padding: var(--space-3) var(--space-4); font-size: var(--text-sm);
  color: var(--text-secondary); text-decoration: none;
  border-bottom: 2px solid transparent;
}
.admin-nav a:hover { color: var(--text-primary); }
.admin-nav a[aria-current] {
  color: var(--text-primary); border-bottom-color: var(--accent-primary);
}
.admin-main { padding: var(--space-5); max-width: 1160px; margin: 0 auto; }
.admin-h2 {
  /* The global h1/h2/h3 rule hands every heading --font-headline (Epilogue,
     a serif display face). That is the editorial voice of the family surfaces,
     and set in caps at 14px it renders these section labels as magazine
     eyebrows on a screen whose whole brief is "instrument panel, not a learning
     surface". Token-only swap to the body face — no new token, no forked
     system, and the one element that still read as the student app. */
  font-family: var(--font-body);
  font-size: var(--text-sm); text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-muted); margin: var(--space-6) 0 var(--space-3); font-weight: 600;
}
.admin-h2:first-of-type { margin-top: var(--space-3); }
.admin-h2__soon { text-transform: none; letter-spacing: 0; opacity: 0.7; }

/* --- exceptions band — the reason this screen exists --------------------- */
.exceptions { display: grid; gap: var(--space-3); }
.exc {
  display: grid; grid-template-columns: 3px 1fr auto; gap: var(--space-4);
  align-items: center;
  background: var(--surface-panel); border: 1px solid var(--border-panel);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4);
}
.exc::before { content: ""; align-self: stretch; border-radius: 2px; background: var(--text-muted); }
.exc[data-level="broken"]::before { background: var(--warning-strong); }
.exc[data-level="attention"]::before { background: var(--warning); }
.exc[data-level="ok"]::before { background: var(--success); }
.exc__tag {
  display: inline-block; margin-bottom: var(--space-1);
  font-family: ui-monospace, Menlo, monospace; font-size: 10px;
  letter-spacing: 0.10em; text-transform: uppercase;
}
.exc[data-level="broken"] .exc__tag { color: var(--warning-strong); }
.exc[data-level="attention"] .exc__tag { color: var(--warning); }
.exc[data-level="ok"] .exc__tag { color: var(--success); }
/* An eyebrow used OUTSIDE an .exc, where no data-level sets its colour — the
   families table's "reparented" marker. Replaces an inline style, which the
   tokens-only rule does not allow. */
.exc__tag--alert { color: var(--warning-strong); }
.exc__tag--warn { color: var(--warning); }
.exc__tag--ok { color: var(--success); }
.exc__title { font-size: var(--text-sm); }
.exc__detail { font-size: var(--text-xs); color: var(--text-secondary); margin-top: 2px; }
.exc__detail code { color: var(--text-primary); }
.exc__act {
  font-size: var(--text-xs); color: var(--text-primary); white-space: nowrap;
  background: var(--surface-panel-strong); border: 1px solid var(--border-panel);
  border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
}
/* A fix that does not exist yet is labelled with its phase rather than dressed
   up as a working button — a dead control teaches an operator to distrust the
   live ones. */
.exc__act--soon { color: var(--text-muted); opacity: 0.7; }

/* --- inventory — demoted below the exceptions on purpose ----------------- */
.inventory {
  display: flex; flex-wrap: wrap; gap: var(--space-5);
  background: var(--surface-panel); border: 1px solid var(--border-panel);
  border-radius: var(--radius-sm); padding: var(--space-4);
}
.inv__n { font-size: var(--text-lg); font-family: ui-monospace, Menlo, monospace; }
.inv__k { font-size: var(--text-xs); color: var(--text-muted); }

.admin-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.admin-table th, .admin-table td {
  text-align: left; padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-panel);
}
.admin-table th { font-size: var(--text-xs); color: var(--text-muted); font-weight: 600; }
.admin-table td.mono { font-family: ui-monospace, Menlo, monospace; font-size: var(--text-xs); }
.admin-table .cell { font-size: var(--text-xs); }
/* Where a repeat-suppressed column starts a new group, the rule above it does
   the grouping work a repeated label used to — no extra row, no extra height. */
.admin-table tr.admin-row-newgroup td { border-top: 1px solid var(--border-panel); }
/* The action column carries a button, so it should be only as wide as one. */
.admin-table td.admin-cell-act { width: 1%; white-space: nowrap; }
.admin-table .cell[data-s="ok"] { color: var(--success); }
.admin-table .cell[data-s="none"] { color: var(--warning-strong); }

/* --- jobs — each names the engine it runs -------------------------------- */
.jobs { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: var(--space-3); }
.job {
  background: var(--surface-panel); border: 1px solid var(--border-panel);
  border-radius: var(--radius-sm); padding: var(--space-4);
}
.job__name { font-size: var(--text-sm); }
.job__engine { font-size: var(--text-xs); color: var(--text-muted); margin-top: var(--space-1); }
.job__run {
  margin-top: var(--space-3); padding: var(--space-2) var(--space-3);
  font: inherit; font-size: var(--text-xs);
  background: var(--surface-panel-strong); border: 1px solid var(--border-panel);
  border-radius: var(--radius-sm); color: inherit; cursor: pointer;
}
.job__run:disabled { opacity: 0.45; cursor: not-allowed; }
/* Destructive is a different CLASS of thing, and states its guardrail up front
   rather than discovering it as an error after the click. */
.job[data-destructive] { border-color: var(--warning-strong); }
.job[data-destructive] .job__run { border-color: var(--warning-strong); color: var(--warning-strong); }
.job__guard { margin-top: var(--space-2); font-size: 11px; color: var(--warning-strong); }

.audit td { font-size: var(--text-xs); }
.audit .ts { color: var(--text-muted); white-space: nowrap; }
.audit .cross { color: var(--warning); }

/* WS4 Admin P1 — identity ops (families list + family detail). Same token set
   as the P0 chrome; no new tokens. */
.admin-crumb { margin: 0 0 var(--space-3); font-size: var(--text-xs); }
.admin-crumb a { color: var(--text-muted); text-decoration: none; }
.admin-crumb a:hover { color: var(--text-primary); }
.admin-sub { font-size: var(--text-xs); color: var(--text-muted); }
.admin-tag {
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-muted); border: 1px solid var(--border-panel);
  border-radius: var(--radius-pill); padding: 1px var(--space-2);
}
.admin-actions { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.admin-actions form { margin: 0; display: flex; gap: var(--space-2); align-items: center; }
.admin-inline-form input { max-width: 180px; padding: var(--space-1) var(--space-2); }
.admin-blast {
  margin: var(--space-2) 0; padding-left: var(--space-4);
  font-size: var(--text-xs); color: var(--text-secondary);
  columns: 2; column-gap: var(--space-5);
}
.admin-blast li { break-inside: avoid; }
.admin-danger-form {
  margin-top: var(--space-4); display: flex; flex-direction: column;
  gap: var(--space-2); max-width: 420px;
}
/* Links inside admin tables/chrome inherit the panel palette — the browser
   default (bright blue, underlined) is the one thing on this screen that
   doesn't belong to the theme. */
/* Scoped to body.admin rather than to individual components: the browser
   default (bright blue, underlined) is the one thing on these screens that
   doesn't belong to the theme, and enumerating components meant every new
   surface re-introduced it. .admin-nav keeps its own colours. */
body.admin :is(.admin-main, .admin-crumb) a {
  color: var(--accent-primary); text-decoration: none;
}
body.admin :is(.admin-main, .admin-crumb) a:hover { text-decoration: underline; }
/* Anything wearing .exc__act is a BUTTON, whether it's an <a> or a <button> —
   equal specificity to the rule above and declared after it, so it wins.
   (An earlier :not() version out-specified this and quietly rendered the
   filter chips as links.) */
body.admin a.exc__act { color: var(--text-primary); text-decoration: none; }
body.admin a.exc__act:hover {
  text-decoration: none; background: var(--surface-panel-strong);
}
/* .admin-h2 uppercases its section label; an id is not a label — the mono span
   carrying a family_id must keep its real case to stay copy-pasteable. */
.admin-h2 .admin-sub { text-transform: none; letter-spacing: 0; }
/* WS4 Admin P1 — onboarding form. */
.admin-onboard { display: grid; gap: var(--space-4); max-width: 640px; }
.admin-onboard .job { display: flex; flex-direction: column; gap: var(--space-2); }
.admin-onboard .job__run { align-self: flex-start; }
.admin-student-row { display: flex; gap: var(--space-2); margin-bottom: var(--space-2); }
.admin-student-row input { flex: 1; }
.admin-student-row select { max-width: 190px; }
.admin-h2-row { display: flex; align-items: baseline; gap: var(--space-4); }
.admin-h2-row .admin-h2 { margin-bottom: var(--space-3); }

/* WS4 Admin P2 — content-flag triage. */
.admin-filters { display: flex; gap: var(--space-2); margin-left: auto; }
.exc__act--on { color: var(--text-primary); border-color: var(--accent-primary); }
/* Evidence left, verbs right. The row was a single column with the whole
   resolve form always open under it: 208 of 332px — 63% of the card — was form
   an operator uses on one row in seven, so seven targets made a 2,511px page
   against a 964px viewport and you could see 2.9 of them. Side-by-side, the
   height is set by the evidence (87px) and the verbs ride in the space beside
   it, so the open queue fits one screen. */
.flag-row { display: grid; grid-template-columns: 1fr auto; gap: var(--space-4); align-items: start; }
.flag-row::before { content: none; }
.flag-row[data-level="broken"] { border-left: 3px solid var(--warning-strong); }
.flag-row[data-level="attention"] { border-left: 3px solid var(--warning); }
/* The repo-workflow constant, stated once for the page instead of per row. */
.flag-engine-note {
  margin: 0 0 var(--space-3); font-size: var(--text-xs); color: var(--text-muted);
}
.flag-reports { margin-top: var(--space-3); }
.flag-reports > summary {
  cursor: pointer; font-size: var(--text-xs); color: var(--text-muted);
}
.flag-reports > summary:hover { color: var(--text-primary); }
.flag-reports .admin-table td { font-size: var(--text-xs); vertical-align: top; }
.flag-actions { display: grid; gap: var(--space-2); width: 250px; }
.flag-verbs { display: flex; gap: var(--space-2); }
/* .job__run carries a margin-top for the job-card layout it was written for;
   in this flex row that pushed "Mark fixed" 12px below its two siblings. */
.flag-verbs .job__run { margin-top: 0; }
.flag-note > summary {
  cursor: pointer; font-size: var(--text-xs); color: var(--text-muted);
  list-style-position: inside;
}
.flag-note > summary:hover { color: var(--text-primary); }
.flag-note > * + * { margin-top: var(--space-2); }

/* WS4 Admin P2 — content anatomy inspector. */
.anat-meta { font-size: var(--text-xs); color: var(--text-muted); margin-bottom: var(--space-2); }
.anat-prompt { margin: var(--space-2) 0 0; font-size: var(--text-base); }
.anat-passage {
  margin-top: var(--space-2); padding: var(--space-3); font-size: var(--text-sm);
  background: var(--surface-panel); border-radius: var(--radius-sm);
  white-space: pre-wrap;
}
.anat-choice {
  background: var(--surface-panel); border: 1px solid var(--border-panel);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
}
/* The correct answer reads differently from the distractors at a glance —
   they have different jobs, and confusing them is the first way to misread
   this screen. */
.anat-choice[data-answer="yes"] { border-left: 3px solid var(--success); }
.anat-choice[data-answer="no"]  { border-left: 3px solid var(--border-panel); }
.anat-choice__head { display: flex; gap: var(--space-3); align-items: baseline; }
.anat-choice__letter { color: var(--text-muted); }
.anat-choice__text { flex: 1; font-size: var(--text-sm); }
/* Indented under its choice: the wiring belongs TO the distractor, and the
   nesting is the claim that a hint is judged against the mistake it answers. */
.anat-wire {
  margin: var(--space-3) 0 0 var(--space-5); padding-left: var(--space-4);
  border-left: 1px dashed var(--border-panel); font-size: var(--text-xs);
}
.anat-wire__label {
  color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.06em;
  font-size: 10px; margin-top: var(--space-2);
}
.anat-wire__desc { color: var(--text-secondary); }
.anat-wire__hook { color: var(--text-primary); font-style: italic; }
.anat-wire--missing { color: var(--warning); font-style: italic; }

/* WS4 Admin P2 — job runner output. Monospace, scrollable, never wrapped:
   script output is column-aligned and rewrapping it destroys the alignment
   that makes it readable. */
.job-output {
  margin: var(--space-3) 0 var(--space-5);
  padding: var(--space-4);
  background: var(--surface-panel); border: 1px solid var(--border-panel);
  border-radius: var(--radius-sm);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-xs); color: var(--text-secondary);
  white-space: pre; overflow-x: auto; max-height: 480px; overflow-y: auto;
}
.jobs .job form { margin: var(--space-3) 0 0; }

/* WS4 P4 — borrowed-session banner. Deliberately loud and undismissible on the
   FAMILY's chrome: the entire risk of impersonation is forgetting you are in
   it. Amber, not red — nothing is wrong, but nothing here is yours either. */
.imp-banner {
  position: sticky; top: 0; z-index: 999;
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  background: var(--warning-strong); color: #fff;
  font-size: var(--text-xs);
}
.imp-banner__dot {
  width: 8px; height: 8px; border-radius: var(--radius-pill);
  background: #fff; flex: 0 0 auto;
}
.imp-banner__exit { margin: 0 0 0 auto; }
.imp-banner__exit button {
  font: inherit; cursor: pointer; color: var(--warning-strong);
  background: #fff; border: 0; border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-3);
}

/* ============================================================
   RECORDS — the screen masthead's paper counterpart
   ============================================================ */
/* Hidden on screen; the @media print block below reveals it. The chrome says
   whose family and which surface, so on screen this would be a third copy. */
.records-doc-head { display: none; }
.records-print-btn { flex: 0 0 auto; }

/* ============================================================
   PRINT — Records is a document before it is a screen
   (design system §4: no new tokens; print REBINDS the existing palette)
   ============================================================ */
/* WHY THIS EXISTS
   ---------------
   Records' whole purpose is producing a sheet a family files with their state,
   and Cmd-P produced a dark screenshot with navigation on it. Three separate
   causes, none of which a "print button" alone would have fixed:

     1. `html`/`body`/`.shell` are pinned to 100dvh with `overflow: hidden` —
        the app is a fixed FRAME with an inner scroller. Printing that gives
        exactly ONE viewport-height page and silently clips every row below the
        fold. A seven-child roster printed as three children.
     2. The palette is dark glass. Browsers drop backgrounds when printing by
        default, so #F0F9FF body text landed on white paper — invisible ink.
     3. Chrome, substrate and controls have no meaning on paper.

   PRINT IS A THEME. Rather than writing a parallel set of print rules, this
   rebinds the existing tokens — so every rule already written in terms of
   `--text-primary` / `--surface-glass` becomes ink-on-paper for free, and the
   locked "tokens only, no new token names" rule holds exactly. Same trick as
   `body.theme-bloom`, bound by medium instead of class. */
@media print {
  /* --- 1. Repaint the palette ------------------------------------------ */
  /* Specificity note: the dark palette is bound on `body:not(.theme-bloom)`
     (0,1,1), so a bare `body` (0,0,1) would lose. `body.parent-console` ties
     at 0,1,1 and wins on source order, being last in the file. */
  :root,
  body,
  body.parent-console {
    --bg-base: #fff;
    --bg-elevated: #fff;
    --text-primary: #000;
    --text-secondary: #333;
    --text-muted: #444;
    /* Glass becomes nothing. Zebra striping a compliance table with grey fills
       is how you get a sheet that reads as a draft — paper wants rules, not
       fills, and toner is the family's. */
    --surface-glass: transparent;
    --surface-glass-strong: transparent;
    --surface-glass-chrome: transparent;
    --border-glass: #767676;
    --glass-inner-shadow: none;
    --shadow-sm: none;
    --shadow-md: none;
    --shadow-lg: none;
    --shadow-glow: none;
    /* Accents survive as near-black: an amber caveat rule prints as a grey
       smudge, and these carry no meaning the text does not already carry. */
    --accent-primary: #000;
    --accent-secondary: #000;
    --accent-highlight: #000;
    --info: #767676;
    --warning: #767676;
    --success: #767676;
  }

  /* --- 2. Unpin the frame so content can flow onto page 2 -------------- */
  /* This is the one that actually made rows disappear. */
  html, body {
    height: auto;
    min-height: 0;
    overflow: visible;
    background: #fff;
  }
  .shell {
    display: block;
    height: auto;
    max-height: none;
    overflow: visible;
  }
  .shell__main,
  .shell__surface {
    display: block;
    overflow: visible;
    height: auto;
    max-height: none;
    padding: 0;
    width: auto;
  }

  /* --- 3. Drop what paper cannot use ----------------------------------- */
  /* Navigation, decoration, and the control that produced this page. */
  .pbar,
  .shell__substrate,
  .imp-banner,
  .records-print-btn,
  /* The date-range picker is a control, not content — on paper it is a pair of
     empty boxes beside a button that does nothing. The range itself still
     prints, in the masthead, where a filed document needs it. */
  .portfolio-range {
    display: none !important;
  }

  /* --- 4. The document's own masthead ----------------------------------- */
  .records-doc-head {
    display: block;
    margin-bottom: var(--space-5);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid #000;
  }
  .records-doc-head__title {
    margin: 0;
    font-size: var(--text-xl);
    font-weight: var(--weight-bold);
    color: #000;
  }
  .records-doc-head__meta {
    margin: var(--space-1) 0 0;
    font-size: var(--text-sm);
    color: #333;
  }
  /* The screen header restates what the masthead now says, in a smaller voice. */
  .parent-records .parent-schedule__header { display: none; }

  /* --- 5. Cards become sections, not panels ---------------------------- */
  .parent-records .card {
    background: none;
    border: 0;
    border-radius: 0;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    padding: 0;
    margin: 0 0 var(--space-5);
    break-inside: avoid;
  }
  .parent-records .card__icon { display: none; }
  .parent-records .card__title { font-size: var(--text-base); }

  /* --- 6. The table: rules, and no split rows -------------------------- */
  /* A student whose name lands on page 1 and hours on page 2 is a filing
     error, not a layout nit. */
  .records-table__row {
    break-inside: avoid;
    page-break-inside: avoid;
    padding: var(--space-2) 0;
    border-bottom: 1px solid #c7c7c7;
    border-radius: 0;
  }
  .records-table__row--head {
    border-bottom: 1px solid #000;
    color: #000;
  }
  /* Repeat nothing per-page: the grid is flex, so a running header is not
     available without a real <table>. The masthead carries identification. */

  /* --- 6b. The portfolio log ------------------------------------------- */
  /* A month's worth of entries is longer than a page, so unlike the roster
     these sections MUST be allowed to break — pinning `break-inside: avoid` on
     a 40-row month would push the whole month to page 2 and leave page 1
     blank. Individual ROWS still never split. */
  .parent-portfolio .card { break-inside: auto; }
  .portfolio-table__row {
    break-inside: avoid;
    page-break-inside: avoid;
    padding: var(--space-1) 0;
    border-bottom: 1px solid #c7c7c7;
    border-radius: 0;
  }
  .portfolio-table__row--head { border-bottom: 1px solid #000; color: #000; }
  .portfolio-subject { border: 1px solid #c7c7c7; border-radius: 0; }
  /* The half-a-portfolio notice is the single most important thing on the
     printed page — it is what stops a parent filing this as a whole
     portfolio — so it prints boxed, and never splits across a page. */
  /* Specificity note: `.parent-records .card` (0,2,0) above zeroes border and
     padding on every card, so this must match it to win — hence the descendant
     form rather than a bare `.portfolio-scope`. */
  .parent-portfolio .portfolio-scope {
    border: 1px solid #000;
    padding: var(--space-3);
    break-inside: avoid;
  }

  /* --- 6c. Standards coverage ------------------------------------------ */
  /* Same break policy as the portfolio log, for the same reason: 102 TEKS
     standards do not fit on a page, so the SECTION may break while an
     individual standard never does — a standard split across a page break
     would put a code on one sheet and its status on the next. */
  .parent-standards .card { break-inside: auto; }
  .standards-item {
    break-inside: avoid;
    page-break-inside: avoid;
    padding: var(--space-1) 0 var(--space-2);
    border-left: 0;
    border-bottom: 1px solid #c7c7c7;
    border-radius: 0;
  }
  .standards-chip { border-color: #000; color: #000; }
  .standards-legend__row { break-inside: avoid; }
  /* The "not a compliance check" notice is to this page what the
     half-a-portfolio notice is to the log: the sentence that stops the
     printout being read as something it is not. Boxed, never split.
     Specificity matches `.parent-records .card` (0,2,0), as above. */
  .parent-standards .standards-scope {
    border: 1px solid #000;
    padding: var(--space-3);
    break-inside: avoid;
  }

  /* --- 7. Caveats must survive the trip -------------------------------- */
  /* These are the honesty block — what the numbers do and don't include. A
     printout that dropped them would be the most misleading artifact the app
     can produce, so they print, and they never split. */
  .records-caveats {
    border-left: 0;
    border-top: 1px solid #000;
    padding-top: var(--space-3);
    break-inside: avoid;
  }
  .records-caveats__list { color: #000; }

  /* --- 8. Page setup ---------------------------------------------------- */
  @page { margin: 18mm 16mm; }
  /* Belt and braces: some engines still honour the legacy property only. */
  h1, h2, h3 { break-after: avoid; page-break-after: avoid; }
}

/* ============================================================
   YEAR — each child's next-year section, inside their own card
   (parent-year.md §3.1, step 3 — tokens only, no new names)
   ============================================================ */
/* Everything substantive here reuses classes the old family-level roster
   already styled (.subj-pill, .remediation*, .grade-move,
   .roll-student__subjects, .roll-student__blocker), so the fold needed no
   restyling — only these four wrappers. */
.card-next-year {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.card-next-year__move,
.card-next-year__state {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
/* NEVER --error, per the locked rule. A parent who has not planned next year
   has done nothing wrong, and a grade that isn't available yet is our gap,
   not theirs. Amber is the strongest this is allowed to get. */
.card-next-year--unplanned .card-next-year__state,
.card-next-year--unavailable .card-next-year__state {
  color: var(--warning);
}
.card-next-year__cta {
  margin: 0;
}

/* The quiet state of the Year page's roll section (parent-year.md §6.4).
   Present, not shouting: one muted line at the foot for the ~28 of 36 weeks
   when there is nothing to press. Tokens only. */
.year-quiet {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  margin: var(--space-5) 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-glass);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.year-quiet__label {
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
}
.year-quiet__count { color: var(--text-secondary); }
.year-quiet__when { flex: 1 1 100%; }

/* ============================================================
   RECORDS — state rule pack (docs/systems/state-rule-pack.md)
   Levels A + B. Tokens only, no new names.
   ============================================================ */
.records-rules__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-4);
}
.records-rule-student__name {
  margin: 0 0 var(--space-2);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.records-rule-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-1) var(--space-2);
  margin-bottom: var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.records-rule-row__figure { color: var(--text-primary); }
.records-rule-row__bar {
  grid-column: 1 / -1;
  display: block;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-glass);
  overflow: hidden;
}
/* Progress, never judgement. Short of a threshold is the NORMAL state for most
   of a school year — a family at 90 of 180 days in January is exactly on
   track — so the unmet bar is --info, not --warning and never --error. */
.records-rule-row__bar > i {
  display: block;
  height: 100%;
  width: var(--pct, 0%);
  background: var(--info);
}
.records-rule-row--met .records-rule-row__bar > i { background: var(--success); }
.records-rules__foot {
  margin: var(--space-4) 0 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* --- Transcript (credit record) ------------------------------------------ */
/* Tokens only (foundation-design-system.md §4); `--pct` is a documented
   dynamic custom property, the same one the trophy and XP bars use. */
.transcript__summary {
  margin-bottom: var(--space-5);
}
.transcript__credits {
  font-size: 1.25rem;
  margin: 0 0 var(--space-2);
}
.transcript__note {
  color: var(--text-muted);
  margin: 0;
  max-width: 60ch;
}
.transcript__table-scroll {
  overflow-x: auto;          /* wide content scrolls inside its own box */
}
.transcript__table {
  width: 100%;
  border-collapse: collapse;
}
.transcript__table th,
.transcript__table td {
  text-align: left;
  padding: var(--space-3);
  border-bottom: 1px solid var(--border-glass);
  vertical-align: middle;
}
.transcript__table thead th {
  color: var(--text-muted);
  font-weight: 600;
}
.transcript__bar {
  display: inline-block;
  width: 72px;
  height: 6px;
  margin-right: var(--space-2);
  border-radius: 3px;
  background: var(--surface-glass);
  background-image: linear-gradient(to right,
                    var(--success) var(--pct, 0%),
                    transparent var(--pct, 0%));
}
.transcript__table tr[data-status="earned"] th[scope="row"] {
  color: var(--success);
}

/* === Account-recovery nudge ==============================================
   Shown in the parent chrome when an account has no email and no recovery
   code, i.e. no way back in after a forgotten password. Amber, never red:
   this is a warning about a future problem, not an error state, and --error
   appears nowhere in these flows (CLAUDE.md §Locked rules). */
.recovery-nudge {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--surface-glass);
  border: 1px solid var(--warning);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-size: var(--text-sm);
}
.recovery-nudge__icon {
  flex: 0 0 auto;
  color: var(--warning);
  width: var(--text-lg);
  height: var(--text-lg);
}
.recovery-nudge__body {
  flex: 1 1 auto;
  line-height: 1.45;
  color: var(--text-secondary);
}
.recovery-nudge__body strong {
  color: var(--text-primary);
  display: block;
}
.recovery-nudge__cta {
  flex: 0 0 auto;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--warning);
  color: var(--text-on-accent);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.recovery-nudge__dismiss {
  flex: 0 0 auto;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  padding: var(--space-1);
}
.recovery-nudge__dismiss:hover { color: var(--text-primary); }

/* === Account recovery (parent surface) =================================== */
.recovery-setup { max-width: 34rem; }
.recovery-setup__title {
  font-size: var(--text-2xl);
  margin: 0 0 var(--space-2) 0;
  color: var(--text-primary);
}
.recovery-setup__lede {
  color: var(--text-secondary);
  margin: 0 0 var(--space-5) 0;
  line-height: 1.5;
}
.recovery-setup__panel {
  background: var(--surface-glass);
  border: 1px solid var(--success);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-5);
}
.recovery-setup__subtitle {
  font-size: var(--text-base);
  margin: 0 0 var(--space-2) 0;
  color: var(--text-primary);
}
.recovery-setup__code {
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: var(--text-xl);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-align: center;
  color: var(--text-primary);
  padding: var(--space-3);
  margin: var(--space-3) 0;
  border: 1px dashed var(--border-glass);
  border-radius: var(--radius-sm);
  word-break: break-all;
}
.recovery-setup__note {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1.5;
  margin: var(--space-2) 0 0 0;
}
.recovery-setup__form {
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
.recovery-setup__label {
  display: block;
  font-weight: 600;
  font-size: var(--text-sm);
  margin-bottom: var(--space-2);
  color: var(--text-secondary);
}
.recovery-setup__input {
  width: 100%;
  padding: var(--space-3);
  border: var(--glass-border-width) solid var(--border-glass);
  background: var(--surface-raised);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: var(--text-base);
  font-family: inherit;
  box-sizing: border-box;
}
.recovery-setup__submit {
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: none;
  border-radius: var(--radius-sm);
  background: var(--accent-primary);
  color: var(--text-on-accent);
  font-weight: 600;
  font-size: var(--text-base);
  font-family: inherit;
  cursor: pointer;
}

/* === Session history + the FCC pace line ================================
   Observations about how a child worked. Amber for "worth a look", never
   red: nothing has gone wrong that a conversation cannot fix, and --error
   appears nowhere in these flows (CLAUDE.md §Locked rules). */
.student-card__pace-line {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: var(--space-2) 0 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.45;
}
.student-card__pace-line i {
  flex: 0 0 auto;
  color: var(--warning);
  width: var(--text-base);
  height: var(--text-base);
  margin-top: 0.15em;
}
.student-card__pace-line a {
  color: var(--accent-primary);
  text-decoration: none;
  font-weight: 600;
  white-space: nowrap;
}

.sessions { max-width: 46rem; }
.sessions__crumb { margin: 0 0 var(--space-4) 0; font-size: var(--text-sm); }
.sessions__crumb a {
  color: var(--text-secondary);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.sessions__title {
  font-size: var(--text-2xl);
  margin: 0 0 var(--space-2) 0;
  color: var(--text-primary);
}
.sessions__lede,
.sessions__note,
.sessions__empty {
  color: var(--text-secondary);
  font-size: var(--text-sm);
  line-height: 1.55;
  margin: 0 0 var(--space-4) 0;
}
/* The note sits at the BOTTOM of the page, where the substrate gradient is at
   its lightest — and its vertical position moves with the number of session
   rows, so it cannot be tuned against one background. Measured at
   rgb(157,177,199) on the light end, it was close to unreadable, and it is the
   one paragraph that stops a parent over-reading an amber flag.

   Giving it its own surface fixes it independently of position: text tokens
   are guaranteed legible on surface tokens, which is not a guarantee the
   substrate makes. */
.sessions__note {
  margin-top: var(--space-5);
  color: var(--text-secondary);
  background: var(--surface-glass);
  border: var(--glass-border-width) solid var(--border-glass);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
/* Wide content scrolls inside its own container; the page never scrolls
   sideways (design-system §6). */
.sessions__scroll { overflow-x: auto; }
.sessions__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.sessions__table th,
.sessions__table td {
  text-align: left;
  padding: var(--space-3);
  border-bottom: 1px solid var(--border-glass);
  white-space: nowrap;
}
.sessions__table th {
  color: var(--text-muted);
  font-weight: 600;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.sessions__table td { color: var(--text-primary); }
.sessions__muted { color: var(--text-muted); }
.sessions__row--flagged { background: var(--surface-glass); }
.sessions__flag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--warning);
  font-weight: 600;
}
.sessions__flag i { width: var(--text-base); height: var(--text-base); }
