/* 漫 Mandarin — Patient Mandarin study. Honest data, no theatrics.
   Domestic Continuity aesthetic: plaster, bougainvillea, cypress, indigo water at dusk.
   Source Serif 4 body · Cormorant Garamond headings · Noto Serif SC hanzi
   Continuous surface · Horizon-line dividers · Upward-drift motion
   Voice: calm adult, data-grounded, respects intelligence, no praise inflation. */

/* ── Design tokens ────────────────────────── */

:root {
  /* Palette — light (default) */
  --color-base: #F2EBE0;
  --color-surface: #F2EBE0;
  --color-surface-alt: #EAE2D6;
  --color-text: #2A3650;
  --color-text-dim: #5A6678;
  --color-text-faint: #6A7080;  /* 5.0:1 on #F2EBE0 — WCAG AA */
  --color-accent: #946070;
  --color-accent-dim: #7A5060;
  --color-on-accent: #FFFFFF;   /* text/icons on accent backgrounds — 4.89:1 AA, large-text only */
  --color-secondary: #6A7A5A;
  --color-correct: #5A7A5A;
  --color-incorrect: #806058;
  --color-border: transparent;
  --color-divider: #D8D0C4;
  --color-shadow: rgba(42, 54, 80, 0.04);

  /* Flash message backgrounds */
  --color-flash-error-bg: #F0E0DD;
  --color-flash-info-bg: #DDE8DD;

  /* Accessible faint text — meets 4.5:1 for small text where --color-text-faint (5.0:1 large) is insufficient */
  --color-text-faintest: #707A8A;  /* 4.5:1 on #F2EBE0 — WCAG AA small text */

  /* Mastery stage colors */
  --color-mastery-durable: #4A6A4A;
  --color-mastery-stable: #6A8A5A;
  --color-mastery-stabilizing: #B8A050;

  /* Typography */
  --font-heading: 'Cormorant Garamond', 'Noto Serif SC', Georgia, serif;
  --font-body: 'Source Serif 4', 'Noto Serif SC', Georgia, serif;
  --font-hanzi: 'Noto Serif SC', 'Noto Sans SC', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', serif;
  --font-mono: 'SF Mono', 'Menlo', 'Consolas', monospace;

  /* Spacing (8px base) */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;

  /* Type scale — 1.2 ratio (minor third), fluid with clamp() */
  --text-xs: 0.694rem;
  --text-sm: 0.833rem;
  --text-base: 1rem;
  --text-lg: 1.2rem;
  --text-xl: clamp(1.2rem, 2vw, 1.44rem);
  --text-2xl: clamp(1.4rem, 2.8vw, 1.728rem);
  --text-3xl: clamp(1.6rem, 3.5vw, 2.074rem);
  --text-display: clamp(2.2rem, 5vw, 3.2rem);

  /* Spring easing for physical motion */
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Line heights per size step */
  --lh-display: 1.1;
  --lh-3xl: 1.2;
  --lh-xl: 1.3;
  --lh-lg: 1.3;
  --lh-base: 1.6;
  --lh-sm: 1.5;
  --lh-xs: 1.4;
  --lh-tight: 1.2;
  --lh-relaxed: 1.8;

  /* Tracking (letter-spacing) */
  --tracking-tight: 0.01em;
  --tracking-normal: 0.03em;
  --tracking-wide: 0.15em;

  /* Component tokens */
  --card-padding: var(--space-3) var(--space-4);
  --card-border: 1px solid var(--color-border);
  --card-radius: var(--radius);
  --panel-padding: var(--space-3) var(--space-4);
  --btn-padding: 14px 32px;
  --btn-radius: var(--radius);

  /* Shadow tokens — 6-level depth system */
  --shadow-xs: 0 1px 1px var(--color-shadow);
  --shadow-sm: 0 1px 3px var(--color-shadow), 0 1px 2px var(--color-shadow);
  --shadow-md: 0 2px 6px var(--color-shadow), 0 1px 3px var(--color-shadow);
  --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.08), 0 2px 8px var(--color-shadow);
  --shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.10), 0 4px 12px rgba(0, 0, 0, 0.05);
  --shadow-2xl: 0 24px 64px rgba(0, 0, 0, 0.14), 0 8px 24px rgba(0, 0, 0, 0.06);

  /* Glass tokens */
  --glass-bg: color-mix(in srgb, var(--color-surface) 78%, transparent);
  --glass-bg-dense: color-mix(in srgb, var(--color-surface) 88%, transparent);
  --glass-border: 1px solid color-mix(in srgb, var(--color-divider) 40%, transparent);
  --glass-blur: blur(20px) saturate(1.2);

  /* Gradient mesh tokens — animated background */
  --mesh-color-1: var(--color-sky-top);
  --mesh-color-2: color-mix(in srgb, var(--color-accent) 6%, var(--color-base));
  --mesh-color-3: color-mix(in srgb, var(--color-secondary) 4%, var(--color-base));
  --mesh-color-4: var(--color-base);

  /* Overlay */
  --color-overlay: rgba(0, 0, 0, 0.45);

  /* Illustration */
  --color-illustration: var(--color-accent);

  /* Sky gradient tokens */
  --color-sky-top: #E4E0D6;
  --color-sky-bottom: #F2EBE0;

  /* Shape — strategic rounding for human warmth */
  --radius: 0;
  --radius-sm: 2px;
  --radius-lg: 6px;
  --radius-card: 8px;
  --radius-illustration: 12px;
  --focus-ring-color: var(--color-accent);
  --focus-ring: 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent);

  /* Motion */
  --duration-press: 0.08s;      /* button press feedback — near-instant */
  --duration-snappy: 0.12s;     /* feedback bar — snappier confirmation */
  --duration-fast: 0.18s;
  --duration-base: 0.3s;
  --duration-slow: 0.4s;
  --duration-ambient: 0.8s;     /* shimmer, ambient loops */
  --duration-float: 1.5s;       /* illustration hover */
  --ease-default: cubic-bezier(0.25, 0.1, 0.25, 1);
  --ease-upward: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);  /* ease-in — things leaving accelerate out */

  /* Structural sizes (not in spacing scale — element-specific) */
  --sky-height: 280px;
  --horizon-width: 48px;
  --status-gap: 6px;
  --skeleton-height: 14px;
}

/* ── Awwwards-tier animation enrichment ──────────────── */

/* Input focus glow — soft accent ring on all text inputs */
input:focus, textarea:focus, select:focus {
  box-shadow: var(--focus-ring) !important;
  border-color: var(--color-accent) !important;
  outline: none;
  transition: box-shadow 0.2s var(--ease-default), border-color 0.2s;
}

/* Scroll-driven reveal — CSS states for visual-elevation.js .is-revealed */
[data-reveal], .stagger-children > [data-reveal-child] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s var(--ease-upward), transform 0.6s var(--ease-upward);
}
[data-reveal].is-revealed, .stagger-children.is-revealed > [data-reveal-child].is-revealed {
  opacity: 1;
  transform: translateY(0);
}

/* Empty-state illustration float/breathe loop */
@keyframes illustrationFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}
.empty-state-illustration {
  animation: gentleBloom 0.6s var(--ease-upward) 0.1s forwards,
             illustrationFloat 4s ease-in-out 0.8s infinite;
}

/* Skeleton shimmer animation */
@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
.skeleton-line {
  background: linear-gradient(90deg,
    var(--color-surface-alt) 25%,
    color-mix(in srgb, var(--color-surface-alt) 60%, var(--color-base)) 50%,
    var(--color-surface-alt) 75%) !important;
  background-size: 200% 100%;
  animation: shimmer 1.5s ease-in-out infinite;
}

/* Session complete — enhanced celebration sequence */
@keyframes scoreReveal {
  0% { opacity: 0; transform: scale(0.8); }
  60% { transform: scale(1.05); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes pctSlideUp {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}
#complete-content h2 {
  animation: scoreReveal 0.6s var(--ease-spring) 0.4s backwards;
}
.complete-score {
  animation: scoreReveal 0.5s var(--ease-spring) 0.6s backwards;
}
.complete-pct {
  animation: pctSlideUp 0.5s var(--ease-upward) 0.8s backwards;
}

/* Stat cards — hover lift with shadow depth change */
@media (hover: hover) {
  .stat {
    transition: transform 0.3s var(--ease-default), box-shadow 0.3s var(--ease-default);
  }
  .stat:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
  }
}

/* Card components — strategic border radius */
.panel, .panel-body, .metric-card {
  border-radius: var(--radius-card);
}

/* Link hover transition */
a {
  transition: color 0.15s var(--ease-default);
}

/* ── Warm dark mode ────────────────────────── */

@media (prefers-color-scheme: dark) {
  :root {
    --color-base: #1C2028;
    --color-surface: #1C2028;
    --color-surface-alt: #242A34;
    --color-text: #E4DDD0;
    --color-text-dim: #A09888;
    --color-text-faint: #A8A090;  /* 5.2:1 on #1C2028 — WCAG AA */
    --color-accent: #B07888;
    --color-accent-dim: #946070;
    --color-on-accent: #FFFFFF;
    --color-secondary: #8AAA7A;
    --color-correct: #7A9A7A;
    --color-incorrect: #A8988E;
    --color-border: transparent;
    --color-divider: #3A3530;
    --color-shadow: rgba(0, 0, 0, 0.12);

    /* Dark mode shadow depth */
    --shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.2);
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.15);
    --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.15);
    --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.12);
    --shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.15);
    --shadow-2xl: 0 24px 64px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.18);

    /* Dark mode glass — slightly lighter glass for contrast against dark bg */
    --glass-bg: color-mix(in srgb, var(--color-surface-alt) 72%, transparent);
    --glass-bg-dense: color-mix(in srgb, var(--color-surface-alt) 85%, transparent);
    --glass-border: 1px solid color-mix(in srgb, var(--color-divider) 30%, transparent);

    /* Dark mode gradient mesh */
    --mesh-color-1: var(--color-sky-top);
    --mesh-color-2: color-mix(in srgb, var(--color-accent) 4%, var(--color-base));
    --mesh-color-3: color-mix(in srgb, var(--color-secondary) 3%, var(--color-base));
    --mesh-color-4: var(--color-base);

    --color-flash-error-bg: #3A2828;
    --color-flash-info-bg: #283A28;
    --color-text-faintest: #A0A8B8;  /* 4.6:1 on #1C2028 — WCAG AA small text */

    --color-mastery-durable: #5A8A5A;
    --color-mastery-stable: #7AAA6A;
    --color-mastery-stabilizing: #D4B060;

    --color-sky-top: #222838;
    --color-sky-bottom: #1C2028;
    --color-illustration: var(--color-accent);
  }
}

/* ── Time-of-day dark mode override ────────────────────────── */
/* JS sets data-theme="dark" or "light" on <html> based on local hour.
   These override the @media query so the page follows time of day,
   not just the OS setting. Placed after @media for cascade precedence. */

html[data-theme="dark"] {
  --color-base: #1C2028;
  --color-surface: #1C2028;
  --color-surface-alt: #242A34;
  --color-text: #E4DDD0;
  --color-text-dim: #A09888;
  --color-text-faint: #A8A090;  /* 5.2:1 on #1C2028 — WCAG AA */
  --color-accent: #B07888;
  --color-accent-dim: #946070;
  --color-on-accent: #FFFFFF;
  --color-flash-error-bg: #3A2828;
  --color-flash-info-bg: #283A28;
  --color-text-faintest: #A0A8B8;
  --color-secondary: #8AAA7A;
  --color-correct: #7A9A7A;
  --color-incorrect: #A8988E;
  --color-border: transparent;
  --color-divider: #3A3530;
  --color-shadow: rgba(0, 0, 0, 0.12);

  /* Dark mode depth & glass */
  --shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.2);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.15);
  --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.15);
  --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.12);
  --shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.15);
  --shadow-2xl: 0 24px 64px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.18);
  --glass-bg: color-mix(in srgb, var(--color-surface-alt) 72%, transparent);
  --glass-bg-dense: color-mix(in srgb, var(--color-surface-alt) 85%, transparent);
  --glass-border: 1px solid color-mix(in srgb, var(--color-divider) 30%, transparent);
  --mesh-color-1: var(--color-sky-top);
  --mesh-color-2: color-mix(in srgb, var(--color-accent) 4%, var(--color-base));
  --mesh-color-3: color-mix(in srgb, var(--color-secondary) 3%, var(--color-base));
  --mesh-color-4: var(--color-base);

  --color-mastery-durable: #5A8A5A;
  --color-mastery-stable: #7AAA6A;
  --color-mastery-stabilizing: #D4B060;

  --color-sky-top: #222838;
  --color-sky-bottom: #1C2028;
  --color-illustration: var(--color-accent);
}

html[data-theme="light"] {
  --color-base: #F2EBE0;
  --color-surface: #F2EBE0;
  --color-surface-alt: #EAE2D6;
  --color-text: #2A3650;
  --color-text-dim: #5A6678;
  --color-text-faint: #6A7080;  /* 5.0:1 on #F2EBE0 — WCAG AA */
  --color-accent: #946070;
  --color-accent-dim: #7A5060;
  --color-on-accent: #FFFFFF;
  --color-flash-error-bg: #F0E0DD;
  --color-flash-info-bg: #DDE8DD;
  --color-text-faintest: #707A8A;
  --color-secondary: #6A7A5A;
  --color-correct: #5A7A5A;
  --color-incorrect: #806058;
  --color-border: transparent;
  --color-divider: #D8D0C4;
  --color-shadow: rgba(42, 54, 80, 0.04);

  --color-mastery-durable: #4A6A4A;
  --color-mastery-stable: #6A8A5A;
  --color-mastery-stabilizing: #B8A050;

  --color-sky-top: #E4E0D6;
  --color-sky-bottom: #F2EBE0;
  --color-illustration: var(--color-accent);
}

/* ── High contrast mode (WCAG AAA: 7:1 body, 4.5:1 large) ────── */
/* Activated via html[data-contrast="high"]. Layers ON TOP of light/dark theme. */

html[data-contrast="high"] {
  --color-text: #1A1A2E;
  --color-text-dim: #3A3A50;
  --color-text-faint: #5A5A70;
  --color-text-faintest: #6A6A80;
  --color-accent: #7A3050;
  --color-accent-dim: #5A2040;
  --color-secondary: #2A5A2A;
  --color-correct: #1A5A1A;
  --color-incorrect: #6A2A2A;
  --color-divider: #B0A898;
  --color-surface-alt: #E0D8CC;
}

html[data-theme="dark"][data-contrast="high"] {
  --color-text: #F5F0E8;
  --color-text-dim: #D0C8B8;
  --color-text-faint: #B0A898;
  --color-text-faintest: #908880;
  --color-accent: #E0A0B8;
  --color-accent-dim: #C08098;
  --color-secondary: #A0D0A0;
  --color-correct: #90C890;
  --color-incorrect: #E0A0A0;
  --color-divider: #5A5048;
  --color-surface-alt: #2A3040;
  --color-base: #141820;
  --color-surface: #141820;
}

/* ── Reset ────────────────────────── */

html {
  scrollbar-gutter: stable;
  background-color: var(--color-base);
  -webkit-text-size-adjust: 100%;      /* Prevent iOS landscape font inflation */
  text-size-adjust: 100%;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Selection color — warm accent tint */
::selection {
  background: color-mix(in srgb, var(--color-accent) 25%, transparent);
  color: var(--color-text);
}

body {
  /* Sky gradient + paper grain as stacked background layers.
     Sky fades from cooler top to base in top 280px, then base below.
     Noise is blended via soft-light for plaster texture.
     Single-element approach — no pseudo-element stacking-context issues. */
  background-color: var(--color-base);
  background-image:
    radial-gradient(ellipse at 20% 0%, var(--mesh-color-2) 0%, transparent 50%),
    radial-gradient(ellipse at 80% 10%, var(--mesh-color-3) 0%, transparent 45%),
    radial-gradient(ellipse at 50% 60%, var(--mesh-color-2) 0%, transparent 55%),
    linear-gradient(180deg, var(--color-sky-top) 0%, var(--color-sky-bottom) var(--sky-height), var(--color-base) var(--sky-height)),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.06'/%3E%3C/svg%3E");
  background-blend-mode: normal, normal, normal, normal, soft-light;
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: 1.65;
  min-height: 100vh;
  width: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Sky warmth during session — applied via CSS custom property on body.
   The sky gradient is now a background-image layer on body (no pseudo-element). */

#app {
  max-width: clamp(360px, 100%, 1600px);
  width: 100%;
  margin: 0 auto;
  padding: var(--space-5) var(--space-6);
  /* Vertical aspiration: more space above, content settles below.
     safe-area-inset-top adds space for notch/dynamic island on iOS. */
  padding-top: calc(var(--space-6) + env(safe-area-inset-top, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  overflow-x: hidden;
}

/* On wide screens, add horizontal padding so content doesn't hug edges */
@media (min-width: 1200px) {
  #app {
    padding-left: var(--space-8, 3rem);
    padding-right: var(--space-8, 3rem);
  }
}

/* On small screens, tighter padding */
@media (max-width: 480px) {
  #app {
    padding-left: var(--space-4);
    padding-right: var(--space-4);
  }
}

/* ── Focus & accessibility ────────────────────────── */

*:focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
  box-shadow: none;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
  z-index: 100;
  background: var(--color-accent);
  color: var(--color-on-accent);
  padding: 8px 16px;
  font-family: var(--font-body);
  border-radius: 0;
}

.skip-link:focus {
  left: 0;
  top: 0;
  width: auto;
  height: auto;
  overflow: visible;
}

#app:focus {
  outline: none;
}

/* ── Status bar ────────────────────────── */

#status-bar {
  display: flex;
  align-items: center;
  gap: var(--status-gap);
  padding: var(--space-2) 0;
  font-size: var(--text-sm);
  color: var(--color-text-faint);
}

#status-bar .dot-idle {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-text-faint);
}

#status-bar .dot-connected {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-correct);
}

#status-bar .dot-loading {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-secondary);
  animation: pulse var(--duration-ambient) var(--ease-default) infinite;
}

#status-bar .dot-disconnected {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-incorrect);
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* ── Header ────────────────────────── */

header {
  text-align: center;
  padding: var(--space-3) 0 var(--space-4);
}

/* Logo icon (PNG) */
.logo-icon {
  display: block;
  width: 64px;
  height: 64px;
  margin: 0 auto var(--space-2);
  border-radius: 14px;
  mix-blend-mode: multiply;
}
html[data-theme="dark"] .logo-icon {
  mix-blend-mode: normal;
  box-shadow: 0 1px 4px rgba(0,0,0,0.4);
}

/* Legacy logo mark (漫 character) — kept for auth pages */
.logo-mark {
  font-family: var(--font-hanzi);
  font-size: var(--text-display);
  font-weight: 700;
  color: var(--color-accent);
  line-height: var(--lh-display);
  letter-spacing: var(--tracking-normal);
  animation: logoSettle 1s var(--ease-upward);
  animation-fill-mode: backwards;
}

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

.logo-text {
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: 400;
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-wide);
  margin-top: var(--space-1);
  animation: logoSettle 1s var(--ease-upward) 0.15s;
  animation-fill-mode: backwards;
}

/* Horizon line — the signature visual motif */
.horizon {
  width: var(--horizon-width);
  height: 1px;
  background: var(--color-divider);
  margin: var(--space-2) auto;
}

header .horizon {
  animation: horizonDraw 0.8s var(--ease-upward) 0.3s;
  animation-fill-mode: backwards;
}

@keyframes horizonDraw {
  from { width: 0; opacity: 0; }
  to { width: var(--horizon-width); opacity: 1; }
}

/* Account bar in header */
.account-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.account-name {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-link {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: transparent;
  transition: text-decoration-color var(--duration-fast) var(--ease-default);
}

@media (hover: hover) {
  .account-link:hover {
  text-decoration-color: var(--color-text-faint);
}
}

.logout-form {
  display: inline;
}

.session-info {
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-tight);
  animation: logoSettle 1s var(--ease-upward) 0.4s;
  animation-fill-mode: backwards;
}

/* ── Resume banner ────────────────────────── */

.resume-banner {
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
  text-align: center;
  animation: driftUp var(--duration-base) var(--ease-upward);
}

.resume-banner p {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-2);
}

.resume-banner-actions {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
}

.resume-btn {
  font-size: var(--text-sm);
  padding: var(--space-1) var(--space-3);
}

/* ── Dashboard illustrations ─────────────────────────────────────── */

.dashboard-illustration {
  display: block;
  max-width: 320px;
  width: 70%;
  height: auto;
  margin: var(--space-2) auto var(--space-3);
  opacity: 0;
  pointer-events: none;
  color: var(--color-text);
  mix-blend-mode: multiply;
  animation: slowReveal 1.2s cubic-bezier(0.2, 0, 0.2, 1) 0.3s forwards;
}

/* PNG illustrations (photographic) — multiply blends white bg into page */
.dashboard-illustration[src$=".png"] {
  mix-blend-mode: multiply;
  border-radius: var(--radius);
  animation: slowRevealPhoto 1.2s cubic-bezier(0.2, 0, 0.2, 1) 0.3s forwards;
}

@keyframes slowReveal {
  from { opacity: 0; }
  to { opacity: 0.5; }
}

@keyframes slowRevealPhoto {
  from { opacity: 0; }
  to { opacity: 0.85; }
}

.dashboard-illustration.illustration-secondary {
  max-width: 200px;
  width: 40%;
}

html[data-theme="dark"] .dashboard-illustration {
  filter: none;
  color: var(--color-text);
  mix-blend-mode: normal;
  animation-name: slowRevealDark;
}

html[data-theme="dark"] .dashboard-illustration[src$=".png"] {
  filter: invert(0.88) sepia(0.2) hue-rotate(180deg) brightness(0.9);
  mix-blend-mode: screen;
  animation-name: slowRevealDark;
}

/* Dark-specific PNGs (e.g. stone-bridge-dark.png) — no filter needed */
html[data-theme="dark"] .dashboard-illustration[src*="-dark.png"] {
  filter: none;
  animation-name: slowRevealPhoto;
}

@keyframes slowRevealDark {
  from { opacity: 0; }
  to { opacity: 0.4; }
}

/* ── Dashboard ────────────────────────── */

/* Dashboard hero — welcoming illustration for new/returning users */
.dashboard-hero {
  position: relative;
  text-align: center;
  margin-bottom: var(--space-5);
  opacity: 0;
  animation: gentleBloom 0.8s var(--ease-upward) 0.1s forwards;
}

.dashboard-hero-img {
  display: block;
  max-width: 480px;
  width: 100%;
  height: auto;
  margin: 0 auto;
  border-radius: 8px;
  box-shadow: var(--shadow-md);
  mask-image: linear-gradient(to bottom, black 70%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, black 70%, transparent 100%);
}

html[data-theme="dark"] .dashboard-hero-img {
  box-shadow: var(--shadow-lg);
}

.dashboard-hero-dismiss {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-surface) 80%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--color-text-dim);
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.15s;
  opacity: 0.6;
}

.dashboard-hero-dismiss:hover {
  opacity: 1;
}

.stats-row {
  display: flex;
  gap: var(--space-3);
  flex-wrap: nowrap;
  justify-content: center;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: var(--space-4) 0 var(--space-5);
  padding-bottom: var(--space-2);
  /* Fade hint that more content is scrollable */
  mask-image: linear-gradient(to right, transparent 0, black 8px, black calc(100% - 8px), transparent 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0, black 8px, black calc(100% - 8px), transparent 100%);
}

/* Hide scrollbar but keep scrollable */
.stats-row::-webkit-scrollbar { height: 0; }
.stats-row { scrollbar-width: none; }

/* On desktop, let stat items grow to fill space instead of scrolling */
@media (min-width: 1024px) {
  .stats-row {
    flex-wrap: wrap;
    overflow-x: visible;
    mask-image: none;
    -webkit-mask-image: none;
    gap: var(--space-3) var(--space-4);
  }
  .stat {
    flex: 1 1 0;
    min-width: 100px;
  }
}

.stat {
  text-align: center;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: var(--space-2) var(--space-3);
  min-width: 56px;
  flex-shrink: 0;
  transition: background var(--duration-fast) var(--ease-default);
}

@media (hover: hover) {
  .stat:hover {
    background: color-mix(in srgb, var(--color-surface-alt) 50%, transparent);
  }
}

.stat-value {
  font-family: var(--font-heading);
  font-size: var(--text-display);
  font-weight: 600;
  color: var(--color-accent);
  line-height: var(--lh-display);
}

/* Streak: quiet, same treatment as other stats — no special color */
.stat-streak .stat-value {
  color: var(--color-text);
}

.stat-label {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  margin-top: var(--space-1);
  line-height: var(--lh-xs);
}

.error-summary {
  margin: var(--space-3) 0;
  text-align: center;
}

.error-summary h3 {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-weight: normal;
  margin-bottom: var(--space-2);
  letter-spacing: var(--tracking-normal);
}

.error-tag {
  display: inline-block;
  background: transparent;
  color: var(--color-secondary);
  padding: var(--space-1) var(--space-3);
  border-radius: 0;
  border-bottom: 1px solid var(--color-divider);
  font-size: var(--text-xs);
  margin: 2px;
}

.actions {
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  margin: var(--space-4) 0 var(--space-3);
}

/* ── Dashboard hierarchy — Begin is the singular focal point ── */

#btn-start {
  padding: 18px 48px;
  font-size: var(--text-lg);
  letter-spacing: var(--tracking-normal);
}

#btn-mini {
  font-size: var(--text-sm);
  padding: 10px 20px;
  opacity: 0.85;
}

.stats-row { opacity: 0.92; }

/* ── Buttons ────────────────────────── */

.btn-primary {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border: none;
  padding: var(--btn-padding);
  border-radius: var(--radius-lg);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-default),
              transform var(--duration-press) var(--ease-default),
              box-shadow var(--duration-fast) var(--ease-default);
  min-height: 44px;
  min-width: 44px;
  letter-spacing: var(--tracking-tight);
}

@media (hover: hover) {
  .btn-primary:hover {
    opacity: 0.92;
    transform: translateY(-2px);
    box-shadow: 0 4px 16px color-mix(in srgb, var(--color-accent) 25%, transparent);
  }
}
.btn-primary:active {
  opacity: 1;
  transform: scale(0.95) translateY(0);
  transition: transform 0.06s ease;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent);
}
/* Spring bounce back after press */
.btn-primary:not(:active) {
  transition: transform 0.4s var(--ease-spring), opacity 0.2s, box-shadow 0.3s;
}
.btn-primary:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.btn-primary:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

.btn-secondary {
  background: transparent;
  color: var(--color-accent);
  border: 1px solid var(--color-accent-dim);
  padding: 14px 24px;
  border-radius: var(--radius-lg);
  font-family: var(--font-body);
  font-size: var(--text-base);
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-default),
              transform var(--duration-press) var(--ease-default),
              box-shadow var(--duration-fast) var(--ease-default),
              background var(--duration-fast) var(--ease-default);
  min-height: 44px;
  min-width: 44px;
}

@media (hover: hover) {
  .btn-secondary:hover {
    opacity: 0.92;
    transform: translateY(-2px);
    background: color-mix(in srgb, var(--color-accent) 6%, transparent);
    box-shadow: 0 4px 12px color-mix(in srgb, var(--color-accent) 12%, transparent);
  }
}
.btn-secondary:active { transform: scale(0.95) translateY(0); transition: transform 0.06s ease; }
.btn-secondary:not(:active) { transition: transform 0.4s var(--ease-spring), opacity 0.2s, box-shadow 0.3s, background 0.2s; }
.btn-secondary:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.btn-secondary:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

/* ── Session area ────────────────────────── */

#session {
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  width: 100%;
}

#drill-area {
  flex: 1;
  padding: var(--space-5) 0;
  max-width: 960px;
  margin: 0 auto;
  width: 100%;
}

.msg {
  padding: 2px 0;
  margin-bottom: var(--space-1);
  line-height: var(--lh-base);
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow-wrap: anywhere;
  max-width: 100%;
  animation: driftUp var(--duration-base) var(--ease-upward);
}

@keyframes driftUp {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.msg-hanzi {
  font-family: var(--font-hanzi);
  font-size: var(--text-3xl);
  color: var(--color-accent);
  font-weight: 700;
  text-align: center;
  letter-spacing: var(--tracking-wide);
  padding: var(--space-5) var(--space-4);
  margin: var(--space-4) 0;
  background: transparent;
  border: none;
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
  border-radius: 0;
  animation: hanziReveal var(--duration-slow) var(--ease-upward);
  animation-delay: 0.1s;
  animation-fill-mode: backwards;
  line-height: var(--lh-3xl);
}

/* Hanzi inline: sans-serif CJK at body size matches Source Serif 4 optical weight
   better than serif CJK. Slight size reduction + vertical alignment correction. */
.hanzi-inline {
  font-family: 'Noto Sans SC', 'PingFang SC', 'Hiragino Sans GB', sans-serif;
  font-size: 0.94em;
  vertical-align: -0.04em;
  letter-spacing: 0.02em;
}

@keyframes hanziReveal {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ── Drill group — one drill = one visual unit ── */
.drill-group {
  padding: var(--space-3) 0;
}

/* Faint horizon between completed drill groups — the wall has marks */
.drill-group + .drill-group::before {
  content: '';
  display: block;
  width: 24px;
  height: 1px;
  background: var(--color-divider);
  margin: var(--space-2) 0 var(--space-3);
  opacity: 0.5;
}

.drill-group.past {
  opacity: 0.45;
  transition: opacity var(--duration-slow) var(--ease-default);
}

.drill-group:not(.past) {
  animation: drillEnter 0.2s var(--ease-upward) forwards;
}

@keyframes drillEnter {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* breathe animation removed — infinite opacity oscillation during active learning is distraction */

/* Vertical rhythm: more breathing room between drill messages */
.drill-group > .msg {
  margin: 0.5rem 0;
}

/* Stagger-cascade: messages within a drill group enter 50ms apart */
.drill-group:not(.past) > .msg {
  animation-fill-mode: backwards;  /* stay invisible until delay passes */
}
.drill-group:not(.past) > .msg:nth-child(2) { animation-delay: 50ms; }
.drill-group:not(.past) > .msg:nth-child(3) { animation-delay: 100ms; }
.drill-group:not(.past) > .msg:nth-child(4) { animation-delay: 150ms; }
.drill-group:not(.past) > .msg:nth-child(5) { animation-delay: 200ms; }
.drill-group:not(.past) > .msg:nth-child(6) { animation-delay: 250ms; }

.msg-correct {
  color: var(--color-correct);
  padding-left: var(--space-3);
  border-left: 2px solid var(--color-correct);
  background: color-mix(in srgb, var(--color-correct) 5%, transparent);
  padding-top: 4px;
  padding-bottom: 4px;
  animation: feedbackIn var(--duration-fast) var(--ease-upward),
             correctWarmPulse 1.5s ease-out forwards;
  position: relative;
  overflow: hidden;
}

@keyframes correctWarmPulse {
  0% { background: color-mix(in srgb, var(--color-correct) 6%, var(--color-base)); }
  100% { background: transparent; }
}

.msg-correct::after {
  content: '';
  position: absolute;
  top: 50%; left: 0;
  width: 200%; height: 200%;
  transform: translate(0, -50%) scale(0);
  background: radial-gradient(
    ellipse at center,
    color-mix(in srgb, var(--color-correct) 8%, transparent) 0%,
    transparent 70%
  );
  animation: inkSpread var(--duration-base) var(--ease-upward) forwards;
  pointer-events: none;
}

@keyframes inkSpread {
  from { transform: translate(0, -50%) scale(0); }
  to { transform: translate(0, -50%) scale(1); }
}

.msg-wrong {
  color: var(--color-incorrect);
  padding-left: var(--space-3);
  border-left: 2px solid var(--color-incorrect);
  background: color-mix(in srgb, var(--color-incorrect) 5%, transparent);
  padding-top: 4px;
  padding-bottom: 4px;
  animation: feedbackIn var(--duration-fast) var(--ease-upward),
             softAcknowledge 0.4s var(--ease-default) 0.15s;
}

/* Soft acknowledge — brief opacity dip, no shaking. "Acknowledges difficulty without framing it as failure." */
@keyframes softAcknowledge {
  0% { opacity: 1; }
  30% { opacity: 0.7; }
  100% { opacity: 1; }
}

@keyframes feedbackIn {
  from { opacity: 0; transform: translateX(-4px); }
  to { opacity: 1; transform: translateX(0); }
}

/* ── Ink Settle: correct answer character animation ── */
.ink-settle {
  animation: inkSettleScale 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
  position: relative;
}

.ink-settle::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 100%;
  height: 2px;
  background: var(--color-correct);
  transform: scaleX(0);
  transform-origin: left;
  animation: inkUnderlineDraw 0.4s var(--ease-upward, ease-out) 0.15s forwards;
}

@keyframes inkSettleScale {
  0% { transform: scale(1); }
  30% { transform: scale(1.05); }
  100% { transform: scale(1); }
}

@keyframes inkUnderlineDraw {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

/* inkBlurPulse removed — blurring content during learning defocuses what the learner needs to read */
.ink-scatter {
  /* class retained for JS compatibility, animation removed */
}

/* ── Drill group transitions: slide between drills ── */
.drill-group.exiting {
  animation: drillExit 0.15s var(--ease-exit) forwards;
  pointer-events: none;
}

@keyframes drillExit {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-12px); }
}

/* ── Progress ink line: extends with each completed drill ── */
.drill-progress-line {
  height: 4px;
  background: linear-gradient(to right, var(--color-accent), color-mix(in srgb, var(--color-accent) 40%, transparent));
  transform-origin: left;
  transition: width 0.5s var(--ease-upward, ease-out);
  opacity: 0.85;
  margin-bottom: var(--space-2);
}

@media (prefers-reduced-motion: reduce) {
  .ink-settle, .ink-scatter, .drill-group.exiting, .drill-group:not(.past) { animation: none !important; }
  .ink-settle::after { animation: none !important; transform: scaleX(1); }
  .drill-exit, .drill-enter { animation: none !important; }
}

.msg-dim {
  opacity: 0.7;
  font-style: italic;
}

.msg-label {
  font-family: var(--font-heading);
  color: var(--color-text-dim);
  font-size: var(--text-xs);
  font-weight: 600;
  font-style: italic;
  letter-spacing: var(--tracking-normal);
  text-transform: uppercase;
  margin-top: var(--space-5);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-divider);
  line-height: var(--lh-xs);
}

.msg-label:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

/* Mastery stage pill — subtle inline badge after drill feedback */
.msg-mastery-stage {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  letter-spacing: var(--tracking-normal);
  padding: 2px 10px;
  margin-top: var(--space-1);
  margin-bottom: var(--space-1);
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-divider) 40%, transparent);
  animation: fadeIn var(--duration-fast) var(--ease-default);
}

/* Modality break — elegant spacing divider between drill modes */
.msg-modality-break {
  text-align: center;
  font-size: 0;  /* hide the text */
  height: 1px;
  background: var(--color-divider);
  margin: var(--space-4) auto;
  max-width: 48px;
  opacity: 0.5;
  border: none;
}

/* Score summary (e.g. "✓ Dialogue score: 85%") — used with msg-correct/msg-wrong */
.msg-score-summary {
  font-weight: 600;
  letter-spacing: var(--tracking-normal);
  margin-top: var(--space-3);
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ── Input ────────────────────────── */

#input-area {
  background: var(--color-surface);
  border-radius: 0;
  border-top: 1px solid var(--color-divider);
  padding: var(--space-4);
  margin-top: var(--space-4);
  animation: driftUp var(--duration-fast) var(--ease-upward);
  transition: opacity var(--duration-fast) var(--ease-default),
              transform var(--duration-fast) var(--ease-exit);
  position: relative;
  z-index: 20;
}

#input-area.input-exit {
  opacity: 0;
  transform: translateY(4px);
}

#prompt-text {
  color: var(--color-text-dim);
  font-size: var(--text-sm);
  margin-bottom: var(--space-2);
}

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

#answer-input {
  flex: 1;
  background: transparent;
  border: none;
  border-bottom: 2px solid var(--color-divider);
  border-radius: 0;
  color: var(--color-text);
  padding: 12px 4px;
  font-family: var(--font-body);
  font-size: var(--text-lg);
  line-height: var(--lh-lg);
  outline: none;
  transition: border-color var(--duration-fast) var(--ease-default), box-shadow var(--duration-fast) var(--ease-default);
  min-height: 44px;
}

#answer-input:focus {
  border-color: var(--color-accent);
  box-shadow: none;
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}
#answer-input:focus:not(:focus-visible) { outline: none; }

#btn-submit {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border: none;
  border-radius: var(--btn-radius);
  padding: 10px 16px;
  font-size: var(--text-lg);
  cursor: pointer;
  font-weight: 600;
  min-height: 44px;
  min-width: 44px;
  transition: opacity var(--duration-fast) var(--ease-default), transform var(--duration-press) var(--ease-default);
}

@media (hover: hover) { #btn-submit:hover { opacity: 0.88; } }
#btn-submit:active { transform: scale(0.98); }

/* End session / done button — visually distinct as the session-ending action */
.btn-shortcut-end {
  margin-left: auto;
  color: var(--color-text-faint);
  border-color: transparent;
  background: transparent;
}
@media (hover: hover) {
  .btn-shortcut-end:hover {
    color: var(--color-text-dim);
    border-color: var(--color-divider);
    background: var(--color-surface-alt);
  }
}

.shortcuts {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
  flex-wrap: wrap;
  justify-content: center;
}

.btn-shortcut {
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-bottom: 2px solid var(--color-divider);
  color: var(--color-text-dim);
  padding: 8px 16px;
  border-radius: var(--btn-radius);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-tight);
  cursor: pointer;
  min-height: 44px;
  transition: background var(--duration-fast) var(--ease-default), color var(--duration-fast) var(--ease-default), transform var(--duration-press) var(--ease-default);
}

@media (hover: hover) {
  .btn-shortcut:hover {
    background: var(--color-surface-alt);
    color: var(--color-text);
  }
}

.btn-shortcut:active {
  background: var(--color-surface-alt);
  transform: translateY(1px);
  border-bottom-width: 1px;
}

/* ── Progress ────────────────────────── */

/* Progress row integrated into input area bottom bar */
#input-progress-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

#progress-bar {
  flex: 1;
  height: 10px;
  background: var(--color-divider);
  border-radius: 5px;
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.08);
}

#progress-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: 5px;
  width: 0%;
  transition: width var(--duration-slow) var(--ease-default);
}

#progress-label {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  white-space: nowrap;
  flex-shrink: 0;
}

/* ── Complete ────────────────────────── */

#complete {
  text-align: center;
  padding: var(--space-4) 0 var(--space-6);
  animation: driftUp var(--duration-base) var(--ease-upward);
}

#complete-content {
  margin-bottom: var(--space-4);
  line-height: 1.6;
}

.complete-illustration {
  display: block;
  max-width: 400px;
  max-height: 320px;
  width: 85%;
  margin: 0 auto var(--space-5);
  border-radius: 8px;
  opacity: 0;
  animation: gentleBloom 0.8s cubic-bezier(0.2, 0, 0.2, 1) 0.15s forwards;
  box-shadow: var(--shadow-md);
}

html[data-theme="dark"] .complete-illustration {
  box-shadow: var(--shadow-lg);
}

@keyframes gentleBloom {
  from { opacity: 0; transform: scale(0.92); }
  to { opacity: 1; transform: scale(1); }
}

#complete-content h2 {
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: var(--text-xl);
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-normal);
  margin-bottom: var(--space-2);
  line-height: var(--lh-xl);
  display: block;
  position: relative;
}

#complete-content h2::after {
  content: '';
  display: block;
  margin: 4px auto 0;
  width: 0;
  height: 1px;
  background: var(--color-divider);
  animation: underlineGrow 1.2s var(--ease-upward) 0.3s forwards;
}

@keyframes underlineGrow {
  to { width: 60px; }
}

.complete-message {
  color: var(--color-text-dim);
  font-size: var(--text-sm);
  margin-bottom: var(--space-2);
}

/* Score with progress ring — grounded resolve, not celebration */
.complete-score {
  font-family: var(--font-heading);
  font-size: var(--text-display);
  font-weight: 600;
  color: var(--color-accent);
  margin: var(--space-3) 0 var(--space-1);
  line-height: var(--lh-display);
  animation: scoreReveal var(--duration-slow) var(--ease-upward);
  animation-delay: 0.15s;
  animation-fill-mode: backwards;
  position: relative;
  display: block;
}

@keyframes scoreReveal {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Thin arc behind the score — a settling circle */
.complete-score::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 140px;
  height: 140px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 1px solid var(--color-divider);
  opacity: 0;
  animation: ringSettle 1.6s var(--ease-upward) 0.4s forwards;
  pointer-events: none;
  z-index: -1;
}

@keyframes ringSettle {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); }
  60% { opacity: 0.6; }
  100% { opacity: 0.3; transform: translate(-50%, -50%) scale(1); }
}

.complete-pct {
  color: var(--color-text-dim);
  font-size: var(--text-base);
  margin-bottom: var(--space-3);
}

/* ── Accuracy bar — fills left-to-right ── */
.complete-accuracy-bar {
  width: 200px;
  max-width: 80%;
  height: 3px;
  margin: var(--space-2) auto var(--space-3);
  background: var(--color-divider);
  border-radius: 2px;
  overflow: hidden;
}
.complete-accuracy-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: 2px;
  width: 0;
  animation: accuracyFill 0.8s var(--ease-upward, ease-out) 0.6s forwards;
}
.complete-accuracy-fill.score-high { background: var(--color-correct); }

@keyframes accuracyFill {
  to { width: var(--accuracy-pct, 0%); }
}

@media (prefers-reduced-motion: reduce) {
  .complete-accuracy-fill { animation: none; width: var(--accuracy-pct, 0%); }
}

/* Score color classes */
.complete-score.score-high { color: var(--color-correct); }
.complete-score.score-mid { color: var(--color-text-dim); }
.complete-score.score-low { color: var(--color-text-dim); }

.complete-details {
  text-align: left;
  background: transparent;
  border: none;
  border-top: 1px solid var(--color-divider);
  border-radius: 0;
  padding: var(--space-3) var(--space-5);
  margin: var(--space-3) 0;
}

.complete-details h3 {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-normal);
  margin-bottom: var(--space-2);
  font-weight: 600;
}

.gains-summary {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-2);
}

.gains-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.gain-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-family: var(--font-hanzi);
  font-size: var(--text-base);
  padding: var(--space-1) var(--space-2);
  background: var(--color-surface-alt);
  border-radius: var(--radius);
  border-left: 3px solid var(--color-accent);
}

.gain-chip small {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.gain-chip.stage-stable,
.gain-chip.stage-durable {
  border-left-color: var(--color-correct);
}

.gain-chip.gain-more {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  border-left: none;
}

.complete-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-1) 0;
  font-size: var(--text-sm);
  border-bottom: 1px solid var(--color-divider);
}

.complete-row span {
  min-width: 0;
}

.complete-row:last-child {
  border-bottom: none;
}

.complete-row .value-good { color: var(--color-correct); font-weight: 500; }
.complete-row .value-mid { color: var(--color-text-dim); font-weight: 500; }
.complete-row .value-low { color: var(--color-text-faint); font-weight: 500; }

/* "What happens next" — adaptive reaction section */
.complete-next-item {
  display: block;
  font-size: var(--text-sm);
  color: var(--color-text);
  padding: var(--space-1) 0 var(--space-1) var(--space-4);
  position: relative;
  border-bottom: none;
}
.complete-next-item::before {
  content: "\2192";
  position: absolute;
  left: 0;
  color: var(--color-accent);
  opacity: 0.7;
}

/* "What you practiced" grid */
.practiced-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.practiced-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--space-2) var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  transition: border-color 0.2s ease;
}
.practiced-hanzi {
  font-family: var(--font-hanzi);
  font-size: 1.25rem;
  line-height: 1.3;
  color: var(--color-text);
}
.practiced-stage {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-dim);
  margin-top: 2px;
}
.practiced-pinyin {
  font-size: 0.7rem;
  color: var(--color-text-dim);
  margin-top: 1px;
}
.practiced-english {
  font-size: 0.65rem;
  color: var(--color-text-faint);
  margin-top: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.practiced-correction {
  font-size: 0.65rem;
  color: var(--color-incorrect);
  margin-top: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.practiced-wrong {
  border-color: var(--color-incorrect);
  background: color-mix(in srgb, var(--color-incorrect) 6%, var(--color-surface));
}
.practiced-right .practiced-hanzi::after {
  content: "";
}
.practiced-more {
  justify-content: center;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}
/* Stage-specific accent borders (overridden by practiced-wrong) */
.practiced-right.stage-stable { border-color: var(--color-correct); }
.practiced-right.stage-durable { border-color: var(--color-accent); }
.practiced-right.stage-stabilizing { border-color: var(--color-secondary); }
.practiced-right.stage-passed-once { border-color: var(--color-text-dim); }
.practiced-right.stage-seen { border-color: var(--color-divider); }
.stage-stable { border-color: var(--color-correct); }
.stage-durable { border-color: var(--color-accent); }
.stage-stabilizing { border-color: var(--color-secondary); }
.stage-passed-once { border-color: var(--color-text-dim); }
.stage-seen { border-color: var(--color-divider); }
.stage-decayed, .stage-weak { border-color: var(--color-incorrect); }

/* Progress ring on completion screen */
.progress-ring-container {
  position: relative;
  width: 120px;
  height: 120px;
  margin: var(--space-3) auto;
}
.progress-ring {
  width: 100%;
  height: 100%;
}
.progress-ring-fill {
  animation: ringFill 1s var(--ease-upward) 0.2s backwards;
}
@keyframes ringFill {
  from { stroke-dashoffset: 264; }
}
.progress-ring-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
}
.progress-ring-pct {
  font-family: var(--font-heading);
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--color-text);
  line-height: 1.2;
}
.progress-ring-level {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-dim);
}
.progress-ring-delta {
  font-size: 0.7rem;
  font-weight: 600;
}

.complete-transition {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) 0;
  font-size: var(--text-sm);
}

.complete-transition .arrow {
  color: var(--color-accent-dim);
}

/* Streak on completion — quiet, not celebratory */
.complete-streak {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 8px 0;
  margin: var(--space-3) 0;
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-style: italic;
}

/* Next session narrative — concrete, not ambiguous */
.complete-next {
  margin-top: var(--space-3);
  color: var(--color-text-dim);
  font-size: var(--text-sm);
  font-style: italic;
}

.complete-return-hook {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--color-text);
  opacity: 0;
  animation: settleIn 0.6s ease 0.8s forwards;
}

@keyframes settleIn {
  from { opacity: 0; transform: translateY(4px); }
  60% { opacity: 1; transform: translateY(-1px); }
  to { opacity: 1; transform: translateY(0); }
}
.return-hook-label {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-2);
}
.return-word-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.return-word {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  padding: var(--space-1) var(--space-2);
  background: var(--color-base);
  border-radius: var(--radius-sm);
  min-width: 4rem;
}
.return-word-hanzi {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  color: var(--color-hanzi, var(--color-accent));
  line-height: 1.3;
}
.return-word-gloss {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  white-space: nowrap;
  max-width: 10rem;
  overflow: hidden;
  text-overflow: ellipsis;
}
.return-hook-extra {
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}
.complete-brand-line {
  margin-top: var(--space-4);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  text-align: center;
  letter-spacing: 0.04em;
  opacity: 0;
  animation: settleIn 0.6s ease 1.6s forwards;
}

/* Daily reminder prompt on first completion */
.complete-reminder {
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--color-text);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  opacity: 0;
  animation: settleIn 0.6s ease 1.2s forwards;
  transition: border-color var(--duration-fast) var(--ease-default);
}
.complete-reminder .btn-sm {
  padding: var(--space-2) var(--space-3);
  min-height: 44px;
  font-size: var(--text-xs);
  white-space: nowrap;
}
.complete-reminder.reminder-success {
  border-left-color: var(--color-correct);
}
.complete-reminder.reminder-fallback {
  border-left-color: var(--color-text-faint);
}

.complete-encounters {
  margin-top: var(--space-3);
}

/* Accuracy delta — subtle directional indicator */
.complete-accuracy-delta {
  font-size: var(--text-sm);
  margin-bottom: var(--space-3);
}
.complete-accuracy-down {
  color: var(--color-text-dim);
}

/* Felt-progress summary — one line beneath section header */
.complete-felt-progress {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-2);
}

/* First session explanation */
.complete-first-explain {
  line-height: 1.6;
}

/* Pace projection — anchoring line */
.complete-pace {
  margin-top: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  opacity: 0;
  animation: settleIn 0.6s ease 1s forwards;
}

/* ── Milestone toasts ────────────────────────── */

.milestone-toast {
  position: fixed;
  bottom: var(--space-4);
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  opacity: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  box-shadow: var(--shadow-lg);
  z-index: 1000;
  transition: opacity 0.4s var(--ease-upward), transform 0.4s var(--ease-upward);
  pointer-events: none;
  max-width: 90vw;
}
.milestone-toast.milestone-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.milestone-toast.milestone-exit {
  opacity: 0;
  transform: translateX(-50%) translateY(-10px);
}
.milestone-icon {
  font-size: var(--text-lg);
  color: var(--color-accent);
  flex-shrink: 0;
}
.milestone-text {
  font-size: var(--text-sm);
  color: var(--color-text);
  font-family: var(--font-body);
}

/* ── Prerequisite notice toast ────────────────── */

.prereq-notice {
  position: fixed;
  bottom: var(--space-4);
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  opacity: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-secondary);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text);
  font-family: var(--font-body);
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  z-index: 1000;
  transition: opacity 0.4s var(--ease-upward), transform 0.4s var(--ease-upward);
  pointer-events: none;
  max-width: 90vw;
}
.prereq-notice.prereq-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.prereq-notice.prereq-exit {
  opacity: 0;
  transform: translateX(-50%) translateY(-10px);
}

/* ── Disconnect banner ────────────────────────── */

#disconnect-banner.banner-exit {
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity var(--duration-fast) var(--ease-default),
              transform var(--duration-fast) var(--ease-exit);
}

/* ── Panels group — visually grouped as a single unit ────────────────────────── */

.panels-group {
  margin-top: var(--space-4);
}

/* Desktop: 2-column dashboard panels */
@media (min-width: 820px) {
  .panels-group {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4) var(--space-6);
  }
  /* Let the weekly summary span full width as the hero panel */
  .panels-group > .panel:first-child {
    grid-column: 1 / -1;
  }
}

/* ── Details wrapper — progressive disclosure for technical panels ── */
.details-wrapper {
  margin-top: var(--space-2);
}

.details-summary {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  cursor: pointer;
  padding: var(--space-2) 0;
  letter-spacing: var(--tracking-tight);
  list-style: none;
}

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

.details-summary::before {
  content: "\25B8\00a0";
  font-size: 0.75em;
}

.details-wrapper[open] > .details-summary::before {
  content: "\25BE\00a0";
}

/* On desktop grid, details wrapper spans full width */
@media (min-width: 820px) {
  .details-wrapper {
    grid-column: 1 / -1;
  }
}

/* ── Dashboard panels ────────────────────────── */

.panel {
  background: transparent;
  border: none;
  border-top: 1px solid var(--color-divider);
  border-radius: 0;
  padding: var(--space-3) var(--space-4);
  margin: var(--space-2) 0;
}

.panel h3 {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-weight: 600;
  margin-bottom: var(--space-3);
  letter-spacing: var(--tracking-normal);
}

.panel-row {
  display: flex;
  justify-content: space-between;
  padding: var(--space-1) 0;
  font-size: var(--text-sm);
  gap: var(--space-2);
}

.panel-row .label {
  color: var(--color-text-dim);
  min-width: 0;
  overflow-wrap: break-word;
}

.panel-row .value {
  color: var(--color-text);
  font-weight: 500;
  min-width: 0;
  text-align: right;
  flex-shrink: 0;
}

.panel-row-dim .label {
  color: var(--color-text-faint);
  font-size: var(--text-xs);
  font-style: italic;
}
.panel-section-divider {
  border: none;
  border-top: 1px solid color-mix(in srgb, var(--color-divider) 50%, transparent);
  margin: var(--space-2) 0;
}

.panel-row .value-good {
  color: var(--color-correct);
  font-weight: 500;
}

.panel-row .value-warn {
  color: var(--color-secondary);
  font-weight: 500;
}

/* ── Settings panel (Account) ────────────────────────── */

.settings-section {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.settings-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-2) 0;
  font-size: var(--text-sm);
  border-bottom: 1px solid color-mix(in srgb, var(--color-divider) 50%, transparent);
  gap: var(--space-3);
  flex-wrap: wrap;
}

.settings-row:last-child {
  border-bottom: none;
}

.settings-label {
  color: var(--color-text-dim);
  flex: 0 0 auto;
  max-width: 45%;
}

.settings-value {
  color: var(--color-text);
  text-align: right;
  flex: 1 1 auto;
  min-width: 0;
  word-break: break-word;
}

/* Allow button groups in settings values to wrap */
.settings-value .btn-sm {
  white-space: nowrap;
}

.settings-value .btn-sm + .btn-sm {
  margin-left: var(--space-1);
}

.settings-divider {
  border: none;
  border-top: 1px solid var(--color-divider);
  margin: var(--space-2) 0;
}

.settings-inline-form {
  padding: var(--space-3) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.settings-form-actions {
  display: flex;
  gap: var(--space-2);
}

.settings-message {
  font-size: var(--text-xs);
  padding: var(--space-1) 0;
}

.settings-hint {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  line-height: 1.5;
}

.settings-danger-zone .settings-label {
  color: var(--color-incorrect);
}

/* Shared small button modifier */
.btn-sm {
  font-size: var(--text-xs);
  padding: var(--space-2) var(--space-3);
  min-height: 44px;
}

/* Danger button */
.btn-danger {
  background: var(--color-incorrect);
  color: var(--color-on-accent);
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 600;
  transition: opacity var(--duration-fast) var(--ease-default);
}
@media (hover: hover) { .btn-danger:hover { opacity: 0.88; } }
.btn-danger:focus-visible { outline: 2px solid var(--color-incorrect); outline-offset: 2px; }
.btn-danger:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

/* Shared input field */
.input-field {
  width: 100%;
  padding: 10px 14px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  transition: border-color 0.2s;
}
.input-field:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
  border-color: var(--color-accent);
}
.input-field:focus:not(:focus-visible) { outline: none; }

/* Toggle switch */
.toggle-switch {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 22px;
}
.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
}
.toggle-slider {
  position: absolute;
  inset: 0;
  cursor: pointer;
  background: var(--color-divider);
  border-radius: 22px;
  transition: background 0.2s;
}
.toggle-slider::before {
  content: '';
  position: absolute;
  left: 2px;
  bottom: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-surface);
  transition: transform 0.2s;
}
.toggle-switch input:checked + .toggle-slider {
  background: var(--color-accent);
}
.toggle-switch input:checked + .toggle-slider::before {
  transform: translateX(18px);
}
.toggle-switch input:focus-visible + .toggle-slider {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

/* MFA-specific */
.mfa-secret {
  display: block;
  font-size: var(--text-sm);
  padding: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-sm);
  word-break: break-all;
  user-select: all;
}

.mfa-backup pre {
  font-size: var(--text-xs);
  padding: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-sm);
  white-space: pre-wrap;
}

.session-history-item {
  padding: var(--space-2) 0;
  font-size: var(--text-sm);
  border-bottom: 1px solid color-mix(in srgb, var(--color-divider) 50%, transparent);
  line-height: var(--lh-sm);
}

.session-history-item:last-child {
  border-bottom: none;
}

.session-history-item .session-date {
  font-family: var(--font-heading);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  letter-spacing: var(--tracking-tight);
  display: block;
  margin-bottom: 1px;
}

.session-history-item .session-narrative {
  color: var(--color-text-dim);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 6px;
}

.session-history-item .session-assessment {
  font-style: italic;
  color: var(--color-text-faint);
}

/* ── Mastery bars ────────────────────────── */

.mastery-bars {
  margin: var(--space-2) 0;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-divider);
}

.mastery-bar-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
  padding: var(--space-2) var(--space-2);
  padding-left: var(--space-3);
  flex-wrap: wrap;
  cursor: default;
  /* Hairline that feels printed, not digital */
  border-bottom: 1px solid color-mix(in srgb, var(--color-divider) 40%, transparent);
  transition: background var(--duration-fast) var(--ease-default);
}

@media (hover: hover) {
  .mastery-bar-row:hover {
    background: color-mix(in srgb, var(--color-surface-alt) 50%, transparent);
  }
}

.mastery-bar-row:last-of-type {
  border-bottom: none;
}

.mastery-bar-label {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  min-width: 52px;
  letter-spacing: var(--tracking-tight);
}

.mastery-bar {
  flex: 1;
  height: 6px;
  background: var(--color-surface-alt);
  border-radius: 0;
  display: flex;
  overflow: hidden;
}

.bar-seg {
  height: 100%;
  min-width: 2px;
  transition: width var(--duration-slow) var(--ease-upward);
  animation: barFadeIn var(--duration-slow) var(--ease-upward) backwards;
}

.bar-seg:nth-child(1) { animation-delay: 0s; }
.bar-seg:nth-child(2) { animation-delay: 0.06s; }
.bar-seg:nth-child(3) { animation-delay: 0.12s; }
.bar-seg:nth-child(4) { animation-delay: 0.18s; }
.bar-seg:nth-child(5) { animation-delay: 0.24s; }
.bar-seg:nth-child(6) { animation-delay: 0.3s; }

@keyframes barFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Mastery stage colors — warm, muted, earth-toned */
.bar-durable { background: var(--color-mastery-durable); }
.bar-stable { background: var(--color-mastery-stable); }
.bar-stabilizing { background: var(--color-mastery-stabilizing); }
.bar-passed { background: var(--color-secondary); }
.bar-seen { background: var(--color-divider); }
.bar-unseen { background: var(--color-divider); }

.mastery-bar-meta {
  font-family: var(--font-heading);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  min-width: 72px;
  text-align: right;
  white-space: nowrap;
  font-style: italic;
  letter-spacing: var(--tracking-tight);
  opacity: 0.85;
}

/* Post-session mastery delta badge */
.mastery-delta {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--color-correct);
  margin-left: auto;
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--color-correct) 10%, transparent);
  animation: delta-fade-in 0.4s ease;
}
@keyframes delta-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}
.mastery-bar-glow {
  box-shadow: 0 0 6px 1px color-mix(in srgb, var(--color-accent) 25%, transparent);
  transition: box-shadow 0.6s ease;
}

/* Bar detail is now shown via JS tooltip — hide inline detail */
.mastery-bar-detail {
  display: none;
}

/* Mastery tooltip — positioned via JS */
.mastery-tooltip {
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  background: var(--color-base);
  color: var(--color-text);
  border: 1px solid var(--color-divider);
  padding: 8px 12px;
  font-size: var(--text-xs);
  line-height: var(--lh-sm);
  max-width: 280px;
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-default);
  font-family: var(--font-body);
}
.mastery-tooltip.visible {
  opacity: 1;
}
.mastery-tooltip .tooltip-title {
  font-weight: 600;
  font-family: var(--font-heading);
  margin-bottom: 4px;
  color: var(--color-text);
}
.mastery-tooltip .tooltip-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 1px 0;
}
.mastery-tooltip .tooltip-label {
  color: var(--color-text-dim);
}
.mastery-tooltip .tooltip-value {
  color: var(--color-text);
  font-weight: 500;
  text-align: right;
}
.mastery-tooltip .tooltip-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  margin-right: 4px;
  vertical-align: middle;
}

.mastery-bar-row {
  cursor: pointer;
}

/* Mastery bars section header — understated */
.mastery-bars {
  position: relative;
}

.mastery-legend {
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
  flex-wrap: wrap;
  padding-top: var(--space-2);
  border-top: none;
  opacity: 0.72;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 3px;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  letter-spacing: var(--tracking-tight);
  font-style: italic;
}

.legend-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 0;
}

/* ── Collapsible panels ────────────────────────── */

.panel.collapsible h3 {
  cursor: pointer;
  user-select: none;
  padding: var(--space-2) 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  margin-bottom: 0;
}

.panel.collapsible h3 {
  transition: color var(--duration-fast) var(--ease-default);
}

@media (hover: hover) {
  .panel.collapsible h3:hover {
  color: var(--color-text);
}
}

.toggle-icon {
  display: inline-block;
  width: 16px;
  font-weight: 400;
  color: var(--color-text-faint);
  font-size: var(--text-xs);
}

.panel-body {
  margin-top: var(--space-2);
  overflow: hidden;
  opacity: 1;
  /* max-height managed by JS (scrollHeight) for accurate transition timing.
     Static max-height causes timing mismatch: 600px declared vs ~150px actual
     means the visible animation completes in 25% of the duration, then stalls. */
  transition: max-height var(--duration-slow) var(--ease-default),
              opacity var(--duration-fast) var(--ease-default),
              margin-top var(--duration-fast) var(--ease-default);
}

.panel-body.panel-closed {
  max-height: 0;
  opacity: 0;
  margin-top: 0;
}

/* Panel toggle buttons — reset browser defaults, match h3 styling */
.panel-toggle {
  display: flex;
  align-items: center;
  width: 100%;
  background: none;
  border: none;
  padding: var(--space-2) 0;
  min-height: 44px;
  cursor: pointer;
  user-select: none;
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-weight: 600;
  letter-spacing: var(--tracking-normal);
  text-align: left;
  transition: color var(--duration-fast) var(--ease-default);
}

@media (hover: hover) {
  .panel-toggle:hover {
    color: var(--color-text);
  }
}

/* SVG icon sizing */
svg.icon {
  width: 1em;
  height: 1em;
  vertical-align: middle;
  flex-shrink: 0;
}

/* ── Export links ────────────────────────── */

.export-link {
  display: flex;
  align-items: center;
  color: var(--color-accent);
  font-family: var(--font-heading);
  padding: 6px 0;
  font-size: var(--text-sm);
  text-decoration: none;
  min-height: 44px;
  letter-spacing: var(--tracking-normal);
  transition: color var(--duration-fast) var(--ease-default);
}

@media (hover: hover) {
  .export-link:hover {
  text-decoration: underline;
  color: var(--color-accent-dim);
}
}

/* ── Content crossfade — used when API data replaces skeletons ── */

.content-enter {
  animation: contentFadeIn var(--duration-fast) var(--ease-default);
}

@keyframes contentFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ── Loading skeletons ────────────────────────── */

.panel-skeleton {
  padding: 4px 0;
}

.skeleton-line {
  height: var(--skeleton-height);
  background: var(--color-surface-alt);
  opacity: 0.4;
  border-radius: 0;
  margin: var(--space-2) 0;
}

.skeleton-line.short {
  width: 60%;
}

/* ── Empty state ────────────────────────── */

.empty-state {
  text-align: center;
  padding: var(--space-5) var(--space-3);
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  line-height: var(--lh-sm);
  font-style: italic;
}

/* SVG vignette: horizon + sun — the visual signature for empty/waiting states
   Uses mask-image so color auto-adapts via --color-illustration token */
.empty-state::before {
  content: '';
  display: block;
  width: 80px;
  height: 40px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 40' fill='none'%3E%3Cline x1='12' y1='28' x2='68' y2='28' stroke='black' stroke-width='2.25'/%3E%3Ccircle cx='56' cy='16' r='12' stroke='black' stroke-width='2.25'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 40' fill='none'%3E%3Cline x1='12' y1='28' x2='68' y2='28' stroke='black' stroke-width='2.25'/%3E%3Ccircle cx='56' cy='16' r='12' stroke='black' stroke-width='2.25'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Hide the generic ::before when a real illustration is present */
/* :has() requires Safari 15.4+ / Chrome 105+ — JS fallback below for older browsers */
.empty-state:has(.empty-state-illustration)::before {
  display: none;
}
/* JS-applied fallback class for browsers without :has() support */
.empty-state.has-illustration::before {
  display: none;
}

.empty-state-illustration {
  display: block;
  max-width: 340px;
  width: 100%;
  height: auto;
  margin: 0 auto var(--space-4);
  border-radius: 8px;
  pointer-events: none;
  opacity: 0;
  animation: gentleBloom 0.6s var(--ease-upward) 0.1s forwards,
             illustrationFloat 6s ease-in-out 1s infinite;
  box-shadow: var(--shadow-md);
}

/* illustrationFloat defined in tokens section — no duplicate */

/* Empty state invitation pulse — the SVG vignette gently pulses */
.empty-state::before {
  animation: vignettePulse 3s ease-in-out infinite;
}
@keyframes vignettePulse {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.7; }
}

/* Horizontal ink line that draws itself — for empty timeline states */
.empty-state-timeline {
  width: 120px;
  height: 2px;
  margin: var(--space-3) auto var(--space-2);
  background: var(--color-accent);
  transform-origin: left;
  transform: scaleX(0);
  animation: timelineDraw 0.8s var(--ease-upward, ease-out) 0.4s forwards;
  position: relative;
}
.empty-state-timeline::after {
  content: '';
  position: absolute;
  right: -4px;
  top: -3px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-accent);
  opacity: 0;
  animation: timelineDot 0.4s var(--ease-upward, ease) 1.2s forwards;
}
@keyframes timelineDraw {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}
@keyframes timelineDot {
  from { opacity: 0; transform: scale(0); }
  to { opacity: 0.6; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .empty-state-illustration { animation: gentleBloom 0.6s var(--ease-upward) 0.1s forwards !important; }
  .empty-state::before { animation: none !important; }
  .empty-state-timeline, .empty-state-timeline::after { animation: none !important; transform: scaleX(1); opacity: 0.6; }
}

/* Dedicated dark images — no filter/invert needed */
html[data-theme="dark"] .empty-state-illustration {
  box-shadow: var(--shadow-lg);
}

/* ── Section horizon dividers ────────────────────────── */

/* Completion screen horizon arc — uses mask for theme adaptability */
/* ── Illustration vocabulary ────────────────────────── */
/* All illustrations use mask-image with --color-illustration for auto theme adaptation */

/* Horizon + cloud wisps — loading/preparing state */
.illustration-loading::before {
  content: '';
  display: block;
  width: 80px;
  height: 40px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 40' fill='none'%3E%3Cline x1='12' y1='28' x2='68' y2='28' stroke='black' stroke-width='2.25'/%3E%3Cpath d='M28 14 Q32 10 36 14' stroke='black' stroke-width='1.5' fill='none'/%3E%3Cpath d='M42 11 Q48 7 54 11' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 40' fill='none'%3E%3Cline x1='12' y1='28' x2='68' y2='28' stroke='black' stroke-width='2.25'/%3E%3Cpath d='M28 14 Q32 10 36 14' stroke='black' stroke-width='1.5' fill='none'/%3E%3Cpath d='M42 11 Q48 7 54 11' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  animation: illustrationFloat var(--duration-float) var(--ease-default) infinite;
}

/* Horizon + bird — session in progress / journey */
.illustration-journey::before {
  content: '';
  display: block;
  width: 80px;
  height: 40px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 40' fill='none'%3E%3Cline x1='12' y1='28' x2='68' y2='28' stroke='black' stroke-width='2.25'/%3E%3Cpath d='M44 12 L48 8 L52 12' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 40' fill='none'%3E%3Cline x1='12' y1='28' x2='68' y2='28' stroke='black' stroke-width='2.25'/%3E%3Cpath d='M44 12 L48 8 L52 12' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Horizon + settling sun — session complete / arrival */
.illustration-complete::before {
  content: '';
  display: block;
  width: 120px;
  height: 32px;
  margin: 0 auto var(--space-4);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 32' fill='none'%3E%3Cline x1='10' y1='26' x2='110' y2='26' stroke='black' stroke-width='2.25'/%3E%3Ccircle cx='60' cy='20' r='12' stroke='black' stroke-width='2.25'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 32' fill='none'%3E%3Cline x1='10' y1='26' x2='110' y2='26' stroke='black' stroke-width='2.25'/%3E%3Ccircle cx='60' cy='20' r='12' stroke='black' stroke-width='2.25'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Horizon + stars — streak/consistency / time passage */
.illustration-stars::before {
  content: '';
  display: block;
  width: 80px;
  height: 40px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 40' fill='none'%3E%3Cline x1='12' y1='28' x2='68' y2='28' stroke='black' stroke-width='2.25'/%3E%3Ccircle cx='30' cy='10' r='3' fill='black'/%3E%3Ccircle cx='50' cy='6' r='3' fill='black'/%3E%3Ccircle cx='62' cy='14' r='3' fill='black'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 40' fill='none'%3E%3Cline x1='12' y1='28' x2='68' y2='28' stroke='black' stroke-width='2.25'/%3E%3Ccircle cx='30' cy='10' r='3' fill='black'/%3E%3Ccircle cx='50' cy='6' r='3' fill='black'/%3E%3Ccircle cx='62' cy='14' r='3' fill='black'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}


/* Lantern path — onboarding / getting started */
.illustration-welcome::before {
  content: '';
  display: block;
  width: 120px;
  height: 60px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cpath d='M15 50 Q35 38 55 34 Q75 30 105 22' stroke='black' stroke-width='2' fill='none'/%3E%3Cline x1='0' y1='52' x2='120' y2='52' stroke='black' stroke-width='1.5'/%3E%3Crect x='42' y='32' width='8' height='11' rx='1' fill='black'/%3E%3Ccircle cx='46' cy='28' r='4' fill='black'/%3E%3Crect x='68' y='24' width='8' height='11' rx='1' fill='black'/%3E%3Ccircle cx='72' cy='20' r='4' fill='black'/%3E%3Crect x='92' y='16' width='8' height='11' rx='1' fill='black'/%3E%3Ccircle cx='96' cy='12' r='4' fill='black'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cpath d='M15 50 Q35 38 55 34 Q75 30 105 22' stroke='black' stroke-width='2' fill='none'/%3E%3Cline x1='0' y1='52' x2='120' y2='52' stroke='black' stroke-width='1.5'/%3E%3Crect x='42' y='32' width='8' height='11' rx='1' fill='black'/%3E%3Ccircle cx='46' cy='28' r='4' fill='black'/%3E%3Crect x='68' y='24' width='8' height='11' rx='1' fill='black'/%3E%3Ccircle cx='72' cy='20' r='4' fill='black'/%3E%3Crect x='92' y='16' width='8' height='11' rx='1' fill='black'/%3E%3Ccircle cx='96' cy='12' r='4' fill='black'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Moon gate — invitation / open passage */
.illustration-gateway::before {
  content: '';
  display: block;
  width: 120px;
  height: 60px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='50' x2='120' y2='50' stroke='black' stroke-width='1.5'/%3E%3Ccircle cx='60' cy='32' r='18' stroke='black' stroke-width='2.5'/%3E%3Cline x1='0' y1='55' x2='42' y2='55' stroke='black' stroke-width='1.5'/%3E%3Cline x1='78' y1='55' x2='120' y2='55' stroke='black' stroke-width='1.5'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='50' x2='120' y2='50' stroke='black' stroke-width='1.5'/%3E%3Ccircle cx='60' cy='32' r='18' stroke='black' stroke-width='2.5'/%3E%3Cline x1='0' y1='55' x2='42' y2='55' stroke='black' stroke-width='1.5'/%3E%3Cline x1='78' y1='55' x2='120' y2='55' stroke='black' stroke-width='1.5'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Ink stone — memory / retention */
.illustration-memory::before {
  content: '';
  display: block;
  width: 120px;
  height: 60px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='48' x2='120' y2='48' stroke='black' stroke-width='1.5'/%3E%3Cellipse cx='60' cy='40' rx='22' ry='6' stroke='black' stroke-width='2'/%3E%3Ccircle cx='60' cy='28' r='5' fill='black'/%3E%3Cpath d='M55 28 Q60 18 65 28' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='48' x2='120' y2='48' stroke='black' stroke-width='1.5'/%3E%3Cellipse cx='60' cy='40' rx='22' ry='6' stroke='black' stroke-width='2'/%3E%3Ccircle cx='60' cy='28' r='5' fill='black'/%3E%3Cpath d='M55 28 Q60 18 65 28' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Mountain path — forecast / journey ahead */
.illustration-forecast::before {
  content: '';
  display: block;
  width: 120px;
  height: 60px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='50' x2='120' y2='50' stroke='black' stroke-width='1.5'/%3E%3Cpath d='M20 50 L50 18 L80 50' stroke='black' stroke-width='2' fill='none'/%3E%3Cpath d='M55 50 L78 26 L100 50' stroke='black' stroke-width='2' fill='none'/%3E%3Cpath d='M42 18 Q50 12 56 18' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='50' x2='120' y2='50' stroke='black' stroke-width='1.5'/%3E%3Cpath d='M20 50 L50 18 L80 50' stroke='black' stroke-width='2' fill='none'/%3E%3Cpath d='M55 50 L78 26 L100 50' stroke='black' stroke-width='2' fill='none'/%3E%3Cpath d='M42 18 Q50 12 56 18' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Courtyard rain — error / interruption */
.illustration-error::before {
  content: '';
  display: block;
  width: 120px;
  height: 60px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='48' x2='120' y2='48' stroke='black' stroke-width='1.5'/%3E%3Cpath d='M30 48 L30 20 Q60 10 90 20 L90 48' stroke='black' stroke-width='2' fill='none'/%3E%3Cline x1='45' y1='30' x2='45' y2='38' stroke='black' stroke-width='1.5'/%3E%3Cline x1='60' y1='26' x2='60' y2='36' stroke='black' stroke-width='1.5'/%3E%3Cline x1='75' y1='30' x2='75' y2='38' stroke='black' stroke-width='1.5'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='48' x2='120' y2='48' stroke='black' stroke-width='1.5'/%3E%3Cpath d='M30 48 L30 20 Q60 10 90 20 L90 48' stroke='black' stroke-width='2' fill='none'/%3E%3Cline x1='45' y1='30' x2='45' y2='38' stroke='black' stroke-width='1.5'/%3E%3Cline x1='60' y1='26' x2='60' y2='36' stroke='black' stroke-width='1.5'/%3E%3Cline x1='75' y1='30' x2='75' y2='38' stroke='black' stroke-width='1.5'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Morning tea — fresh start / empty history */
.illustration-arrival::before {
  content: '';
  display: block;
  width: 120px;
  height: 60px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='48' x2='120' y2='48' stroke='black' stroke-width='1.5'/%3E%3Cellipse cx='60' cy='42' rx='14' ry='5' stroke='black' stroke-width='2'/%3E%3Cpath d='M46 42 L46 34 Q60 28 74 34 L74 42' stroke='black' stroke-width='2' fill='none'/%3E%3Cpath d='M74 36 Q82 36 80 42' stroke='black' stroke-width='1.5' fill='none'/%3E%3Cpath d='M55 30 Q58 24 61 30' stroke='black' stroke-width='1' fill='none'/%3E%3Cpath d='M62 28 Q65 22 68 28' stroke='black' stroke-width='1' fill='none'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='48' x2='120' y2='48' stroke='black' stroke-width='1.5'/%3E%3Cellipse cx='60' cy='42' rx='14' ry='5' stroke='black' stroke-width='2'/%3E%3Cpath d='M46 42 L46 34 Q60 28 74 34 L74 42' stroke='black' stroke-width='2' fill='none'/%3E%3Cpath d='M74 36 Q82 36 80 42' stroke='black' stroke-width='1.5' fill='none'/%3E%3Cpath d='M55 30 Q58 24 61 30' stroke='black' stroke-width='1' fill='none'/%3E%3Cpath d='M62 28 Q65 22 68 28' stroke='black' stroke-width='1' fill='none'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Reading lamp — reading view */
.illustration-reading::before {
  content: '';
  display: block;
  width: 120px;
  height: 60px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='50' x2='120' y2='50' stroke='black' stroke-width='1.5'/%3E%3Crect x='40' y='38' width='28' height='12' rx='2' stroke='black' stroke-width='2'/%3E%3Cline x1='48' y1='44' x2='62' y2='44' stroke='black' stroke-width='1.5'/%3E%3Cline x1='48' y1='47' x2='58' y2='47' stroke='black' stroke-width='1'/%3E%3Crect x='78' y='30' width='3' height='20' fill='black'/%3E%3Ccircle cx='80' cy='26' r='6' stroke='black' stroke-width='2'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='50' x2='120' y2='50' stroke='black' stroke-width='1.5'/%3E%3Crect x='40' y='38' width='28' height='12' rx='2' stroke='black' stroke-width='2'/%3E%3Cline x1='48' y1='44' x2='62' y2='44' stroke='black' stroke-width='1.5'/%3E%3Cline x1='48' y1='47' x2='58' y2='47' stroke='black' stroke-width='1'/%3E%3Crect x='78' y='30' width='3' height='20' fill='black'/%3E%3Ccircle cx='80' cy='26' r='6' stroke='black' stroke-width='2'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Evening sky — media view */
.illustration-media::before {
  content: '';
  display: block;
  width: 120px;
  height: 60px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='48' x2='120' y2='48' stroke='black' stroke-width='1.5'/%3E%3Crect x='35' y='22' width='50' height='28' rx='3' stroke='black' stroke-width='2'/%3E%3Cpolygon points='55,30 55,44 68,37' fill='black'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='48' x2='120' y2='48' stroke='black' stroke-width='1.5'/%3E%3Crect x='35' y='22' width='50' height='28' rx='3' stroke='black' stroke-width='2'/%3E%3Cpolygon points='55,30 55,44 68,37' fill='black'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Paper crane — listening view */
.illustration-listening::before {
  content: '';
  display: block;
  width: 120px;
  height: 60px;
  margin: 0 auto var(--space-3);
  background-color: var(--color-illustration);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='50' x2='120' y2='50' stroke='black' stroke-width='1.5'/%3E%3Cpath d='M40 38 L60 20 L80 38' stroke='black' stroke-width='2' fill='none'/%3E%3Cpath d='M60 20 L55 30 L60 28 L65 30 Z' fill='black'/%3E%3Cpath d='M60 20 L70 24' stroke='black' stroke-width='1.5' fill='none'/%3E%3Cpath d='M50 42 Q60 36 70 42' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 60' fill='none'%3E%3Cline x1='0' y1='50' x2='120' y2='50' stroke='black' stroke-width='1.5'/%3E%3Cpath d='M40 38 L60 20 L80 38' stroke='black' stroke-width='2' fill='none'/%3E%3Cpath d='M60 20 L55 30 L60 28 L65 30 Z' fill='black'/%3E%3Cpath d='M60 20 L70 24' stroke='black' stroke-width='1.5' fill='none'/%3E%3Cpath d='M50 42 Q60 36 70 42' stroke='black' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* illustrationFloat defined in tokens section — no duplicate */
/* Shared illustration opacity — subtle but visible */
.illustration-loading::before,
.illustration-journey::before,
.illustration-complete::before,
.illustration-stars::before,
.illustration-welcome::before,
.illustration-gateway::before,
.illustration-memory::before,
.illustration-forecast::before,
.illustration-error::before,
.illustration-arrival::before,
.illustration-reading::before,
.illustration-media::before,
.illustration-listening::before,
.empty-state::before {
  opacity: 0.5;
}

/* ── Frequency dots enhancement ────────────────────────── */

.freq-dot.active-1 {
  opacity: 0.5;
  background: var(--color-accent);
}

.freq-dot.active-2 {
  background: var(--color-accent);
}

.freq-dot.today {
  box-shadow: 0 0 0 2px var(--color-accent);
}

/* ── Sound toggle ────────────────────────── */

.sound-toggle {
  background: none;
  border: none;
  color: var(--color-text-faint);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  cursor: pointer;
  padding: 2px 6px;
  margin-left: auto;
  transition: color var(--duration-fast) var(--ease-default);
  border-radius: var(--radius);
}

@media (hover: hover) {
  .sound-toggle:hover { color: var(--color-text-dim); }
}

.sound-toggle:focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

.sound-toggle.sound-off {
  opacity: 0.5;
}

/* ── Audio state indicator ────────────────────────── */

.audio-indicator {
  margin-left: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

/* ── Recording overlay ────────────────────────── */

#recording-overlay {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-5) 0;
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-default);
}
#recording-overlay.recording-active {
  opacity: 1;
}
#recording-overlay.hidden {
  display: none;
}

.recording-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-accent);
  animation: recordPulse 1.4s ease-in-out infinite;
}
@keyframes recordPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(0.85); }
}

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

.recording-label {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  letter-spacing: 0.06em;
}

.recording-countdown {
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  color: var(--color-accent);
  font-weight: 300;
  line-height: 1;
  min-height: 1.2em;
}

/* ── Recording panel (speaking drills) ────────── */

.recording-panel {
  background: var(--color-surface);
  border-radius: var(--radius);
  padding: var(--space-4);
  margin: var(--space-3) 0;
  text-align: center;
}

/* State visibility: only show the active state's child */
.rec-safari-notice {
  font-size: var(--text-xs);
  color: var(--color-secondary);
  background: var(--color-base);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-2);
}

.recording-panel .rec-idle,
.recording-panel .rec-recording,
.recording-panel .rec-review,
.recording-panel .rec-analyzing { display: none; }

.recording-panel.rec-state-idle .rec-idle { display: block; }
.recording-panel.rec-state-recording .rec-recording { display: block; }
.recording-panel.rec-state-review .rec-review { display: block; }
.recording-panel.rec-state-analyzing .rec-analyzing { display: block; }

/* Mic button (idle state) */
.rec-mic-btn {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 2px solid var(--color-accent);
  background: transparent;
  color: var(--color-accent);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background var(--duration-fast) var(--ease-default),
              color var(--duration-fast) var(--ease-default);
  padding: 0;
}
.rec-mic-btn svg {
  width: 28px;
  height: 28px;
  fill: currentColor;
}
@media (hover: hover) {
  .rec-mic-btn:hover { background: var(--color-accent); color: var(--color-on-accent); }
}
.rec-mic-btn:focus-visible {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.rec-hint {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-top: var(--space-2);
}

/* Recording state */
.rec-recording {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}

.rec-waveform {
  width: 280px;
  height: 64px;
  border-radius: var(--radius);
}

.rec-elapsed {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  letter-spacing: 0.06em;
}

.rec-stop-btn {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 2px solid var(--color-accent);
  background: transparent;
  color: var(--color-accent);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin-top: var(--space-2);
  transition: background var(--duration-fast) var(--ease-default),
              color var(--duration-fast) var(--ease-default);
}
.rec-stop-btn svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}
@media (hover: hover) {
  .rec-stop-btn:hover { background: var(--color-accent); color: var(--color-on-accent); }
}
.rec-stop-btn:focus-visible {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

/* Review state */
.rec-review {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}

.rec-waveform-frozen {
  width: 280px;
  height: 64px;
  border-radius: var(--radius);
}

.rec-duration {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
}

.rec-review-actions {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

.rec-redo-btn, .rec-submit-btn {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--btn-radius);
  border: 1px solid var(--color-accent);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-default),
              color var(--duration-fast) var(--ease-default);
}

.rec-redo-btn {
  background: transparent;
  color: var(--color-text-dim);
  border-color: var(--color-text-dim);
}
@media (hover: hover) { .rec-redo-btn:hover { background: var(--color-surface-alt); } }

.rec-submit-btn {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
}
@media (hover: hover) { .rec-submit-btn:hover { background: var(--color-accent-dim); } }

/* Analyzing state */
.rec-analyzing {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) 0;
}

.rec-spinner {
  width: 28px;
  height: 28px;
  border: 2px solid color-mix(in srgb, var(--color-accent) 20%, transparent);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

.rec-analyzing-label {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
}

/* Skip link */
.rec-skip {
  display: inline-block;
  margin-top: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  text-decoration: none;
}
@media (hover: hover) { .rec-skip:hover { color: var(--color-text-dim); } }

/* Error state (shown when getUserMedia fails) */
.rec-error {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-incorrect);
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--color-incorrect);
  background: color-mix(in srgb, var(--color-incorrect) 5%, transparent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

/* ── State transitions ────────────────────────── */

/* Section exits: elements leaving should go somewhere, not just fade.
   Exits use ease-in (accelerate out) — the opposite of entrances (ease-out/decelerate in). */
.section-exit {
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity var(--duration-fast) var(--ease-default),
              transform var(--duration-fast) var(--ease-exit);
}

.section-enter {
  animation: sectionEnter var(--duration-base) var(--ease-upward);
}

@keyframes sectionEnter {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ── Page grounding ────────────────────────── */

#app::after {
  content: '';
  display: block;
  width: var(--horizon-width);
  height: 1px;
  background: var(--color-divider);
  margin: var(--space-7) auto var(--space-5);
}

/* ── Utility ────────────────────────── */

.hidden { display: none !important; }

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

.msg-user-echo {
  color: var(--color-text-faint);
  font-style: italic;
  padding-left: var(--space-3);
  margin-bottom: var(--space-2);
}

/* ── Sparkline & frequency ────────────────────────── */

/* Inline sparklines from bridge.py Rich markup conversion */
.sparkline-inline {
  font-size: var(--text-lg);
  letter-spacing: 2px;
  line-height: 1;
  vertical-align: middle;
}

.sparkline-row {
  color: var(--color-accent);
  font-size: var(--text-lg);
  letter-spacing: 2px;
  text-align: center;
  margin-bottom: var(--space-2);
}

.sparkline-label {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  letter-spacing: normal;
}
.sparkline-value {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  font-variant-numeric: tabular-nums;
}

.frequency-row {
  display: flex;
  gap: 3px;
  justify-content: center;
  margin: var(--space-2) 0;
  align-items: center;
}

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

.freq-dot.active {
  background: var(--color-accent);
}

.freq-dot.inactive {
  background: var(--color-divider);
}

.freq-label {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-left: 6px;
}

/* ── Forecast timeline ────────────────────────── */

.forecast-timeline {
  margin: var(--space-2) 0;
}

.forecast-bar {
  height: 3px;
  background: var(--color-divider);
  border-radius: 0;
  position: relative;
  overflow: hidden;
}

.forecast-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: var(--color-accent);
  border-radius: 0;
}

.forecast-fill-animate {
  animation: fillBar 0.6s var(--ease-upward) forwards;
}

@keyframes fillBar {
  from { width: 0; }
}

.forecast-marker {
  position: absolute;
  height: 9px;
  width: 3px;
  background: var(--color-accent);
  top: -3px;
  border-radius: 0;
}

.forecast-timeline-label {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-top: var(--space-1);
}

/* ── Diagnostics / Skill Balance ────────────────── */

.diag-gaps {
  margin-top: var(--space-2);
  border-top: 1px solid var(--color-divider);
  padding-top: var(--space-2);
}

.diag-gap-row .label.dim {
  color: var(--color-text-dim);
  font-size: var(--text-sm);
  font-style: italic;
}

#diagnostics-content .forecast-timeline {
  margin: 0 0 var(--space-2) 0;
}

/* ── Weekly summary card ────────────────────────── */

/* Streak calendar on dashboard */
.streak-calendar {
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  margin: 0 0 var(--space-2) 0;
  text-align: center;
  animation: driftUp var(--duration-base) var(--ease-upward);
}
.streak-header {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.streak-count {
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-accent);
  line-height: 1;
}
.streak-rhythm {
  display: inline-flex;
  gap: 3px;
  align-items: center;
}
.rhythm-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-divider);
}
.rhythm-dot.rhythm-active {
  background: var(--color-accent);
}
.streak-label {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
}
.cal-heatmap {
  display: flex;
  gap: var(--space-1);
  justify-content: center;
}
.cal-labels {
  display: grid;
  grid-template-rows: repeat(7, 14px);
  gap: 2px;
  text-align: right;
  padding-right: 2px;
}
.cal-labels span {
  font-size: 0.65rem;
  color: var(--color-text-faint);
  line-height: 14px;
}
.cal-grid {
  display: grid;
  grid-template-rows: repeat(7, 14px);
  grid-auto-flow: column;
  gap: 2px;
}
.cal-cell {
  width: 14px;
  height: 14px;
  border-radius: 2px;
  display: block;
}
.cal-empty { background: transparent; }
.cal-0 { background: var(--color-divider); }
.cal-1 { background: var(--color-secondary); opacity: 0.7; }
.cal-2 { background: var(--color-accent); }

/* Next session preview — matches weekly-summary styling */
.next-session-preview {
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  margin: 0 0 var(--space-3) 0;
  text-align: left;
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  animation: driftUp var(--duration-base) var(--ease-upward);
  transition: background var(--duration-fast) var(--ease-default);
}
@media (hover: hover) {
  .next-session-preview:hover { background: var(--color-surface-alt); }
}
.session-preview-header {
  font-size: var(--text-xs);
  color: var(--color-accent);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  margin-bottom: var(--space-2);
}
.session-preview-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.session-preview-list li {
  font-size: var(--text-sm);
  color: var(--color-text);
  padding: var(--space-1) 0;
  padding-left: var(--space-4);
  position: relative;
}
.session-preview-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--color-accent);
  transform: translateY(-50%);
  opacity: 0.5;
}

.weekly-summary {
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  margin: 0 0 var(--space-3) 0;
  text-align: center;
  animation: driftUp var(--duration-base) var(--ease-upward);
}
.weekly-summary-label {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: var(--space-1);
}
.weekly-summary-stats {
  font-size: var(--text-sm);
  color: var(--color-text);
}
.weekly-summary-words {
  margin-top: var(--space-1);
  font-family: var(--font-hanzi);
  font-size: var(--text-base);
  color: var(--color-accent);
}
.weekly-summary-words sub {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-left: 1px;
}
.weekly-word {
  margin: 0 var(--space-1);
}

/* ── Option buttons (MC drills) ────────────────────────── */

.option-buttons {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: var(--space-2) 0;
}

.btn-option {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  color: var(--color-text);
  border: none;
  border-bottom: 1px solid var(--color-divider);
  border-left: 3px solid transparent;
  padding: 14px 18px;
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-default), border-color var(--duration-fast) var(--ease-default), transform var(--duration-press) var(--ease-default);
  min-height: 48px;
  line-height: 1.4;
  /* Stagger entrance — delay set per-item in JS via style attribute.
     Uses opacity-only animation (not driftUp with transform) to avoid
     WebKit hit-test stale region bug where transform-animated elements
     don't register clicks until a scroll forces repaint. */
  animation: optionFadeIn var(--duration-fast) var(--ease-upward) backwards;
}

@keyframes optionFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (hover: hover) {
  .btn-option:hover {
    background: var(--color-surface-alt);
    border-left-color: var(--color-accent);
  }
}

.btn-option:active {
  transform: scale(0.98);
  background: var(--color-accent);
  color: var(--color-on-accent);
}
.btn-option:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

/* Keyboard shortcut hint pill (1-9 next to MC options) */
.key-hint {
  display: inline-block;
  font-family: var(--font-mono, monospace);
  font-size: var(--text-xs);
  color: var(--color-text-faintest, #707A8A);
  border: 1px solid var(--color-divider, #D8D0C4);
  padding: 1px 5px;
  margin-left: 6px;
  border-radius: 3px;
  line-height: 1.3;
  vertical-align: middle;
  opacity: 0.6;
}

.btn-option-action {
  text-align: center;
  font-weight: 500;
}

.btn-option-primary {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
  font-weight: 600;
  text-align: center;
}

@media (hover: hover) {
  .btn-option-primary:hover {
    opacity: 0.88;
    background: var(--color-accent);
    border-color: var(--color-accent);
  }
}

.btn-option-replay {
  background: transparent;
  border: 1px solid var(--color-accent-dim);
  border-left: 1px solid var(--color-accent-dim);
  color: var(--color-accent);
  text-align: center;
  font-size: var(--text-xs);
  padding: 10px 14px;
  min-height: 44px;
}

@media (hover: hover) {
  .btn-option-replay:hover {
  background: var(--color-surface);
  border-color: var(--color-accent);
}
}

.option-buttons-row {
  flex-direction: row;
  flex-wrap: wrap;
}

.option-buttons-row .btn-option {
  flex: 1;
  min-width: 80px;
  text-align: center;
}

/* ── Exposure buttons (Read / Watch / Listen) ────────────────────────── */

.actions-exposure {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  margin: var(--space-1) 0 var(--space-3);
}

.actions-exposure .btn-secondary {
  padding: 10px 20px;
  font-size: var(--text-sm);
}

.encounter-badge {
  text-align: center;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  font-style: italic;
  margin-bottom: var(--space-3);
}

/* ── Back nav button ────────────────────────── */

.btn-back-nav {
  padding: 8px 16px;
  font-size: var(--text-sm);
  margin-bottom: var(--space-3);
}

/* ── Reading view ────────────────────────── */

.reading-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

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

.reading-controls select {
  background: var(--color-surface-alt);
  color: var(--color-text);
  border: 1px solid var(--color-divider);
  padding: 6px 10px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  border-radius: 0;
}

.toggle-label {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
}

.toggle-label input[type="checkbox"] {
  accent-color: var(--color-accent);
}

.reading-list {
  margin: var(--space-3) 0;
}

@media (min-width: 1024px) {
  .reading-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 var(--space-4);
  }
}

.reading-list-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--color-divider);
  padding: 12px var(--space-3);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-text);
  text-align: left;
  transition: background var(--duration-fast) var(--ease-default);
  min-height: 44px;
}

@media (hover: hover) {
  .reading-list-item:hover {
  background: var(--color-surface-alt);
}
}

.reading-list-title {
  font-family: var(--font-hanzi);
}

.reading-list-meta {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  flex-shrink: 0;
}

.reading-upgrade-hint {
  text-align: center;
  padding: var(--space-4) var(--space-3);
  color: var(--color-text-faint);
  font-size: var(--text-sm);
}

/* Feature onboarding tooltip */
.feature-tooltip {
  position: fixed;
  bottom: var(--space-6);
  left: 50%;
  transform: translateX(-50%);
  max-width: 360px;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  box-shadow: 0 4px 24px rgba(0,0,0,0.12);
  z-index: 100;
  text-align: center;
  animation: driftUp var(--duration-base) var(--ease-upward);
}

.feature-tooltip p {
  font-size: var(--text-sm);
  color: var(--color-text);
  margin: 0 0 var(--space-2);
  line-height: 1.5;
}

.feature-tooltip-dismiss {
  color: var(--color-accent);
}

.feature-tooltip-exit {
  opacity: 0;
  transform: translateX(-50%) translateY(8px);
  transition: opacity 0.3s, transform 0.3s;
}

.reading-passage {
  animation: driftUp var(--duration-base) var(--ease-upward);
  max-width: 780px;
  margin: 0 auto;
}

/* Focus insight — adaptive intelligence card shown at session start */
.focus-insight {
  text-align: left;
  padding: var(--space-4) var(--space-5);
  margin: var(--space-4) auto;
  max-width: 420px;
  background: color-mix(in srgb, var(--color-accent) 6%, var(--color-surface));
  border: 1px solid color-mix(in srgb, var(--color-accent) 18%, transparent);
  border-radius: var(--radius);
  animation: driftUp var(--duration-base) var(--ease-upward);
  transition: opacity 0.4s ease;
}
.focus-insight-header {
  font-size: var(--text-xs);
  color: var(--color-accent);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: var(--space-2);
  font-weight: 600;
}
.focus-insight-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-2);
}
.focus-insight-list li {
  font-size: var(--text-sm);
  color: var(--color-text);
  padding: var(--space-1) 0;
  padding-left: var(--space-4);
  position: relative;
}
.focus-insight-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-accent);
  transform: translateY(-50%);
  opacity: 0.6;
}
.focus-insight-plan {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  padding-top: var(--space-2);
  border-top: 1px solid color-mix(in srgb, var(--color-accent) 12%, transparent);
}

/* Reading opener — shown before drills */
.reading-opener {
  text-align: center;
  padding: var(--space-6) var(--space-4);
  animation: driftUp var(--duration-base) var(--ease-upward);
}

.reading-opener-label {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: var(--space-2);
}

.reading-opener-title {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  color: var(--color-text);
  margin-bottom: var(--space-4);
}

.reading-opener-text {
  font-family: var(--font-hanzi);
  font-size: var(--text-2xl);
  line-height: 2.0;
  color: var(--color-text);
  text-align: left;
  max-width: 480px;
  margin: 0 auto var(--space-4);
  padding: var(--space-4);
  background: var(--color-surface);
  border-radius: var(--radius);
}

.reading-opener-hint {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-bottom: var(--space-4);
}

.reading-opener-continue {
  margin-top: var(--space-3);
}

/* Post-drills reading opener — scaffolded */
.reading-opener-intro {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-4);
  max-width: 400px;
  margin-left: auto;
  margin-right: auto;
}

/* Ruby annotations for unknown characters */
.reading-opener-text ruby {
  ruby-position: over;
}

.reading-opener-text ruby rt {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-accent);
  font-weight: 400;
  letter-spacing: 0;
}

.reading-word-unknown {
  color: var(--color-text);
  cursor: pointer;
  border-bottom: 1px dotted var(--color-accent);
}

.reading-word-known {
  cursor: pointer;
}

.reading-text {
  font-family: var(--font-hanzi);
  font-size: var(--text-2xl);
  line-height: 2.0;
  color: var(--color-text);
  padding: var(--space-5) var(--space-4);
  background: var(--color-surface-alt);
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
  margin: var(--space-3) 0;
}

.reading-word {
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-default);
  border-bottom: 1px dotted transparent;
  padding: 0 1px;
}

@media (hover: hover) {
  .reading-word:hover {
    background: color-mix(in srgb, var(--color-accent) 12%, transparent);
    border-bottom-color: var(--color-accent);
  }
}

.reading-word.gloss-active {
  background: color-mix(in srgb, var(--color-accent) 20%, transparent);
  transition: background var(--duration-fast) var(--ease-default);
}

@keyframes glossFade {
  from { background: color-mix(in srgb, var(--color-accent) 20%, transparent); }
  to { background: transparent; }
}

.reading-word.gloss-fading {
  animation: glossFade 1s var(--ease-default) forwards;
}

/* Adaptive script — known vs unknown word styling */
.reading-word.unknown {
  border-bottom-color: color-mix(in srgb, var(--color-accent) 30%, transparent);
}

/* ── Reading block (cleanup loop: exposure → drills → re-read) ──── */

.reading-block {
  text-align: center;
  padding: var(--space-6) var(--space-4);
}

.reading-block-label {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-2);
}

.reading-block-title {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  margin-bottom: var(--space-3);
}

.reading-block-text {
  font-family: var(--font-hanzi);
  font-size: var(--text-2xl);
  line-height: 2;
  text-align: left;
  margin-bottom: var(--space-4);
}

.reading-block-hint {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-bottom: var(--space-3);
}

.reading-block-ready {
  margin-top: var(--space-3);
}

/* Re-read mode: drilled words get a subtle green glow */
.reading-word-drilled {
  background: color-mix(in srgb, var(--color-correct) 15%, transparent);
  border-radius: 2px;
  transition: background 0.3s;
}

/* Exposure label styling */
.reading-block-exposure .reading-block-label {
  color: var(--color-accent);
}

/* Re-read label styling */
.reading-block-reread .reading-block-label {
  color: var(--color-correct);
}

.reading-text ruby {
  ruby-position: over;
}

.reading-text rt {
  font-size: 0.45em;
  color: var(--color-accent);
  font-family: var(--font-body);
  font-weight: normal;
  opacity: 0.8;
}

.reading-pinyin {
  font-size: var(--text-base);
  color: var(--color-text-dim);
  line-height: 1.8;
  padding: var(--space-3) var(--space-4);
}

.reading-translation {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  font-style: italic;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-divider);
}

.reading-gloss {
  position: fixed;
  z-index: 9999;
  background: var(--color-base);
  color: var(--color-text);
  border: 1px solid var(--color-divider);
  padding: 8px 14px;
  font-size: var(--text-sm);
  font-family: var(--font-body);
  max-width: 240px;
  pointer-events: none;
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

.reading-stats {
  text-align: center;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  padding: var(--space-2) 0;
  font-style: italic;
}

.reading-nav {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.reading-nav button {
  flex: 1;
}

/* ── Media view ────────────────────────── */

.media-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.media-header h2 {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 400;
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-normal);
}

.media-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}

@media (min-width: 480px) {
  .media-grid {
    grid-template-columns: 1fr 1fr;
  }
}

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

.media-card {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  padding: var(--space-4);
  transition: background var(--duration-fast) var(--ease-default);
  animation: driftUp var(--duration-base) var(--ease-upward);
}

@media (hover: hover) {
  .media-card:hover {
    background: color-mix(in srgb, var(--color-surface-alt) 80%, var(--color-accent) 5%);
  }
}

.media-card-header {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  flex-wrap: wrap;
}

.media-hsk-badge {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-text-dim);
  padding: 2px 6px;
  border: 1px solid var(--color-divider);
}

.media-cost-badge {
  font-size: var(--text-xs);
  padding: 2px 6px;
  border: 1px solid;
}

.cost-free { color: var(--color-correct); border-color: var(--color-correct); }
.cost-sub { color: var(--color-text-dim); border-color: var(--color-divider); }
.cost-purchase { color: var(--color-accent); border-color: var(--color-accent); }

.media-watched-badge {
  font-size: var(--text-xs);
  color: var(--color-correct);
  font-style: italic;
}

.media-card-title {
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-1);
}

.media-card-type {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  text-transform: capitalize;
  margin-bottom: var(--space-1);
}

.media-card-where {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  font-style: italic;
  margin-bottom: var(--space-2);
}

.media-card-where a {
  color: var(--color-accent);
  text-decoration: none;
  font-style: normal;
}

.media-card-where a:hover {
  text-decoration: underline;
}

.media-card-alt {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  font-style: normal;
  margin-left: 0.25em;
}

.media-card-alt a {
  color: var(--color-text-dim);
  text-decoration: underline;
  font-style: normal;
}

.media-card-alt a:hover {
  color: var(--color-accent);
}

.media-card-actions {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.media-card-actions button {
  background: transparent;
  border: 1px solid var(--color-divider);
  color: var(--color-text-dim);
  padding: 8px 10px;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-default), color var(--duration-fast) var(--ease-default);
  min-height: 44px;
}

@media (hover: hover) {
  .media-card-actions button:hover {
    background: var(--color-surface);
    color: var(--color-accent);
  }
}

.media-history-section {
  border-top: 1px solid var(--color-divider);
  padding-top: var(--space-4);
}

.media-history-section h3 {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-weight: 600;
  margin-bottom: var(--space-3);
  letter-spacing: var(--tracking-normal);
}

.media-stats {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-bottom: var(--space-3);
}

.media-history-item {
  display: flex;
  justify-content: space-between;
  padding: var(--space-2) 0;
  border-bottom: 1px solid color-mix(in srgb, var(--color-divider) 50%, transparent);
  font-size: var(--text-sm);
}

.media-history-title {
  color: var(--color-text-dim);
}

.media-history-score {
  color: var(--color-text-faint);
  font-style: italic;
}

/* ── Media comprehension quiz ─────────────── */

.media-quiz-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.media-quiz-header h2 {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  color: var(--color-text);
}

.media-quiz-source {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-3);
  padding-left: var(--space-1);
}

.media-quiz-vocab {
  background: var(--color-surface);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

.quiz-vocab-label {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-bottom: var(--space-2);
}

.quiz-vocab-item {
  display: flex;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-1) 0;
}

.quiz-vocab-hanzi {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  color: var(--color-accent);
}

.quiz-vocab-pinyin {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
}

.quiz-vocab-english {
  font-size: var(--text-sm);
  color: var(--color-text);
}

.media-quiz-passage {
  background: var(--color-surface);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

.quiz-passage-label {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-bottom: var(--space-2);
}

.quiz-passage-zh {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  line-height: 1.8;
  margin-bottom: var(--space-2);
}

.quiz-passage-en {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  font-style: italic;
}

.quiz-question {
  margin-bottom: var(--space-4);
}

.quiz-q-number {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-bottom: var(--space-2);
}

.quiz-q-text {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  color: var(--color-text);
  margin-bottom: var(--space-1);
}

.quiz-q-en {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-bottom: var(--space-3);
}

.quiz-option {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-size: var(--text-base);
  color: var(--color-text);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-default), border-color var(--duration-fast) var(--ease-default);
}

@media (hover: hover) {
  .quiz-option:hover:not(:disabled) {
    background: var(--color-surface-alt);
    border-color: var(--color-accent);
  }
}

.quiz-option:disabled {
  cursor: default;
  opacity: 0.85;
}

.quiz-option-en {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
}

.quiz-option-pinyin {
  font-size: var(--text-sm);
  color: var(--color-accent);
  margin-left: var(--space-1);
}

.quiz-q-secondary {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-top: calc(-1 * var(--space-2));
  margin-bottom: var(--space-3);
}

.quiz-option-correct {
  background: color-mix(in srgb, var(--color-correct) 15%, var(--color-surface));
  border-color: var(--color-correct);
}

.quiz-option-incorrect {
  background: color-mix(in srgb, var(--color-incorrect) 15%, var(--color-surface));
  border-color: var(--color-incorrect);
}

.media-quiz-result {
  text-align: center;
  padding: var(--space-4);
}

.quiz-score {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  color: var(--color-text);
}

.media-quiz-cultural {
  background: var(--color-surface);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  margin-top: var(--space-3);
}

.quiz-cultural-note {
  font-size: var(--text-sm);
  color: var(--color-text);
  line-height: 1.6;
  margin-bottom: var(--space-2);
}

.quiz-follow-up {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  font-style: italic;
}

.btn-media-quiz {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border: none;
  border-radius: var(--radius);
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-default);
}

@media (hover: hover) { .btn-media-quiz:hover { opacity: 0.85; } }
.btn-media-quiz:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.btn-media-quiz:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

/* ── Listening view ────────────────────────── */

.listening-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

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

.listening-controls select {
  background: var(--color-surface-alt);
  color: var(--color-text);
  border: 1px solid var(--color-divider);
  padding: 6px 10px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  border-radius: 0;
}

.speed-control {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--text-xs);
  color: var(--color-text-dim);
}

.listening-content {
  text-align: center;
}

.listening-title {
  font-family: var(--font-hanzi);
  font-size: var(--text-xl);
  color: var(--color-accent);
  margin-bottom: var(--space-4);
  font-weight: 700;
}

.listening-actions {
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.listening-questions {
  text-align: left;
  margin-top: var(--space-4);
  border-top: 1px solid var(--color-divider);
  padding-top: var(--space-4);
}

.listening-questions h3 {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-weight: 600;
  margin-bottom: var(--space-3);
  letter-spacing: var(--tracking-normal);
}

.listening-question {
  margin-bottom: var(--space-4);
}

.listening-q-text {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  color: var(--color-text);
  margin-bottom: var(--space-1);
}

.listening-q-en {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-bottom: var(--space-2);
}

.listening-answer {
  font-family: var(--font-hanzi);
  font-size: var(--text-base);
  color: var(--color-correct);
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--color-correct);
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

.btn-show-answer {
  font-size: var(--text-xs);
  padding: 4px 12px;
}

.listening-self-assess {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

.listening-assess-label {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.listening-assess-result {
  font-size: var(--text-xs);
  margin-top: var(--space-1);
  display: block;
}

.listening-assess-result.correct { color: var(--color-correct); }
.listening-assess-result.incorrect { color: var(--color-incorrect); }

.listening-score {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text);
  padding: var(--space-3);
  border-top: 1px solid var(--color-divider);
  margin-top: var(--space-3);
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

/* ── Reusable MC question styles (reading + listening) ──── */

.reading-questions,
.listening-questions {
  text-align: left;
  margin-top: var(--space-4);
  border-top: 1px solid var(--color-divider);
  padding-top: var(--space-4);
}

.reading-questions h3,
.listening-questions h3 {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-weight: 600;
  margin-bottom: var(--space-3);
  letter-spacing: var(--tracking-normal);
}

.mc-question {
  margin-bottom: var(--space-5);
}

.mc-q-number {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-bottom: var(--space-1);
}

.mc-q-zh {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  color: var(--color-text);
  margin-bottom: var(--space-1);
}

.mc-q-secondary {
  font-size: var(--text-base);
  color: var(--color-text-dim);
}

.mc-q-en {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-bottom: var(--space-2);
}

.mc-options {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.mc-option {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-base);
  cursor: pointer;
  transition: background var(--duration-fast), border-color var(--duration-fast);
  min-height: 44px;
}

.mc-option:hover:not(:disabled) {
  background: var(--color-surface);
  border-color: var(--color-accent);
}

.mc-option:disabled {
  cursor: default;
  opacity: 0.7;
}

.mc-opt-pinyin {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
}

.mc-opt-en {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
}

.mc-correct {
  background: color-mix(in srgb, var(--color-correct) 12%, var(--color-surface)) !important;
  border-color: var(--color-correct) !important;
  color: var(--color-correct);
  opacity: 1 !important;
}

.mc-incorrect {
  background: color-mix(in srgb, var(--color-incorrect) 12%, var(--color-surface)) !important;
  border-color: var(--color-incorrect) !important;
  color: var(--color-incorrect);
  opacity: 1 !important;
}

.mc-feedback {
  font-size: var(--text-sm);
  color: var(--color-text-secondary, var(--color-text));
  opacity: 0.85;
  padding: var(--space-2) var(--space-3);
  margin-top: var(--space-2);
  border-left: 2px solid var(--color-accent);
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

.mc-score {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text);
  padding: var(--space-3);
  border-top: 1px solid var(--color-divider);
  margin-top: var(--space-3);
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

/* ── Media action buttons ────────────────────────── */

.btn-media-watched,
.btn-media-skip,
.btn-media-like {
  background: transparent;
  border: 1px solid var(--color-divider);
  color: var(--color-text-dim);
  padding: 4px 10px;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-default),
              color var(--duration-fast) var(--ease-default),
              border-color var(--duration-fast) var(--ease-default);
  min-height: 44px;
}

@media (hover: hover) { .btn-media-watched:hover { border-color: var(--color-correct); color: var(--color-correct); } }
@media (hover: hover) { .btn-media-skip:hover { border-color: var(--color-text-faint); color: var(--color-text-faint); } }
@media (hover: hover) { .btn-media-like:hover { border-color: var(--color-accent); color: var(--color-accent); } }

/* ── Onboarding wizard ────────────────────────── */

.onboarding-wizard {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-overlay);
  padding: var(--space-4);
  opacity: 1;
  transition: opacity 0.3s ease;
}
.onboarding-wizard.onboarding-exit {
  opacity: 0;
}

.onboarding-wizard-card {
  background: var(--color-base);
  border-radius: var(--radius);
  padding: var(--space-6);
  max-width: 420px;
  width: 100%;
}

.onboarding-wizard p {
  font-family: var(--font-body);
  font-size: var(--text-lg);
  color: var(--color-text);
  margin-bottom: var(--space-4);
  text-align: center;
}

.onboarding-step.hidden {
  display: none;
}

.onboarding-options {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.onboarding-opt {
  text-align: left !important;
  padding: 12px 16px !important;
}

.onboarding-back-btn {
  margin-top: var(--space-3);
  width: 100%;
}

/* ── Classroom / teacher view ────────────────────────── */

/* Compact header when inside a sub-view */
#app.subview-active > header {
  padding: var(--space-1) 0 var(--space-2);
}

#app.subview-active .logo-icon {
  width: 36px;
  height: 36px;
  margin-bottom: var(--space-1);
}

#app.subview-active .logo-text {
  font-size: var(--text-base);
  margin-bottom: 0;
}

#app.subview-active .account-bar {
  font-size: var(--text-xs);
  margin-bottom: 0;
}

#app.subview-active .horizon,
#app.subview-active .session-info {
  display: none;
}

.teacher-header {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.teacher-header h2 {
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  font-weight: 400;
  color: var(--color-text);
  letter-spacing: var(--tracking-tight);
  margin: 0;
}

/* #1: Lighter back button in teacher view */
#teacher-dashboard .btn-back-nav {
  background: none;
  border: none;
  color: var(--color-accent);
  padding: 0;
  font-size: var(--text-sm);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

#teacher-dashboard .btn-back-nav:hover {
  color: var(--color-accent-dim);
  text-decoration: underline;
}

.teacher-actions {
  margin-bottom: var(--space-5);
}

.teacher-create-form {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  padding: var(--space-4);
  margin-bottom: var(--space-5);
}

.teacher-create-form .field {
  margin-bottom: var(--space-3);
}

.teacher-create-btns {
  display: flex;
  gap: var(--space-2);
}

.class-detail-header {
  margin-bottom: var(--space-4);
}

.class-detail-header h3 {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: 400;
  color: var(--color-text);
}

.class-code-display {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-top: var(--space-1);
}

.class-detail-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--color-divider);
  margin-bottom: var(--space-5);
}

.class-tab {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  background: none;
  border: none;
  padding: var(--space-2) var(--space-4);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color var(--duration-fast) var(--ease-default), border-color var(--duration-fast) var(--ease-default);
}

.class-tab:hover {
  color: var(--color-text);
}

.class-tab.active {
  color: var(--color-text);
  border-bottom-color: var(--color-accent);
}

/* Summary cards */
.teacher-summary-cards {
  display: flex;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
  flex-wrap: wrap;
}

.teacher-summary-card {
  flex: 1;
  min-width: 100px;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  padding: var(--space-3) var(--space-4);
  text-align: center;
  border-top: 3px solid var(--color-divider);
}

/* #5: Color-differentiated summary cards */
.teacher-summary-card:nth-child(1) { border-top-color: var(--color-accent); }
.teacher-summary-card:nth-child(2) { border-top-color: var(--color-secondary); }
.teacher-summary-card:nth-child(3) { border-top-color: var(--color-mastery-stabilizing); }
.teacher-summary-card:nth-child(4) { border-top-color: var(--color-text-dim); }

.teacher-summary-value {
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  font-weight: 600;
  color: var(--color-text);
  line-height: var(--lh-tight);
}

.teacher-summary-label {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  margin-top: var(--space-1);
  letter-spacing: var(--tracking-normal);
}

.teacher-summary-alert {
  border-top-color: var(--color-incorrect) !important;
}

.teacher-summary-alert .teacher-summary-value {
  color: var(--color-incorrect);
}

/* Student status badges */
.student-status {
  font-size: var(--text-xs);
  font-family: var(--font-body);
  padding: 2px 8px;
  border-radius: 2px;
  letter-spacing: var(--tracking-normal);
}

.student-status-active {
  color: var(--color-correct);
  background: color-mix(in srgb, var(--color-correct) 10%, transparent);
}

.student-status-ok {
  color: var(--color-text-dim);
  background: color-mix(in srgb, var(--color-text-dim) 8%, transparent);
}

.student-status-idle {
  color: var(--color-text-faint);
  background: color-mix(in srgb, var(--color-text-faint) 8%, transparent);
}

.student-status-risk {
  color: var(--color-incorrect);
  background: color-mix(in srgb, var(--color-incorrect) 10%, transparent);
}

/* Student table */
.class-student-table table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
}

.class-student-table thead th {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-divider);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.class-student-table thead th:hover {
  color: var(--color-text);
}

.class-student-table tbody tr {
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-default);
}

.class-student-table tbody tr:hover {
  background: color-mix(in srgb, var(--color-surface-alt) 80%, var(--color-accent) 5%);
}

.class-student-table tbody td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-divider);
  font-size: var(--text-base);
  color: var(--color-text);
}

.class-student-table tbody td:first-child {
  font-weight: 600;
}

.class-student-table tbody td:nth-child(2) {
  color: var(--color-text-dim);
  font-size: var(--text-sm);
}

.class-student-table tbody td:nth-child(3),
.class-student-table tbody td:nth-child(4) {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
}

/* #3: Row click affordance — chevron on last cell */
.class-student-table tbody td:last-child {
  position: relative;
  padding-right: calc(var(--space-3) + 16px);
}

.class-student-table tbody td:last-child::after {
  content: "\203A";
  position: absolute;
  right: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--text-lg);
  color: var(--color-text-faint);
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-default);
}

.class-student-table tbody tr:hover td:last-child::after {
  opacity: 1;
}

/* Contextual tip for small rosters */
.teacher-tip {
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--color-accent);
  color: var(--color-text-dim);
  font-size: var(--text-sm);
  font-family: var(--font-body);
}

.teacher-tip p { margin: 0; }

/* Invite section */
.invite-section {
  max-width: 480px;
}

.invite-code-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-3) 0 var(--space-5);
}

.invite-code-big {
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.2em;
  padding: var(--space-2) var(--space-4);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
}

.invite-bulk-section {
  border-top: 1px solid var(--color-divider);
  padding-top: var(--space-4);
}

.invite-bulk-section h4 {
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: 600;
  margin-bottom: var(--space-2);
}

.invite-bulk-section textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  padding: var(--space-2);
  border: 1px solid var(--color-divider);
  background: var(--color-base);
  color: var(--color-text);
  margin-bottom: var(--space-2);
  resize: vertical;
}

/* Student detail panel */
.student-detail-panel {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  padding: var(--space-5);
  margin-top: var(--space-4);
}

.student-detail-panel h4 {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 400;
  margin-bottom: var(--space-4);
}

.class-card {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-default);
  margin-bottom: var(--space-2);
}

@media (hover: hover) {
  .class-card:hover {
    background: color-mix(in srgb, var(--color-surface-alt) 80%, var(--color-accent) 5%);
  }
}

.class-card-header {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}

.class-card-name {
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text);
}

.class-card-code {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.class-card-stats {
  display: flex;
  gap: var(--space-3);
  font-size: var(--text-xs);
  color: var(--color-text-dim);
}

/* ── Analytics / student detail ────────────────────────── */

.analytics-row {
  display: flex;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.analytics-card {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
}

.analytics-card h4 {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-normal);
  margin-bottom: var(--space-2);
}

.analytics-value {
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  font-weight: 600;
  color: var(--color-text);
}

.student-stat-row {
  display: flex;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.student-stat-card {
  flex: 1;
  text-align: center;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  padding: var(--space-3);
}

.drill-accuracy-bars {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.drill-accuracy-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.drill-accuracy-row .label {
  flex: 0 0 120px;
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.drill-accuracy-row .value {
  flex: 0 0 40px;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  text-align: right;
}

.bar-track {
  flex: 1;
  height: 8px;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: 4px;
  transition: width var(--duration-fast) var(--ease-default);
}

.weekly-trend-row {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 60px;
}

.weekly-trend-bar {
  flex: 1;
  background: var(--color-accent);
  border-radius: 2px 2px 0 0;
  min-height: 3px;
}

/* ── Struggle Areas ──────────────────────────────────── */
.struggle-list { display: flex; flex-direction: column; gap: var(--space-1); }
.struggle-item { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) 0; border-bottom: 1px solid var(--color-divider); font-size: var(--text-sm); }
.struggle-item:last-child { border-bottom: none; }
.struggle-hanzi { font-family: var(--font-hanzi); font-size: var(--text-base); min-width: 3em; }
.struggle-pinyin { color: var(--color-text-dim); min-width: 5em; }
.struggle-english { flex: 1; color: var(--color-text-dim); }
.struggle-errors { color: var(--color-incorrect); font-weight: 600; min-width: 5em; text-align: right; }
.struggle-drill { font-size: var(--text-xs); color: var(--color-text-faint); min-width: 4em; text-align: right; }

/* ── Small icons & sort arrows ────────────────────────── */

.icon-sm {
  width: 14px;
  height: 14px;
  vertical-align: middle;
}

.sort-arrow {
  display: inline-flex;
  align-items: center;
  margin-left: 2px;
  vertical-align: middle;
}

/* ── Session Explainability ─────────────────────── */
.session-explain {
  text-align: center;
  margin-top: var(--space-2);
}
.btn-link {
  background: none;
  border: none;
  color: var(--color-text-dim);
  cursor: pointer;
  font-size: var(--text-sm);
  text-decoration: underline;
  padding: var(--space-1) var(--space-2);
}
@media (hover: hover) { .btn-link:hover { color: var(--color-accent); } }
.btn-danger-text { color: var(--color-incorrect); }
.session-explain-content {
  text-align: left;
  margin-top: var(--space-2);
  padding: var(--space-3);
  background: var(--color-surface);
  border-radius: var(--radius);
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
}
.explain-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.explain-list li {
  padding: var(--space-1) 0;
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  border-bottom: 1px solid var(--color-border);
}
.explain-list li:last-child { border-bottom: none; }

/* ── Mastery Criteria Modal ────────────────────── */
.mastery-modal-overlay {
  position: fixed;
  inset: 0;
  background: var(--color-overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.mastery-modal-card {
  background: var(--color-base);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  max-width: 420px;
  width: 90%;
  box-shadow: var(--shadow-lg);
}
.mastery-modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-3);
}
.mastery-modal-title {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  color: var(--color-text);
}
.mastery-modal-close {
  background: none;
  border: none;
  font-size: 1.5rem;
  color: var(--color-text-dim);
  cursor: pointer;
  padding: var(--space-1);
}
@media (hover: hover) { .mastery-modal-close:hover { color: var(--color-text); } }
.mastery-stage {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-3);
}
.mastery-gates { display: flex; flex-direction: column; gap: var(--space-3); }
.mastery-gate { }
.mastery-modal-body { }
.mastery-gate-label {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-1);
}
.mastery-gate-bar {
  height: 6px;
  background: var(--color-surface);
  border-radius: 3px;
  overflow: hidden;
}
.mastery-gate-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: 3px;
  transition: width 0.4s ease;
}
.mastery-gate-fill.met { background: var(--color-correct); }
.mastery-gate-values {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-top: 2px;
}

/* ── Personalization Domains ───────────────────── */
.personalization-domains {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.personalization-domain-label {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-sm);
  cursor: pointer;
}
.personalization-domain-label input[type=checkbox] {
  flex-shrink: 0;
}
.personalization-domain-name {
  font-weight: 500;
  color: var(--color-text);
}
.personalization-domain-desc {
  color: var(--color-text-dim);
  font-size: var(--text-xs);
}

/* ── Placement Quiz ────────────────────────────── */
.placement-progress {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-3);
}
.placement-question { text-align: center; }
.placement-hanzi {
  font-family: var(--font-hanzi);
  font-size: 2.5rem;
  color: var(--color-accent);
  margin-bottom: var(--space-1);
}
.placement-pinyin {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-3);
}
.placement-result {
  text-align: center;
  padding: var(--space-4) 0;
}
.placement-result strong {
  font-size: var(--text-xl);
  color: var(--color-accent);
}

/* Session history: early exit badge */
.session-badge-early {
  display: inline-block;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  padding: 1px 6px;
  margin-left: 6px;
  vertical-align: middle;
}

/* ── Time-of-day illustration tinting ────────────────────────── */

html[data-theme="dark"] .illustration-loading::before,
html[data-theme="dark"] .illustration-journey::before,
html[data-theme="dark"] .illustration-complete::before,
html[data-theme="dark"] .illustration-stars::before,
html[data-theme="dark"] .illustration-welcome::before,
html[data-theme="dark"] .illustration-gateway::before,
html[data-theme="dark"] .illustration-memory::before,
html[data-theme="dark"] .illustration-forecast::before,
html[data-theme="dark"] .illustration-error::before,
html[data-theme="dark"] .illustration-arrival::before,
html[data-theme="dark"] .illustration-reading::before,
html[data-theme="dark"] .illustration-media::before,
html[data-theme="dark"] .illustration-listening::before,
html[data-theme="dark"] .empty-state::before {
  opacity: 0.6;
  filter: brightness(1.3) hue-rotate(15deg);
}

/* ── Reduced motion ────────────────────────── */

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

/* ── Mobile: small phones ────────────────────────── */

@media (max-width: 360px) {
  #app { padding: var(--space-2) var(--space-2); padding-top: calc(var(--space-5) + env(safe-area-inset-top, 0px)); }
  .logo-icon { width: 48px; height: 48px; }
  .msg-hanzi { font-size: var(--text-2xl); letter-spacing: var(--tracking-wide); }
  .stat { padding: var(--space-2) var(--space-3); min-width: 48px; }
  .stat-value { font-size: var(--text-lg); }
  .stats-row { gap: var(--space-2); }
  .actions { flex-direction: column; }
  .actions button { width: 100%; }
  .shortcuts { gap: 4px; }
  .btn-shortcut { padding: 6px 8px; font-size: var(--text-xs); }
}

/* ── Mobile: standard phones ────────────────────────── */

@media (max-width: 480px) {
  #app { padding: var(--space-3); padding-top: calc(var(--space-6) + env(safe-area-inset-top, 0px)); }
  .logo-icon { width: 52px; height: 52px; }

  /* Settings rows stack on narrow screens */
  .settings-row {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
  }
  .settings-value {
    text-align: left;
    width: 100%;
    white-space: normal;
  }
  .settings-label {
    max-width: none;
  }

  .msg-hanzi {
    font-size: var(--text-2xl);
    padding: var(--space-4) var(--space-2);
  }
  .stat { padding: var(--space-2) var(--space-3); min-width: 60px; }
  .stat-value { font-size: var(--text-lg); }
  .btn-option { min-height: 48px; }

  /* Mobile: session fills viewport, drill area scrolls, input fixed at bottom */
  #session {
    height: calc(100vh - env(safe-area-inset-top, 0px));
    height: calc(100dvh - env(safe-area-inset-top, 0px));
    min-height: 0;  /* override default min-height: 60vh */
  }

  #session #drill-area {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    min-height: 0;  /* allow flex shrink below content size */
  }

  #input-area {
    flex-shrink: 0;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    z-index: 10;
    background: var(--color-base);
  }
}

/* ── Small tablet / large phone (iPad Mini portrait, etc.) ────────────────────────── */

@media (min-width: 600px) {
  .stats-row {
    flex-wrap: nowrap;
  }
  .stat {
    padding: var(--space-3) var(--space-4);
  }
  .stat-value {
    font-size: var(--text-2xl);
  }
  .msg-hanzi {
    font-size: var(--text-3xl);
  }
}

/* ── Tablet+ ────────────────────────── */

@media (min-width: 768px) {
  #app {
    padding: var(--space-6);
    padding-top: var(--space-8);
  }
  .stats-row {
    gap: var(--space-5);
    flex-wrap: nowrap;
  }
  .stat {
    padding: var(--space-4) var(--space-5);
  }
  .stat-value {
    font-size: var(--text-display);
  }
  .msg-hanzi {
    font-size: var(--text-3xl);
    padding: var(--space-6) 0;
  }
  .complete-score {
    font-size: var(--text-display);
  }
  /* Mastery legend inline on wider screens */
  .mastery-legend {
    justify-content: flex-start;
  }
  /* Mastery bars breathe on wider screens */
  .mastery-bar {
    height: 8px;
  }
  .mastery-bar-label {
    min-width: 60px;
  }
  /* Panels stay single-column — content is text-heavy and truncates in 2-col */
}

/* ── Desktop scrollbar — thin, unobtrusive, matches aesthetic ── */

@media (pointer: fine) {
  /* Thin scrollbar for Firefox */
  * {
    scrollbar-width: thin;
    scrollbar-color: var(--color-divider) transparent;
  }
}

/* Webkit (Safari, Chrome) thin scrollbar */
@media (pointer: fine) {
  ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
  }
  ::-webkit-scrollbar-track {
    background: transparent;
  }
  ::-webkit-scrollbar-thumb {
    background: var(--color-divider);
    border-radius: 3px;
  }
  ::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--color-text-faint) 40%, transparent);
  }
}

/* ── Desktop (macOS, large tablets landscape) ────────────────────────── */

@media (min-width: 1024px) {
  #app {
    max-width: 1320px;
  }
  .stats-row {
    opacity: 1;
  }
  .mastery-bar {
    height: 10px;
  }
  .mastery-bar-label {
    font-size: var(--text-base);
    min-width: 68px;
  }
  .mastery-bar-meta {
    font-size: var(--text-sm);
    opacity: 0.9;
  }
  .mastery-legend {
    opacity: 0.82;
  }
  .panel-toggle {
    font-size: var(--text-base);
  }
  .stat-value {
    font-size: var(--text-display);
  }
  .cal-cell {
    width: 16px;
    height: 16px;
  }
  .cal-grid {
    grid-template-rows: repeat(7, 16px);
  }
  .cal-labels {
    grid-template-rows: repeat(7, 16px);
  }
  .cal-labels span {
    font-size: 0.7rem;
    line-height: 16px;
  }
  .hsk-bar-track {
    height: 10px;
  }
  .dashboard-illustration {
    max-width: 380px;
  }
  .dashboard-footer {
    padding-top: var(--space-7);
  }
  .dashboard-footer-link {
    font-size: var(--text-sm);
    padding: 6px 10px;
  }
}

/* ── Large desktop ────────────────────────── */

@media (min-width: 1280px) {
  #app {
    max-width: 1440px;
  }
}

/* ── Ultrawide desktop ────────────────────────── */

@media (min-width: 1440px) {
  #app {
    max-width: 1560px;
  }
}

/* ── Landscape phones ────────────────────────── */

@media (max-height: 500px) and (orientation: landscape) {
  .msg-hanzi {
    font-size: var(--text-xl);
    padding: var(--space-3);
    margin: var(--space-2) 0;
  }
  #input-area { padding: var(--space-2); }
  header { padding: var(--space-2) 0; }
  .logo-icon { width: 52px; height: 52px; }
}

/* ── Safe area insets for notched devices ────────────────────────── */

@supports (padding: env(safe-area-inset-bottom)) {
  #app {
    padding-left: max(var(--space-5), env(safe-area-inset-left));
    padding-right: max(var(--space-5), env(safe-area-inset-right));
  }
}

/* ═══════════════════════════════════════════════════════════════════
   Feature 1: In-App Referral UI
   ═══════════════════════════════════════════════════════════════════ */

.referral-section {
  padding: var(--space-2) 0;
}

.referral-description {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-3);
  line-height: var(--lh-sm);
}

.referral-link-row {
  display: flex;
  gap: var(--space-2);
  align-items: stretch;
}

.referral-link-input {
  flex: 1;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  border-radius: 0;
  color: var(--color-text);
  padding: 8px 12px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  min-height: 44px;
  cursor: text;
}

.referral-link-input:focus {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

.referral-copy-btn {
  padding: 8px 16px;
  font-size: var(--text-sm);
  white-space: nowrap;
  min-height: 44px;
}

.referral-copy-status {
  font-size: var(--text-xs);
  color: var(--color-correct);
  margin-top: var(--space-2);
  transition: opacity var(--duration-fast) var(--ease-default);
}

.referral-stats {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-top: var(--space-3);
  font-style: italic;
}

/* ═══════════════════════════════════════════════════════════════════
   Feature 2: Onboarding Nudges
   ═══════════════════════════════════════════════════════════════════ */

.onboarding-checklist {
  margin: var(--space-4) 0;
  padding: var(--space-4);
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
  transition: opacity var(--duration-slow) var(--ease-default);
  animation: driftUp var(--duration-base) var(--ease-upward);
}

.onboarding-checklist.onboarding-fade-out {
  opacity: 0;
}

.onboarding-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-3);
}

.onboarding-header h3 {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-normal);
  margin: 0;
}

.onboarding-dismiss {
  background: none;
  border: none;
  color: var(--color-text-faint);
  font-size: var(--text-lg);
  cursor: pointer;
  padding: 8px;
  line-height: 1;
  transition: color var(--duration-fast) var(--ease-default);
  min-height: 44px;
  min-width: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (hover: hover) {
  .onboarding-dismiss:hover {
  color: var(--color-text);
}
}

.onboarding-items {
  list-style: none;
  padding: 0;
  margin: 0;
}

.onboarding-item {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  border-bottom: 1px solid color-mix(in srgb, var(--color-divider) 40%, transparent);
  font-size: var(--text-sm);
  line-height: var(--lh-sm);
}

.onboarding-item:last-child {
  border-bottom: none;
}

.onboarding-check {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-divider);
  font-size: var(--text-xs);
  color: var(--color-correct);
  line-height: 1;
}

.onboarding-done .onboarding-check {
  background: color-mix(in srgb, var(--color-correct) 10%, transparent);
  border-color: var(--color-correct);
}

.onboarding-label {
  font-weight: 600;
  color: var(--color-text);
  min-width: 100px;
}

.onboarding-done .onboarding-label {
  color: var(--color-text-dim);
}

.onboarding-desc {
  color: var(--color-text-faint);
  font-size: var(--text-xs);
}

.onboarding-complete {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-style: italic;
  margin-top: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-divider);
}

/* ═══════════════════════════════════════════════════════════════════
   Feature 3: Feedback / NPS Form
   ═══════════════════════════════════════════════════════════════════ */

/* ── NPS Modal ────────────────────────────────────── */
.nps-modal {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--color-overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}
.nps-modal-inner {
  background: var(--color-surface);
  max-width: 440px;
  width: 100%;
  padding: var(--space-5);
  text-align: center;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}
.nps-title {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-4);
}
.nps-scale {
  margin-bottom: var(--space-3);
}
.nps-scores {
  display: flex;
  gap: 4px;
  justify-content: center;
  flex-wrap: wrap;
}
.nps-score-btn {
  width: 44px;
  height: 44px;
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  cursor: pointer;
  border-radius: var(--radius);
  transition: background 0.15s, border-color 0.15s;
}
@media (hover: hover) { .nps-score-btn:hover { border-color: var(--color-accent); } }
.nps-score-btn.nps-score-selected {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
}
.nps-labels {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-top: var(--space-1);
  padding: 0 var(--space-1);
}
.nps-followup {
  margin-top: var(--space-3);
}
.nps-question {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-2);
}
.nps-comment {
  width: 100%;
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  padding: var(--space-2);
  border-radius: var(--radius);
  resize: vertical;
  margin-bottom: var(--space-2);
}
.nps-submit-btn {
  display: inline-block;
  padding: var(--space-2) var(--space-4);
  background: var(--color-accent);
  color: var(--color-on-accent);
  border: none;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
}
@media (hover: hover) { .nps-submit-btn:hover { opacity: 0.88; } }
.nps-submit-btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.nps-submit-btn:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
.nps-thanks {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  color: var(--color-accent);
  margin: var(--space-3) 0;
}
.nps-dismiss {
  background: none;
  border: none;
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  cursor: pointer;
  padding: var(--space-2);
  font-family: var(--font-body);
  margin-top: var(--space-2);
}
@media (hover: hover) { .nps-dismiss:hover { color: var(--color-text); } }
.share-overlay {
  display: flex;
  gap: var(--space-2);
  justify-content: center;
  flex-wrap: wrap;
  margin: var(--space-3) 0;
}
.share-btn {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 0.15s;
}
@media (hover: hover) { .share-btn:hover { border-color: var(--color-accent); } }

.feedback-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 50;
  background: var(--color-base);
  border-top: 1px solid var(--color-divider);
  padding: var(--space-3) var(--space-4);
  padding-bottom: max(var(--space-3), env(safe-area-inset-bottom, 0px));
  animation: feedbackSlideUp var(--duration-snappy) var(--ease-upward);
}

@keyframes feedbackSlideUp {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

.feedback-bar-inner {
  max-width: 600px;
  margin: 0 auto;
  position: relative;
}

.feedback-prompt {
  text-align: center;
}

.feedback-question {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  display: block;
  margin-bottom: var(--space-2);
}

.feedback-ratings {
  display: flex;
  justify-content: center;
  gap: 4px;
  flex-wrap: wrap;
}

.feedback-rating-btn {
  width: 36px;
  height: 36px;
  background: transparent;
  border: 1px solid var(--color-divider);
  color: var(--color-text-dim);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-default),
              color var(--duration-fast) var(--ease-default),
              border-color var(--duration-fast) var(--ease-default);
  border-radius: 0;
}

@media (hover: hover) {
  .feedback-rating-btn:hover {
    background: var(--color-surface-alt);
    border-color: var(--color-accent);
    color: var(--color-text);
  }
}

.feedback-rating-btn.feedback-rating-selected {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
}

.feedback-comment-area {
  margin-top: var(--space-3);
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

.feedback-comment-label {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-bottom: var(--space-1);
}

.feedback-comment-input {
  width: 100%;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  border-radius: 0;
  color: var(--color-text);
  padding: 8px 12px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  resize: vertical;
  line-height: var(--lh-base);
}

.feedback-comment-input:focus {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

.feedback-submit-btn {
  margin-top: var(--space-2);
  padding: 10px 24px;
  font-size: var(--text-sm);
}
.feedback-submit-btn:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

.feedback-thanks {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-style: italic;
  padding: var(--space-3) 0;
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

.feedback-close {
  position: absolute;
  top: 0;
  right: 0;
  background: none;
  border: none;
  color: var(--color-text-faint);
  font-size: var(--text-lg);
  cursor: pointer;
  padding: 8px;
  line-height: 1;
  transition: color var(--duration-fast) var(--ease-default);
  min-height: 44px;
  min-width: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (hover: hover) { .feedback-close:hover { color: var(--color-text); } }

/* Dashboard footer */

.dashboard-footer {
  text-align: center;
  padding: var(--space-7) 0 var(--space-4);
  border-top: 1px solid var(--color-divider);
  margin-top: var(--space-4);
}

.dashboard-footer-link {
  background: none;
  border: none;
  color: var(--color-text-faint);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  cursor: pointer;
  padding: 6px 10px;
  letter-spacing: var(--tracking-normal);
  transition: color var(--duration-fast) var(--ease-default);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

@media (hover: hover) { .dashboard-footer-link:hover { color: var(--color-accent); } }

/* Mobile adjustments for feedback bar */
@media (max-width: 480px) {
  .feedback-rating-btn {
    width: 44px;
    height: 44px;
    font-size: var(--text-sm);
  }
  .feedback-ratings {
    gap: 3px;
  }
  .onboarding-item {
    flex-wrap: wrap;
  }
  .onboarding-desc {
    flex-basis: 100%;
    padding-left: calc(18px + var(--space-2));
  }
}

/* ── Mobile / Capacitor UX ────────────────────────── */

/* Global mobile hardening */
button, a, input, select, textarea, [role="button"] {
  -webkit-tap-highlight-color: transparent;  /* Remove iOS tap flash */
}

button, [role="button"], .btn-shortcut, .btn-option, .btn-primary, .btn-secondary {
  -webkit-touch-callout: none;               /* Prevent long-press callout */
  touch-action: manipulation;                /* Kill 300ms click delay */
}

/* Active press states for touch (complement :hover for touch devices) */
@media (pointer: coarse) {
  .btn-primary:active { opacity: 0.8; transform: scale(0.97); }
  .btn-secondary:active { opacity: 0.8; transform: scale(0.97); }
  .btn-shortcut:active { opacity: 0.7; }
  .btn-option:active { opacity: 0.85; }
}

/* Keyboard-aware input area — --keyboard-height set by capacitor-bridge.js */
.input-row {
  padding-bottom: calc(var(--keyboard-height, 0px) + env(safe-area-inset-bottom, 0px));
  transition: padding-bottom 0.25s ease-out;
}

/* Larger touch targets for drill buttons (Apple HIG: 44pt minimum) */
@media (pointer: coarse) {
  .btn-shortcut { min-height: 48px; min-width: 48px; }
  .btn-primary, .btn-secondary { min-height: 48px; padding: 14px 24px; }
  #answer-input { font-size: 18px; min-height: 48px; }
}

/* Desktop mouse refinements — precise pointer devices */
@media (pointer: fine) {
  .btn-shortcut { min-height: 36px; padding: 6px 12px; }
  .panel-toggle { min-height: 36px; }
  .stat { cursor: default; }
  .mastery-bar-row { cursor: pointer; }
}

/* Swipe gesture affordance */
.drill-card { touch-action: pan-y; }

/* Prevent iOS text selection during drills */
#drill-area { -webkit-user-select: none; user-select: none; }

/* Disable pull-to-refresh during sessions */
body.in-session { overscroll-behavior-y: contain; }

/* Offline indicator */
.offline-indicator {
  position: fixed;
  top: env(safe-area-inset-top, 0px);
  left: 0;
  right: 0;
  background: var(--color-incorrect);
  color: var(--color-on-accent);
  text-align: center;
  padding: 4px var(--space-3);
  font-size: var(--text-xs);
  font-family: var(--font-body);
  z-index: 1000;
  transform: translateY(-100%);
  transition: transform 0.3s ease-out;
}
.offline-indicator.visible { transform: translateY(0); }

/* ── Rich markup CSS classes (CSP: replaces inline style=) ── */
.rich-bold { font-weight: bold; }
.rich-dim { opacity: 0.7; }
.rich-italic { font-style: italic; }
.rich-dim-italic { opacity: 0.7; font-style: italic; }
.rich-bold-dim { font-weight: bold; opacity: 0.7; }
.rich-accent { color: var(--color-accent); }
.rich-accent-bold { font-weight: bold; color: var(--color-accent); }
.rich-accent-dim { color: var(--color-accent-dim); }
.rich-accent-dim-bold { font-weight: bold; color: var(--color-accent-dim); }
.rich-text-bold { font-weight: bold; color: var(--color-text); }
.rich-correct { color: var(--color-correct); }
.rich-correct-bold { font-weight: bold; color: var(--color-correct); }
.rich-incorrect { color: var(--color-incorrect); }
.rich-incorrect-bold { font-weight: bold; color: var(--color-incorrect); }
.rich-secondary { color: var(--color-secondary); }
.rich-secondary-bold { font-weight: bold; color: var(--color-secondary); }

/* Auth page shared styles */
.auth-page { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: var(--space-4); }
.auth-card { width: 100%; max-width: 400px; }
.auth-logo { text-align: center; margin-bottom: var(--space-6); }
.auth-logo .logo-mark { font-size: var(--text-display); font-family: var(--font-hanzi); color: var(--color-accent); }
.auth-logo .logo-text { font-family: var(--font-heading); font-size: var(--text-2xl); color: var(--color-text); margin-top: var(--space-1); letter-spacing: var(--tracking-wide); }
.auth-form { display: flex; flex-direction: column; gap: var(--space-4); }
.auth-field label { display: block; font-family: var(--font-body); font-size: var(--text-sm); color: var(--color-text-dim); margin-bottom: var(--space-1); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.auth-field input { width: 100%; padding: 12px 16px; font-family: var(--font-body); font-size: var(--text-base); border: 1px solid var(--color-divider); border-radius: var(--radius); background: var(--color-surface); color: var(--color-text); transition: border-color 0.2s; box-sizing: border-box; }
.auth-field input:focus { border-color: var(--color-accent); outline: 2px solid var(--color-accent); outline-offset: 1px; }
.auth-field input:focus:not(:focus-visible) { outline: none; }
.auth-submit { padding: var(--btn-padding); font-family: var(--font-heading); font-size: var(--text-lg); background: var(--color-accent); color: var(--color-on-accent); border: none; border-radius: var(--radius); cursor: pointer; transition: opacity 0.2s; letter-spacing: var(--tracking-normal); }
@media (hover: hover) { .auth-submit:hover { opacity: 0.9; } }
.auth-submit:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.auth-submit:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
.auth-links { text-align: center; margin-top: var(--space-4); font-family: var(--font-body); font-size: var(--text-sm); color: var(--color-text-dim); }
.auth-links a { color: var(--color-accent); text-decoration: none; }
@media (hover: hover) { .auth-links a:hover { text-decoration: underline; } }
.auth-mfa-prompt { font-family: var(--font-body); font-size: var(--text-base); color: var(--color-text-dim); text-align: center; margin-bottom: var(--space-4); }
.flash-messages { list-style: none; padding: 0; margin: 0 0 var(--space-4); }
.flash-messages li { padding: 10px 14px; border-radius: var(--radius); font-family: var(--font-body); font-size: var(--text-sm); margin-bottom: var(--space-2); }
.flash-error { background: var(--color-flash-error-bg); color: var(--color-incorrect); }
.flash-info { background: var(--color-flash-info-bg); color: var(--color-correct); }

/* ── Nielsen Heuristic Fixes ────────────────────────── */

/* #1 — Persistent drill-type label + #3 — Session timer */
.session-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-1) 0;
  min-height: 1.5em;
}

.drill-type-label {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.session-timer {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  font-variant-numeric: tabular-nums;
}

/* Session error recovery actions */
.session-error-actions {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

/* #2 — Audio error recovery UI */
.audio-error-actions {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-2);
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

.audio-error-actions button {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  padding: 6px 14px;
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  color: var(--color-text-dim);
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-default);
}

@media (hover: hover) { .audio-error-actions button:hover { border-color: var(--color-accent); } }

/* #4 — Completion details loading skeleton */
.complete-skeleton {
  padding: var(--space-4) 0;
}

.complete-skeleton .skeleton-line {
  height: var(--skeleton-height);
  background: var(--color-surface-alt);
  margin-bottom: var(--space-2);
  animation: opacityPulse var(--duration-ambient) infinite;
}

.complete-skeleton .skeleton-line.short {
  width: 60%;
}

/* #7 — Input shake on blocked submission */
@keyframes opacityPulse {
  0% { opacity: 0.5; }
  50% { opacity: 1; }
  100% { opacity: 0.5; }
}

@keyframes inputShake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-3px); }
  40% { transform: translateX(3px); }
  60% { transform: translateX(-2px); }
  80% { transform: translateX(2px); }
}

.input-shake {
  animation: inputShake 0.3s var(--ease-default);
}

/* #8 — Done button confirm state */
.btn-shortcut.confirm-tap {
  color: var(--color-incorrect);
  border-color: var(--color-incorrect);
}

/* #12/#16 — Keyboard hint badges */
.btn-shortcut kbd,
.btn-secondary kbd {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.65em;
  color: var(--color-text-faint);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  padding: 0 4px;
  margin-left: 4px;
  line-height: 1.4;
  vertical-align: middle;
  opacity: 0.7;
}

/* #21 — Hide hint/unsure during MC */
.shortcuts.mc-mode .btn-shortcut[data-quick="?"],
.shortcuts.mc-mode .btn-shortcut[data-quick="N"] {
  display: none;
}

/* Hide all shortcuts during action prompts (Begin/Mini/Quit, Continue, etc.) */
.shortcuts.action-mode {
  display: none;
}

/* MC option selected/unselected feedback */
.btn-option-selected {
  background: var(--color-accent) !important;
  color: var(--color-on-accent) !important;
  border-left-color: var(--color-accent) !important;
  transition: background 0.15s ease, color 0.15s ease;
}
.btn-option-unselected {
  opacity: 0.35;
  transition: opacity 0.15s ease;
}

/* #23 — Disconnect banner with progress */
#disconnect-banner {
  background: var(--color-surface-alt);
  color: var(--color-text);
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

#disconnect-banner button {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  padding: 6px 14px;
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
  white-space: nowrap;
}

@media (hover: hover) {
  #disconnect-banner button:hover {
  border-color: var(--color-accent);
}
}

#disconnect-banner .banner-progress {
  color: var(--color-text-faint);
  font-size: var(--text-xs);
}

#disconnect-banner .reconnect-countdown {
  color: var(--color-text-dim);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}

#disconnect-banner button:active {
  transform: scale(0.98);
}

/* Fetch error toast */
#fetch-error-toast {
  position: fixed;
  bottom: var(--space-4);
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  background: var(--color-surface-alt);
  color: var(--color-text);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  border: 1px solid var(--color-divider);
  font-size: var(--text-sm);
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  animation: feedbackSlideUp var(--duration-fast) var(--ease-upward);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
#fetch-error-toast button {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  padding: 4px 12px;
  border: 1px solid var(--color-divider);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
}
#fetch-error-toast .toast-dismiss {
  border: none;
  background: none;
  padding: 2px 6px;
  color: var(--color-text-dim);
  font-size: var(--text-base);
}

/* Keyboard shortcut overlay */
#shortcut-overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(0,0,0,0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: fadeIn var(--duration-fast) var(--ease-default);
}
/* fadeIn defined in tokens section above — no duplicate */
.shortcut-overlay-inner {
  background: var(--color-surface);
  border-radius: var(--radius-lg, 12px);
  padding: var(--space-5, 24px);
  max-width: 380px;
  width: 90%;
  position: relative;
  box-shadow: 0 4px 24px rgba(0,0,0,0.18);
}
.shortcut-overlay-inner h3 {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--text-lg);
  color: var(--color-text);
}
.shortcut-section { margin-bottom: var(--space-3); }
.shortcut-section h4 {
  margin: 0 0 var(--space-1) 0;
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.shortcut-overlay-inner dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-1) var(--space-3);
  margin: 0;
}
.shortcut-overlay-inner dt { text-align: right; }
.shortcut-overlay-inner dd { margin: 0; color: var(--color-text-dim); font-size: var(--text-sm); }
.shortcut-overlay-inner kbd {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  background: var(--color-base);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  min-width: 1.5em;
  text-align: center;
}
.shortcut-overlay-close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  border: none;
  background: none;
  font-size: var(--text-lg);
  color: var(--color-text-dim);
  cursor: pointer;
  padding: var(--space-1);
  line-height: 1;
}

/* #26 — Panel error with retry */
.empty-state {
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  padding: var(--space-2) 0;
}

.panel-retry-btn {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-accent);
  background: none;
  border: none;
  cursor: pointer;
  padding: 2px 0;
  margin-left: var(--space-2);
  text-decoration: underline;
  text-decoration-color: transparent;
  transition: text-decoration-color var(--duration-fast) var(--ease-default);
}

@media (hover: hover) { .panel-retry-btn:hover { text-decoration-color: var(--color-accent); } }

/* #27 — Onboarding wizard intro text */
.onboarding-wizard-intro {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  text-align: center;
  margin-bottom: var(--space-4);
  line-height: var(--lh-base);
}

/* ── Onboarding intro slides ──────────────────────── */
.onboarding-intro-slide {
  text-align: center;
  animation: slideFadeIn 0.5s cubic-bezier(0.2, 0, 0.2, 1) forwards;
}
.onboarding-intro-slide.hidden {
  display: none;
}
.onboarding-intro-slide.slide-out {
  animation: slideFadeOut 0.3s ease forwards;
}
@keyframes slideFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes slideFadeOut {
  from { opacity: 1; transform: translateY(0); }
  to { opacity: 0; transform: translateY(-6px); }
}
.onboarding-intro-body {
  margin-bottom: var(--space-5);
}
.onboarding-intro-heading {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  color: var(--color-text);
  margin-bottom: var(--space-3);
  font-weight: 500;
  line-height: var(--lh-tight);
}
.onboarding-intro-text {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  line-height: var(--lh-relaxed);
  max-width: 340px;
  margin: 0 auto;
}
.onboarding-intro-img {
  display: block;
  max-width: 220px;
  max-height: 180px;
  margin: var(--space-4) auto var(--space-5);
  border-radius: var(--radius);
  object-fit: contain;
  opacity: 0;
  animation: gentleBloom 0.8s ease 0.15s forwards;
}
.onboarding-next-btn {
  width: 100%;
  margin-bottom: var(--space-2);
}
.onboarding-skip-btn {
  display: block;
  margin: 0 auto;
  color: var(--color-text-faint);
  font-size: var(--text-xs);
}
@media (hover: hover) {
  .onboarding-skip-btn:hover {
    color: var(--color-text-dim);
  }
}

/* ── Report a Problem modal ────────────────────────── */

.report-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}

.report-modal.hidden {
  display: none;
}

.report-modal-backdrop {
  position: absolute;
  inset: 0;
  background: var(--color-overlay);
}

.report-modal-card {
  position: relative;
  background: var(--color-base);
  padding: var(--space-5);
  max-width: 480px;
  width: 100%;
  z-index: 1;
  animation: driftUp var(--duration-base) var(--ease-upward);
}

.report-modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-3);
}

.report-modal-header h3 {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-text);
  margin: 0;
}

.report-close {
  background: none;
  border: none;
  color: var(--color-text-faint);
  font-size: var(--text-xl);
  cursor: pointer;
  padding: 8px;
  line-height: 1;
  transition: color var(--duration-fast) var(--ease-default);
  min-height: 44px;
  min-width: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (hover: hover) {
  .report-close:hover {
  color: var(--color-text);
}
}

.report-modal-desc {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-3);
  line-height: var(--lh-base);
}

.report-label {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-bottom: var(--space-1);
}

.report-textarea {
  width: 100%;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-divider);
  border-radius: 0;
  color: var(--color-text);
  padding: 8px 12px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  resize: vertical;
  line-height: var(--lh-base);
  margin-bottom: var(--space-3);
}

.report-textarea:focus {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

.report-actions {
  display: flex;
  gap: var(--space-2);
}

.report-btn {
  flex: 1;
  font-size: var(--text-sm);
  padding: 10px 16px;
}

.report-status {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-correct);
  margin-top: var(--space-2);
  animation: driftUp var(--duration-fast) var(--ease-upward);
}

/* #28 — Dashboard footer separator */
.dashboard-footer-sep {
  color: var(--color-text-faint);
  margin: 0 var(--space-1);
}

.dashboard-footer a.dashboard-footer-link {
  text-decoration: none;
}

@media (hover: hover) {
  .dashboard-footer a:hover { color: var(--color-accent); }
}

/* #29 — Hint first-use tooltip */
.hint-tooltip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--color-surface-alt);
  color: var(--color-text-dim);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  padding: 6px 12px;
  white-space: nowrap;
  z-index: 10;
  animation: driftUp var(--duration-fast) var(--ease-upward);
  pointer-events: none;
}

.hint-tooltip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--color-surface-alt);
}

/* #30 — TTS playing indicator */
.listening-playing-indicator {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-accent);
  padding: var(--space-1) var(--space-2);
  animation: pulse var(--duration-ambient) var(--ease-default) infinite;
}

.listening-playing-indicator::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-accent);
  animation: pulse var(--duration-ambient) var(--ease-default) infinite;
}

/* ── WCAG 2.1 AA Accessibility Enhancements (Item 10) ────────── */

/* Color contrast: ensure dim text meets 4.5:1 ratio */
.stat-label,
.meta-dim,
.session-meta,
.context-note {
  color: var(--color-text-dim);  /* #5A6678 on #F2EBE0 = 4.8:1 ✓ */
}

/* Faint text upgraded to meet minimum contrast */
.timestamp,
.version-tag,
.footer-note {
  color: var(--color-text-faintest);
}

/* Focus indicators: ensure all interactive elements have visible focus */
a:focus-visible,
button:focus-visible,
select:focus-visible,
textarea:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
  box-shadow: none;
}

/* Focus ring for custom interactive elements */
.btn:focus-visible,
.stat:focus-visible,
.mastery-bar:focus-visible,
.choice-btn:focus-visible,
.option-pill:focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

/* ARIA live region styling — screen reader announces, visible feedback */
[aria-live="polite"],
[aria-live="assertive"] {
  /* No visual change — content announced by screen reader */
}

/* Form error identification */
.field-error {
  color: var(--color-incorrect);
  font-size: var(--text-sm);
  margin-top: var(--space-1);
}

input[aria-invalid="true"],
textarea[aria-invalid="true"] {
  border-color: var(--color-incorrect);
}

/* Icon-only button screen reader labels */
.icon-btn {
  position: relative;
}
.icon-btn .sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Screen reader only utility class */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Ensure minimum 44x44px touch targets */
.choice-btn,
.option-pill,
.btn,
.sound-toggle,
.nav-btn {
  min-height: 44px;
  min-width: 44px;
}

/* Keyboard-accessible drill interactions */
@media (hover: hover) {
  .choice-btn:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
  }
}
.choice-btn:focus-visible {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

/* ── Review card (sticky wrong-answer feedback) ── */
.review-card {
  position: sticky;
  top: 0;
  z-index: 10;
  background: color-mix(in srgb, var(--color-incorrect) 12%, var(--color-surface));
  border-left: 3px solid var(--color-incorrect);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--space-3) var(--space-4);
  padding-right: var(--space-6);
  margin-bottom: var(--space-3);
  color: var(--color-text);
  font-size: var(--text-sm);
  animation: feedbackIn var(--duration-fast) var(--ease-upward);
  transition: opacity var(--duration-base) var(--ease-default),
              transform var(--duration-base) var(--ease-default);
}
.review-card-exit {
  opacity: 0;
  transform: translateY(-8px);
}
.review-card-dismiss {
  position: absolute;
  top: var(--space-1);
  right: var(--space-1);
  background: none;
  border: none;
  color: var(--color-text);
  opacity: 0.4;
  font-size: var(--text-lg);
  cursor: pointer;
  padding: 8px 10px;
  min-width: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
@media (hover: hover) { .review-card-dismiss:hover { opacity: 0.8; } }
.review-card-dismiss:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; opacity: 0.8; }

/* ── Override button ──────────────────────────── */
.btn-override {
  display: inline-block;
  margin-top: var(--space-2);
  margin-left: var(--space-3);
  padding: 2px var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  background: transparent;
  border: 1px solid currentColor;
  border-radius: var(--radius);
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-default);
}
@media (hover: hover) { .btn-override:hover { opacity: 1; } }
.btn-override:disabled { cursor: default; opacity: 0.4; }
.btn-override-done {
  color: var(--color-correct);
  border-color: var(--color-correct);
  opacity: 0.8;
}

/* ── Error elaboration tag ──────────────────────────── */
.error-elaboration {
  display: block;
  margin-top: var(--space-1);
  padding-left: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  font-style: italic;
  opacity: 0.85;
}

/* ── Requirement provenance tag ─────────────────────────── */
.requirement-ref {
  display: block;
  margin-top: var(--space-1);
  padding-left: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  opacity: 0.7;
}

/* Dark mode: contrast-upgraded colors now handled via --color-text-faintest token */

/* ── Onboarding bridge overlay ─────────────────────────────── */
.onboarding-bridge {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-base);
  opacity: 0;
  transition: opacity 0.4s ease;
}
.onboarding-bridge-visible { opacity: 1; }
.onboarding-bridge-exit { opacity: 0; transition: opacity 0.5s ease; }
.onboarding-bridge-inner {
  text-align: center;
  animation: bridge-drift 2s ease-out both;
}
.onboarding-bridge-logo {
  font-family: var(--font-hanzi);
  font-size: 3.5rem;
  color: var(--color-accent);
  margin-bottom: 1rem;
}
.onboarding-bridge-text {
  font-family: var(--font-heading);
  font-size: 1.15rem;
  color: var(--color-text);
  opacity: 0.8;
}
@keyframes bridge-drift {
  from { transform: translateY(8px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* ── Recording level bar ───────────────────────────────────── */
.rec-level-bar {
  width: 100%;
  height: 4px;
  background: var(--color-divider);
  border-radius: 2px;
  margin-top: 0.5rem;
  overflow: hidden;
}
.rec-level-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: 2px;
  transition: width 0.1s linear;
  width: 0%;
}

/* ── HSK progress bars (dashboard) ─────────────────────────── */
.hsk-progress-bars {
  margin-top: 1rem;
}
.hsk-bar-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.hsk-bar-label {
  font-family: var(--font-body);
  font-size: 0.82rem;
  color: var(--color-text);
  min-width: 3.5rem;
  text-align: right;
}
.hsk-bar-track {
  flex: 1;
  height: 8px;
  background: var(--color-divider);
  border-radius: 4px;
  overflow: hidden;
}
.hsk-bar-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: 4px;
  transition: width 0.6s ease;
}
.hsk-bar-count {
  font-family: var(--font-body);
  font-size: 0.78rem;
  color: var(--color-text-dim);
  min-width: 5rem;
}

/* ── Upgrade modal ────────────────────────────────── */
.upgrade-modal {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: var(--color-overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  animation: fadeIn var(--duration-fast) var(--ease-default);
}
.upgrade-modal-inner {
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  max-width: 420px;
  width: 100%;
  text-align: center;
}
.upgrade-promise {
  font-family: var(--font-heading);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-3);
}
.upgrade-context {
  font-size: var(--text-sm);
  color: var(--color-text-dim, var(--color-text-faint));
  margin-bottom: var(--space-4);
  line-height: 1.5;
}
.upgrade-pricing {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.upgrade-plan {
  flex: 1;
  padding: var(--space-3);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 0.15s;
  position: relative;
}
@media (hover: hover) { .upgrade-plan:hover { border-color: var(--color-accent); } }
.upgrade-plan-selected {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 8%, var(--color-surface));
}
.upgrade-plan-price {
  font-family: var(--font-heading);
  font-size: 1.4rem;
  font-weight: 600;
}
.upgrade-plan-price span {
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--color-text-faint);
}
.upgrade-plan-note {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-top: var(--space-1);
}
.upgrade-plan-badge {
  position: absolute;
  top: -0.5rem;
  right: var(--space-2);
  background: var(--color-correct);
  color: var(--color-on-accent);
  font-size: 0.65rem;
  font-weight: 600;
  padding: 0.15rem 0.5rem;
  border-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.upgrade-cta {
  width: 100%;
  padding: var(--space-3);
  font-size: 1rem;
  margin-bottom: var(--space-2);
}
.upgrade-cta:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
.upgrade-dismiss {
  background: none;
  border: none;
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  cursor: pointer;
  padding: var(--space-2);
  font-family: var(--font-body);
}
@media (hover: hover) { .upgrade-dismiss:hover { color: var(--color-text); } }
.upgrade-trust {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-top: var(--space-2);
}

/* ── Upgrade progress stats (smart paywall) ──────── */
.upgrade-progress {
  display: flex;
  justify-content: center;
  gap: var(--space-4);
  margin: var(--space-3) 0;
  padding: var(--space-3) 0;
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}
.upgrade-stat {
  text-align: center;
}
.upgrade-stat-value {
  display: block;
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--color-accent);
}
.upgrade-stat-label {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-top: 0.1rem;
}
.upgrade-hsk-bar {
  margin: var(--space-2) 0 var(--space-3);
  text-align: center;
}
.upgrade-hsk-bar-label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-1);
}
.upgrade-hsk-bar-track {
  height: 6px;
  background: var(--color-surface-alt);
  border-radius: 3px;
  overflow: hidden;
  margin: var(--space-1) 0;
}
.upgrade-hsk-bar-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: 3px;
  transition: width 0.6s ease;
}
.upgrade-hsk-bar-hint {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

/* ── Dashboard upgrade banner ─────────────────────── */
.upgrade-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  margin-top: var(--space-3);
  background: color-mix(in srgb, var(--color-accent) 6%, var(--color-surface));
  border: 1px solid color-mix(in srgb, var(--color-accent) 20%, var(--color-divider));
  border-radius: var(--radius-sm);
  opacity: 0;
  animation: settleIn 0.6s ease 1.5s forwards;
}
.upgrade-banner-text {
  font-size: var(--text-sm);
  color: var(--color-text);
}
.upgrade-banner-cta {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border: none;
  padding: var(--space-1) var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  border-radius: var(--radius-sm);
  transition: opacity 0.15s;
}
@media (hover: hover) { .upgrade-banner-cta:hover { opacity: 0.85; } }

/* ── Grammar View ────────────────────────── */

.grammar-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.grammar-header h2 {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 400;
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-normal);
}

/* Grammar button icon in exposure bar */
.btn-grammar-icon {
  font-family: var(--font-hanzi);
  font-size: var(--text-base);
  line-height: 1;
}

/* HSK level tabs */
.grammar-level-tabs {
  display: flex;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-divider);
}

.grammar-level-tab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-default),
              border-color var(--duration-fast) var(--ease-default);
  min-height: 44px;
}

.grammar-level-tab.active {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}

@media (hover: hover) {
  .grammar-level-tab:hover {
    color: var(--color-text);
  }
}

/* Mastery summary bar */
.grammar-mastery-summary {
  margin-bottom: var(--space-4);
}

.grammar-mastery-text {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  display: block;
  margin-bottom: var(--space-1);
}

.grammar-mastery-bar {
  height: 4px;
  background: var(--color-divider);
  width: 100%;
  overflow: hidden;
}

.grammar-mastery-fill {
  height: 100%;
  background: var(--color-secondary);
  transition: width var(--duration-base) var(--ease-default);
}

/* Grammar list */
.grammar-list {
  margin: var(--space-3) 0;
}

.grammar-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--color-divider);
  padding: 12px var(--space-3);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-text);
  text-align: left;
  transition: background var(--duration-fast) var(--ease-default);
  min-height: 44px;
  gap: var(--space-1);
  animation: driftUp var(--duration-base) var(--ease-upward);
}

@media (hover: hover) {
  .grammar-card:hover {
    background: var(--color-surface-alt);
  }
}

.grammar-card-studied {
  opacity: 0.75;
}

.grammar-card-main {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.grammar-card-name {
  font-weight: 600;
  font-size: var(--text-base);
}

.grammar-card-name-zh {
  font-family: var(--font-hanzi);
  font-size: var(--text-base);
  color: var(--color-text-dim);
}

.grammar-card-meta {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}

.grammar-card-category {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  padding: 2px 6px;
  border: 1px solid var(--color-divider);
  white-space: nowrap;
}

.grammar-card-studied-badge {
  font-size: var(--text-xs);
  color: var(--color-secondary);
  font-weight: 600;
}

/* Grammar lesson view */
.grammar-lesson {
  animation: driftUp var(--duration-base) var(--ease-upward);
}

.grammar-lesson-title {
  margin-bottom: var(--space-2);
}

.grammar-lesson-title h3 {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: 400;
  color: var(--color-text);
  letter-spacing: var(--tracking-normal);
  margin: 0;
}

.grammar-lesson-name-zh {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  color: var(--color-text-dim);
}

.grammar-lesson-meta {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

.grammar-lesson-level {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.grammar-lesson-description {
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
  color: var(--color-text);
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-divider);
}

/* Examples */
.grammar-examples {
  margin-bottom: var(--space-5);
}

.grammar-examples h4 {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 400;
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-normal);
  margin-bottom: var(--space-3);
}

.grammar-example {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-divider);
}

.grammar-example:last-child {
  border-bottom: none;
}

.grammar-example-zh {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}

.grammar-example-text {
  font-family: var(--font-hanzi);
  font-size: var(--text-lg);
  color: var(--color-text);
}

.grammar-audio-btn {
  background: transparent;
  border: 1px solid var(--color-divider);
  color: var(--color-accent);
  cursor: pointer;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  flex-shrink: 0;
  transition: background var(--duration-fast) var(--ease-default),
              color var(--duration-fast) var(--ease-default);
  min-height: 44px;
  min-width: 44px;
}

@media (hover: hover) {
  .grammar-audio-btn:hover {
    background: var(--color-surface-alt);
    color: var(--color-accent-dim);
  }
}

.grammar-example-pinyin {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-1);
}

.grammar-example-en {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
}

.grammar-example-note {
  font-size: var(--text-xs);
  color: var(--color-text-faintest);
  font-style: italic;
  margin-top: var(--space-1);
}

/* ── Grammar visual annotations — color-coded sentence structure ── */

/* Annotated sentence: highlights subject/verb/object in brand palette tones */
.grammar-annotated {
  font-family: var(--font-hanzi);
  font-size: var(--text-xl);
  line-height: 2.2;
  padding: var(--space-3) var(--space-4);
  margin: var(--space-3) 0;
  background: color-mix(in srgb, var(--color-surface-alt) 50%, transparent);
  border-radius: var(--radius-card);
}

/* Individual word/phrase annotation spans */
.grammar-ann-subject {
  border-bottom: 2px solid var(--color-secondary);
  padding-bottom: 2px;
}

.grammar-ann-verb {
  border-bottom: 2px solid var(--color-accent);
  padding-bottom: 2px;
}

.grammar-ann-object {
  border-bottom: 2px solid var(--color-mastery-stabilizing);
  padding-bottom: 2px;
}

.grammar-ann-particle {
  border-bottom: 2px dashed var(--color-text-dim);
  padding-bottom: 2px;
}

/* Annotation legend — small inline key */
.grammar-ann-legend {
  display: flex;
  gap: var(--space-3);
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  margin-top: var(--space-2);
  flex-wrap: wrap;
}

.grammar-ann-legend span::before {
  content: '';
  display: inline-block;
  width: 12px;
  height: 2px;
  margin-right: 4px;
  vertical-align: middle;
}

.grammar-ann-legend .legend-subject::before { background: var(--color-secondary); }
.grammar-ann-legend .legend-verb::before { background: var(--color-accent); }
.grammar-ann-legend .legend-object::before { background: var(--color-mastery-stabilizing); }
.grammar-ann-legend .legend-particle::before { background: var(--color-text-dim); border-style: dashed; }

/* Linked vocabulary */
.grammar-linked-vocab {
  margin-bottom: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-divider);
}

.grammar-linked-vocab h4 {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 400;
  color: var(--color-text-dim);
  letter-spacing: var(--tracking-normal);
  margin-bottom: var(--space-3);
}

.grammar-vocab-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.grammar-vocab-item {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-divider);
  font-size: var(--text-sm);
}

.grammar-vocab-item:last-child {
  border-bottom: none;
}

.grammar-vocab-hanzi {
  font-family: var(--font-hanzi);
  font-size: var(--text-base);
  color: var(--color-text);
  min-width: 3em;
}

.grammar-vocab-pinyin {
  color: var(--color-text-dim);
  min-width: 5em;
}

.grammar-vocab-english {
  color: var(--color-text-faint);
  flex: 1;
}

.grammar-vocab-mastery {
  font-size: var(--text-xs);
  color: var(--color-text-faintest);
  text-transform: capitalize;
  white-space: nowrap;
}

/* Mastery stage color coding for vocab items */
.grammar-vocab-stage-durable { border-left: 3px solid var(--color-mastery-durable); }
.grammar-vocab-stage-stable { border-left: 3px solid var(--color-mastery-stable); }
.grammar-vocab-stage-stabilizing { border-left: 3px solid var(--color-mastery-stabilizing); }
.grammar-vocab-stage-unseen { border-left: 3px solid var(--color-divider); }

/* Lesson actions — layout overrides below in grammar quiz section */

.grammar-mark-studied {
  width: 100%;
}

.grammar-lesson-actions {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-divider);
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  align-items: center;
}

.grammar-lesson-actions .btn-primary,
.grammar-lesson-actions .btn-secondary {
  flex: 1;
  min-width: 140px;
}

.grammar-practice-btn {
  white-space: nowrap;
}

.grammar-studied-confirmation {
  font-size: var(--text-sm);
  color: var(--color-secondary);
  text-align: center;
  padding: var(--space-3) 0;
  flex: 1;
}

/* Grammar quiz */
.grammar-quiz {
  padding: var(--space-4) 0;
}

.grammar-quiz-progress {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  text-align: center;
  margin-bottom: var(--space-4);
}

.grammar-quiz-prompt {
  text-align: center;
  margin-bottom: var(--space-3);
}

.grammar-quiz-hanzi {
  font-family: var(--font-hanzi);
  font-size: var(--text-3xl);
  color: var(--color-text);
}

.grammar-quiz-pinyin {
  font-size: var(--text-base);
  color: var(--color-text-dim);
  margin-top: var(--space-2);
}

.grammar-quiz-question {
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-4);
}

.grammar-quiz-options {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.grammar-quiz-option {
  width: 100%;
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-text);
  cursor: pointer;
  text-align: left;
  transition: background var(--duration-fast) var(--ease-default);
  min-height: 44px;
}

@media (hover: hover) {
  .grammar-quiz-option:hover:not(:disabled) {
    background: var(--color-surface-alt);
  }
}

.grammar-quiz-option:disabled {
  cursor: default;
  opacity: 0.7;
}

.grammar-quiz-correct {
  background: var(--color-correct-bg, color-mix(in srgb, var(--color-correct) 15%, transparent));
  border-color: var(--color-correct);
  opacity: 1;
}

.grammar-quiz-wrong {
  background: var(--color-incorrect-bg, color-mix(in srgb, var(--color-incorrect) 15%, transparent));
  border-color: var(--color-incorrect);
  opacity: 1;
}

.grammar-quiz-result {
  text-align: center;
  padding: var(--space-5) 0;
}

.grammar-quiz-result h3 {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  margin-bottom: var(--space-3);
}

.grammar-quiz-score {
  font-size: var(--text-lg);
  color: var(--color-text);
  margin-bottom: var(--space-4);
}

.grammar-quiz-result-actions {
  display: flex;
  gap: var(--space-3);
  justify-content: center;
}

/* ── Grammar category chips ──────────────────────── */

.grammar-category-chips {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  padding: var(--space-2) 0 var(--space-3);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.grammar-category-chips::-webkit-scrollbar {
  display: none;
}

.grammar-category-chip {
  flex-shrink: 0;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full, 999px);
  border: 1px solid var(--color-divider);
  background: transparent;
  color: var(--color-text-dim);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: all var(--duration-fast, 0.15s) ease;
  white-space: nowrap;
}

.grammar-category-chip:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.grammar-category-chip.active {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
}

.grammar-chip-count {
  font-size: var(--text-xs);
  opacity: 0.7;
}

/* ── Grammar mastery badges ──────────────────────── */

.grammar-mastery-badge {
  display: inline-block;
  padding: 0.1em var(--space-2);
  border-radius: var(--radius-full, 999px);
  font-size: var(--text-xs);
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.mastery-learning {
  background: rgba(184, 160, 80, 0.15);
  color: var(--color-mastery-stabilizing);
}

.mastery-practiced {
  background: rgba(106, 138, 90, 0.15);
  color: var(--color-mastery-stable);
}

.mastery-mastered {
  background: rgba(74, 106, 74, 0.15);
  color: var(--color-mastery-durable);
}

/* ── Listening stats ──────────────────────── */

.listening-stats {
  display: flex;
  justify-content: center;
  gap: var(--space-5);
  padding: var(--space-3) 0;
  margin-bottom: var(--space-3);
}

.listening-stats-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}

.listening-stats-value {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  color: var(--color-text);
}

.listening-stats-label {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

/* ── Listening mode tabs ──────────────────────── */

.listening-mode-tabs {
  display: flex;
  gap: var(--space-1);
  justify-content: center;
  margin-bottom: var(--space-3);
}

.listening-mode-tab {
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-border, #ddd);
  background: transparent;
  color: var(--color-text-dim);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: all var(--duration-fast) var(--ease-default);
}

.listening-mode-tab:first-child {
  border-radius: var(--radius-sm) 0 0 var(--radius-sm);
}

.listening-mode-tab:last-child {
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.listening-mode-tab.active {
  background: var(--color-accent);
  color: var(--color-on-accent, #fff);
  border-color: var(--color-accent);
}

/* ── Dictation area ──────────────────────── */

.listening-dictation-area {
  margin: var(--space-3) 0;
  text-align: left;
}

.dictation-instruction {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-2);
  text-align: center;
}

.dictation-input {
  width: 100%;
  padding: var(--space-2);
  font-family: var(--font-hanzi, 'Noto Serif SC', serif);
  font-size: var(--text-lg);
  line-height: 1.8;
  border: 1px solid var(--color-border, #ddd);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  resize: vertical;
  box-sizing: border-box;
}

.dictation-input:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: -1px;
}

.dictation-result {
  margin-top: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  border: 1px solid var(--color-border, #ddd);
}

.dictation-score {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  text-align: center;
  margin-bottom: var(--space-2);
}

.dictation-diff {
  font-family: var(--font-hanzi, 'Noto Serif SC', serif);
  font-size: var(--text-base);
  line-height: 2;
  word-break: break-all;
}

.dictation-diff .char-correct {
  color: var(--color-correct);
}

.dictation-diff .char-wrong {
  color: var(--color-incorrect);
  text-decoration: underline;
}

.dictation-diff .char-missing {
  color: var(--color-incorrect);
  opacity: 0.5;
}

/* ── Analyze Text panel ──────────────────────── */

.reading-analyze {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border, #ddd);
  text-align: center;
}

.reading-analyze-panel {
  margin-top: var(--space-2);
  text-align: left;
}

.analyze-input {
  width: 100%;
  padding: var(--space-2);
  font-family: var(--font-hanzi, 'Noto Serif SC', serif);
  font-size: var(--text-base);
  line-height: 1.8;
  border: 1px solid var(--color-border, #ddd);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  resize: vertical;
  box-sizing: border-box;
  margin-bottom: var(--space-2);
}

.analyze-input:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: -1px;
}

.analyze-results {
  margin-top: var(--space-3);
}

.analyze-level-badge {
  display: inline-block;
  padding: var(--space-1) var(--space-2);
  background: var(--color-accent);
  color: var(--color-on-accent, #fff);
  border-radius: var(--radius-sm);
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  margin-bottom: var(--space-2);
}

.analyze-metrics {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}

.analyze-metric {
  text-align: center;
}

.analyze-metric-value {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  color: var(--color-text);
}

.analyze-metric-label {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
}

.analyze-vocab-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.analyze-vocab-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) 0;
  border-bottom: 1px solid var(--color-border, #eee);
  font-size: var(--text-sm);
}

.analyze-vocab-item:last-child {
  border-bottom: none;
}

.analyze-vocab-hanzi {
  font-family: var(--font-hanzi, 'Noto Serif SC', serif);
  font-size: var(--text-base);
  min-width: 3em;
}

.analyze-vocab-known {
  color: var(--color-correct);
  font-size: var(--text-xs);
}

.analyze-vocab-unknown {
  color: var(--color-incorrect);
  font-size: var(--text-xs);
}

/* ── Listening word highlight ──────────────────────── */

.listening-word-looked-up {
  background: rgba(148, 96, 112, 0.12);
  border-radius: 2px;
  padding: 0 1px;
}

/* ── Reading word highlight ──────────────────────── */

.reading-word-looked-up {
  background: rgba(148, 96, 112, 0.12);
  border-radius: 2px;
}

/* ── Reading progress dashboard ──────────────────────── */

.reading-progress-dashboard {
  display: flex;
  justify-content: center;
  gap: var(--space-5);
  padding: var(--space-3) 0;
  margin-bottom: var(--space-2);
}

.reading-dashboard-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}

.reading-dashboard-value {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  color: var(--color-text);
}

.reading-dashboard-label {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

/* ── Reading completion badges ──────────────────────── */

.reading-list-meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.reading-hsk-tag {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.reading-completion-badge {
  display: inline-block;
  padding: 0.1em var(--space-2);
  border-radius: var(--radius-full, 999px);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

.completion-started {
  background: rgba(184, 160, 80, 0.15);
  color: var(--color-mastery-stabilizing);
}

.completion-read {
  background: rgba(106, 138, 90, 0.15);
  color: var(--color-mastery-stable);
}

.completion-mastered {
  background: rgba(74, 106, 74, 0.15);
  color: var(--color-mastery-durable);
}

.reading-list-read {
  opacity: 0.85;
}

/* ── Media stats dashboard ──────────────────────── */

.media-stats-dashboard {
  display: flex;
  justify-content: center;
  gap: var(--space-5);
  padding: var(--space-3) 0;
  margin-bottom: var(--space-2);
}

.media-stats-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}

.media-stats-value {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  color: var(--color-text);
}

.media-stats-label {
  font-size: var(--text-xs);
  color: var(--color-text-dim);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

/* ── Media type filter chips ──────────────────────── */

.media-type-chips {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  padding: var(--space-2) 0 var(--space-3);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.media-type-chips::-webkit-scrollbar {
  display: none;
}

.media-type-chip {
  flex-shrink: 0;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full, 999px);
  border: 1px solid var(--color-divider);
  background: transparent;
  color: var(--color-text-dim);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: all var(--duration-fast, 0.15s) ease;
  white-space: nowrap;
  text-transform: capitalize;
}

.media-type-chip:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.media-type-chip.active {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
}

/* ── Media mastery badge ──────────────────────── */

.media-mastery-badge {
  display: inline-block;
  padding: 0.1em var(--space-2);
  border-radius: var(--radius-full, 999px);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
}

/* ── Media upgrade hint ──────────────────────── */

.media-upgrade-hint {
  text-align: center;
  padding: var(--space-4) var(--space-3);
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  grid-column: 1 / -1;
}

/* ── Print ────────────────────────── */

@media print {
  @page { margin: 1.5cm 2cm; }

  /* Force light colors */
  :root {
    --color-base: #fff;
    --color-surface: #fff;
    --color-text: #1a1a2e;
    --color-text-dim: #444;
    --color-accent: #946070;
    --color-divider: #ccc;
  }

  /* Hide UI chrome */
  #status-bar,
  #input-area,
  .shortcuts,
  .skip-link,
  .sound-toggle,
  .offline-indicator,
  .btn-primary,
  .btn-secondary,
  .btn-danger,
  .actions,
  .dashboard-illustration,
  .dashboard-footer,
  .account-bar,
  .onboarding-checklist,
  .feedback-bar,
  .upgrade-banner,
  .session-error-actions,
  .recording-panel,
  .next-session-preview {
    display: none !important;
  }

  /* Expand all panels */
  .panel-body {
    max-height: none !important;
    opacity: 1 !important;
    overflow: visible !important;
  }

  /* Full width, no background effects */
  body {
    background: #fff !important;
    background-image: none !important;
    color: #1a1a2e;
    font-size: 11pt;
  }

  #app {
    max-width: 100%;
    padding: 0;
  }

  /* Remove animations */
  * {
    animation: none !important;
    transition: none !important;
  }

  /* Bar fills print cleanly */
  .mastery-bar,
  #progress-fill,
  .bar-fill,
  .bar-seg,
  .hsk-bar-fill,
  .upgrade-hsk-bar-fill,
  .forecast-fill,
  .mastery-gate-fill,
  .rec-level-fill,
  .upgrade-hsk-bar-track {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* Hide decorative illustrations */
  .complete-illustration {
    display: none !important;
  }

  /* Stats row: no scroll, wrap */
  .stats-row {
    overflow: visible;
    flex-wrap: wrap;
    mask-image: none;
    -webkit-mask-image: none;
  }

  /* Page breaks */
  .panel { page-break-inside: avoid; }
  h2, h3 { page-break-after: avoid; }
}

/* ═══════════════════════════════════════════════════════════════════
   PWA Mobile Responsiveness — A+ Quality
   Comprehensive breakpoints for 320px (iPhone SE) to 428px (iPhone Pro Max)
   Touch targets: minimum 44x44px per Apple HIG
   ═══════════════════════════════════════════════════════════════════ */

/* ── Prevent horizontal scroll globally ────────────────────────── */

html, body {
  overflow-x: hidden;
  max-width: 100vw;
}

/* ── Tablet breakpoint (max-width: 768px) ────────────────────────── */

@media (max-width: 768px) {
  /* App container: tighter padding, full width */
  #app {
    max-width: 100%;
    padding: var(--space-4) var(--space-4);
    padding-top: calc(var(--space-5) + env(safe-area-inset-top, 0px));
  }

  /* Stats row: allow horizontal scroll, no wrap forcing */
  .stats-row {
    gap: var(--space-3);
    justify-content: flex-start;
    padding: var(--space-2) 0;
  }

  /* Drill area: full width, no overflow issues */
  #drill-area {
    padding: var(--space-4) 0;
  }

  /* Reading controls stack */
  .reading-header {
    flex-direction: column;
    align-items: flex-start;
  }

  .reading-controls {
    width: 100%;
    flex-wrap: wrap;
  }

  .reading-controls select {
    flex: 1;
    min-width: 120px;
    min-height: 44px;
    font-size: var(--text-base);
  }

  /* Media grid: single column on tablet-portrait */
  .media-grid {
    grid-template-columns: 1fr;
  }

  /* Complete details: tighter padding */
  .complete-details {
    padding: var(--space-3);
  }

  /* Practiced grid: smaller cells */
  .practiced-grid {
    grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
  }

  /* Upgrade banner stacks vertically */
  .upgrade-banner {
    flex-direction: column;
    text-align: center;
    gap: var(--space-2);
  }

  /* Auth page full width */
  .auth-card {
    max-width: 100%;
  }
}

/* ── Phone breakpoint (max-width: 480px) — extended ────────────────────────── */

@media (max-width: 480px) {
  /* Typography: ensure readability on small screens */
  body {
    font-size: 0.9rem;
    line-height: 1.6;
  }

  /* App container: minimal side padding, use full width */
  #app {
    padding: var(--space-3) var(--space-3);
    padding-top: calc(var(--space-5) + env(safe-area-inset-top, 0px));
    padding-bottom: calc(var(--space-6) + env(safe-area-inset-bottom, 0px));
  }

  /* Header: compact */
  header {
    padding: var(--space-2) 0 var(--space-3);
  }

  .logo-icon {
    width: 56px;
    height: 56px;
  }

  .session-info {
    font-size: var(--text-xs);
  }

  /* Account bar: prevent truncation */
  .account-bar {
    flex-wrap: wrap;
    justify-content: center;
  }

  .account-name {
    max-width: 180px;
  }

  /* Stats row: scrollable, compact */
  .stats-row {
    gap: var(--space-2);
    margin: var(--space-3) 0 var(--space-4);
    padding-bottom: var(--space-1);
  }

  .stat {
    padding: var(--space-2);
    min-width: 56px;
  }

  .stat-value {
    font-size: var(--text-lg);
  }

  .stat-label {
    font-size: 0.65rem;
  }

  /* Actions: stack vertically on narrow phones */
  .actions {
    flex-direction: column;
    gap: var(--space-2);
  }

  .actions button,
  .actions .btn-primary,
  .actions .btn-secondary {
    width: 100%;
  }

  /* Main CTA button: full width */
  #btn-start {
    width: 100%;
    padding: 16px 32px;
  }

  #btn-mini {
    width: 100%;
  }

  /* Exposure buttons: stack on narrow */
  .actions-exposure {
    flex-direction: column;
    gap: var(--space-2);
  }

  .actions-exposure .btn-secondary {
    width: 100%;
    justify-content: center;
    text-align: center;
  }

  /* Hanzi display: slightly smaller but still prominent */
  .msg-hanzi {
    font-size: var(--text-2xl);
    padding: var(--space-4) var(--space-2);
    margin: var(--space-3) 0;
    word-break: keep-all;
  }

  /* Drill groups: tighter spacing */
  .drill-group {
    padding: var(--space-2) 0;
  }

  /* Option buttons: full width, taller tap targets */
  .btn-option {
    min-height: 48px;
    padding: 12px var(--space-3);
    font-size: var(--text-base);
  }

  .option-buttons {
    gap: var(--space-2);
  }

  .option-buttons-row {
    flex-direction: column;
  }

  .option-buttons-row .btn-option {
    flex: none;
    width: 100%;
    min-width: auto;
  }

  /* Input area: full-width, anchored at bottom via flex (no sticky) */
  #input-area {
    flex-shrink: 0;
    margin-left: calc(-1 * var(--space-3));
    margin-right: calc(-1 * var(--space-3));
    padding: var(--space-3) var(--space-3);
    padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
    z-index: 10;
    background: var(--color-base);
    border-top: 1px solid var(--color-divider);
  }

  #answer-input {
    font-size: 16px; /* Prevents iOS zoom on focus */
    min-height: 48px;
  }

  #btn-submit {
    min-height: 48px;
    min-width: 48px;
    padding: 12px 18px;
  }

  /* Shortcuts: wrap, smaller buttons */
  .shortcuts {
    gap: var(--space-1);
    justify-content: center;
  }

  .btn-shortcut {
    padding: 8px 12px;
    font-size: var(--text-xs);
    min-height: 44px;
  }

  /* Progress bar (now inside input-area) */
  #input-progress-row {
    margin-bottom: var(--space-2);
  }

  /* Complete screen: compact */
  #complete {
    padding: var(--space-3) 0 var(--space-4);
  }

  .complete-score {
    font-size: var(--text-3xl);
  }

  .complete-score::before {
    width: 100px;
    height: 100px;
  }

  .complete-details {
    padding: var(--space-2);
    margin: var(--space-2) 0;
  }

  .practiced-grid {
    grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
    gap: var(--space-1);
  }

  .practiced-hanzi {
    font-size: 1.1rem;
  }

  .progress-ring-container {
    width: 100px;
    height: 100px;
  }

  /* Complete return hook: full width */
  .complete-return-hook {
    padding: var(--space-2) var(--space-3);
  }

  .return-word-list {
    gap: var(--space-1);
  }

  .return-word {
    min-width: 3.5rem;
    padding: var(--space-1);
  }

  /* Panels: full width, readable */
  .panel-row {
    flex-wrap: wrap;
    gap: var(--space-1);
  }

  .panel-row .label {
    flex: 1 1 60%;
  }

  .panel-row .value {
    flex: 1 1 35%;
    text-align: right;
  }

  /* Reading view: full width */
  .reading-passage {
    padding: var(--space-3) var(--space-2);
  }

  .reading-text {
    font-size: var(--text-lg);
    line-height: 2;
  }

  .reading-nav {
    flex-direction: column;
    gap: var(--space-2);
  }

  .reading-nav button {
    width: 100%;
    min-height: 48px;
  }

  /* Reading opener: compact */
  .reading-opener {
    padding: var(--space-3);
  }

  /* Media cards: full width, tall tap targets */
  .media-card {
    padding: var(--space-3);
  }

  .media-card-actions {
    flex-wrap: wrap;
  }

  .media-card-actions button {
    flex: 1;
    min-width: 80px;
    min-height: 44px;
  }

  /* Referral section: stack */
  .referral-link-row {
    flex-direction: column;
  }

  .referral-copy-btn {
    width: 100%;
    min-height: 48px;
  }

  /* Session header: compact */
  .session-header {
    flex-wrap: wrap;
    gap: var(--space-1);
  }

  /* Feature tooltip: edge-to-edge on mobile */
  .feature-tooltip {
    left: var(--space-3);
    right: var(--space-3);
    transform: none;
    max-width: none;
  }

  /* Dashboard illustration: smaller */
  .dashboard-illustration {
    max-width: 200px;
    width: 60%;
  }

  /* Complete illustration: smaller */
  .complete-illustration {
    max-width: 240px;
    width: 70%;
  }

  /* Upgrade progress: compact */
  .upgrade-progress {
    gap: var(--space-2);
    padding: var(--space-2) 0;
  }

  .upgrade-stat-value {
    font-size: var(--text-lg);
  }

  /* Dashboard footer: wrap links */
  .dashboard-footer {
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-1);
  }

  .dashboard-footer-link {
    font-size: var(--text-xs);
    padding: 8px;
    min-height: 44px;
  }

  /* Resume banner: compact */
  .resume-banner {
    padding: var(--space-2) var(--space-3);
  }

  .resume-banner-actions {
    flex-direction: column;
    gap: var(--space-1);
  }

  .resume-banner-actions button,
  .resume-btn {
    width: 100%;
    min-height: 44px;
  }
}

/* ── Narrow phone breakpoint (max-width: 360px) — iPhone SE, Galaxy S series ── */

@media (max-width: 360px) {
  #app {
    padding: var(--space-2) var(--space-2);
    padding-top: calc(var(--space-4) + env(safe-area-inset-top, 0px));
  }

  /* Even smaller logo */
  .logo-icon {
    width: 44px;
    height: 44px;
  }

  .logo-text {
    font-size: var(--text-sm);
  }

  /* Hanzi: still readable but tighter */
  .msg-hanzi {
    font-size: var(--text-xl);
    padding: var(--space-3) var(--space-1);
    margin: var(--space-2) 0;
    letter-spacing: var(--tracking-normal);
  }

  /* Stats: ultra-compact */
  .stats-row {
    gap: var(--space-1);
    margin: var(--space-2) 0 var(--space-3);
  }

  .stat {
    padding: var(--space-1) var(--space-2);
    min-width: 44px;
  }

  .stat-value {
    font-size: var(--text-base);
  }

  .stat-label {
    font-size: 0.6rem;
  }

  /* Shortcuts: very compact */
  .shortcuts {
    gap: 3px;
  }

  .btn-shortcut {
    padding: 6px 8px;
    font-size: 0.65rem;
    min-height: 40px;
  }

  /* Buttons: full width at this size */
  .btn-primary, .btn-secondary {
    width: 100%;
    padding: 12px 20px;
  }

  /* Option buttons: smaller text but still tappable */
  .btn-option {
    font-size: var(--text-sm);
    padding: 10px var(--space-2);
    min-height: 44px;
  }

  /* Input: compact */
  #answer-input {
    padding: 10px 4px;
  }

  /* Complete details: minimal padding */
  .complete-details {
    padding: var(--space-1) var(--space-2);
  }

  .complete-score {
    font-size: var(--text-2xl);
  }

  .complete-score::before {
    width: 80px;
    height: 80px;
  }

  .practiced-grid {
    grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
  }

  .practiced-hanzi {
    font-size: 1rem;
  }

  .practiced-stage,
  .practiced-pinyin,
  .practiced-english,
  .practiced-correction {
    font-size: 0.58rem;
  }

  /* Reading: tighter */
  .reading-text {
    font-size: var(--text-base);
    line-height: 1.9;
  }

  /* Media card: compact */
  .media-card {
    padding: var(--space-2);
  }

  /* Complete return hook: compact */
  .return-word {
    min-width: 3rem;
    padding: 2px var(--space-1);
  }

  .return-word-hanzi {
    font-size: var(--text-base);
  }

  .return-word-gloss {
    font-size: 0.58rem;
  }

  /* Onboarding items: very compact */
  .onboarding-item {
    font-size: var(--text-xs);
    padding: var(--space-1) 0;
  }

  .onboarding-label {
    min-width: 70px;
  }

  /* Session error actions: stack */
  .session-error-actions {
    flex-direction: column;
  }

  .session-error-actions button {
    width: 100%;
  }
}

/* ── Touch device enhancements ────────────────────────── */

@media (pointer: coarse) {
  /* Ensure all interactive elements meet 44px minimum tap target */
  .toggle-label {
    min-height: 44px;
    display: flex;
    align-items: center;
  }

  .toggle-label input[type="checkbox"] {
    width: 20px;
    height: 20px;
    margin-right: var(--space-1);
  }

  /* Reading word targets: taller for finger tapping */
  .reading-word {
    padding: 4px 2px;
    min-height: 36px;
    display: inline-flex;
    align-items: center;
  }

  /* Export links: taller */
  .export-link {
    min-height: 48px;
    padding: 10px 0;
  }

  /* Panel toggles: taller for easier tapping */
  .panel-toggle {
    min-height: 48px;
    padding: var(--space-3) 0;
  }

  /* Select elements: taller */
  select {
    min-height: 44px;
  }

  /* Onboarding dismiss: larger */
  .onboarding-dismiss {
    min-height: 48px;
    min-width: 48px;
  }

  /* Media history items: taller tap area */
  .media-history-item {
    padding: var(--space-3) 0;
    min-height: 44px;
    align-items: center;
  }

  /* Reading list items: taller */
  .reading-list-item {
    min-height: 52px;
    padding: var(--space-3);
  }

  /* Dashboard footer links: larger touch targets */
  .dashboard-footer-link {
    min-height: 48px;
    padding: 10px 12px;
  }

  /* Complete reminder button: taller */
  .complete-reminder .btn-sm {
    min-height: 48px;
    padding: var(--space-2) var(--space-4);
  }
}

/* ── Standalone PWA mode adjustments ────────────────────────── */
/* When running as installed PWA, adjust for OS-level status bars */

@media (display-mode: standalone) {
  body {
    /* Extra top padding for iOS status bar in standalone */
    padding-top: env(safe-area-inset-top, 0px);
  }

  #app {
    /* Ensure content doesn't hide behind home indicator */
    padding-bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px));
  }

  /* Input area respects bottom safe area */
  #input-area {
    padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
  }

  /* Offline indicator below status bar */
  .offline-indicator {
    top: env(safe-area-inset-top, 0px);
  }
}

/* ── iOS-specific: prevent double-tap zoom on interactive elements ── */

@supports (-webkit-touch-callout: none) {
  /* Prevent zoom on double-tap for all buttons */
  button, [role="button"], .btn-option, .btn-shortcut, .btn-primary, .btn-secondary {
    touch-action: manipulation;
  }

  /* Fix iOS momentum scrolling for drill area */
  #drill-area {
    -webkit-overflow-scrolling: touch;
  }

  /* Fix iOS input zoom: 16px minimum prevents Safari from zooming */
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="search"],
  textarea,
  select {
    font-size: max(16px, 1em);
  }
}

/* ── Passage Comments ──────────────────── */
.reading-comments {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--color-surface);
}
.passage-comments-header {
  font-size: 13px;
  color: var(--color-text-dim);
  margin-bottom: 8px;
}
.passage-comments-list {
  max-height: 200px;
  overflow-y: auto;
}
.passage-comment {
  padding: 6px 0;
  border-bottom: 1px solid var(--color-surface);
}
.comment-author {
  font-weight: 600;
  font-size: 12px;
  color: var(--color-accent);
  margin-right: 6px;
}
.comment-text {
  font-size: 13px;
  color: var(--color-text);
}
.passage-comment-form {
  margin-top: 10px;
  display: flex;
  gap: 8px;
  align-items: flex-start;
}
.passage-comment-form textarea {
  flex: 1;
  font-size: 13px;
  border: 1px solid var(--color-surface);
  border-radius: 6px;
  padding: 6px 8px;
  resize: none;
  background: var(--color-base);
  color: var(--color-text);
}

/* ── Grammar Explanation Modal ──────────── */
.grammar-explanation-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,0.4);
}
.grammar-explanation-modal.hidden { display: none; }
.grammar-explanation-content {
  background: var(--color-base);
  border-radius: 12px;
  padding: 24px;
  max-width: 420px;
  width: 90%;
  max-height: 80vh;
  overflow-y: auto;
  box-shadow: 0 8px 32px rgba(0,0,0,0.15);
  position: relative;
}
.grammar-explanation-close {
  position: absolute;
  top: 8px;
  right: 12px;
  background: none;
  border: none;
  font-size: 20px;
  cursor: pointer;
  color: var(--color-text-dim);
}
.grammar-pattern {
  font-family: var(--font-hanzi);
  font-size: 18px;
  color: var(--color-accent);
  margin: 8px 0;
  padding: 8px;
  background: var(--color-surface);
  border-radius: 6px;
}
.grammar-explanation-text {
  line-height: 1.6;
  font-size: 14px;
}
.btn-grammar-explain {
  display: inline-block;
  margin-top: 8px;
  padding: 4px 12px;
  font-size: 12px;
  background: var(--color-surface);
  border: 1px solid var(--color-accent);
  color: var(--color-accent);
  border-radius: 4px;
  cursor: pointer;
}
.btn-grammar-explain:hover {
  background: var(--color-accent);
  color: var(--color-base);
}

/* ── Dictionary Tooltip ──────────────────── */
.dict-hanzi { font-family: var(--font-hanzi); font-size: 18px; }
.dict-pinyin { font-size: 13px; color: var(--color-accent); }
.dict-english { font-size: 13px; }
.dict-hsk { font-size: 11px; background: var(--color-surface); padding: 1px 5px; border-radius: 3px; }

/* ── Import Summary ──────────────────────── */
.import-summary {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin: 8px 0;
}
.import-stat { font-size: 14px; }
.import-unmatched {
  font-size: 12px;
  color: var(--color-text-dim);
  margin-top: 8px;
}

/* ── Mobile responsive improvements ──────── */
@media (max-width: 480px) {
  .drill-card, .reading-passage, .listening-content, .grammar-lesson-content {
    padding: 12px 8px;
  }
  .reading-nav {
    flex-direction: row;
    gap: 8px;
  }
  .reading-nav button {
    flex: 1;
    font-size: 13px;
    padding: 8px;
  }
  .grammar-explanation-content {
    padding: 16px;
    width: 95%;
  }
  .passage-comment-form {
    flex-direction: column;
  }
  .passage-comment-form textarea {
    width: 100%;
  }
  .speed-control select {
    font-size: 14px;
    padding: 4px;
  }
}

/* ── Academic Features (Learning Science) ──────────────────────────── */

/* Minimal Pair Drills */
.minimal-pair { text-align: center; padding: 1.5rem; }
.mp-label { font-size: 0.85rem; color: var(--color-text-faint); margin-bottom: 0.5rem; }
.mp-question { font-size: 1.1rem; font-weight: 600; margin-bottom: 1.5rem; }
.mp-options { display: flex; gap: 1rem; justify-content: center; }
.mp-option { flex: 1; max-width: 180px; padding: 1.5rem 1rem; border-radius: 12px; border: 2px solid var(--color-divider); background: var(--color-base); cursor: pointer; transition: all 0.2s; }
.mp-option:hover { border-color: var(--color-accent); }
.mp-option.selected { border-color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 10%, var(--color-base)); }
.mp-hanzi { font-size: 2rem; margin-bottom: 0.5rem; }
.mp-pinyin { font-size: 0.9rem; color: var(--color-text-faint); }
.mp-hint { font-size: 0.8rem; color: var(--color-text-faintest); margin-top: 1rem; font-style: italic; }
.mp-feedback { margin-top: 1rem; padding: 0.75rem; border-radius: 8px; }
.mp-feedback.correct { background: color-mix(in srgb, var(--color-correct) 10%, transparent); color: var(--color-correct); }
.mp-feedback.incorrect { background: color-mix(in srgb, var(--color-incorrect) 10%, transparent); color: var(--color-incorrect); }

/* Tone Sandhi Drills */
.sandhi-drill { text-align: center; padding: 1.5rem; }
.sandhi-label { font-size: 0.8rem; color: var(--color-accent); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.5rem; }
.sandhi-hanzi { font-size: 2.5rem; margin-bottom: 0.5rem; }
.sandhi-question { font-size: 1rem; color: var(--color-text-faint); margin-bottom: 1.5rem; }
.sandhi-options { display: flex; gap: 0.75rem; justify-content: center; }
.sandhi-option { padding: 1rem 2rem; border-radius: 10px; border: 2px solid var(--color-divider); background: var(--color-base); font-size: 1rem; cursor: pointer; transition: all 0.2s; }
.sandhi-option:hover { border-color: var(--color-accent); }
.sandhi-option.selected { border-color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 10%, var(--color-base)); }
.sandhi-feedback { margin-top: 1rem; padding: 0.75rem; border-radius: 8px; }
.sandhi-feedback.correct { background: color-mix(in srgb, var(--color-correct) 10%, transparent); color: var(--color-correct); }
.sandhi-feedback.incorrect { background: color-mix(in srgb, var(--color-incorrect) 10%, transparent); color: var(--color-incorrect); }
.sandhi-explanation { font-size: 0.85rem; margin-top: 0.5rem; color: var(--color-text-faint); }

/* Character Decomposition (Shen 2005, Taft & Zhu 1997) */
.char-decomposition { position: relative; background: var(--color-surface-alt, #EAE2D6); border-radius: 12px; padding: var(--space-5); margin-bottom: var(--space-4); text-align: center; border: 1px solid var(--color-divider, #D8D0C4); animation: fadeIn 0.3s ease; cursor: pointer; }
.char-decomp-main { font-size: var(--text-display, 3rem); font-family: var(--font-hanzi); margin-bottom: var(--space-3); line-height: var(--lh-display, 1.1); }
.char-decomp-radical { display: flex; align-items: center; justify-content: center; gap: var(--space-2); margin-bottom: var(--space-2); }
.char-decomp-radical-char { font-size: var(--text-xl, 1.5rem); font-family: var(--font-hanzi); color: var(--color-accent, #946070); }
.char-decomp-radical-meaning { font-size: var(--text-sm, 0.9rem); color: var(--color-text-dim, #5A6678); }
.char-decomp-phonetic { font-size: var(--text-sm, 0.85rem); color: var(--color-text-dim, #5A6678); margin-bottom: var(--space-2); }
.char-decomp-family { font-size: var(--text-lg, 1.1rem); font-family: var(--font-hanzi); letter-spacing: 0.3em; color: var(--color-text-faint, #6A7080); margin-bottom: var(--space-2); }
.char-decomp-dismiss { font-size: var(--text-xs, 0.75rem); color: var(--color-text-faint, #6A7080); margin-top: var(--space-2); }

/* Metacognitive Prompts */
.meta-prompt { text-align: center; padding: 1.5rem; }
.meta-label { font-size: 0.9rem; color: var(--color-text-faint); margin-bottom: 0.75rem; }
.meta-question { font-size: 1rem; margin-bottom: 1rem; }
.meta-options { display: flex; gap: 0.5rem; justify-content: center; }
.meta-options-col { flex-direction: column; max-width: 280px; margin: 0 auto; }
.meta-option { padding: 0.75rem 1.25rem; border-radius: 8px; border: 2px solid var(--color-divider); background: var(--color-base); cursor: pointer; transition: all 0.2s; }
.meta-option:hover { border-color: var(--color-accent); }

/* Session Choice (SDT Autonomy) */
.session-choice { text-align: center; padding: 2rem; }
.session-choice-label { font-size: 1.1rem; font-weight: 600; margin-bottom: 1.5rem; }
.session-choice-options { display: flex; flex-direction: column; gap: 0.75rem; max-width: 300px; margin: 0 auto; }
.session-choice-option { padding: 1rem; border-radius: 10px; border: 2px solid var(--color-divider); background: var(--color-base); cursor: pointer; font-size: 1rem; transition: all 0.2s; }
.session-choice-option:hover { border-color: var(--color-accent); transform: translateY(-1px); }

/* Competence Toast (SDT) */
.competence-toast { position: fixed; bottom: 1.5rem; left: 50%; transform: translateX(-50%) translateY(20px); background: var(--color-accent); color: var(--color-base); padding: 0.75rem 1.5rem; border-radius: 10px; font-size: 0.9rem; opacity: 0; transition: all 0.3s; z-index: 1000; }
.competence-toast.visible { opacity: 1; transform: translateX(-50%) translateY(0); }

/* fadeIn defined in tokens section — no duplicate needed */

/* Dark mode overrides for academic features */
[data-theme="dark"] .mp-option, [data-theme="dark"] .sandhi-option, [data-theme="dark"] .meta-option, [data-theme="dark"] .session-choice-option { background: var(--color-surface); border-color: var(--color-divider); color: var(--color-text); }
[data-theme="dark"] .mp-option:hover, [data-theme="dark"] .sandhi-option:hover, [data-theme="dark"] .meta-option:hover, [data-theme="dark"] .session-choice-option:hover { border-color: var(--color-accent); }
[data-theme="dark"] .mp-option.selected, [data-theme="dark"] .sandhi-option.selected { background: var(--color-accent-dim); border-color: var(--color-accent); }
[data-theme="dark"] .char-decomposition { background: var(--color-surface-alt); border-color: var(--color-divider); }

/* === UI Fixes === */

/* Form error states */
.input-field[aria-invalid="true"], .input-field.input-error {
    border-color: var(--color-incorrect) !important;
    box-shadow: 0 0 0 2px rgba(180, 80, 70, 0.15);
}
.input-error-message { font-size: var(--text-sm); color: var(--color-incorrect); margin-top: var(--space-1); }

/* Responsive tables */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 8px; }
.admin-table thead th { position: sticky; top: 0; background: var(--color-surface); z-index: 1; }
@media (max-width: 768px) {
    .admin-table { font-size: var(--text-sm); }
    .admin-table td, .admin-table th { padding: 6px 8px; white-space: nowrap; }
}

/* Admin semantic metric colors */
.metric-value-revenue { color: var(--color-correct); }
.metric-value-users { color: var(--color-accent); }
.metric-value-warning { color: #E6A23C; }
.metric-value-danger { color: var(--color-incorrect); }

/* Base card */
.card { background: var(--color-surface); border-radius: 12px; padding: var(--space-3) var(--space-4); border: 1px solid rgba(0,0,0,0.06); }
.card-elevated { box-shadow: 0 2px 8px rgba(0,0,0,0.06); }

/* Measure */
:root { --measure: 65ch; }

/* Placeholder contrast */
::placeholder { color: var(--color-text-dim); opacity: 0.7; }

/* Drill skip */
.drill-skip-wrap { text-align: center; margin-top: 0.75rem; }
.drill-skip { font-size: 0.8rem; color: var(--color-text-faint); }

/* Error explanation */
.error-explanation { font-size: 0.85rem; color: var(--color-text-dim); margin-top: 0.5rem; padding: 0.5rem; background: rgba(0,0,0,0.03); border-radius: 6px; font-style: italic; }

/* Confirm modal */
.confirm-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; }
.confirm-modal-content { background: var(--color-surface); border-radius: 12px; padding: 1.5rem; text-align: center; max-width: 300px; }
.confirm-detail { font-size: 0.85rem; color: var(--color-text-dim); margin: 0.5rem 0 1rem; }

/* Dark mode toggle */
.dark-toggle { font-size: 1.2rem; padding: 4px 8px; cursor: pointer; background: none; border: none; }

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

/* Dark mode overrides for new UI components */
@media (prefers-color-scheme: dark) {
    .error-explanation { background: rgba(255,255,255,0.05); }
    .card { border-color: rgba(255,255,255,0.08); }
    .confirm-modal-content { background: var(--color-base); }
}

/* ── Loading skeletons with shimmer ────────────────────────── */

@keyframes skeleton-shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

.skeleton {
  background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-surface-alt) 50%, var(--color-surface) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer var(--duration-ambient) ease infinite;
}

.skeleton-text {
  height: var(--skeleton-height, 14px);
  margin-bottom: var(--space-2);
  background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-surface-alt) 50%, var(--color-surface) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer var(--duration-ambient) ease infinite;
}

.skeleton-text-short { width: 60%; }
.skeleton-text-long { width: 90%; }

.skeleton-stat {
  width: 100%;
  height: 64px;
  background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-surface-alt) 50%, var(--color-surface) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer var(--duration-ambient) ease infinite;
}

.skeleton-card {
  padding: var(--card-padding);
  min-height: 80px;
  background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-surface-alt) 50%, var(--color-surface) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer var(--duration-ambient) ease infinite;
}

.skeleton-drill {
  height: 48px;
  border-left: 3px solid var(--color-divider);
  padding-left: var(--space-4);
  margin-bottom: var(--space-3);
  background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-surface-alt) 50%, var(--color-surface) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer var(--duration-ambient) ease infinite;
}

[aria-busy="true"] { pointer-events: none; opacity: 0.7; }

/* ── Mobile swipe feedback ────────────────────────── */

.drill-group.swipe-left {
  transform: translateX(-12px);
  opacity: 0.9;
  transition: transform var(--duration-fast) var(--ease-default), opacity var(--duration-fast) var(--ease-default);
}

.drill-group.swipe-right {
  transform: translateX(12px);
  opacity: 0.9;
  transition: transform var(--duration-fast) var(--ease-default), opacity var(--duration-fast) var(--ease-default);
}

.drill-group.swipe-settle {
  transform: translateX(0);
  opacity: 1;
  transition: transform var(--duration-base) var(--ease-default), opacity var(--duration-base) var(--ease-default);
}

/* ── Tablet-optimized layout (768px–1024px) ────────────────────────── */

@media (min-width: 768px) and (max-width: 1024px) {
  .stats-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: var(--space-3);
  }

  .stat {
    padding: var(--space-3) var(--space-4);
  }

  .actions {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
  }

  .actions .btn-primary,
  .actions .btn-secondary {
    flex: 0 1 auto;
    min-width: 140px;
  }

  .actions-exposure {
    flex-direction: row;
    gap: var(--space-3);
  }

  #drill-area {
    max-width: 640px;
    margin: 0 auto;
  }

  .drill-group {
    padding: var(--space-4) var(--space-5);
  }

  .msg .hanzi {
    font-size: var(--text-3xl);
  }

  .panel {
    max-width: 640px;
    margin-left: auto;
    margin-right: auto;
  }

  .session-info {
    font-size: var(--text-base);
    padding: var(--space-2) var(--space-4);
  }

  header {
    padding: var(--space-4) var(--space-5);
  }

  section {
    padding: 0 var(--space-5);
  }
}

/* ══════════════════════════════════════════════════════════════════
   2026 Visual Design Modernization
   Backdrop blur, view transitions, spring animations, color shifts
   ══════════════════════════════════════════════════════════════════ */

/* ── 1a. Frosted glass system ────────────────────────── */
/* Layered glass: semi-transparent background + backdrop blur + subtle border.
   Three densities: light (cards), standard (panels), dense (overlays). */

@supports (backdrop-filter: blur(1px)) {
  /* Reusable glass utility */
  .surface-glass {
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
    background: var(--glass-bg);
    border: var(--glass-border);
  }

  .surface-glass-dense {
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
    background: var(--glass-bg-dense);
    border: var(--glass-border);
  }

  .stat {
    backdrop-filter: blur(16px) saturate(1.15);
    -webkit-backdrop-filter: blur(16px) saturate(1.15);
    background: var(--glass-bg);
    border: var(--glass-border);
    transition: transform var(--duration-fast) var(--ease-default),
                box-shadow var(--duration-fast) var(--ease-default);
  }

  .stat:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
  }

  .panel {
    backdrop-filter: blur(20px) saturate(1.2);
    -webkit-backdrop-filter: blur(20px) saturate(1.2);
    background: color-mix(in srgb, var(--color-surface) 82%, transparent);
    border: var(--glass-border);
  }

  .msg {
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    background: var(--glass-bg-dense);
  }

  /* Glass cards for reading, media, grammar */
  .reading-list .passage-card,
  .media-grid .media-card,
  .grammar-list .grammar-card {
    backdrop-filter: blur(12px) saturate(1.1);
    -webkit-backdrop-filter: blur(12px) saturate(1.1);
    background: var(--glass-bg);
    border: var(--glass-border);
    transition: transform var(--duration-fast) var(--ease-default),
                box-shadow var(--duration-fast) var(--ease-default);
  }

  .reading-list .passage-card:hover,
  .media-grid .media-card:hover,
  .grammar-list .grammar-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
  }
}

/* ── 1b. View Transitions API ────────────────────────── */

@keyframes vt-fade-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

@keyframes vt-fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

::view-transition-old(root) {
  animation: vt-fade-out 0.2s var(--ease-exit) forwards;
}

::view-transition-new(root) {
  animation: vt-fade-in 0.25s var(--ease-default) forwards;
}

/* ── Shared-element view transitions ── */
/* Cards morph into detail views; progress rings morph into score displays */
.passage-card { view-transition-name: reading-card; }
.grammar-card { view-transition-name: grammar-card; }
#progress-bar { view-transition-name: session-progress; }
.complete-score { view-transition-name: session-score; }

/* Morph animation for shared elements */
::view-transition-group(reading-card),
::view-transition-group(grammar-card),
::view-transition-group(session-progress),
::view-transition-group(session-score) {
  animation-duration: 0.3s;
  animation-timing-function: var(--ease-upward);
}

/* ── 1f. Mastery bar animation ────────────────────────── */

.bar-seg {
  transition: width 0.8s var(--ease-upward, cubic-bezier(0.16, 1, 0.3, 1));
}

.bar-seg.bar-animate-in {
  animation: barSpringIn 0.8s var(--ease-upward) backwards;
}

@keyframes barSpringIn {
  from { transform: scaleX(0); transform-origin: left; }
  to { transform: scaleX(1); transform-origin: left; }
}

/* ── 1g. Contextual color temperature shifts ────────────────────────── */
/* Background color shifts subtly based on session state.
   Active session: slightly cooler (focused). Complete: slightly warmer (rewarding). */

html[data-session-state="active"] {
  --color-base: #EDE8DF;
  --color-surface: #EDE8DF;
  --color-sky-bottom: #EDE8DF;
}

html[data-session-state="complete"] {
  --color-base: #F5EFE4;
  --color-surface: #F5EFE4;
  --color-sky-bottom: #F5EFE4;
}

html[data-theme="dark"][data-session-state="active"] {
  --color-base: #1A1E26;
  --color-surface: #1A1E26;
  --color-sky-bottom: #1A1E26;
}

html[data-theme="dark"][data-session-state="complete"] {
  --color-base: #1E222C;
  --color-surface: #1E222C;
  --color-sky-bottom: #1E222C;
}

/* Smooth color temperature transition */
html {
  transition: background-color 1.5s var(--ease-default);
}

body {
  transition: background-color 1.5s var(--ease-default);
}

/* ── 1e. Parallax depth ────────────────────────── */

.sky-bg {
  will-change: transform;
  transition: transform 0.1s linear;
}

.horizon {
  will-change: transform;
}

/* ── 1f2. Typography as graphic element ────────────────────────── */
/* Oversized hanzi watermarks, animated text reveals, display-scale type. */

/* Hero hanzi watermark — massive background character behind content */
.hanzi-watermark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--font-hanzi);
  font-size: clamp(8rem, 20vw, 16rem);
  line-height: 1;
  color: var(--color-accent);
  opacity: 0.06;
  mix-blend-mode: multiply;
  pointer-events: none;
  user-select: none;
  z-index: 0;
  white-space: nowrap;
}

html[data-theme="dark"] .hanzi-watermark {
  mix-blend-mode: screen;
  opacity: 0.04;
}

/* Animated text reveal — characters slide in via clip-path */
.text-reveal-char {
  display: inline-block;
  clip-path: inset(0 100% 0 0);
  animation: charReveal 0.4s var(--ease-upward) forwards;
}

@keyframes charReveal {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0% 0 0); }
}

/* Stagger delay applied via inline style: animation-delay: calc(var(--char-index) * 30ms) */

/* Section heading — animated underline draw-in on entry */
.heading-reveal {
  position: relative;
  display: inline-block;
}

.heading-reveal::after {
  content: '';
  position: absolute;
  bottom: -4px;
  left: 0;
  width: 0;
  height: 2px;
  background: var(--color-accent);
  transition: width 0.8s var(--ease-upward);
}

.heading-reveal.is-visible::after {
  width: 60px;
}

/* Display-scale typography for hero moments */
.text-display-hero {
  font-family: var(--font-heading);
  font-size: clamp(2.8rem, 6vw, 4.5rem);
  line-height: var(--lh-display);
  letter-spacing: var(--tracking-tight);
  font-weight: 300;
}

.text-display-hanzi {
  font-family: var(--font-hanzi);
  font-size: clamp(3rem, 8vw, 6rem);
  line-height: 1;
  color: var(--color-accent);
}

/* ── 1f3. Scroll-driven reveals ────────────────────────── */
/* Elements with [data-reveal] fade/slide in when scrolled into view.
   Children with [data-reveal-child] stagger with delay set by JS. */

[data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s var(--ease-upward), transform 0.6s var(--ease-upward);
}

[data-reveal].is-revealed {
  opacity: 1;
  transform: translateY(0);
}

[data-reveal-child] {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s var(--ease-upward), transform 0.5s var(--ease-upward);
}

[data-reveal-child].is-revealed {
  opacity: 1;
  transform: translateY(0);
}

/* Native CSS scroll-driven animations (progressive enhancement) */
@supports (animation-timeline: view()) {
  .scroll-reveal {
    animation: scrollRevealUp linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 100%;
  }

  @keyframes scrollRevealUp {
    from { opacity: 0; transform: translateY(24px); }
    to { opacity: 1; transform: translateY(0); }
  }
}

/* Stagger animation for lists of items */
.stagger-children > * {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.4s var(--ease-upward), transform 0.4s var(--ease-upward);
}

.stagger-children.is-revealed > *:nth-child(1) { transition-delay: 0ms; opacity: 1; transform: translateY(0); }
.stagger-children.is-revealed > *:nth-child(2) { transition-delay: 60ms; opacity: 1; transform: translateY(0); }
.stagger-children.is-revealed > *:nth-child(3) { transition-delay: 120ms; opacity: 1; transform: translateY(0); }
.stagger-children.is-revealed > *:nth-child(4) { transition-delay: 180ms; opacity: 1; transform: translateY(0); }
.stagger-children.is-revealed > *:nth-child(5) { transition-delay: 240ms; opacity: 1; transform: translateY(0); }
.stagger-children.is-revealed > *:nth-child(6) { transition-delay: 300ms; opacity: 1; transform: translateY(0); }
.stagger-children.is-revealed > *:nth-child(n+7) { transition-delay: 360ms; opacity: 1; transform: translateY(0); }

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  [data-reveal-child],
  .stagger-children > *,
  .scroll-reveal {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
    transition: none !important;
  }
}

/* ── 1h. Interactive data viz ────────────────────────── */

/* Study heatmap (7-cell GitHub-style contribution grid) */
.study-heatmap {
  display: flex;
  gap: 3px;
  justify-content: center;
  margin: var(--space-3) 0;
}

.heatmap-cell {
  width: 20px;
  height: 20px;
  background: var(--color-surface-alt);
  transition: background-color var(--duration-fast) var(--ease-default), transform var(--duration-fast) var(--ease-default);
}

.heatmap-cell[data-intensity="1"] { background: color-mix(in srgb, var(--color-correct) 25%, var(--color-surface-alt)); }
.heatmap-cell[data-intensity="2"] { background: color-mix(in srgb, var(--color-correct) 50%, var(--color-surface-alt)); }
.heatmap-cell[data-intensity="3"] { background: color-mix(in srgb, var(--color-correct) 75%, var(--color-surface-alt)); }
.heatmap-cell[data-intensity="4"] { background: var(--color-correct); }

@media (hover: hover) {
  .heatmap-cell:hover {
    transform: scale(1.3);
    box-shadow: var(--shadow-md);
  }
}

/* Animated counter value */
.stat-value[data-animate] {
  font-variant-numeric: tabular-nums;
}

/* ── Move 5: Motion & interaction polish ────────────────────────── */

/* Card entrance stagger — panels enter 50ms apart */
.panel.panel-stagger-enter {
  animation: panelEnter var(--duration-base) var(--ease-upward) backwards;
}

.panel.panel-stagger-enter:nth-child(1) { animation-delay: 0s; }
.panel.panel-stagger-enter:nth-child(2) { animation-delay: 0.05s; }
.panel.panel-stagger-enter:nth-child(3) { animation-delay: 0.1s; }
.panel.panel-stagger-enter:nth-child(4) { animation-delay: 0.15s; }
.panel.panel-stagger-enter:nth-child(5) { animation-delay: 0.2s; }
.panel.panel-stagger-enter:nth-child(6) { animation-delay: 0.25s; }
.panel.panel-stagger-enter:nth-child(7) { animation-delay: 0.3s; }
.panel.panel-stagger-enter:nth-child(8) { animation-delay: 0.35s; }

@keyframes panelEnter {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Correct answer ripple effect */
.msg-correct .ripple {
  position: absolute;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-correct) 20%, transparent);
  animation: rippleExpand 0.6s var(--ease-default) forwards;
  pointer-events: none;
}

@keyframes rippleExpand {
  from { width: 0; height: 0; opacity: 1; }
  to { width: 200px; height: 200px; opacity: 0; margin-left: -100px; margin-top: -100px; }
}

/* Pull-to-refresh indicator (horizon-line style, not spinner) */
.ptr-indicator {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duration-fast) var(--ease-default);
  z-index: 100;
}

.ptr-indicator.ptr-active {
  transform: scaleX(var(--ptr-progress, 0));
}

.ptr-indicator.ptr-refreshing {
  animation: ptrRefresh 1s var(--ease-default) infinite;
}

@keyframes ptrRefresh {
  0% { transform: scaleX(0); transform-origin: left; }
  50% { transform: scaleX(1); transform-origin: left; }
  50.01% { transform: scaleX(1); transform-origin: right; }
  100% { transform: scaleX(0); transform-origin: right; }
}

/* Session radial progress in header */
.session-progress-ring {
  width: 24px;
  height: 24px;
  display: inline-block;
  vertical-align: middle;
  margin-right: var(--space-2);
}

.session-progress-ring circle {
  fill: none;
  stroke-width: 2;
}

.session-progress-ring .ring-bg {
  stroke: var(--color-divider);
}

.session-progress-ring .ring-fill {
  stroke: var(--color-accent);
  stroke-linecap: round;
  transition: stroke-dashoffset var(--duration-fast) var(--ease-default);
  transform: rotate(-90deg);
  transform-origin: center;
}

/* ── Move 2: Learner Intelligence Panel ────────────────────────── */

.intelligence-stat {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-divider);
}

.intelligence-stat:last-child { border-bottom: none; }

.intelligence-stat-label {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
}

.intelligence-stat-value {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-accent);
}

.intelligence-note {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  font-style: italic;
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-divider);
  line-height: var(--lh-relaxed);
}

/* ── Move 4: Onboarding walkthrough ────────────────────────── */

.walkthrough-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.walkthrough-backdrop {
  position: absolute;
  inset: 0;
  background: var(--color-overlay);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.walkthrough-card {
  position: relative;
  z-index: 1;
  max-width: 380px;
  width: 90%;
  background: var(--color-surface);
  padding: var(--space-5) var(--space-5) var(--space-4);
  animation: panelEnter var(--duration-base) var(--ease-upward);
}

.walkthrough-step-indicator {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin-bottom: var(--space-4);
}

.walkthrough-dot {
  width: 6px;
  height: 6px;
  background: var(--color-divider);
  transition: background var(--duration-fast) var(--ease-default);
}

.walkthrough-dot.active {
  background: var(--color-accent);
  width: 18px;
}

.walkthrough-title {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-2);
  text-align: center;
}

.walkthrough-text {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  line-height: var(--lh-relaxed);
  text-align: center;
  margin-bottom: var(--space-4);
}

.walkthrough-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* ── Move 3: Streaming session analysis ────────────────────────── */

.session-analysis {
  margin: var(--space-4) 0;
  padding: var(--space-4);
  border-top: 1px solid var(--color-divider);
  animation: panelEnter var(--duration-slow) var(--ease-upward);
}

@supports (backdrop-filter: blur(1px)) {
  .session-analysis {
    backdrop-filter: blur(20px) saturate(1.2);
    -webkit-backdrop-filter: blur(20px) saturate(1.2);
    background: color-mix(in srgb, var(--color-surface) 85%, transparent);
  }
}

.session-analysis-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-3);
}

.session-analysis-header h3 {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-text);
}

.session-analysis-content {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  line-height: var(--lh-relaxed);
}

.analysis-typing::after {
  content: '|';
  animation: blink 0.8s step-end infinite;
  color: var(--color-accent);
}

.analysis-typing.done::after {
  display: none;
}

@keyframes blink {
  50% { opacity: 0; }
}

/* ══════════════════════════════════════════════════════════════════
   Non-core feature elevation — reading, listening, grammar, media, teacher
   Glass cards, hover lift, animated interactions, polished empty states
   ══════════════════════════════════════════════════════════════════ */

/* ── Reading list items — hover lift + accent bar ── */
.reading-list-item {
  transition: background var(--duration-fast) var(--ease-default),
              transform var(--duration-fast) var(--ease-default),
              box-shadow var(--duration-fast) var(--ease-default);
}

@media (hover: hover) {
  .reading-list-item:hover {
    transform: translateX(4px);
    background: color-mix(in srgb, var(--color-accent) 4%, var(--color-surface));
  }
}

/* ── Reading passage — generous typography ── */
.reading-passage { animation: driftUp 0.4s var(--ease-upward) backwards; }
.reading-text { font-size: var(--text-lg); line-height: var(--lh-relaxed, 1.8); }
/* driftUp defined in tokens section — no duplicate */

/* ── Reading typography elevation — drop cap, generous Chinese line-height, pull quotes ── */

/* Chinese text needs more vertical breathing room */
.reading-text[lang="zh"],
.reading-text .passage-hanzi,
.reading-text .hanzi {
  line-height: 2.0;
  letter-spacing: 0.05em;
}

/* Drop cap — first character of each passage rendered large */
.reading-dropcap::first-letter {
  font-family: var(--font-hanzi);
  font-size: 3.2em;
  float: left;
  line-height: 0.8;
  padding-right: 0.1em;
  padding-top: 0.05em;
  color: var(--color-accent);
}

/* Pull quote — key vocabulary sentence highlighted */
.reading-pullquote {
  border-left: 3px solid var(--color-accent);
  padding: var(--space-3) var(--space-4);
  margin: var(--space-4) 0;
  font-size: var(--text-lg);
  color: var(--color-text);
  font-style: italic;
  background: color-mix(in srgb, var(--color-accent) 3%, transparent);
}

/* Two-column layout on wide screens */
@media (min-width: 820px) {
  .reading-text-columns {
    column-count: 2;
    column-gap: var(--space-6);
    column-rule: 1px solid var(--color-divider);
  }
}

/* Passage title — Cormorant heading */
.reading-passage-title {
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  font-weight: 600;
  line-height: var(--lh-3xl, 1.2);
  margin-bottom: var(--space-3);
  color: var(--color-text);
}

/* Passage metadata — dim, small */
.reading-passage-meta {
  font-size: var(--text-sm);
  color: var(--color-text-dim);
  margin-bottom: var(--space-4);
}

/* ── Reading gloss tooltip — glass ── */
@supports (backdrop-filter: blur(1px)) {
  .reading-gloss {
    backdrop-filter: blur(16px) saturate(1.15);
    -webkit-backdrop-filter: blur(16px) saturate(1.15);
    background: var(--glass-bg, color-mix(in srgb, var(--color-surface) 85%, transparent));
    border: var(--glass-border, 1px solid color-mix(in srgb, var(--color-divider) 40%, transparent));
    box-shadow: var(--shadow-lg);
  }
}

/* ── Media grid cards — glass + hover ── */
.media-grid {
  display: grid;
  gap: var(--space-3);
}

@supports (backdrop-filter: blur(1px)) {
  .media-type-chips button {
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    transition: background var(--duration-fast) var(--ease-default),
                color var(--duration-fast) var(--ease-default),
                transform var(--duration-fast) var(--ease-default);
  }

  .media-type-chips button:hover {
    transform: translateY(-1px);
  }
}

/* ── Listening — playback waveform visualization ── */
.listening-waveform {
  display: block;
  width: 100%;
  max-width: 320px;
  height: 48px;
  margin: var(--space-2) auto;
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--color-surface-alt) 50%, transparent);
}

/* ── Listening — waveform area + mode tabs ── */
.listening-mode-tab {
  transition: color 0.25s var(--ease-default), border-color 0.25s var(--ease-default);
}

.listening-mode-tab.active {
  border-bottom-color: var(--color-accent);
  color: var(--color-accent);
}

.dictation-input {
  transition: border-color 0.3s var(--ease-default);
}

.dictation-input:focus {
  border-bottom-color: var(--color-accent);
}

/* ── Grammar cards — glass + stagger ── */
.grammar-mastery-summary {
  animation: driftUp 0.4s var(--ease-upward) backwards;
}

/* ── Grammar level tabs — animated underline ── */
.grammar-level-tabs [role="tab"] {
  transition: color 0.25s var(--ease-default), border-color 0.25s var(--ease-default);
}

/* ── Teacher dashboard — class cards ── */
@supports (backdrop-filter: blur(1px)) {
  .classroom-card {
    backdrop-filter: blur(12px) saturate(1.1);
    -webkit-backdrop-filter: blur(12px) saturate(1.1);
    background: var(--glass-bg, color-mix(in srgb, var(--color-surface) 78%, transparent));
    border: var(--glass-border, 1px solid color-mix(in srgb, var(--color-divider) 40%, transparent));
    transition: transform var(--duration-fast) var(--ease-default),
                box-shadow var(--duration-fast) var(--ease-default);
  }

  .classroom-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
  }
}

/* ── Empty states — centered with illustration float ── */
.empty-state {
  text-align: center;
  padding: var(--space-6) var(--space-4);
  animation: driftUp 0.5s var(--ease-upward) backwards;
}

.empty-state-illustration {
  transition: transform var(--duration-float, 3s) var(--ease-default);
}

@media (hover: hover) {
  .empty-state-illustration:hover {
    transform: translateY(-4px);
  }
}

/* ── Session complete — enhanced completion screen ── */
.complete-illustration {
  animation: gentleBloom 0.8s var(--ease-upward) backwards;
}

#complete-content h2 {
  animation: driftUp 0.5s var(--ease-upward) 0.2s backwards;
}

.complete-score {
  animation: driftUp 0.5s var(--ease-upward) 0.3s backwards;
}

.complete-pct {
  animation: driftUp 0.5s var(--ease-upward) 0.4s backwards;
}

/* ── Onboarding wizard — enhanced transitions ── */
.onboarding-wizard-card {
  animation: authCardEnter 0.5s var(--ease-upward) backwards;
}

.onboarding-intro-slide {
  animation: driftUp 0.5s var(--ease-upward) backwards;
}

.onboarding-opt {
  transition: transform var(--duration-fast) var(--ease-default),
              border-color var(--duration-fast) var(--ease-default),
              box-shadow var(--duration-fast) var(--ease-default);
}

@media (hover: hover) {
  .onboarding-opt:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
  }
}

/* ── Settings rows — smooth expand ── */
.settings-inline-form {
  animation: driftUp 0.3s var(--ease-upward) backwards;
}

/* ── Next session preview — glass card ── */
@supports (backdrop-filter: blur(1px)) {
  .next-session-preview {
    backdrop-filter: blur(12px) saturate(1.1);
    -webkit-backdrop-filter: blur(12px) saturate(1.1);
    background: var(--glass-bg, color-mix(in srgb, var(--color-surface) 78%, transparent));
    border: var(--glass-border, 1px solid color-mix(in srgb, var(--color-divider) 40%, transparent));
  }
}

/* ── 2026-03 Aesthetic elevation: card hover depth, section texture, scroll progress ── */

/* Card image zoom on hover — images inside cards gently scale within overflow:hidden boundary */
.passage-card, .media-card, .grammar-card, .classroom-card, .class-card {
  overflow: hidden;
}

.passage-card img, .media-card img, .grammar-card img,
.classroom-card img, .class-card img {
  transition: transform 0.4s var(--ease-upward);
}

@media (hover: hover) {
  .passage-card:hover img, .media-card:hover img, .grammar-card:hover img,
  .classroom-card:hover img, .class-card:hover img {
    transform: scale(1.03);
  }

  /* Warm background tint on card hover (subtle accent bleed) */
  .reading-list .passage-card:hover,
  .media-grid .media-card:hover,
  .grammar-list .grammar-card:hover {
    background: color-mix(in srgb, var(--color-accent) 3%, var(--glass-bg, var(--color-surface)));
  }
}

/* Section-level texture variation — per-section grain overlays for physical depth.
   Uses same SVG noise pattern as body but at varying intensities per section. */
.hero::after,
#dashboard::after,
#complete-content::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.08'/%3E%3C/svg%3E");
  background-blend-mode: soft-light;
  z-index: 0;
}

/* Hero gets heavier grain — "different paper weight" */
.hero { position: relative; }
.hero::after { opacity: 0.7; }

/* Dashboard and complete screens get lighter grain */
#dashboard { position: relative; }
#dashboard::after { opacity: 0.4; }
#complete-content { position: relative; }
#complete-content::after { opacity: 0.5; }

/* Ensure content sits above grain overlay */
.hero > *, #dashboard > *, #complete-content > * {
  position: relative;
  z-index: 1;
}

/* ── Scroll progress bar (marketing pages inject .scroll-progress-bar) ── */
.scroll-progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  background: var(--color-accent);
  width: 0%;
  z-index: 9999;
  transition: none;
  will-change: width;
  pointer-events: none;
}

/* ── Hanzi stroke animation container ── */
.hanzi-stroke-target {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: var(--space-3) auto;
}

.hanzi-stroke-target svg {
  display: block;
}

/* ── Drill-to-drill transitions — cinematic flow between questions ── */
.drill-exit {
  animation: drillExit 0.15s var(--ease-exit) forwards;
  pointer-events: none;
}

.drill-enter {
  animation: drillEnter 0.2s var(--ease-upward) forwards;
}

/* ── Session entry cinematic — brief curtain-rise when session starts ── */
@keyframes sessionCurtainRise {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}

.session-entering #drill-area {
  animation: sessionCurtainRise 0.6s var(--ease-upward) 0.1s backwards;
}

.session-entering #progress-bar {
  animation: sessionCurtainRise 0.5s var(--ease-upward) backwards;
}

.session-entering .session-header {
  animation: sessionCurtainRise 0.4s var(--ease-upward) backwards;
}

.session-entering #input-area {
  animation: sessionCurtainRise 0.55s var(--ease-upward) 0.15s backwards;
}

/* ── Scroll-scrubbed animations — elements transform proportionally to scroll ── */

/* Heading scale: grows from 95% to 100% as section scrolls in */
[data-scroll-section] h2,
[data-scroll-section] h3 {
  transform: scale(calc(0.95 + var(--scroll-progress, 0) * 0.05));
  opacity: calc(0.6 + var(--scroll-progress, 0) * 0.4);
  transition: none; /* driven by scroll, not time */
}

/* Image parallax depth — images move at 80% of scroll speed */
[data-scroll-section] .parallax-img {
  transform: translateY(calc(var(--scroll-progress, 0) * -20px));
  transition: none;
}

/* Accent line reveal — dividers expand from center with scroll */
[data-scroll-section] .scroll-reveal-line {
  width: calc(var(--scroll-progress, 0) * 100%);
  max-width: 100%;
  transition: none;
}

/* Stat counter opacity — numbers become fully visible as section enters */
[data-scroll-section] .stat .metric-value,
[data-scroll-section] .stat .stat-value {
  opacity: calc(0.3 + var(--scroll-progress, 0) * 0.7);
  transition: none;
}

/* Panel depth shift — panels gain shadow as they scroll into view */
[data-scroll-section] .panel {
  box-shadow: 0 calc(var(--scroll-progress, 0) * 8px) calc(var(--scroll-progress, 0) * 24px) var(--color-shadow);
  transition: none;
}

/* Respect reduced motion for all 2026 additions */
@media (prefers-reduced-motion: reduce) {
  html, body { transition: none !important; }
  .bar-seg { transition: none !important; }
  .bar-seg.bar-animate-in { animation: none !important; }
  .panel.panel-stagger-enter { animation: none !important; opacity: 1 !important; }
  .heatmap-cell { transition: none !important; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none !important; }
  .ptr-indicator { transition: none !important; animation: none !important; }
  .reading-passage, .grammar-mastery-summary, .empty-state,
  .complete-illustration, #complete-content h2, .complete-score, .complete-pct,
  .onboarding-wizard-card, .onboarding-intro-slide, .settings-inline-form { animation: none !important; }
  .passage-card img, .media-card img, .grammar-card img,
  .classroom-card img, .class-card img { transition: none !important; }
  .drill-exit, .drill-enter { animation: none !important; }
  .session-entering #drill-area, .session-entering #progress-bar,
  .session-entering .session-header, .session-entering #input-area { animation: none !important; }
  /* Scroll-scrubbed: flatten to static state */
  [data-scroll-section] h2, [data-scroll-section] h3 { transform: none !important; opacity: 1 !important; }
  [data-scroll-section] .parallax-img { transform: none !important; }
  [data-scroll-section] .stat .metric-value, [data-scroll-section] .stat .stat-value { opacity: 1 !important; }
  [data-scroll-section] .panel { box-shadow: var(--shadow-md) !important; }
}
