/* "new version available" bar (service-worker update prompt) */
.sb-update-banner {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%);
  z-index: 2147483000; display: flex; align-items: center; gap: 12px;
  max-width: calc(100vw - 24px); padding: 10px 12px 10px 16px;
  background: #20252d; color: #e9e7e0; border: 1px solid #2e343e;
  border-radius: 12px; box-shadow: 0 8px 30px rgba(0,0,0,0.45);
  font: 500 13.5px/1.3 system-ui, -apple-system, sans-serif; animation: sbUpIn .25s ease;
}
@keyframes sbUpIn { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translate(-50%, 0); } }
.sb-update-btn {
  flex: 0 0 auto; border: none; cursor: pointer; font: 700 13px/1 system-ui, sans-serif;
  color: #14171c; background: #f5d76e; border-radius: 8px; padding: 8px 14px;
}
.sb-update-btn:disabled { opacity: .7; cursor: default; }
.sb-update-dismiss {
  flex: 0 0 auto; border: none; background: transparent; color: #9aa0aa;
  cursor: pointer; font-size: 18px; line-height: 1; padding: 2px 4px;
}
.sb-update-dismiss:hover { color: #e9e7e0; }

:root {
  --bg: #14171c;
  --bg-raised: #1d2128;
  --bg-card: #20252d;
  --line: #2e343e;
  --text: #e9e7e0;
  --text-dim: #9aa1ab;
  --accent: #e8b04b;
  --accent-soft: rgba(232, 176, 75, 0.14);
  --on-accent: #221a08;              /* text/icon color that sits ON an accent fill (dark on gold) */
  --chalk: #ece9df;
  --radius: 14px;
  --font-ui: "Sora", sans-serif;
  --font-display: "Fraunces", serif;
  /* elevation, motion & focus — one source of truth for a consistent, elegant feel */
  --line-soft: rgba(255, 255, 255, 0.06);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25);
  --shadow-md: 0 10px 28px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.5);
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --t: 0.18s var(--ease);
  --ring: 0 0 0 2px var(--bg), 0 0 0 4px rgba(232, 176, 75, 0.55);
  /* these were referenced but never defined — alias to existing tokens so both
     themes resolve them (and so the light theme below can override them) */
  --muted: var(--text-dim);
  --danger: #f08a8a;
  --panel: var(--bg-card);
  --panel-2: var(--bg-raised);
}

/* ===== APP-WIDE LIGHT THEME (opt-in via the toggle; dark stays the default).
   The UI is ~390 var()-driven, so redefining the core tokens re-themes most of
   the app. data-theme="light" is set on <html> early (boot.js) to avoid a flash.
   The board canvas + the test player keep their own independent themes. ===== */
html[data-theme="light"] {
  --bg: #f3f5f8;
  --bg-raised: #ffffff;
  --bg-card: #ffffff;
  --line: #e3e7ee;
  --line-soft: rgba(20, 30, 50, 0.08);
  --text: #1b2230;
  --text-dim: #5b6675;
  --muted: #6b7482;
  --accent: #7c3aed;                 /* Render-style violet for light mode */
  --accent-strong: #6d28d9;          /* darker violet for hovers/gradients */
  --on-accent: #fff;                 /* violet is dark → white text on accent fills */
  --accent-soft: rgba(124, 58, 237, 0.12);
  --danger: #c0392b;
  --panel: #ffffff;
  --panel-2: #eef1f5;
  --shadow-sm: 0 1px 2px rgba(20, 30, 50, 0.08);
  --shadow-md: 0 10px 28px rgba(20, 30, 50, 0.10);
  --shadow-lg: 0 24px 60px rgba(20, 30, 50, 0.14);
  --ring: 0 0 0 2px var(--bg), 0 0 0 4px rgba(124, 58, 237, 0.5);
}
/* ===== Light-mode VIOLET accent: repaint the gold-hardcoded components (the token
   swap above already handles everything var(--accent)-driven). ===== */
html[data-theme="light"] .btn-primary {
  background: linear-gradient(180deg, var(--accent), var(--accent-strong));
  color: #fff;
  box-shadow: 0 8px 24px rgba(124, 58, 237, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
html[data-theme="light"] .btn-primary:hover { box-shadow: 0 12px 30px rgba(124, 58, 237, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.3); }
html[data-theme="light"] .btn-primary:active { box-shadow: 0 4px 14px rgba(124, 58, 237, 0.32); }
/* gold rgba tints used as chip/badge/tab backgrounds → violet tints */
html[data-theme="light"] .qb-folder-n,
html[data-theme="light"] .sh-tab.active .sh-tab-n,
html[data-theme="light"] .library-count { background: rgba(124, 58, 237, 0.12); }
html[data-theme="light"] .library-count { color: #fff; }
html[data-theme="light"] .class-code,
html[data-theme="light"] .class-manage,
html[data-theme="light"] .lib-tag-concepts,
html[data-theme="light"] .lib-class-chip { border-color: rgba(124, 58, 237, 0.32); }
html[data-theme="light"] .class-code { background: rgba(124, 58, 237, 0.1); }
html[data-theme="light"] .class-code:hover,
html[data-theme="light"] .class-manage:hover { background: rgba(124, 58, 237, 0.18); }
html[data-theme="light"] .account-btn-primary { background: linear-gradient(180deg, var(--accent), var(--accent-strong)) !important; border-color: var(--accent) !important; color: #fff !important; }
/* active auth tab: white text on the violet fill (the dark text was tuned for gold) */
html[data-theme="light"] .auth-tab.active { color: #fff; }
html[data-theme="light"] .account-btn.account-btn-primary:hover { background: var(--accent-strong) !important; }
html[data-theme="light"] .lib-class-chip { background: rgba(124, 58, 237, 0.1); }
/* the "Generate" tool card + upgrade button carried a gold gradient/border */
html[data-theme="light"] .qb-tool-primary { background: linear-gradient(180deg, rgba(124, 58, 237, 0.14), rgba(124, 58, 237, 0.05)); border-color: rgba(124, 58, 237, 0.4); }
html[data-theme="light"] .account-btn.account-upgrade { border-color: rgba(124, 58, 237, 0.5); }
html[data-theme="light"] .sh-tab.active .sh-tab-n { background: rgba(124, 58, 237, 0.22); }
/* a couple of hard-coded dark overlays that would vanish/misread on light */
html[data-theme="light"] .account-btn,
html[data-theme="light"] .sb-tool,
html[data-theme="light"] .qb-tool { background: #f4f6f9; }
html[data-theme="light"] .board-frame,
html[data-theme="light"] body { background: var(--bg); }

/* ---- Light-theme component refinements ----------------------------------------
   The app chrome is dark-tuned: black scrims + dark-tinted rgba badge fills. On a
   white surface those turn into a muddy gray wash and washed-out pills. These
   overrides give the light theme what a modern light UI needs — a clean page,
   white cards with real (soft) elevation, and crisp, legible tinted pills. */

/* the dark theme darkens the library panel with an 18% black scrim; full-width in
   teacher view that greys the ENTIRE page. Sit it on the page colour instead and
   let the elevated cards below provide the contrast. */
html[data-theme="light"] .library-panel { background: transparent; }

/* white cards need a hairline + soft shadow to lift off the page (a transparent
   border on white is invisible, so they read as one flat sheet). */
html[data-theme="light"] .user-stats .stat,
html[data-theme="light"] .library-list li {
  border-color: #e8ecf2;
  box-shadow: 0 1px 2px rgba(20, 30, 50, 0.04), 0 3px 12px rgba(20, 30, 50, 0.05);
}
html[data-theme="light"] .library-list li:hover {
  border-color: #d5dde8;
  background: #fff;
  box-shadow: 0 2px 6px rgba(20, 30, 50, 0.07), 0 12px 28px rgba(20, 30, 50, 0.10);
}

/* tinted status pills: the dark-theme rgba fills (green/amber over black) go muddy
   on white — repaint them as clean, high-legibility light chips. */
html[data-theme="light"] .lib-assign.on,
html[data-theme="light"] .lib-mastery,
html[data-theme="light"] .lib-classavg {
  color: #2c7a4b; background: #e9f7ef; border-color: #c3e4cf;
}
html[data-theme="light"] .lib-classavg.mid {
  color: #9a6b12; background: #fbf3e0; border-color: #ecdcb4;
}
html[data-theme="light"] .lib-mastery.low,
html[data-theme="light"] .lib-classavg.low {
  color: #b0562a; background: #fcf0e7; border-color: #f0d4bf;
}
html[data-theme="light"] .lib-class-chip {
  color: var(--accent); background: rgba(124, 58, 237, 0.1); border-color: rgba(124, 58, 237, 0.3);
}

/* the primary CTA reads as a confident gold fill on white (the pale-yellow gradient
   from the dark theme all but disappears against a white bar). */
html[data-theme="light"] .account-btn-primary {
  background: var(--accent) !important;
  border-color: var(--accent) !important;
  color: #fff !important;
  box-shadow: 0 1px 2px rgba(120, 80, 10, 0.18);
}
html[data-theme="light"] .account-btn-primary:hover { background: var(--accent-strong) !important; }

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

[hidden] { display: none !important; }

html {
  height: 100%;
  overflow-x: hidden;              /* never let a stray wide element make the page drag side-to-side on mobile */
  font-size: 16px;                 /* deterministic base — the UI never rides on the (drifting) UA default */
  /* Stop mobile/embedded browsers from auto-resizing text per page ("font boosting"), which
     made the app font look like it "kept changing" between pages and logins. Pin it to 100%. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  height: 100%;
  overflow-x: hidden;              /* pair with html: kill horizontal drift/rubber-banding on phones */
  overscroll-behavior-x: none;     /* no accidental left/right swipe navigation over the board */
  font-family: var(--font-ui);
  font-size: 1rem;                 /* pin to the fixed base above, not the adjustable default */
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  letter-spacing: -0.002em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* keyboard focus: one clear, accessible ring everywhere (mouse clicks stay clean) */
:focus-visible { outline: none; box-shadow: var(--ring); border-radius: 6px; }
button:focus-visible, a:focus-visible, .btn:focus-visible { outline: none; box-shadow: var(--ring); }

/* refined display headings — gentle optical tightening at large sizes */
h1, h2, h3, .lesson-title, #loading-text { letter-spacing: -0.015em; }

/* respect a user's reduced-motion preference */
@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; }
}

/* small refinements: branded text selection + quiet, modern scrollbars */
::selection { background: rgba(232, 176, 75, 0.26); color: var(--text); }
* { scrollbar-width: thin; scrollbar-color: #343b46 transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #2e343e; border-radius: 8px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: #3a414c; }

.screen { min-height: 100vh; min-height: 100dvh; }

button { font-family: inherit; cursor: pointer; }

/* ============ SETUP SCREEN ============ */

#setup-screen {
  display: flex;
  align-items: stretch;
  min-height: 100vh;
  min-height: 100dvh;
  background:
    radial-gradient(1200px 600px at 70% -15%, rgba(232, 176, 75, 0.06), transparent 60%),
    radial-gradient(1000px 700px at -10% 115%, rgba(110, 140, 190, 0.05), transparent 60%),
    var(--bg);
}

.setup-main {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 56px 48px;
  overflow-y: auto;
}

.setup-card {
  width: 100%;
  max-width: 560px;
}

.brand { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 30px; }

.brand-mark {
  width: 52px; height: 52px;
  flex-shrink: 0;
  display: grid; place-items: center;
  background: linear-gradient(150deg, #2c3f26, #1e2c1a);
  border: 1px solid #3a4d35;
  border-radius: 14px;
  font-family: "Caveat", cursive;
  font-size: 28px; font-weight: 700;
  color: var(--chalk);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 6px 16px rgba(0, 0, 0, 0.3);
}

.brand h1 {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.1;
}

.brand-text { padding-top: 2px; }
.tagline { color: var(--text-dim); font-size: 14.5px; line-height: 1.55; margin-top: 6px; }

.drop-zone {
  border: 1.5px dashed #3a414d;
  border-radius: 16px;
  padding: 30px 20px;
  text-align: center;
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.012);
  transition: border-color 0.2s, background 0.2s, color 0.2s, transform 0.15s;
}

.drop-zone:hover, .drop-zone.dragging {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--text);
  cursor: pointer;
}

.drop-icon {
  width: 50px; height: 50px;
  margin: 0 auto 12px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  color: var(--accent);
  transition: transform 0.15s;
}
.drop-zone:hover .drop-icon { transform: translateY(-2px); }
.drop-zone p { font-size: 14px; }
.drop-zone strong { color: var(--text); font-weight: 600; }
.drop-zone .hint { font-size: 12px; opacity: 0.65; display: block; margin-top: 6px; letter-spacing: 0.04em; }

.divider {
  display: flex; align-items: center; gap: 14px;
  margin: 22px 0;
  color: var(--text-dim); font-size: 12px;
  text-transform: uppercase; letter-spacing: 0.12em;
}
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }

textarea {
  width: 100%;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.6;
  padding: 14px 16px;
  resize: vertical;
  outline: none;
  transition: border-color var(--t), box-shadow var(--t);
}
textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
textarea::placeholder { color: #5e6671; }

/* consistent, elegant focus for every text/number input + the short-answer box */
.setting input[type=number]:focus, #set-providers:focus, .quiz-short-input:focus,
input[type=text]:focus, input[type=password]:focus, input[type=email]:focus, input[type=number]:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}

.file-status {
  margin-top: 14px;
  padding: 10px 14px;
  background: var(--accent-soft);
  border: 1px solid rgba(232, 176, 75, 0.3);
  border-radius: 10px;
  font-size: 13px;
  color: var(--accent);
  display: flex; align-items: center; gap: 8px;
}

/* soft "this is a lot of material" guardrail + the per-section stepper */
.big-hint, .section-stepper {
  margin-top: 10px; padding: 9px 12px;
  background: var(--accent-soft);
  border: 1px solid rgba(232, 176, 75, 0.3);
  border-radius: 10px;
  font-size: 13px; color: var(--accent);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.big-hint .btn-link, .section-stepper .btn-link {
  background: none; border: none; padding: 0;
  color: var(--accent); font: inherit; font-weight: 600;
  text-decoration: underline; cursor: pointer;
}
.big-hint-x {
  margin-left: auto; background: none; border: none;
  color: var(--accent); font-size: 18px; line-height: 1; cursor: pointer; opacity: 0.7;
}
.big-hint-x:hover { opacity: 1; }
.section-stepper #section-label { font-weight: 600; }
.section-stepper .btn-mini {
  background: var(--bg); border: 1px solid var(--line); color: var(--accent);
  border-radius: 7px; width: 28px; height: 26px; font-size: 13px; cursor: pointer;
}
.section-stepper .btn-mini:disabled { opacity: 0.35; cursor: default; }
.section-stepper #section-restore { margin-left: auto; }

.pdf-ocr { margin-top: 12px; padding: 12px 14px; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 10px; }
.pdf-pagemap { font-size: 12.5px; color: var(--accent); margin: 6px 0 8px; display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; }
.pdf-rawpages { color: var(--muted); display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.pdf-ocr-note { font-size: 13px; color: var(--text-dim); margin: 0 0 10px; line-height: 1.45; }
/* one-tap unit/chapter picker (auto-detected from an uploaded book) */
.pdf-units { margin: 0 0 12px; padding: 0 0 12px; border-bottom: 1px solid var(--line); }
.pdf-units-note { font-size: 13px; color: var(--text); margin: 0 0 9px; font-weight: 600; }
.pdf-units-list { display: flex; flex-direction: column; gap: 6px; max-height: 240px; overflow-y: auto; }
.pdf-unit-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; text-align: left;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px; padding: 9px 12px;
  color: var(--text); font-family: inherit; font-size: 13.5px; cursor: pointer; transition: border-color 0.15s, background 0.15s;
}
.pdf-unit-btn:hover { border-color: var(--accent); background: var(--bg); }
/* a subunit (3.2 under Unit 3) is indented and quieter than the unit that holds it */
/* width:100% + margin-left overflows the list and clips the char count on the right */
.pdf-unit-btn.is-sub { margin-left: 18px; width: calc(100% - 18px); padding: 7px 12px; font-size: 12.5px; background: transparent; }
.pdf-unit-btn.is-sub .pdf-unit-title { font-weight: 500; color: var(--text-dim); }
.pdf-unit-btn.is-sub:hover .pdf-unit-title { color: var(--text); }
.pdf-unit-btn.is-sub .pdf-unit-num { color: var(--text-dim); }
/* a unit whose start couldn't be found: it has no text to load, and pretending
   otherwise is what handed the generator the whole book under a unit's name */
.pdf-unit-btn.is-unusable { opacity: 0.5; cursor: not-allowed; border-style: dashed; }
.pdf-unit-btn.is-unusable:hover { border-color: var(--line); background: var(--bg-card); }
.pdf-unit-btn.is-unusable .pdf-unit-pages { font-style: italic; }

.pdf-unit-exercise { border-style: dashed; }
.pdf-unit-exercise .pdf-unit-title { font-weight: 500; color: var(--text-dim); }
.pdf-unit-tag { display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; color: var(--accent); border: 1px solid var(--accent); border-radius: 5px; padding: 0 5px; margin-right: 2px; }
.pdf-unit-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.pdf-unit-pages { flex: none; font-size: 11.5px; color: var(--text-dim); }
.pdf-ocr-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.pdf-ocr-pages { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-dim); }
.pdf-ocr-pages input { width: 64px; background: var(--bg); border: 1px solid var(--line); color: var(--text); border-radius: 8px; font: inherit; font-size: 14px; padding: 7px 9px; }
.pdf-ocr-row .btn { padding: 9px 16px; font-size: 13px; }
.pdf-ocr-progress { display: flex; align-items: center; gap: 12px; margin-top: 10px; font-size: 13px; color: var(--accent); }
.pdf-images { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; margin-top: 10px; max-height: 320px; overflow-y: auto; }
.pdf-img-cell {
  position: relative; padding: 0; border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
  background: var(--bg); cursor: pointer; aspect-ratio: 3 / 4; transition: border-color 0.15s, transform 0.1s;
}
.pdf-img-cell:hover { border-color: var(--accent); }
.pdf-img-cell img { width: 100%; height: 100%; object-fit: cover; display: block; background: #fff; }
.pdf-img-pg { position: absolute; left: 4px; bottom: 4px; font-size: 11px; padding: 1px 6px; border-radius: 6px; background: rgba(0,0,0,0.62); color: #fff; }
.pdf-img-cell.added { border-color: var(--accent); }
.pdf-img-cell.added::after { content: "✓ added"; position: absolute; right: 4px; top: 4px; font-size: 11px; padding: 1px 6px; border-radius: 6px; background: var(--accent); color: #102a17; font-weight: 700; }
.pdf-ocr-progress .btn { padding: 7px 14px; font-size: 12.5px; }

.setup-actions { display: flex; gap: 12px; margin-top: 22px; }

.btn {
  border: none;
  border-radius: 13px;
  padding: 15px 24px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.005em;
  transition: transform 0.12s var(--ease), box-shadow var(--t), background var(--t), border-color var(--t);
}

.btn-primary {
  flex: 1;
  background: linear-gradient(180deg, #eeb955, var(--accent));
  color: var(--on-accent);
  box-shadow: 0 8px 24px rgba(232, 176, 75, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 12px 30px rgba(232, 176, 75, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.3); }
.btn-primary:active { transform: translateY(0) scale(0.985); box-shadow: 0 4px 14px rgba(232, 176, 75, 0.32); }
.btn-primary:disabled { opacity: 0.45; transform: none; box-shadow: none; cursor: default; }

.btn-ghost {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--line);
}
.btn-ghost:hover { color: var(--text); border-color: #4a525e; background: rgba(255, 255, 255, 0.03); }
.btn-ghost:active { transform: scale(0.985); }

.setup-error { margin-top: 16px; color: #f08a8a; font-size: 13px; }
.ai-status {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: 12px; color: #6b7682; text-align: center;
}

/* loading overlay */
.loading-overlay {
  position: fixed; inset: 0;
  background: rgba(13, 15, 19, 0.92);
  backdrop-filter: blur(6px);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 18px;
  z-index: 50;
}

.loader-chalk {
  width: 56px; height: 56px;
  border-radius: 50%;
  border: 3px solid rgba(236, 233, 223, 0.15);
  border-top-color: var(--accent);
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

#loading-text { font-family: var(--font-display); font-size: 20px; }
.loading-sub { color: var(--text-dim); font-size: 13px; }
.loading-steps {
  list-style: none; margin: 16px 0 0; padding: 0; max-width: 340px;
  text-align: left; counter-reset: ls;
}
.loading-steps li {
  counter-increment: ls; font-size: 13px; color: var(--text-dim);
  padding: 3px 0 3px 24px; position: relative;
  animation: ls-in .35s ease both;
}
.loading-steps li::before {
  content: counter(ls); position: absolute; left: 0; top: 3px;
  width: 17px; height: 17px; border-radius: 50%;
  background: rgba(230, 196, 106, 0.18); color: var(--accent);
  font-size: 10px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
@keyframes ls-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* ============ CLASSROOM ============ */

/* 100dvh (dynamic viewport) so the layout doesn't JUMP each time iOS Safari's top/bottom
   bars slide in or out on scroll — that jump was the "bars transition is disturbing". */
#classroom-screen { display: flex; flex-direction: column; height: 100vh; height: 100dvh; }

/* Gentle fade when a screen appears, so moving between screens (home ⇄ board) is a soft
   transition instead of an abrupt cut. It replays whenever a screen is shown (display goes
   none → flex). The prefers-reduced-motion block neutralizes it for those who opt out. */
@keyframes screenIn { from { opacity: 0; } to { opacity: 1; } }
#setup-screen, #classroom-screen { animation: screenIn 0.34s ease both; }

.classroom-header {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-raised);
}

.icon-btn {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text-dim);
  transition: color 0.2s, border-color 0.2s;
}
.icon-btn:hover { color: var(--text); border-color: #4a525e; }

.lesson-meta { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.lesson-meta h2 {
  font-family: var(--font-display);
  font-size: 19px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.subject-pill {
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 99px;
  padding: 4px 11px;
  white-space: nowrap;
}
/* the lesson's specific sub-topic (Concept) — quieter than the subject pill */
.concept-pill {
  font-size: 11px; font-weight: 600;
  color: var(--text-dim);
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: 99px; padding: 3px 10px; white-space: nowrap;
}
.an-concept { color: var(--accent); font-weight: 600; }

.header-spacer { flex: 1; }

.classroom-body {
  flex: 1;
  display: flex;
  min-height: 0;
}

/* step sidebar */
.step-panel {
  width: 210px;
  flex-shrink: 0;
  background: var(--bg-raised);
  padding: 20px 14px;
  overflow-y: auto;
  overflow-x: hidden;              /* vertical scroller — no elastic sideways drag */
  overscroll-behavior-x: none;
}

/* draggable divider between the lesson plan and the canvas */
.board-resizer {
  flex: 0 0 9px;
  position: relative;
  cursor: col-resize;
  background: var(--bg-raised);
  touch-action: none; /* let pointer-drag resize instead of scrolling on touch */
}
.board-resizer::before {
  content: "";
  position: absolute;
  inset: 0 2px;
  background: var(--line);
  transition: background 0.15s;
}
.board-resizer::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 4px; height: 40px;
  transform: translate(-50%, -50%);
  border-radius: 2px;
  background: rgba(236, 233, 223, 0.34);
}
.board-resizer:hover::before,
.board-resizer.dragging::before { background: var(--accent); }
.board-resizer.dragging::after { background: rgba(34, 26, 8, 0.5); }

/* draggable divider between the setup area and the library/account sidebar */
.library-resizer {
  flex: 0 0 9px;
  position: relative;
  cursor: col-resize;
  background: var(--bg-raised);
  touch-action: none; /* let pointer-drag resize instead of scrolling on touch */
}
.library-resizer::before {
  content: "";
  position: absolute;
  inset: 0 2px;
  background: var(--line);
  transition: background 0.15s;
}
.library-resizer::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 4px; height: 40px;
  transform: translate(-50%, -50%);
  border-radius: 2px;
  background: rgba(236, 233, 223, 0.34);
}
.library-resizer:hover::before,
.library-resizer.dragging::before { background: var(--accent); }
.library-resizer.dragging::after { background: rgba(34, 26, 8, 0.5); }

.step-panel h3 {
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--text-dim);
  padding: 0 10px 12px;
}

.step-list { list-style: none; display: flex; flex-direction: column; gap: 2px; }

.step-list li {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px;
  border-radius: 10px;
  font-size: 13px;
  color: var(--text-dim);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.step-list li:hover { background: rgba(255, 255, 255, 0.04); color: var(--text); }

.step-list li .num {
  width: 22px; height: 22px;
  flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  font-size: 11px;
}

.step-list li.active { background: var(--accent-soft); color: var(--text); }
.step-list li.active .num { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 700; }
.step-list li.done .num { background: #2c3527; border-color: #3a4d35; color: #9fbe8f; }

/* ── a plan made of practice questions ───────────────────────────────────────
   A chained set is one long list in which the row that ASKS a question looked
   identical to the rows that work it out — finding "where does question 4
   start?" meant reading every row. So the question row carries a Q-badge, a
   rule above it and full-strength text, and its working is threaded beneath it,
   indented and dimmed. Ordinary lessons carry no qOpen/qSub and are untouched. */
.step-list li.q-open {
  align-items: flex-start;
  margin-top: 12px;
  padding-top: 13px;
  border-top: 1px solid var(--line);
  color: var(--text);
  font-weight: 600;
  letter-spacing: -0.005em;
}
.step-list li.q-open:first-child { margin-top: 0; padding-top: 9px; border-top: 0; }
.step-list li.q-open .num {
  width: auto; min-width: 26px; height: 20px;
  margin-top: 1px;
  padding: 0 7px;
  border-radius: 999px;
  border-color: transparent;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 10px; font-weight: 700; letter-spacing: 0.05em;
}
.step-list li.q-open.done .num { background: #2c3527; border-color: transparent; color: #9fbe8f; }
.step-list li.q-open.active .num { background: var(--accent); color: var(--on-accent); }

/* the working: a thread under its question, so it never reads as a new count */
.step-list li.q-sub { padding-left: 22px; font-size: 12.5px; }
.step-list li.q-sub .num {
  width: 6px; height: 6px; min-width: 0;
  margin-left: 9px;
  border: 0; border-radius: 50%;
  background: var(--line);
  font-size: 0;
}
.step-list li.q-sub.done .num { background: #3a4d35; }
.step-list li.q-sub.active .num { background: var(--accent); }

/* the answer closes the thread */
.step-list li.q-answer { color: var(--text); }
.step-list li.q-answer .num {
  width: 16px; height: 16px; min-width: 0;
  margin-left: 4px;
  border: 0; border-radius: 0;
  background: none;
  color: var(--accent);
  font-size: 11px; font-weight: 700;
}
.step-list li.q-answer.done .num { background: none; color: #9fbe8f; }
.step-list li.q-answer.active .num { background: none; color: var(--accent); }

/* board */
.board-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px 16px 14px;
  min-width: 0;
  overflow-y: auto;
}

.board-frame {
  position: relative;
  /* fill the available width, but never get so tall the controls fall off-screen
     (canvas aspect ratio is 1280:800 = 1.6) */
  width: min(100%, calc((100vh - 188px) * 1.6)); width: min(100%, calc((100dvh - 188px) * 1.6));
  border-radius: 10px;
  padding: 14px;
  background: linear-gradient(135deg, #6e4f2e, #8a6438 38%, #5e421f 80%);
  box-shadow:
    inset 0 2px 3px rgba(255, 230, 180, 0.25),
    inset 0 -2px 4px rgba(0, 0, 0, 0.5),
    0 24px 60px rgba(0, 0, 0, 0.5);
  /* smooth cross-fade when switching board theme (chalkboard ⇄ whiteboard), BOTH ways —
     was an instant colour flip. */
  transition: background 0.35s ease, box-shadow 0.35s ease;
}

#board {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
  box-shadow: inset 0 0 60px rgba(0, 0, 0, 0.55);
  transition: box-shadow 0.35s ease, opacity 0.28s ease;
}

/* whiteboard theme: a light aluminium frame, a gentle (not dark) inner shadow,
   and a light caption fade with dark caption text — so the board reads as white,
   not a dimmed chalkboard. Toggled by body.board-whiteboard from the theme select. */
.board-whiteboard .board-frame {
  background: linear-gradient(135deg, #c7cacc, #e8eaec 38%, #b4b7ba 80%);
  box-shadow: inset 0 2px 3px rgba(255, 255, 255, 0.65), inset 0 -2px 4px rgba(0, 0, 0, 0.22), 0 24px 60px rgba(0, 0, 0, 0.4);
}
.board-whiteboard #board { box-shadow: inset 0 0 40px rgba(120, 130, 140, 0.12); }
.board-whiteboard .board-footer { background: linear-gradient(transparent, rgba(244, 245, 241, 0.94) 34%); }
.board-whiteboard .caption { color: #2a3540; text-shadow: 0 1px 2px rgba(255, 255, 255, 0.7); }
.board-whiteboard .source-cite { color: #5a6570; }

/* caption + source citation stack inside one footer, so the citation can never grow
   up into the caption (they used to be independently absolute-positioned and collided
   whenever the citation wrapped to two lines). The footer owns the dark fade. */
.board-footer {
  position: absolute;
  left: 14px; right: 14px; bottom: 14px; /* == frame padding: the strip ends at the chalkboard edge, not on the wood */
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-bottom: 10px; /* bottom breathing room whether or not the citation shows */
  background: linear-gradient(transparent, rgba(8, 14, 10, 0.9) 30%);
  border-radius: 0 0 4px 4px;
  pointer-events: none;
  transition: background 0.35s ease;   /* cross-fade the footer fade when the board theme changes */
}
.caption {
  padding: 14px 20px 0;
  color: rgba(240, 238, 230, 0.95);
  font-size: 14.5px;
  line-height: 1.5;
  text-align: center;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
  transition: color 0.3s ease;         /* caption colour eases between chalk (light) and whiteboard (dark) */
  /* A stable TWO-LINE strip on EVERY screen (portrait, landscape, desktop). Playback
     advances it sentence-by-sentence with the voice (runCaptionSync), so the narration
     never fills the screen or covers the chalk. min == 2 lines so it doesn't jump. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  min-height: calc(2 * 1.5em);
}
.caption:empty { opacity: 0; }
/* nothing to show → no dark fade strip either. A plain class (toggled from JS)
   instead of :has(:empty) — Safari fails to re-evaluate that combination when the
   caption later fills, leaving the footer permanently invisible. */
.board-footer.is-empty { opacity: 0; }

/* grounding citation shown under the caption when the lesson is source-grounded.
   Clamped to 2 lines — it's a provenance hint, not a reading passage; an unclamped
   long quote wrapped to 5+ lines and swallowed the bottom of the board. */
.source-cite {
  padding: 0 20px;
  font-size: 11.5px;
  line-height: 1.4;
  text-align: center;
  color: rgba(230, 196, 106, 0.9);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 🧭 exploration hold bar — floats bottom-centre, above the caption strip */
.explore-bar {
  position: absolute;
  left: 50%; bottom: 96px;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 12px;
  background: rgba(12, 20, 16, 0.94);
  border: 1px solid var(--accent);
  border-radius: 99px;
  padding: 8px 10px 8px 18px;
  font-size: 14px; color: var(--text);
  z-index: 40;
  white-space: nowrap;
  box-shadow: 0 8px 28px rgba(0,0,0,0.45);
}
.explore-count { color: var(--accent); font-weight: 700; min-width: 34px; text-align: center; }
.explore-bar .btn { padding: 8px 16px; font-size: 13.5px; border-radius: 99px; flex: none; }

/* 🎬 uploaded demonstration clip, floated on the board like a manipulative */
.video-panel {
  position: absolute;
  top: 14px; right: 14px;
  width: min(58%, 560px);
  background: rgba(12, 20, 16, 0.92);
  border: 1px solid rgba(232, 176, 75, 0.45);
  border-radius: 10px;
  padding: 8px;
  z-index: 5;
}
.video-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.video-head span { font-size: 12.5px; color: var(--accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.video-panel video { width: 100%; border-radius: 6px; background: #000; }

/* 📹 export preview dialog */
.export-dialog { max-width: 900px; width: min(94vw, 900px); }
.export-dialog video { width: 100%; max-height: 70vh; border-radius: 8px; background: #000; margin: 10px 0; }
.export-size { color: var(--muted); }

/* interactive manipulative: live graph + sliders, floated on the board */
.manip {
  position: absolute;
  top: 14px; right: 14px;
  width: min(46%, 320px);
  background: rgba(12, 20, 16, 0.86);
  border: 1px solid rgba(232, 176, 75, 0.45);
  border-radius: 12px;
  padding: 8px 10px 10px;
  backdrop-filter: blur(2px);
  resize: both; overflow: hidden;            /* drag the bottom-right corner to enlarge */
  min-width: 240px; min-height: 170px; max-width: 92vw; max-height: 88vh;
  z-index: 30;
}
.manip-head {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  margin: -8px -10px 6px; padding: 6px 8px;            /* full-width grab bar across the panel top */
  background: rgba(232, 176, 75, 0.14); border-bottom: 1px solid rgba(232, 176, 75, 0.3);
  border-radius: 12px 12px 0 0;
  cursor: move; touch-action: none; user-select: none;
}
/* a draggable-grip affordance so students know the bar moves the window */
.manip-title { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--accent); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.manip-title::before { content: "⠿"; font-size: 14px; line-height: 1; color: rgba(232, 176, 75, 0.7); flex: none; }
.manip { cursor: move; }                                /* the whole panel chrome signals draggable */
.manip canvas, .manip .manip-controls { cursor: default; }   /* …except where you interact */
.manip-close {
  flex: none; width: 20px; height: 20px; border: none; background: transparent;
  color: var(--text-dim); font-size: 17px; line-height: 1; cursor: pointer; border-radius: 5px;
}
.manip-close:hover { color: var(--text); background: rgba(255,255,255,0.08); }
.manip-canvas { width: 100%; height: auto; display: block; border-radius: 6px; }
.manip-controls { margin-top: 6px; display: flex; flex-direction: column; gap: 5px; }
.manip-row { display: flex; align-items: center; gap: 8px; }
.manip-row .manip-name { width: 16px; font-style: italic; color: var(--accent); font-size: 13px; text-align: center; flex: none; }
.manip-row input[type="range"] { flex: 1; min-width: 0; }
.manip-row .manip-val { width: 34px; text-align: right; font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums; flex: none; }
@media (max-width: 640px) {
  .manip { position: static; width: 100%; margin: 8px 0; }
}

/* teacher-reviewed trust badge + toggle, and grounding result chips in the library */
.lib-reviewed {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: rgba(70, 160, 110, 0.22); color: #6fd39b;
  border: 1px solid rgba(80, 170, 120, 0.4);
  font-size: 11px; font-weight: 700; flex: none;
}
.library-list .lib-review {
  flex: none; width: 22px; height: 22px; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-dim);
  border: 1px solid var(--line); cursor: pointer; font-size: 12px; font-weight: 700;
  transition: color .15s, border-color .15s, background .15s;
}
.library-list .lib-review:hover { color: var(--text); border-color: var(--accent); }
.library-list .lib-review.on {
  background: rgba(70, 160, 110, 0.22); color: #6fd39b; border-color: rgba(80, 170, 120, 0.45);
}
/* UNreviewed → a labelled amber pill so the "review to publish" action is obvious */
.library-list .lib-review.needs {
  width: auto; height: 24px; padding: 0 11px; border-radius: 999px; white-space: nowrap;
  background: var(--accent-soft); color: var(--accent); border-color: rgba(245,215,110,0.5);
  font-size: 11.5px; font-weight: 700;
}
.library-list .lib-review.needs:hover { background: rgba(245,215,110,0.16); border-color: var(--accent); color: var(--accent); }

/* controls */
.controls { width: min(100%, calc((100vh - 188px) * 1.6)); width: min(100%, calc((100dvh - 188px) * 1.6)); margin-top: 12px; position: relative; }

/* seekable: the bar is a slider — click/tap a segment to jump to that step.
   Padding (not height) grows the tap target; background-clip keeps the visible
   bar slim. Ticks mark step boundaries; a tooltip names the hovered step. */
.progress-track {
  position: relative;
  height: 6px;
  padding: 7px 0;
  background: var(--line);
  background-clip: content-box;
  border-radius: 99px;
  margin-bottom: 4px;
  cursor: pointer;
  touch-action: none;
}
.progress-track:hover .progress-fill,
.progress-track:focus-visible .progress-fill { filter: brightness(1.15); }
.progress-track:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.progress-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  border-radius: 99px;
  transition: width 0.4s ease;
  pointer-events: none;
}
#progress-ticks { pointer-events: none; }
.progress-tick {
  position: absolute;
  top: 7px;
  width: 2px;
  height: 6px;
  background: rgba(10, 10, 10, 0.55); /* dark notches read on both the dim track and the gold fill */
}
.progress-tip {
  position: absolute;
  bottom: 22px;
  transform: translateX(-50%);
  background: var(--panel, #20242c);
  color: var(--ink, #ece9df);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 4px 9px;
  font-size: 12.5px;
  white-space: nowrap;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  z-index: 6;
}

.controls-row { display: flex; align-items: center; gap: 8px; }

.ctl-btn {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text);
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.ctl-btn:hover { border-color: #4a525e; transform: translateY(-1px); }
.ctl-btn svg { width: 17px; height: 17px; }

.ctl-play {
  width: 44px; height: 44px;
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  border-radius: 13px;
  box-shadow: 0 6px 16px rgba(232, 176, 75, 0.3);
}
.ctl-play svg { width: 21px; height: 21px; }
.ctl-play:hover { border-color: var(--accent); }

.ctl-spacer { flex: 1; }

.speed-ctl {
  display: flex; align-items: center; gap: 10px;
  font-size: 12px; color: var(--text-dim);
}
.speed-ctl input[type="range"] { width: 110px; accent-color: var(--accent); }

.speed-ctl select {
  background: var(--bg-card);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 8px;
  padding: 7px 8px;
  font-family: inherit;
  font-size: 12px;
  max-width: 190px;
  outline: none;
}
.speed-ctl select:focus { border-color: var(--accent); }

/* lesson-settings popover: opened by the ⚙ button; keeps the transport bar clean */
.player-settings {
  position: absolute; right: 6px; bottom: calc(100% + 10px); z-index: 40;
  width: min(330px, calc(100vw - 24px));
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow-lg); padding: 12px 14px 14px;
  display: flex; flex-direction: column; gap: 11px;
  animation: psIn .13s ease;
}
/* opacity-only — NO transform, so the popover can never shift position while opening
   (a translate keyframe reads as "jitter"; this just fades in place) */
@keyframes psIn { from { opacity: 0; } to { opacity: 1; } }
.player-settings .ps-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin-bottom: 1px; }
.player-settings .ps-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; font-size: 13px; color: var(--text-dim); margin: 0; }
.player-settings .ps-row > span { flex: 0 0 auto; }
.player-settings .ps-row select {
  flex: 1 1 auto; min-width: 0; max-width: 200px;
  background-color: var(--bg-raised); border: 1px solid var(--line); color: var(--text);
  border-radius: 8px; padding: 8px 10px; font-family: inherit; font-size: 12.5px; outline: none; cursor: pointer;
}
.player-settings .ps-row select:focus { border-color: var(--accent); }
.player-settings .ps-row input[type="range"] { flex: 1 1 auto; max-width: 200px; accent-color: var(--accent); }
/* a subtle caret on the ⚙ so it reads as "opens a menu" */
#player-settings-btn[aria-expanded="true"] { color: var(--accent); border-color: var(--accent); }

/* ============ LESSON LIBRARY (right rail) ============ */

.library-panel {
  flex: 0 0 340px;
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: rgba(0, 0, 0, 0.18);
  border-left: 1px solid var(--line);
  padding: 28px 20px 20px;
}

/* class-first home: the teacher's classes, shown above the lesson library */
.home-classes { margin: 0 0 22px; }
.hc-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 0 8px 10px; }
.hc-head h3 { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.16em; color: var(--text-dim); margin: 0; }
.hc-new { flex: 0 0 auto; padding: 6px 12px; font-size: 13px; }
.hc-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; padding: 0 8px; }
/* grade groups: one collapsible <details> per grade, so a teacher with a class per
   subject doesn't push the lesson library off the screen. */
.hc-groups { display: flex; flex-direction: column; gap: 2px; }
.hc-group > .hc-cards { padding: 10px 8px 14px; }
.hc-gsum {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 6px 12px; border-radius: 10px; list-style: none;
  /* Compact by default: with up to 17 grades possible, every pixel of header row is paid
     for once per grade. A mouse does not need a 44px target — a finger does, so the height
     is restored below for touch rather than charged to everyone. */
  min-height: 34px;
  border: 1px solid transparent; transition: background .15s, border-color .15s;
}
/* any touch device (phones, tablets, and touch laptops) gets the 44px minimum target */
@media (pointer: coarse) {
  .hc-groups { gap: 4px; }
  .hc-gsum { min-height: 44px; padding: 9px 12px; }
}
.hc-gsum::-webkit-details-marker { display: none; }  /* Safari draws its own triangle */
.hc-gsum:hover { background: var(--accent-soft); border-color: var(--line); }
.hc-gsum:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* chevron: points right when closed, down when open — the only open/closed cue, so it
   must not depend on colour alone */
.hc-gsum::before {
  content: "›"; font-size: 17px; line-height: 1; color: var(--text-dim);
  transform: rotate(0deg); transition: transform .18s ease;
}
.hc-group[open] > .hc-gsum::before { transform: rotate(90deg); }
.hc-group[open] > .hc-gsum { background: var(--bg-raised); border-color: var(--line); }
.hc-gname { font-family: var(--font-display); font-size: 15px; font-weight: 700; }
.hc-gmeta { font-size: 12px; color: var(--text-dim); }
@media (prefers-reduced-motion: reduce) { .hc-gsum::before { transition: none; } }
.hc-card { display: flex; flex-direction: column; background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: 12px; overflow: hidden; transition: border-color .15s, transform .1s; }
.hc-card:hover { border-color: var(--accent); transform: translateY(-1px); }
.hc-open { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; text-align: left;
  background: none; border: none; color: inherit; cursor: pointer; padding: 14px 16px 10px; width: 100%; }
.hc-open:hover { background: var(--accent-soft); }
.hc-name { font-family: var(--font-display); font-size: 16px; font-weight: 700; }
.hc-meta { font-size: 12px; color: var(--text-dim); }
/* quick-jump chips: open the class straight to a tab */
.hc-chips { display: flex; gap: 4px; padding: 6px 10px 10px; }
.hc-chip { flex: 1; background: var(--bg-card); border: 1px solid var(--line); border-radius: 8px; padding: 5px 0;
  font-size: 15px; line-height: 1; cursor: pointer; transition: border-color .15s, background .15s; }
.hc-chip:hover { border-color: var(--accent); background: var(--accent-soft); }
.hc-empty { grid-column: 1 / -1; text-align: left; background: var(--bg-raised); border: 1px dashed var(--line);
  border-radius: 12px; padding: 16px 18px; cursor: pointer; color: var(--text-dim); font-size: 13.5px; }
.hc-empty:hover { border-color: var(--accent); color: var(--text); }
.hc-empty b { color: var(--accent); }
.library-head {
  display: flex; align-items: center; gap: 10px;
  padding: 0 8px 16px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--line);
  /* the offline + tag-concepts pills used to push past the right edge on a phone */
  flex-wrap: wrap;
}
.library-head h3 {
  font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--text-dim);
}
.library-count {
  min-width: 22px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 7px;
  font-size: 11px; font-weight: 700;
  color: var(--on-accent); background: var(--accent);
  border-radius: 99px;
}

/* library toolbar: search + filters share ONE compact row (wraps if cramped) */
.library-toolbar { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; flex-wrap: wrap; }
.library-search {
  flex: 1 1 200px; min-width: 140px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 9px;
  color: var(--text);
  font-family: inherit; font-size: 12.5px;
  padding: 6px 11px;
  margin: 0;
  outline: none;
}
.library-search:focus { border-color: var(--accent); }
.library-search::placeholder { color: #5e6671; }
.library-filters { display: flex; gap: 8px; margin: 0; flex: 0 0 auto; }
/* compact library dropdowns (shorter than the shared .sb-select default) */
.library-filters .library-filter { padding-top: 6px; padding-bottom: 6px; font-size: 12px; border-radius: 9px; background-position: right 10px center; min-width: 128px; }

/* one-time concept-backfill: a small pill in the Library header (not a full bar) */
.lib-tag-concepts {
  margin-left: auto; padding: 4px 11px;
  background: var(--accent-soft); border: 1px solid rgba(245,215,110,0.35);
  color: var(--accent); border-radius: 999px;
  font-family: inherit; font-size: 11px; font-weight: 600; line-height: 1.3;
  white-space: nowrap; cursor: pointer;
}
.lib-tag-concepts:hover { border-color: var(--accent); }
.lib-tag-concepts:disabled { opacity: .6; cursor: default; }

/* Custom dropdown: strips the raw native <select> chrome (the OS gradient +
   double-arrow spinner) for a flat, dark control with a single chevron that
   matches the search field. Reusable app-wide via the .sb-select class. */
.sb-select,
.library-filter {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  background-color: var(--bg-card);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa0aa' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 12px;
  border: 1px solid var(--line); border-radius: 10px; color: var(--text);
  font-family: inherit; font-size: 12.5px; padding: 9px 32px 9px 12px;
  outline: none; cursor: pointer;
}
.library-filter { flex: 1; min-width: 0; }
.sb-select:hover, .library-filter:hover { border-color: #3a424e; }
.sb-select:focus, .library-filter:focus { border-color: var(--accent); }
/* the opened option list follows the OS — keep it legible on the dark theme */
.sb-select option, .library-filter option { background: var(--bg-card); color: var(--text); }

/* App-wide rollout: strip the native <select> chrome (OS gradient + double-arrow
   spinner) from every dropdown and draw the same chevron. Only the chevron and
   right-padding are forced, so each select keeps its own size, colour and border
   from its component styles — no layout regressions. */
.screen select,
.account-bar select,
.editor-overlay select,
#qbank-body select,
#classes-body select,
#user-select, #voice-select, #board-font-select, #board-theme-select, #board-zoom-select, [data-ui-lang] {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa0aa' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right 12px center !important;
  background-size: 12px !important;
  padding-right: 32px !important;
}
.screen select option, .account-bar select option, .editor-overlay select option,
#qbank-body select option, #classes-body select option,
#user-select option, #voice-select option, #board-font-select option, [data-ui-lang] option {
  background: var(--bg-card); color: var(--text);
}

.lib-lang {
  flex-shrink: 0;
  font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 2px 5px;
}

/* AI fact-check badge (automatic verification pass) */
.lib-aicheck {
  flex-shrink: 0;
  font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.03em;
  color: #7fcaa0;
  background: rgba(70, 130, 90, 0.16);
  border: 1px solid rgba(90, 150, 110, 0.4);
  border-radius: 5px;
  padding: 2px 6px;
  white-space: nowrap;
}
.lib-aicheck.flagged { color: #e0a96e; background: rgba(190, 130, 70, 0.16); border-color: rgba(190, 140, 80, 0.4); cursor: pointer; }

.library-list {
  list-style: none;
  display: flex; flex-direction: column; gap: 6px;
  overflow-y: auto;
  padding: 4px;
  margin: 0 -4px;
}

.library-list li {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 12px;
  background: var(--bg-card);
  border: 1px solid transparent;
  border-radius: 13px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, transform 0.1s;
}
.library-list li:hover {
  border-color: var(--line);
  background: var(--bg-raised);
  transform: translateX(2px);
}

.library-list .lib-dot {
  width: 9px; height: 9px;
  flex-shrink: 0;
  border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.03);
}

.library-list .lib-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.library-list .lib-title {
  font-size: 13.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.library-list .lib-meta {
  font-size: 11px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.library-list .lib-delete {
  flex-shrink: 0;
  background: none; border: none;
  color: #5b636e;
  font-size: 17px; line-height: 1;
  padding: 4px 7px; border-radius: 7px;
  opacity: 0.55; /* always discoverable (not hover-only) — full on hover/focus/touch */
  transition: color 0.15s, background 0.15s, opacity 0.15s;
}
.library-list li:hover .lib-delete { opacity: 1; }
.library-list .lib-delete:hover { color: #f08a8a; background: rgba(240, 138, 138, 0.12); }

/* assign-to-class pill on a library lesson (teachers) */
.library-list .lib-assign {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--bg-card); border: 1px solid var(--line);
  color: var(--text-dim);
  font-family: inherit; font-size: 11px; font-weight: 600;
  padding: 5px 9px; border-radius: 8px; cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.library-list .lib-assign:hover { color: var(--text); border-color: var(--accent); }
.library-list .lib-assign.on {
  color: #9fbe8f; border-color: rgba(120, 160, 100, 0.4); background: rgba(63, 110, 49, 0.18);
}

.assign-card { width: min(380px, 100%); }
.assign-head { font-family: var(--font-display); font-size: 19px; font-weight: 600; }
.assign-lesson { font-size: 13px; color: var(--text-dim); margin: 4px 0 16px; line-height: 1.4; }
.assign-list-modal { display: flex; flex-direction: column; gap: 8px; max-height: 50vh; overflow-y: auto; }
.assign-class-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: 11px; padding: 12px 14px; cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.assign-class-row:hover { border-color: #4a525e; }
.assign-class-row.on { border-color: rgba(120, 160, 100, 0.45); background: rgba(63, 110, 49, 0.12); }
.assign-class-row .ac-info { flex: 1; min-width: 0; }
.assign-class-row .ac-name { font-size: 14px; font-weight: 600; }
.assign-class-row .ac-meta { font-size: 11.5px; color: var(--text-dim); }
.assign-check {
  width: 24px; height: 24px; flex-shrink: 0;
  display: grid; place-items: center;
  border: 1.5px solid var(--line); border-radius: 7px;
  color: transparent;
}
.assign-class-row.on .assign-check { background: #6fbf73; border-color: #6fbf73; color: #10240f; }
.assign-empty-modal { font-size: 13px; color: var(--text-dim); line-height: 1.5; text-align: center; padding: 8px 0 4px; }
.assign-make-class { margin-top: 12px; width: 100%; }

.library-list .lib-dl {
  flex-shrink: 0;
  display: grid; place-items: center;
  width: 26px; height: 26px;
  background: none; border: none;
  color: #5b636e;
  border-radius: 7px;
  opacity: 0.55;
  transition: color 0.15s, background 0.15s, opacity 0.15s;
}
.library-list li:hover .lib-dl { opacity: 1; }
.library-list .lib-dl:hover { color: var(--text); background: rgba(255,255,255,0.06); }
.library-list .lib-print {
  flex-shrink: 0; display: grid; place-items: center;
  width: 26px; height: 26px; background: none; border: none; color: #5b636e;
  border-radius: 7px; opacity: 0.55; transition: color 0.15s, background 0.15s, opacity 0.15s;
}
.library-list li:hover .lib-print { opacity: 1; }
.library-list .lib-print:hover { color: var(--text); background: rgba(255,255,255,0.06); }
.library-list .lib-dl.done { opacity: 1; color: #9fbe8f; }       /* downloaded: green check, always shown */
.library-list .lib-dl.busy { opacity: 1; color: var(--accent); animation: rec-blink 0.9s ease-in-out infinite; }
/* keyboard focus reveals the row's actions in full */
.library-list li:focus-within .lib-delete,
.library-list li:focus-within .lib-dl,
.library-list li:focus-within .lib-print { opacity: 1; }
/* touch devices have no hover — keep the management actions fully visible */
@media (hover: none) {
  .library-list .lib-delete,
  .library-list .lib-dl,
  .library-list .lib-print { opacity: 1; }
}

.library-list .lib-empty {
  display: block;
  padding: 18px 14px;
  font-size: 12.5px; line-height: 1.55;
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.015);
  border: 1px dashed var(--line);
  border-radius: 13px;
  cursor: default;
}
.library-list .lib-empty:hover { transform: none; }
.lib-empty-signin { display: block; margin-top: 12px; width: 100%; }

/* ============ RAISE YOUR HAND ============ */

.ctl-hand { color: var(--accent); }
.ctl-hand:hover { border-color: var(--accent); }

.ask-overlay {
  position: absolute;
  inset: 14px;
  border-radius: 4px;
  background: rgba(12, 20, 15, 0.9);
  backdrop-filter: blur(5px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 6;
}

.ask-card {
  width: min(460px, 100%);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 26px 26px 22px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}

.ask-card h3 {
  font-family: var(--font-display);
  font-size: 20px; font-weight: 600;
  display: flex; align-items: center; gap: 9px;
  margin-bottom: 6px;
}
.ask-hand { font-size: 20px; }
.ask-hint { font-size: 13px; color: var(--text-dim); margin-bottom: 16px; }

.ask-card textarea {
  width: 100%;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14.5px; line-height: 1.5;
  padding: 12px 14px;
  resize: none;
  outline: none;
  transition: border-color 0.2s;
}
.ask-card textarea:focus { border-color: var(--accent); }
.ask-card textarea::placeholder { color: #5e6671; }

.ask-error { margin-top: 10px; color: #f08a8a; font-size: 13px; }

.ask-actions { display: flex; justify-content: flex-end; align-items: center; gap: 10px; margin-top: 16px; }
.ask-actions .btn { flex: 0 0 auto; padding: 11px 22px; font-size: 14px; }

/* human-review banner: prompts the owning teacher to vet an AI-generated lesson */
.review-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  margin: 0 0 12px; padding: 12px 16px;
  background: linear-gradient(180deg, rgba(232, 176, 75, 0.12), rgba(232, 176, 75, 0.06));
  border: 1px solid rgba(232, 176, 75, 0.32);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
}
.review-banner-main { display: flex; align-items: flex-start; gap: 11px; min-width: 0; }
.review-banner-icon { font-size: 18px; line-height: 1.4; }
.review-banner-text { display: flex; flex-direction: column; gap: 2px; font-size: 13.5px; line-height: 1.45; }
.review-banner-text strong { color: var(--text); font-weight: 600; }
.review-banner-notes { color: var(--text-dim); font-size: 12.5px; }
.review-banner-notes:empty { display: none; }
.review-banner-actions { display: flex; align-items: center; gap: 9px; flex-shrink: 0; }
.review-banner-actions .btn { flex: 0 0 auto; padding: 9px 16px; font-size: 13px; }

/* active-learning checkpoint card */
.cp-tag { font-size: 11.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
.cp-prompt { font-size: 16px; line-height: 1.45; margin: 0 0 12px; color: var(--text); }
.cp-feedback { margin-top: 14px; font-size: 14px; line-height: 1.5; padding: 10px 12px; border-radius: 10px; background: var(--bg-raised); border: 1px solid var(--line); color: var(--text); }
.cp-feedback.ok { border-color: #3a7d4e; }
.cp-feedback.miss { border-color: #8a6d2a; }

.ask-mic {
  margin-right: auto;
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 11px;
  color: var(--text-dim);
  font-family: var(--font-ui);
  font-size: 13px; font-weight: 600;
  padding: 10px 16px;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.ask-mic:hover { color: var(--text); border-color: #4a525e; }
.ask-mic.listening {
  color: #f08a8a;
  border-color: rgba(240, 138, 138, 0.5);
  background: rgba(240, 138, 138, 0.08);
  animation: mic-pulse 1.2s ease-in-out infinite;
}
@keyframes mic-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(240, 138, 138, 0.25); }
  50% { box-shadow: 0 0 0 6px rgba(240, 138, 138, 0); }
}

.ask-prior { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.ask-prior-label {
  display: block;
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--text-dim);
  margin-bottom: 10px;
}
.ask-prior-list { display: flex; flex-direction: column; gap: 6px; max-height: 160px; overflow-y: auto; }
.ask-prior-chip {
  text-align: left;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 13px; line-height: 1.4;
  padding: 9px 12px;
  display: flex; align-items: center; gap: 9px;
  transition: border-color 0.15s, background 0.15s;
}
.ask-prior-chip:hover { border-color: var(--accent); background: var(--accent-soft); }
.ask-prior-chip svg { flex-shrink: 0; opacity: 0.7; }
.ask-prior-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.ask-cached {
  flex-shrink: 0;
  font-size: 11px; font-weight: 600;
  color: #9fbe8f;
  background: rgba(63, 110, 49, 0.25);
  border: 1px solid rgba(120, 160, 100, 0.4);
  padding: 3px 9px;
  border-radius: 99px;
  white-space: nowrap;
}

.ask-thinking {
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  width: auto; min-width: 260px;
}
.ask-thinking p { font-family: var(--font-display); font-size: 17px; }
.ask-thinking .loader-chalk { width: 44px; height: 44px; }

/* answer action bar — sits at the bottom over the board, leaves the sketch visible */
.ask-bar {
  position: absolute;
  left: 14px; right: 14px; bottom: 14px;
  z-index: 6;
  display: flex; align-items: center; gap: 14px;
  padding: 12px 14px 12px 18px;
  background: rgba(16, 24, 18, 0.92);
  border: 1px solid rgba(232, 176, 75, 0.35);
  border-radius: 12px;
  backdrop-filter: blur(4px);
}
.ask-bar-q {
  flex: 1; min-width: 0;
  font-size: 13px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ask-bar-q::before { content: "You asked: "; color: var(--accent); }
.ask-bar-actions { display: flex; gap: 8px; flex-shrink: 0; }
.ask-bar-actions .btn { padding: 9px 16px; font-size: 13px; }

/* ============ QUIZ ============ */

.quiz-overlay {
  position: absolute;
  inset: 14px;
  border-radius: 4px;
  background: rgba(12, 20, 15, 0.88);
  backdrop-filter: blur(5px);
  display: flex;
  padding: 20px;
  overflow-y: auto;
}

.quiz-card {
  margin: auto; /* centers, but stays scrollable when taller than the board */
  width: min(560px, 100%);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 30px 34px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}

.quiz-progress {
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--accent);
  margin-bottom: 12px;
}

.quiz-card h3 {
  font-family: var(--font-display);
  font-size: 21px; font-weight: 600;
  line-height: 1.4;
  margin-bottom: 20px;
}

.quiz-options { display: flex; flex-direction: column; gap: 9px; }

.quiz-option {
  display: flex; align-items: center; gap: 12px;
  text-align: left;
  padding: 13px 16px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--text);
  font-size: 14px;
  line-height: 1.45;
  transition: border-color 0.15s, background 0.15s, transform 0.1s;
}
.quiz-option:not(:disabled):hover { border-color: var(--accent); transform: translateX(2px); }

.quiz-option .opt-letter {
  width: 26px; height: 26px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 8px;
  border: 1px solid var(--line);
  font-size: 12px; font-weight: 600;
  color: var(--text-dim);
}

.quiz-option.correct { border-color: #6fbf73; background: rgba(111, 191, 115, 0.12); }
.quiz-option.correct .opt-letter { background: #6fbf73; border-color: #6fbf73; color: #10240f; }
.quiz-option.wrong { border-color: #e07b7b; background: rgba(224, 123, 123, 0.1); }
.quiz-option.wrong .opt-letter { background: #e07b7b; border-color: #e07b7b; color: #2a0e0e; }
.quiz-option:disabled { cursor: default; opacity: 0.85; }

.quiz-feedback {
  margin-top: 16px;
  padding: 13px 16px;
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 0 10px 10px 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text);
}
.quiz-feedback.ok { background: rgba(111, 191, 115, 0.12); border-left-color: #6fbf73; }
.quiz-feedback.miss { background: rgba(224, 160, 90, 0.12); border-left-color: #e0a05a; }

/* short-answer quiz input */
.quiz-short-input {
  width: 100%; box-sizing: border-box;
  background: var(--bg-raised); border: 1px solid var(--line);
  color: var(--text); border-radius: 10px; font: inherit; font-size: 14px;
  padding: 11px 13px; resize: vertical; min-height: 56px;
}
.quiz-short-input:focus { border-color: var(--accent); outline: none; }
.quiz-short-input::placeholder { color: #5e6671; }
.quiz-short-check { align-self: flex-end; margin-top: 10px; padding: 10px 20px; }

.quiz-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }

.quiz-result { text-align: center; }

.quiz-score-ring {
  width: 92px; height: 92px;
  margin: 4px auto 18px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 3px solid var(--accent);
  background: var(--accent-soft);
  font-family: var(--font-display);
  font-size: 24px; font-weight: 700;
  color: var(--accent);
}

.quiz-result h3 { margin-bottom: 8px; }
.quiz-result .quiz-feedback { text-align: left; }
.quiz-result .quiz-actions { justify-content: center; }

/* ============ PROFILES & PROGRESS ============ */

.profile-bar {
  display: flex; align-items: center; gap: 9px;
  padding: 0 4px 14px;
}
.profile-label { font-size: 12px; color: var(--text-dim); white-space: nowrap; }
.profile-bar select {
  flex: 1; min-width: 0;
  background: var(--bg-card);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 9px;
  padding: 7px 9px;
  font-family: inherit; font-size: 13px;
  outline: none;
}
.profile-bar select:focus { border-color: var(--accent); }
.icon-btn-sm { width: 32px; height: 32px; border-radius: 9px; font-size: 16px; flex-shrink: 0; }
.user-del:hover { color: #f08a8a; border-color: rgba(240, 138, 138, 0.45); }

.user-stats {
  display: flex; gap: 8px;
  padding: 0 0 16px;
}
.user-stats .stat {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 6px;
}
.stat-num { font-family: var(--font-display); font-size: 19px; font-weight: 700; color: var(--accent); }
.stat-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-dim); }

.lib-mastery {
  flex-shrink: 0;
  font-size: 11px; font-weight: 700;
  padding: 3px 8px;
  border-radius: 99px;
  background: rgba(63, 110, 49, 0.25);
  color: #9fbe8f;
  border: 1px solid rgba(120, 160, 100, 0.35);
}
.lib-mastery.low { background: rgba(190, 120, 60, 0.2); color: #e0a96e; border-color: rgba(190, 140, 80, 0.35); }
/* class-average grade on an assigned lesson (teacher view) — 👥 prefix distinguishes it from personal mastery */
.lib-classavg {
  flex-shrink: 0; white-space: nowrap;
  font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 99px;
  background: rgba(63, 110, 49, 0.25); color: #9fbe8f; border: 1px solid rgba(120, 160, 100, 0.35);
}
.lib-classavg.mid { background: rgba(190, 150, 60, 0.18); color: #e0c46e; border-color: rgba(190, 160, 80, 0.35); }
.lib-classavg.low { background: rgba(190, 90, 80, 0.2); color: #e08a82; border-color: rgba(190, 110, 100, 0.4); }
/* which class(es) a lesson is assigned to, e.g. "Grade 12" */
.lib-classes { display: inline-flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
.lib-class-chip {
  font-size: 10.5px; font-weight: 600; line-height: 1.4;
  padding: 1px 8px; border-radius: 99px;
  background: var(--accent-soft); color: var(--accent);
  border: 1px solid rgba(232, 176, 75, 0.3);
}

/* ============ PHOTO INPUT ============ */

.photo-btn {
  width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 9px;
  margin-top: 10px;
  padding: 12px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 13px;
  color: var(--text-dim);
  font-family: var(--font-ui); font-size: 13.5px; font-weight: 600;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.photo-btn:hover { color: var(--text); border-color: var(--accent); background: var(--accent-soft); }
.photo-btn.busy { opacity: 0.6; pointer-events: none; }

.figure-strip { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.fig-thumb {
  position: relative;
  width: 66px; height: 66px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--line);
}
.fig-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fig-thumb .fig-x {
  position: absolute; top: 2px; right: 2px;
  width: 18px; height: 18px;
  display: grid; place-items: center;
  background: rgba(10, 12, 16, 0.75);
  border: none; border-radius: 6px;
  color: var(--text); font-size: 12px; line-height: 1;
  cursor: pointer;
}
.fig-thumb .fig-x:hover { color: #f08a8a; }
.fig-thumb .fig-crop {
  position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px;
  display: grid; place-items: center;
  background: rgba(10, 12, 16, 0.75);
  border: none; border-radius: 6px;
  color: var(--text); font-size: 11px; line-height: 1;
  cursor: pointer; opacity: 0; transition: opacity var(--t);
}
.fig-thumb:hover .fig-crop { opacity: 1; }
.fig-thumb .fig-crop:hover { color: var(--accent); }
.fig-thumb .fig-n {
  position: absolute; bottom: 2px; left: 2px;
  font-size: 10px; font-weight: 700;
  color: var(--on-accent); background: var(--accent);
  border-radius: 5px; padding: 1px 5px;
}
.fig-thumb .fig-size {
  position: absolute; bottom: 2px; right: 2px;
  display: flex; align-items: center; gap: 1px;
  background: rgba(0,0,0,0.55); border-radius: 6px; padding: 1px 2px;
}
.fig-thumb .fig-size button {
  width: 18px; height: 18px; padding: 0; border: none; background: transparent;
  color: #fff; font-size: 14px; line-height: 1; cursor: pointer; border-radius: 4px;
}
.fig-thumb .fig-size button:hover { background: rgba(255,255,255,0.18); color: var(--accent); }
.fig-thumb .fig-size .fig-pct { font-size: 10px; font-weight: 700; color: #fff; min-width: 30px; text-align: center; }

/* figure crop modal */
.crop-overlay { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: 20px; background: rgba(0, 0, 0, 0.72); }
.crop-dialog { display: flex; flex-direction: column; gap: 12px; max-width: 94vw; max-height: 94vh; padding: 18px; background: var(--bg-card); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow-lg); }
.crop-hint { margin: 0; font-size: 13px; color: var(--text-dim); }
.crop-stage { position: relative; align-self: center; line-height: 0; overflow: hidden; cursor: crosshair; touch-action: none; }
.crop-stage img { display: block; max-width: 82vw; max-height: 72vh; user-select: none; -webkit-user-drag: none; }
.crop-box { position: absolute; border: 2px solid var(--accent); box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5); pointer-events: none; }
.crop-actions { display: flex; justify-content: flex-end; gap: 10px; }

/* figure annotation editor (drag pointer-arrows + labels onto an image) */
.annot-dialog { width: min(94vw, 860px); }
.annot-stage img { max-height: 56vh; }
/* draggable LABEL chip — place the label like you place the pin; gutters around
   the image represent the board's side margins */
.annot-stage { padding: 12px 24%; background: #10150f; overflow: visible; }
.annot-labelchip {
  position: absolute;
  transform: translate(-4px, -50%);
  color: #f3d77c;
  font-size: 13px;
  font-weight: 600;
  padding: 3px 8px;
  border: 1px dashed rgba(243, 215, 124, 0.65);
  border-radius: 7px;
  background: rgba(10, 16, 12, 0.55);
  cursor: grab;
  user-select: none;
  touch-action: none;
  white-space: nowrap;
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 4;
}
.annot-labelchip:active { cursor: grabbing; }

.annot-pin {
  position: absolute; transform: translate(-50%, -50%);
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent); color: #1a1a1a; font-weight: 700; font-size: 13px;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid #fff; box-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);
  cursor: grab; touch-action: none; user-select: none;
}
.annot-pin:active { cursor: grabbing; }
.annot-list { display: flex; flex-direction: column; gap: 6px; max-height: 22vh; overflow-y: auto; }
.annot-row { display: flex; align-items: center; gap: 8px; }
.annot-num {
  flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent); font-size: 12px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.annot-row input {
  flex: 1; min-width: 0; background: var(--bg); border: 1px solid var(--line); color: var(--text);
  border-radius: 8px; font: inherit; font-size: 14px; padding: 7px 10px;
}
.annot-del { background: none; border: none; color: #5b636e; font-size: 16px; cursor: pointer; padding: 2px 7px; border-radius: 6px; }
.annot-del:hover { color: #f08a8a; }
.editor-annot-btn {
  flex-shrink: 0; background: var(--bg-card); border: 1px solid var(--line); color: var(--text-dim);
  border-radius: 7px; padding: 5px 9px; font-size: 12px; cursor: pointer; white-space: nowrap;
}
.editor-annot-btn:hover { border-color: var(--accent); color: var(--accent); }
.editor-mark-btn {
  flex-shrink: 0; background: var(--bg-card); border: 1px solid var(--line); color: var(--text-dim);
  border-radius: 7px; padding: 5px 9px; font-size: 12px; cursor: pointer; white-space: nowrap;
}
.editor-mark-btn:hover { border-color: var(--accent); color: var(--accent); }

/* ============ STANDARDS / GRADE ============ */

.level-pill {
  font-size: 11px; font-weight: 600;
  color: #a9cdef;
  background: rgba(110, 150, 200, 0.14);
  border-radius: 99px;
  padding: 4px 11px;
  white-space: nowrap;
}

.standards-row { display: inline-flex; gap: 6px; min-width: 0; overflow: hidden; }
.std-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 600;
  color: var(--text-dim);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 99px;
  padding: 4px 10px;
  white-space: nowrap;
  cursor: help;
  max-width: 22ch; overflow: hidden; text-overflow: ellipsis;
}
/* the book marks this as a SYLLABUS citation. Without it a bare code like
   "Grade 11 Math Unit 4" reads as the lesson's own level, which contradicted the
   Grade 12 class the teacher had assigned it to. */
.std-chip-tag { font-size: 9.5px; line-height: 1; opacity: 0.75; flex: none; }

/* ============ RECORD / SHARE ============ */

#record-btn { position: relative; }
.record-dot {
  position: absolute;
  top: 6px; right: 6px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #e85b5b;
  animation: rec-blink 1s ease-in-out infinite;
}
@keyframes rec-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
#record-btn.recording { border-color: rgba(232, 91, 91, 0.6); color: #e88; }

.toast {
  position: fixed;
  left: 50%; bottom: 28px;
  transform: translateX(-50%);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--text);
  font-size: 13.5px;
  padding: 12px 20px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
  z-index: 90;
  animation: toast-in 0.2s ease;
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translate(-50%, 0); } }
.toast-action { display: inline-flex; align-items: center; gap: 4px; }
.toast-btn { flex: none; margin-left: 4px; background: var(--accent); color: #1a1208; border: none; border-radius: 8px; padding: 5px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.toast-btn:hover { filter: brightness(1.06); }

/* ============ GENERATION OPTIONS ============ */

.options-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 18px;
}
.opt { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.opt label { font-size: 12px; color: var(--text-dim); }
.opt select, .opt .opt-input {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 11px;
  padding: 10px 12px;
  font-family: inherit; font-size: 13.5px;
  outline: none;
  width: 100%;
}
.opt select:focus, .opt .opt-input:focus { border-color: var(--accent); }

/* ============ ACCOUNTS ============ */

.account-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 0 4px 12px; margin-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
.account-info { display: flex; flex-direction: column; min-width: 0; }
.account-name { font-size: 13.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.account-role { font-size: 11px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.account-org {
  margin-top: 4px; align-self: flex-start; max-width: 100%;
  background: var(--bg-raised); border: 1px solid var(--line);
  color: var(--text-dim); font-family: inherit; font-size: 11px; font-weight: 600;
  padding: 3px 9px; border-radius: 999px; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color 0.15s, border-color 0.15s;
}
.account-org:hover:not(:disabled) { color: var(--text); border-color: var(--accent); }
.account-org:disabled { cursor: default; }
.account-actions { display: flex; gap: 6px; flex-shrink: 0; }
.account-btn {
  background: var(--bg-card); border: 1px solid var(--line);
  color: var(--text-dim);
  font-family: inherit; font-size: 12px; font-weight: 600;
  padding: 6px 11px; border-radius: 8px; cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.account-btn:hover { color: var(--text); border-color: var(--accent); }

/* Settings dropdown — collapses the signed-in account/admin actions */
.settings-wrap { position: relative; display: inline-flex; }
.settings-btn { display: inline-flex; align-items: center; gap: 6px; }
.settings-btn svg { opacity: 0.85; }
.settings-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  min-width: 176px; padding: 6px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
  display: flex; flex-direction: column; gap: 2px;
}
.settings-item {
  display: block; width: 100%; text-align: left;
  background: none; border: 0; border-radius: 7px;
  color: var(--text-dim); font-family: inherit; font-size: 12.5px; font-weight: 600;
  padding: 8px 10px; cursor: pointer; text-decoration: none;
  transition: background 0.12s, color 0.12s;
}
.settings-item:hover { background: var(--bg-raised); color: var(--text); }
.settings-item-danger:hover { color: #ff6b6b; }

.auth-overlay {
  position: fixed; inset: 0;
  background: rgba(10, 12, 16, 0.72); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px; z-index: 90;
}
.auth-card {
  position: relative;
  width: min(420px, 100%);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 26px 24px 24px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
}
.auth-close {
  position: absolute; top: 14px; right: 16px;
  background: none; border: none; color: var(--text-dim);
  font-size: 22px; line-height: 1; cursor: pointer;
}
.auth-close:hover { color: var(--text); }
.auth-tabs { display: flex; gap: 4px; margin-bottom: 18px; background: var(--bg-raised); padding: 4px; border-radius: 11px; }
.auth-tab {
  flex: 1; background: none; border: none; cursor: pointer;
  color: var(--text-dim); font-family: inherit; font-size: 12.5px; font-weight: 600;
  padding: 8px 6px; border-radius: 8px; transition: color 0.15s, background 0.15s;
}
.auth-tab.active { color: var(--on-accent); background: var(--accent); }
.auth-form { display: flex; flex-direction: column; gap: 10px; }
.auth-lead { font-size: 13px; color: var(--text-dim); margin-bottom: 4px; line-height: 1.5; }
.auth-input {
  background: var(--bg-raised); border: 1px solid var(--line);
  color: var(--text); border-radius: 10px;
  font-family: inherit; font-size: 14px; padding: 11px 13px; outline: none;
}
.auth-input:focus { border-color: var(--accent); }
.auth-submit { margin-top: 6px; }
.auth-error { margin-top: 14px; color: #f08a8a; font-size: 13px; text-align: center; }

/* Google sign-in button + "or" divider */
.google-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  background: #fff; color: #1f1f1f; border: 1px solid var(--line);
  border-radius: 10px; padding: 11px 14px; font-size: 14px; font-weight: 600;
  text-decoration: none; cursor: pointer; transition: filter 0.15s;
}
.google-btn:hover { filter: brightness(0.95); }
.auth-or { display: flex; align-items: center; text-align: center; color: var(--text-dim); font-size: 11px; }
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.auth-or span { padding: 0 10px; text-transform: uppercase; letter-spacing: 0.08em; }

/* signup: choose to start a new school or join a colleague's */
.auth-school { display: flex; flex-direction: column; gap: 8px; margin-top: 2px; }
.auth-school-tabs { display: flex; gap: 4px; background: var(--bg-raised); padding: 4px; border-radius: 10px; }
.auth-school-tab {
  flex: 1; background: none; border: none; cursor: pointer;
  color: var(--text-dim); font-family: inherit; font-size: 12px; font-weight: 600;
  padding: 7px 6px; border-radius: 7px; transition: color 0.15s, background 0.15s;
}
.auth-school-tab.active { color: var(--on-accent); background: var(--accent); }
.auth-hint { font-size: 11.5px; color: var(--text-dim); line-height: 1.45; margin: 0; }

/* manage-school modal (org admin) */
.school-card { width: min(560px, 100%); padding: 30px 30px 26px; }
/* the tab panels get a little vertical room so the panel doesn't feel cramped */
.school-card .stp { padding-top: 4px; }
.school-card .school-members, .school-card .ti-list { display: flex; flex-direction: column; gap: 10px; }
.school-card .ti-create { margin-top: 2px; }
.school-row { display: flex; gap: 8px; margin-bottom: 12px; align-items: center; }
.school-row .auth-input { flex: 1; }
.school-code { font-size: 12.5px; color: var(--text-dim); margin: 0; flex: 1; }
.school-code-btn {
  background: var(--bg-raised); padding: 3px 10px; border-radius: 6px;
  color: var(--text); letter-spacing: 0.06em; font-family: var(--font-display);
  font-weight: 700; font-size: 13px; border: 1px solid var(--line); cursor: pointer;
}
.school-code-btn:hover { border-color: var(--accent); color: var(--accent); }
.school-usage { font-size: 12.5px; color: var(--text-dim); margin: 0 0 16px; }
.school-usage b { color: var(--accent); }
/* Manage-school tabs (Classes / Teachers) — same language as the class hub */
.school-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--line); margin: 16px 0 16px; }
.school-tab { flex: 0 0 auto; background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-dim);
  font-family: inherit; font-size: 14px; font-weight: 600; padding: 9px 14px; cursor: pointer; margin-bottom: -1px;
  display: inline-flex; align-items: center; gap: 7px; transition: color .15s, border-color .15s; }
.school-tab:hover { color: var(--text); }
.school-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.stab-n { font-size: 11px; font-weight: 700; color: var(--accent); background: var(--accent-soft); border-radius: 999px; padding: 0 7px; min-width: 18px; text-align: center; }
.stab-n:empty { display: none; }
.stp { min-height: 80px; }
.school-subhead { font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-dim); margin: 18px 0 4px; }
.school-subnote { font-size: 12px; color: var(--text-dim); margin: 0 0 8px; }
.school-members { display: flex; flex-direction: column; gap: 6px; max-height: 320px; overflow-y: auto; }
/* school-admin oversight: all classes in the school */
.school-classes { max-height: 300px; overflow-y: auto; margin-bottom: 6px; }
.school-classes-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.school-classes-tbl th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); font-weight: 600; padding: 4px 8px; border-bottom: 1px solid var(--line); }
.school-classes-tbl td { padding: 7px 8px; border-bottom: 1px solid var(--line); }
.school-classes-tbl td.num, .school-classes-tbl th.num { text-align: right; font-variant-numeric: tabular-nums; }
.school-classes-tbl .scc-name { font-weight: 600; }
.school-classes-tbl .scc-teacher { color: var(--text-dim); }
/* per-teacher invite links */
.ti-create { display: flex; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.ti-create .ti-label, .ti-create .ti-email { flex: 1 1 200px; min-width: 150px; margin: 0; }
.ti-create .ti-subject { flex: 1 1 150px; min-width: 130px; margin: 0; }
.ti-create .ti-grade { flex: 1 1 130px; min-width: 110px; margin: 0; height: 40px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--bg-raised); color: var(--text); font: inherit; font-size: 13px; }
.ti-create .btn { flex: 1 1 100%; margin-top: 2px; }  /* always full-width on its own line so it can't get lost */
.ti-list { display: flex; flex-direction: column; gap: 6px; max-height: 260px; overflow-y: auto; }
.ti-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; }
.ti-row.ti-used, .ti-row.ti-revoked { opacity: 0.6; }
.ti-main { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ti-name { font-size: 13px; font-weight: 600; }
.ti-status { font-size: 11px; color: var(--text-dim); }
.ti-row.ti-pending .ti-status { color: var(--accent); }
.ti-actions { display: flex; gap: 6px; flex: 0 0 auto; }
/* collapsible history of colleagues who joined via a link — keeps the main list clean */
.ti-history { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 8px; }
.ti-history > summary { cursor: pointer; list-style: none; user-select: none; padding: 4px 2px;
  font-size: 12.5px; font-weight: 600; color: var(--text-dim); display: flex; align-items: center; gap: 6px; }
.ti-history > summary::-webkit-details-marker { display: none; }
.ti-history > summary::before { content: "▸"; font-size: 10px; transition: transform .12s; }
.ti-history[open] > summary::before { transform: rotate(90deg); }
.ti-history[open] > summary { margin-bottom: 6px; }
.ti-history .ti-row { margin-top: 6px; }
.ti-actions .btn { padding: 5px 10px; font-size: 12px; }
/* signup: "you've been invited to join X" banner */
.signup-invite-banner { font-size: 13px; line-height: 1.5; padding: 10px 12px; border-radius: 10px; margin-bottom: 4px;
  color: var(--accent-strong, var(--accent)); background: var(--accent-soft); border: 1px solid var(--accent); }
.signup-invite-banner.bad { color: var(--danger, #d14343); background: rgba(209,67,67,0.1); border-color: rgba(209,67,67,0.5); }
.school-member {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px;
}
.school-member-info { display: flex; flex-direction: column; min-width: 0; }
.school-member-name { font-size: 13.5px; font-weight: 600; }
.school-member-meta { font-size: 11px; color: var(--text-dim); }
.school-member-actions { display: flex; gap: 6px; flex-shrink: 0; }
.account-btn.danger:hover { color: var(--danger, #f08a8a); border-color: var(--danger, #f08a8a); }
.account-btn.account-upgrade { color: var(--accent); border-color: rgba(232,176,75,0.5); font-weight: 600; }
.account-btn.account-upgrade:hover { background: var(--accent-soft); border-color: var(--accent); }

/* classes modal reuses .editor-* shell */
.class-list { display: flex; flex-direction: column; gap: 10px; }
.class-card {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: 12px; padding: 12px 14px;
  cursor: pointer; transition: border-color 0.15s, background 0.15s;
}
.class-card:hover { border-color: var(--accent); }
/* list card: name + meta on the left, one aligned action row on the right */
.cc-main { min-width: 0; flex: 1 1 auto; }
.cc-name { font-size: 15px; font-weight: 600; }
.cc-meta { font-size: 12px; color: var(--text-dim); margin-top: 3px; }
/* the student count doubles as a link into the roster */
.cc-students {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; color: var(--accent); font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px;
}
.cc-students:hover { filter: brightness(1.1); }
.cc-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.class-card-head { display: flex; align-items: center; gap: 10px; }
.class-card-head h4 { font-size: 15px; font-weight: 600; flex: 1; }
.class-lesson-row { display: flex; align-items: stretch; gap: 6px; }
.class-lesson-row .class-lesson-open { flex: 1; min-width: 0; }
.cl-share {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0 10px;
  font-size: 15px;
  cursor: pointer;
}
.cl-share:hover { border-color: var(--accent); background: rgba(232, 176, 75, 0.12); }
.class-card-actions { display: inline-flex; align-items: center; gap: 8px; }
/* the actions share one height/rounding so the row reads as a set */
.class-manage, .class-code, .class-invite, .class-remove {
  height: 30px; display: inline-flex; align-items: center; gap: 5px; border-radius: 8px;
  font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
/* primary, discoverable entry into the class detail / roster */
.class-manage {
  background: var(--accent-soft); color: var(--accent);
  border: 1px solid rgba(232,176,75,0.35); padding: 0 12px; font-weight: 700;
}
.class-manage:hover { border-color: var(--accent); background: rgba(232,176,75,0.2); }
.class-invite { background: var(--accent); color: var(--on-accent); border: none; padding: 0 13px; font-weight: 700; }
.class-invite:hover { filter: brightness(1.08); }
.class-code {
  font-family: ui-monospace, "JetBrains Mono", "SF Mono", monospace; letter-spacing: 0.05em;
  color: var(--accent); background: var(--accent-soft);
  border: 1px solid rgba(232,176,75,0.28); padding: 0 11px;
}
.class-code:hover { background: rgba(232,176,75,0.22); }
.class-remove {
  background: none; border: 1px solid var(--line); color: var(--text-dim); padding: 0 12px;
}
.class-remove:hover { color: var(--danger, #f08a8a); border-color: var(--danger, #f08a8a); }

/* ── Class hub: pinned share header + tabs (Students · Lessons · Practice · Mock exams) ── */
.class-hub-head { display: flex; align-items: center; justify-content: space-between; gap: 12px 20px; flex-wrap: wrap; margin: 10px 0 14px; }
.chh-titles { min-width: 0; }
.chh-name { font-size: 20px; font-weight: 700; margin: 0; line-height: 1.15; }
.chh-sub { font-size: 13px; color: var(--text-dim); }
.chh-share { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.chh-code { font-size: 12px; color: var(--text-dim); display: inline-flex; align-items: center; gap: 6px; }
.chh-share .class-code { height: 30px; display: inline-flex; align-items: center; border-radius: 8px; cursor: pointer; }
.chh-share .class-invite { height: 34px; display: inline-flex; align-items: center; border-radius: 9px; }
.class-tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--line); margin-bottom: 16px; overflow-x: auto; }
.class-tab { flex: 0 0 auto; background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-dim);
  font-family: inherit; font-size: 14px; font-weight: 600; padding: 9px 14px; cursor: pointer; white-space: nowrap;
  transition: color .15s, border-color .15s; margin-bottom: -1px; }
.class-tab:hover { color: var(--text); }
.class-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.class-tabpanel { min-height: 120px; }
/* per-tab header: title + description on the left, primary create action on the right */
.ct-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; margin-bottom: 12px; }
.ct-sub { font-size: 12.5px; color: var(--text-dim); margin: 3px 0 0; line-height: 1.45; max-width: 52ch; }
.ct-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.chh-foot { margin-top: 22px; padding-top: 12px; border-top: 1px solid var(--line); }
.chh-del { background: none; border: none; color: var(--text-dim); font-size: 12px; cursor: pointer; }
.chh-del:hover { color: var(--danger, #f08a8a); }
/* Practice tab summary */
.cp-summary { margin-top: 4px; }
.cp-count { font-size: 15px; }
.cp-count b { color: var(--accent); font-size: 20px; }
.cp-empty { color: var(--text-dim); font-size: 13.5px; line-height: 1.6; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 12px; padding: 16px; }
.class-meta { font-size: 12px; color: var(--text-dim); margin-top: 6px; }
.class-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 6px; }
.class-card-foot .class-meta { margin-top: 0; }
.class-lesson-open {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 8px; padding: 11px 14px; cursor: pointer; text-align: left; color: inherit;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: 10px;
}
.class-lesson-open:hover { border-color: var(--accent); background: var(--accent-soft); }
.class-lesson-open .cl-title { font-size: 14px; font-weight: 600; }
.class-lesson-open .cl-due { font-size: 11.5px; color: var(--text-dim); flex: 0 0 auto; }

/* student dashboard (shown instead of the creation composer for role=student) */
#student-home { display: flex; flex-direction: column; gap: 24px; }
/* header row: greeting left, account controls right, on one line (wraps on mobile) */
.sh-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px 24px; flex-wrap: wrap; }
.sh-headings { display: flex; flex-direction: column; gap: 4px; min-width: 240px; }
/* student account controls (sign out / theme / language) — the teacher account bar
   lives in the library panel, which is hidden for students */
.sh-topbar { display: flex; justify-content: flex-end; align-items: center; gap: 8px; margin: 4px 0 0; flex-wrap: wrap; }
.sh-topbar .sh-lang { flex: 0 0 auto; min-width: 120px; }
.sh-iconbtn { display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 13px;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--text-dim);
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px; cursor: pointer;
  transition: border-color .15s, color .15s, background .15s; }
.sh-iconbtn:hover { border-color: var(--accent); color: var(--text); }
.sh-signout:hover { border-color: var(--danger); color: var(--danger); background: transparent; }
.sh-greeting { font-family: var(--font-display); font-size: 32px; font-weight: 700; margin: 0; line-height: 1.15; }
.sh-sub { color: var(--text-dim); font-size: 15px; margin: 0; }
.sh-stats { display: flex; gap: 14px; }
.sh-stat { flex: 1; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 14px; padding: 20px 16px; text-align: center; }
/* subject switcher — one login, many subjects */
.sh-subjects { display: flex; flex-wrap: wrap; align-items: center; gap: 9px; margin: 4px 0; }
.sh-subject { background: var(--bg-raised); border: 1px solid var(--line); color: var(--text); border-radius: 999px; padding: 9px 18px; font-size: 14px; font-weight: 600; cursor: pointer; transition: background .15s, border-color .15s, color .15s; }
.sh-subject:hover { border-color: var(--accent); }
.sh-subject.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); }
.sh-add-subject { border-style: dashed; color: var(--text-dim); font-weight: 500; }
.sh-add-subject:hover { color: var(--accent); }
.sh-add-form { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sh-add-code { width: 130px; padding: 7px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--bg-raised); color: var(--text); font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; }
.sh-add-go { padding: 7px 14px; font-size: 13px; }
.sh-add-cancel { background: none; border: none; color: var(--text-dim); cursor: pointer; font-size: 15px; line-height: 1; padding: 4px; }
.sh-add-err { color: var(--danger, #d14343); font-size: 12px; flex-basis: 100%; }
.sh-stat b { display: block; font-family: var(--font-display); font-size: 34px; line-height: 1.1; color: var(--accent); margin-bottom: 6px; }
.sh-stat span { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-dim); }
.sh-section { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-dim); margin: 0; }
.sh-lessons { display: flex; flex-direction: column; gap: 10px; }
.sh-lesson { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; text-align: left;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; cursor: pointer; color: inherit; }
.sh-lesson:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); }
.sh-lesson:disabled { opacity: 0.55; cursor: default; }
.sh-l-title { font-size: 15px; font-weight: 600; }
.sh-l-meta { font-size: 12px; color: var(--text-dim); }
.sh-empty { color: var(--text-dim); font-size: 14px; }
/* for students the dashboard already shows stats + lessons — slim the sidebar */
/* students: everything (lessons, exams, practice) lives on the dashboard, so hide the
   teacher-facing library sidebar entirely and give the dashboard the full width */
.screen.student-mode #library,
.screen.student-mode #library-resizer,
.screen.student-mode #user-stats { display: none !important; }
/* learner stats (streak/completed/mastery) are meaningless for a teacher — hide them too */
.screen.teacher-view #user-stats { display: none !important; }
.screen.student-mode .setup-main { flex: 1 1 100%; max-width: 100%; align-items: flex-start; padding: 40px 32px; }
/* the student dashboard is wider than the 560px auth/composer card — give it room so it
   doesn't read as a tiny column on a big screen */
.screen.student-mode .setup-card { max-width: 940px; }

/* ── Teacher: lesson creation opens on demand (via the "Create lesson" button),
   so the library gets the whole screen by default. ── */
.screen.teacher-view #library { flex: 1 1 100%; max-width: 100%; }
.screen.teacher-view #library-resizer { display: none; }
.screen.teacher-view .setup-main { display: none; }         /* composer hidden until opened */
#composer-close { display: none; }                           /* only shown in the overlay */

/* opened: the composer becomes a centered, scrollable modal panel over the library */
.screen.teacher-view.composer-open .setup-main {
  display: flex; position: fixed; inset: 0; z-index: 200;
  align-items: flex-start; justify-content: center;
  padding: 40px 16px; overflow-y: auto;
  background: rgba(8, 10, 13, 0.72); backdrop-filter: blur(3px);
  animation: sbFade .18s ease;
}
.screen.teacher-view.composer-open .setup-card {
  position: relative;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 18px;
  padding: 30px 30px 34px; margin: auto 0; max-width: 620px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.screen.teacher-view.composer-open .setup-card { position: relative; }  /* anchor the × */
.screen.teacher-view.composer-open #composer-close {
  display: block; position: absolute; top: 14px; right: 16px; z-index: 2;
  background: none; border: none; color: var(--text-dim);
  font-size: 22px; line-height: 1; cursor: pointer;
}
.screen.teacher-view.composer-open #composer-close:hover { color: var(--text); }
@keyframes sbFade { from { opacity: 0; } to { opacity: 1; } }

/* the "Create lesson" menu button — the primary action, accented */
.account-btn-primary {
  background: linear-gradient(180deg, rgba(245,215,110,0.18), rgba(245,215,110,0.07));
  border-color: rgba(245,215,110,0.5) !important; color: var(--accent) !important; font-weight: 700;
}
.account-btn-primary:hover { border-color: var(--accent) !important; }
#student-home { max-width: 900px; margin: 0 auto; width: 100%; }

/* dashboard activity blocks */
.sh-block { display: flex; flex-direction: column; gap: 10px; }
.sh-section-row { display: flex; align-items: center; gap: 8px; }
.sh-badge { font-size: 12px; font-weight: 700; color: var(--accent); background: var(--accent-soft); border-radius: 999px; padding: 1px 9px; }
.sh-block-sub { margin: -4px 0 2px !important; font-size: 12.5px; }
.sh-cards { list-style: none; display: flex; flex-direction: column; gap: 10px; padding: 0; margin: 0; }
/* the exam rows on the student dashboard read as clean cards */
#student-home .exam-row { background: var(--bg-raised); border: 1px solid var(--line); border-radius: 12px; padding: 13px 15px; }
#student-home .exam-row:hover { border-color: var(--accent); }

/* horizontal launcher: three category tiles; the selected one opens its panel below */
.sh-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 2px 0 14px; }
.sh-tab { display: flex; align-items: center; gap: 12px; text-align: left; padding: 16px 18px;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: 14px; cursor: pointer; color: var(--text);
  transition: border-color .15s, transform .1s, background .15s; }
.sh-tab:hover { border-color: var(--accent); transform: translateY(-1px); }
.sh-tab.active { border-color: var(--accent); background: var(--accent-soft); }
.sh-tab-ic { font-size: 23px; line-height: 1; flex: 0 0 auto; }
.sh-tab-txt { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.sh-tab-txt b { font-size: 15px; font-weight: 700; }
.sh-tab-txt small { font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.sh-tab-n { margin-left: auto; flex: 0 0 auto; font-size: 12px; font-weight: 700; color: var(--accent);
  background: var(--accent-soft); border-radius: 999px; padding: 1px 8px; min-width: 22px; text-align: center; }
.sh-tab.active .sh-tab-n { color: var(--accent); background: rgba(245,215,110,0.22); }
.sh-tab.empty { opacity: .6; }
.sh-tab.empty .sh-tab-n { color: var(--muted); background: rgba(255,255,255,0.06); }
.sh-panel { display: flex; flex-direction: column; gap: 10px; }
@media (max-width: 560px) {
  .sh-tabs { gap: 7px; }
  .sh-tab { flex-direction: column; align-items: flex-start; gap: 6px; padding: 10px 11px; }
  .sh-tab-txt small { display: none; }
  .sh-tab-n { margin: 0; position: absolute; }        /* keep the count from forcing width */
  .sh-tab { position: relative; }
}
.class-create { display: flex; gap: 8px; margin-bottom: 16px; }
.class-create input {
  flex: 1; background: var(--bg-raised); border: 1px solid var(--line);
  color: var(--text); border-radius: 10px; padding: 10px 12px; font-family: inherit; font-size: 13.5px; outline: none;
}
.class-create input:focus { border-color: var(--accent); }

/* structured class creation: grade + subject + section grid */
.class-create-grid { display: grid; grid-template-columns: minmax(90px, 0.7fr) 1.4fr 0.8fr; gap: 10px; margin-bottom: 10px; }
.class-create-grid .qe-lab { margin: 0; }
.class-create-grid select, .class-create-grid input {
  width: 100%; background: var(--bg-raised); border: 1px solid var(--line);
  color: var(--text); border-radius: 10px; padding: 10px 12px; font-family: inherit; font-size: 13.5px; outline: none;
}
.class-create-grid select:focus, .class-create-grid input:focus { border-color: var(--accent); }
.class-create-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; }
@media (max-width: 560px) { .class-create-grid { grid-template-columns: 1fr 1fr; } }

.roster-table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 13px; }
.roster-table th { text-align: left; color: var(--text-dim); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.roster-table td { padding: 8px; border-bottom: 1px solid var(--line); }
.roster-empty, .assign-empty { font-size: 13px; color: var(--text-dim); padding: 10px 2px; }

/* One review for a whole pasted list whose names already exist in the school. Sits inline
   under the textarea rather than in a modal: the teacher needs the names they just pasted
   still visible while deciding, and a modal per name is what this exists to prevent. */
.roster-review {
  border: 1px solid var(--line); border-left: 3px solid var(--warn, #d9a441);
  background: var(--bg-card); border-radius: 10px; padding: 12px 14px; margin: 8px 0 10px;
}
.roster-review .rr-head strong { font-size: 14px; }
.roster-review .rr-rows { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.roster-review .rr-row {
  display: flex; gap: 10px; justify-content: space-between; align-items: center; flex-wrap: wrap;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
}
.roster-review .rr-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.roster-review .rr-who strong { font-size: 14px; }
.roster-review .rr-who .editor-hint { font-size: 12px; }
.roster-review .rr-choice { display: flex; gap: 14px; flex: 0 0 auto; }
.roster-review .rr-choice label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; }
.roster-review .rr-choice input { accent-color: var(--accent); }
.roster-review .rr-actions { display: flex; gap: 8px; }
@media (max-width: 640px) {
  /* stack, and give the radios a full-width row — two targets side by side at this width
     land under a thumb together, and picking the wrong one creates the duplicate account */
  .roster-review .rr-row { flex-direction: column; align-items: stretch; }
  .roster-review .rr-choice { justify-content: space-between; gap: 8px; }
  .roster-review .rr-choice label { flex: 1; min-height: 44px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; }
  .roster-review .rr-actions .btn { flex: 1; min-height: 44px; }
}

/* teacher registers students onto the roster (bulk paste) */
.roster-add { display: flex; gap: 8px; align-items: flex-start; margin: 4px 0 6px; }
.roster-add textarea {
  flex: 1; min-height: 40px; resize: vertical; background: var(--bg-card); border: 1px solid var(--line);
  color: var(--text); border-radius: 10px; padding: 8px 11px; font-family: inherit; font-size: 13px; outline: none;
}
.roster-add textarea:focus { border-color: var(--accent); }
.roster-add .btn { flex: 0 0 auto; padding: 9px 16px; font-size: 13px; }
.roster-table .rs-link {
  background: var(--accent-soft); border: 1px solid rgba(245,215,110,0.4); color: var(--accent);
  border-radius: 8px; padding: 4px 10px; font: 600 11.5px/1 inherit; cursor: pointer; white-space: nowrap;
}
.roster-table .rs-link:hover { border-color: var(--accent); }
.roster-table .rs-del {
  background: none; border: 1px solid var(--line); color: var(--muted); border-radius: 7px;
  width: 24px; height: 24px; line-height: 1; font-size: 15px; cursor: pointer;
}
.roster-table .rs-del:hover { color: #f08a8a; border-color: #f08a8a; }
/* One menu button instead of four loose actions. 32px tall rather than 24 — still compact
   in a table, but no longer a target you have to aim at. */
.roster-table .rs-more {
  background: none; border: 1px solid var(--line); color: var(--muted); border-radius: 8px;
  min-width: 32px; height: 32px; padding: 0 6px; line-height: 1;
  font: 600 16px/1 inherit; cursor: pointer;
}
.roster-table .rs-more:hover, .roster-table .rs-more[aria-expanded="true"] {
  color: var(--accent); border-color: var(--accent);
}
/* Rendered to <body> so a table cell's overflow can't clip it. */
.rs-menu {
  position: fixed; z-index: 300; width: 232px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.32); padding: 6px;
  display: flex; flex-direction: column; gap: 1px;
  animation: sbFade 0.12s ease;
}
.rs-menu-head {
  margin: 0; padding: 7px 10px 8px; font: 700 12px/1.2 inherit; color: var(--muted);
  border-bottom: 1px solid var(--line); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rs-menu-item {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  background: none; border: none; border-radius: 8px; padding: 9px 10px;
  color: var(--text); font: inherit; font-size: 13.5px; cursor: pointer;
}
.rs-menu-item:hover, .rs-menu-item:focus-visible { background: var(--accent-soft); outline: none; }
.rs-menu-item.danger { color: #f08a8a; }
.rs-menu-item.danger:hover, .rs-menu-item.danger:focus-visible { background: rgba(240, 138, 138, 0.12); }
.rs-menu-label { font-weight: 600; }
.rs-menu-hint { font-size: 11.5px; color: var(--muted); line-height: 1.3; }

/* ── Roster on a phone ──────────────────────────────────────────────────────────
   A six-column table needs 397px. On a 360px screen the last column — the ⋯ menu
   holding Reset PIN, a new login link, the data export and Remove — sat entirely
   off the right edge, so on the device most of these teachers actually own, none of
   those actions existed. Below 560px each student becomes a card: name and the two
   controls on the top line, the three stats as a labelled strip underneath. */
@media (max-width: 560px) {
  .roster-table, .roster-table tbody, .roster-table tr, .roster-table td { display: block; width: 100%; }
  .roster-table thead { display: none; }          /* the cards carry their own labels */
  .roster-table tr {
    border: 1px solid var(--line); border-radius: 12px;
    padding: 10px 12px; margin-bottom: 8px; background: var(--bg-raised);
    display: grid; grid-template-columns: 1fr auto auto; gap: 4px 8px; align-items: center;
  }
  .roster-table td { border: none; padding: 0; }
  .roster-table td.rs-name { font-weight: 600; font-size: 14px; grid-column: 1; }
  /* Last seen sits with the name, not down in the stats strip — on a phone it's the line
     that tells a teacher whether this student has ever arrived. */
  .roster-table td:nth-child(2) { grid-column: 1; grid-row: 2; justify-self: start; font-size: 12px; }
  /* streak / done / mastery: one labelled strip across the bottom, not three columns */
  .roster-table td:nth-child(3), .roster-table td:nth-child(4), .roster-table td:nth-child(5) {
    grid-row: 3; font-size: 12px; color: var(--text-dim); justify-self: start;
  }
  .roster-table td:nth-child(3) { grid-column: 1; }
  .roster-table td:nth-child(3)::before { content: "streak "; }
  .roster-table td:nth-child(4)::before { content: "done "; }
  .roster-table td:nth-child(5)::before { content: "mastery "; }
  .roster-table td:nth-child(4), .roster-table td:nth-child(5) { grid-column: span 1; }
  .roster-table td:nth-child(6) { grid-column: 2; grid-row: 1; }   /* Copy link */
  .roster-table td:nth-child(7) { grid-column: 3; grid-row: 1; }   /* ⋯ menu — on screen now */
  .roster-table .rs-link, .roster-table .rs-more { height: 34px; }  /* thumb-sized */
  .rs-menu { width: min(232px, calc(100vw - 24px)); }

  /* The tab strip scrolled horizontally, so "Mock exams" was simply invisible — a phone
     gives no hint that a row scrolls. Four short labels wrap into two rows at 360px and
     every tab is on screen. */
  .class-tabs { flex-wrap: wrap; overflow-x: visible; gap: 2px 4px; }
  .class-tab { font-size: 13px; padding: 8px 10px; }

  /* Textarea beside a button leaves ~210px for a three-line placeholder. Stack them. */
  .roster-add { flex-direction: column; align-items: stretch; }
  .roster-add .btn { width: 100%; }
}
.roster-tools { display: flex; gap: 8px; margin: 2px 0 6px; }
.roster-tools .btn { padding: 7px 13px; font-size: 12.5px; }
/* the print container is only for printing — never show it on screen */
.print-root { display: none; }
/* class concept-level analytics */
.class-analytics .an-card { padding: 10px 0; border-bottom: 1px solid var(--line); }
.an-head { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.an-head .an-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.an-bar { width: 90px; height: 6px; border-radius: 3px; background: rgba(255,255,255,0.08); overflow: hidden; flex: none; }
.an-bar i { display: block; height: 100%; background: #6fd39b; }
.an-bar.mid i { background: #e6c46a; }
.an-bar.low i { background: #e0795f; }
.an-pct { width: 38px; text-align: right; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.an-meta { font-size: 11.5px; color: var(--text-dim); margin: 3px 0 0; }
.an-missed { margin: 6px 0 0; padding: 0; list-style: none; }
.an-missed li { font-size: 12px; color: var(--text-dim); padding: 2px 0; display: flex; gap: 6px; }
.an-missed .an-miss-n { color: #e0795f; font-weight: 600; flex: none; }
.an-missed .an-miss-q { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.assign-row { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.assign-row .a-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.assign-toggle {
  background: var(--bg-card); border: 1px solid var(--line); color: var(--text-dim);
  border-radius: 7px; font-size: 12px; font-weight: 600; padding: 5px 10px; cursor: pointer;
}
.assign-toggle.on { color: #9fbe8f; border-color: rgba(120,160,100,0.4); background: rgba(63,110,49,0.18); }
.assign-toggle:hover { border-color: var(--accent); }
.back-classes { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 13px; padding: 0 0 12px; }
.assign-row .a-due {
  background: var(--bg-card); border: 1px solid var(--line); color: var(--text-dim);
  border-radius: 7px; font: inherit; font-size: 12px; padding: 4px 7px; color-scheme: dark;
}

/* gradebook matrix */
.gradebook-wrap { overflow-x: auto; }
.gb-export { display: inline-flex; align-items: center; gap: 5px; margin: 4px 0 2px; padding: 6px 12px; font: inherit; font-size: 12px; font-weight: 600; color: var(--text); background: var(--bg-raised); border: 1px solid var(--line); border-radius: 8px; cursor: pointer; }
.gb-export:hover { border-color: var(--accent); color: var(--accent); }
.gradebook { border-collapse: collapse; margin: 10px 0 4px; font-size: 12.5px; }
.gradebook th, .gradebook td { border: 1px solid var(--line); padding: 6px 9px; text-align: center; white-space: nowrap; }
.gradebook th { color: var(--text-dim); font-weight: 600; font-size: 11px; vertical-align: bottom; }
.gradebook .gb-col { display: block; max-width: 120px; overflow: hidden; text-overflow: ellipsis; }
.gradebook .gb-due { display: block; font-size: 10px; color: var(--text-dim); font-weight: 400; margin-top: 2px; }
.gradebook .gb-name { text-align: left; position: sticky; left: 0; background: var(--bg-card); font-weight: 600; }
.gb-cell { font-variant-numeric: tabular-nums; font-weight: 600; }
.gb-cell.ok { color: #7fce9b; }
.gb-cell.mid { color: #e6b450; }
.gb-cell.low { color: #f0a07a; }
.gb-cell.overdue { color: #f08a8a; font-weight: 600; font-size: 11px; }
.gb-cell.late::after { content: " ⏰"; font-size: 10px; }
.gb-cell:not(.ok):not(.mid):not(.low):not(.overdue) { color: var(--text-dim); }

/* student due-date badge in the library */
.lib-due { display: inline-block; margin-top: 3px; font-size: 10.5px; font-weight: 600; color: var(--accent); }
.lib-due.overdue { color: #f08a8a; }
.lib-locked { flex: none; font-size: 10.5px; font-weight: 600; color: var(--text-dim); border: 1px solid var(--line); border-radius: 999px; padding: 1px 7px; white-space: nowrap; }
.lib-row-locked { opacity: 0.6; }
.lib-row-locked:hover { opacity: 0.78; }

/* spaced-repetition "Due for review" panel */
.review-due { margin: 0 0 14px; padding: 10px; background: rgba(63,110,49,0.14); border: 1px solid rgba(120,160,100,0.35); border-radius: 12px; }
.review-head { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #9fbe8f; margin: 0 2px 8px; display: flex; align-items: center; gap: 6px; }
.review-count { background: #9fbe8f; color: #16210f; border-radius: 999px; padding: 0 7px; font-size: 11px; }
.review-item { display: flex; align-items: stretch; gap: 8px; width: 100%; background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px; margin-top: 6px; transition: border-color 0.15s; }
.review-item:hover { border-color: var(--accent); }
.review-open { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; text-align: left; background: none; border: 0; padding: 8px 11px; cursor: pointer; }
.review-title { font-size: 13px; font-weight: 600; color: var(--text); }
.review-sub { font-size: 11px; color: var(--text-dim); }
.review-done { flex: none; align-self: center; margin-right: 8px; background: rgba(63,110,49,0.25); border: 1px solid rgba(120,160,100,0.5); color: #cfe3c2; font-family: inherit; font-size: 11.5px; font-weight: 600; border-radius: 999px; padding: 5px 11px; cursor: pointer; white-space: nowrap; transition: background 0.15s, color 0.15s; }
.review-done:hover { background: #9fbe8f; color: #16210f; }
.review-done:disabled { opacity: 0.5; cursor: default; }

/* ============ LESSON EDITOR ============ */

.editor-overlay {
  position: fixed; inset: 0;
  background: rgba(10, 12, 16, 0.7);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px; z-index: 80;
}
.editor-panel {
  position: relative;                 /* anchor the top-right × close */
  width: min(720px, 100%);
  max-height: 88vh;
  display: flex; flex-direction: column;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}
/* the × sits above the head border, top-right, matching every other overlay */
.editor-panel > .auth-close { z-index: 2; }
.editor-head { padding: 20px 22px 14px; border-bottom: 1px solid var(--line); }
.editor-head h3 { font-family: var(--font-display); font-size: 20px; font-weight: 600; }
.editor-hint { display: block; margin-top: 4px; font-size: 12.5px; color: var(--text-dim); }
.editor-body { padding: 18px 22px; overflow-y: auto; }

.editor-field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 18px; }
.editor-field > span { font-size: 12px; color: var(--text-dim); }
.editor-field input, .editor-step textarea, .editor-board input, .editor-board textarea {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 9px;
  color: var(--text);
  font-family: inherit; font-size: 13.5px; line-height: 1.5;
  padding: 9px 11px;
  outline: none; width: 100%;
}
.editor-field input:focus, .editor-step textarea:focus, .editor-board input:focus, .editor-board textarea:focus { border-color: var(--accent); }
.editor-step textarea { resize: vertical; min-height: 56px; }
/* board-line field: a textarea so long lines / multi-line formulas are fully visible.
   auto-grows (JS) and the teacher can drag the corner to enlarge it further. */
.editor-board-text { flex: 1; min-width: 0; resize: vertical; overflow: hidden; white-space: pre-wrap; word-break: break-word; }
.editor-board-textrow { align-items: flex-start; } /* keep the kind picker + controls at the top edge when the field grows tall */

.editor-step {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 12px;
  background: var(--bg-raised);
}
.editor-step-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.editor-step-num {
  width: 22px; height: 22px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 50%; background: var(--accent); color: var(--on-accent);
  font-size: 11px; font-weight: 700;
}
.editor-step-head input { font-weight: 600; }
.editor-step-del, .editor-board-del, .editor-board-ins, .editor-board-move, .editor-step-ins {
  flex-shrink: 0; background: none; border: none; color: #5b636e;
  font-size: 16px; cursor: pointer; padding: 3px 7px; border-radius: 6px;
}
.editor-step-del:hover, .editor-board-del:hover { color: #f08a8a; background: rgba(240,138,138,0.12); }
.editor-board-ins:hover, .editor-step-ins:hover { color: var(--accent); background: var(--accent-soft); }
.editor-board-move { font-size: 10px; padding: 3px 5px; }
.editor-board-move:hover { color: var(--accent); background: var(--accent-soft); }
.editor-insert-menu {
  position: fixed; z-index: 120; min-width: 132px; padding: 4px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px;
  display: flex; flex-direction: column; box-shadow: 0 10px 28px rgba(0,0,0,0.45);
}
.editor-insert-menu button {
  background: none; border: none; text-align: left; color: var(--text);
  font: inherit; font-size: 13px; padding: 8px 12px; border-radius: 6px; cursor: pointer;
}
.editor-insert-menu button:hover { background: var(--accent-soft); color: var(--accent); }
.editor-sub { font-size: 11px; color: var(--text-dim); margin: 8px 0 5px; }
.editor-board { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
.editor-board .tag {
  flex-shrink: 0; font-size: 9.5px; font-weight: 700; text-transform: uppercase;
  color: var(--text-dim); background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 5px; padding: 3px 6px; min-width: 48px; text-align: center;
}
.editor-board input { flex: 1; min-width: 0; }
.editor-kind {
  flex-shrink: 0; width: 86px; font-size: 11px; padding: 6px 6px;
  background: var(--bg-card); color: var(--text-dim); border: 1px solid var(--line);
  border-radius: 6px; text-transform: capitalize; cursor: pointer;
}
.editor-kind:focus { border-color: var(--accent); }
.editor-board-kept .editor-kept-label {
  flex: 1; min-width: 0; font-size: 12.5px; color: var(--text-dim); font-style: italic;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.editor-add-line, .editor-add-step {
  background: transparent; border: 1px dashed var(--line); color: var(--text-dim);
  border-radius: 7px; padding: 6px 12px; font-size: 12.5px; cursor: pointer;
  transition: color .15s, border-color .15s;
}
.editor-add-line { margin: 2px 0 2px 55px; }
/* per-item timing controls in the editor (📌 stays / ⏸ pause to explore) */
.editor-item-opts { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; }
.editor-item-opt { font-size: 12px; color: var(--muted); display: inline-flex; align-items: center; gap: 5px; }
.editor-item-opt select {
  background: var(--panel-2, #1a1f27); color: var(--text);
  border: 1px solid var(--line); border-radius: 7px;
  padding: 4px 6px; font-size: 12px;
}

/* 🎙 record-your-own narration row under each step's script */
.editor-rec-row { display: flex; align-items: center; gap: 8px; margin: 4px 0 10px; }
.editor-rec-btn {
  background: none; border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); padding: 5px 12px; font-size: 12.5px; cursor: pointer;
}
.editor-rec-btn:hover { border-color: var(--accent); color: var(--accent); }
.editor-rec-play, .editor-rec-del {
  background: none; border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); padding: 5px 9px; font-size: 12px; cursor: pointer;
}
.editor-rec-play:hover { color: var(--accent); border-color: var(--accent); }
.editor-rec-del:hover { color: #e05656; border-color: #e05656; }
.editor-rec-status { font-size: 12px; color: var(--accent); }

.editor-add-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 2px 0 2px 55px; }
.editor-add-row .editor-add-line { margin: 0; }
.editor-board-struct { display: flex; align-items: center; gap: 7px; }
.editor-board-struct input { flex: 1; min-width: 0; }
.editor-board-struct .editor-graph-expr { flex: 1.6; font-family: var(--font-mono, monospace); }
.editor-fig-thumb {
  width: 46px; height: 34px; flex-shrink: 0; object-fit: cover;
  border-radius: 6px; border: 1px solid var(--line); background: var(--bg-card);
}
.editor-add-step { display: block; width: 100%; margin: 4px 0 2px; padding: 10px; font-size: 13px; }
.editor-add-line:hover, .editor-add-step:hover { color: var(--accent); border-color: var(--accent); }
.editor-actions {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 14px 22px; border-top: 1px solid var(--line);
}
.editor-actions .btn { flex: 0 0 auto; padding: 11px 22px; font-size: 14px; }

@media (max-width: 640px) {
  /* Full-screen on phones. Stretch (don't center) and size to the DYNAMIC viewport:
     iOS `100vh` is the address-bar-hidden height, so a centered 100vh panel is taller
     than the visible area and its top (title + × close) gets pushed up behind Safari's
     address bar. `100dvh` fills the *visible* height exactly, keeping the header on-screen. */
  .editor-overlay { padding: 0; align-items: stretch; justify-content: stretch; }
  .editor-panel {
    height: 100vh; height: 100dvh;         /* dvh wins where supported */
    max-height: 100vh; max-height: 100dvh;
    border-radius: 0; width: 100%;
  }
  /* header stays pinned at the top of the panel so the × is always reachable */
  .editor-head { position: sticky; top: 0; z-index: 5; background: var(--bg-card); }
}

/* responsive */
@media (max-width: 880px) {
  .board-resizer, .library-resizer { display: none; }
  /* The lesson plan used to be display:none below 880px — i.e. on every phone, which is
     most students. They lost both "where am I in this lesson" and the ability to go back
     to a step they didn't follow. Same list, laid out as a scrolling strip above the
     board: ~46px of height, and tapping a step still jumps to it. */
  .classroom-body { flex-direction: column; }
  .step-panel {
    width: 100%;
    flex: 0 0 auto;
    padding: 6px 10px;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;   /* scrolls the strip, never the page behind it */
    border-bottom: 1px solid var(--line);
    scrollbar-width: none;
  }
  .step-panel::-webkit-scrollbar { display: none; }
  .step-panel h3 { display: none; }         /* the strip is self-evident; the label isn't worth the row */
  .step-list { flex-direction: row; gap: 6px; }
  .step-list li {
    flex: 0 0 auto;
    max-width: 45vw;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    border-radius: 999px;
    padding: 5px 11px 5px 6px;
  }
  /* the phone plan is a horizontal strip of pills — a rule "above" and an indent
     would land sideways, so the question rows keep only weight and their badge */
  .step-list li.q-open { margin-top: 0; padding-top: 5px; border-top: 0; align-items: center; }
  .step-list li.q-sub { padding-left: 6px; }
  .step-list li.q-sub .num { margin-left: 2px; }
  .step-list li.q-answer .num { margin-left: 0; }
  #setup-screen { flex-direction: column; }
  .setup-main { padding: 40px 22px 24px; }
  .library-panel {
    flex: 0 0 auto;
    height: auto;
    max-height: 46vh;
    border-left: none;
    border-top: 1px solid var(--line);
  }
}

/* phones */
@media (max-width: 640px) {
  /* the clip panel takes the full board width — a half-width video is unwatchable
     on a 380px screen; readability beats seeing the chalk behind it */
  .video-panel { left: 8px; right: 8px; top: 8px; width: auto; }
  /* interactive graphs/manipulatives too: 46%-of-board is unusable for sliders on a
     phone — give the panel the full width (still draggable/closable) */
  .manip { left: 8px; right: 8px; top: 8px; width: auto; max-width: none; }
  .explore-bar { bottom: 76px; font-size: 13px; gap: 8px; padding-left: 12px; }
  /* citation readability bump (the caption's is in the static-caption block below) */
  .source-cite { font-size: 12.5px; }
  .setup-main { padding: 26px 16px 18px; }
  .brand h1 { font-size: 26px; }

  /* ---- STUDENT HOME on a phone -------------------------------------------------
     Measured at 375x812 before this: the brand block 104px, the greeting + account
     buttons 200px (the buttons alone wrapped onto THREE rows), the three stat cards
     133px — so the subject chips started at 559px and the Lessons/Practice/Exams tabs
     at 722px, with the actual lesson list below the fold at 849px. A student opened
     the app and saw a logo, a slogan, their name and three numbers.
     The subjects and their lessons are what the student came for; everything above is
     furniture and is sized accordingly. */
  #setup-brand .tagline { display: none; }         /* marketing copy, to a signed-in student */
  #setup-brand { margin-bottom: 14px; }
  .sh-greeting { font-size: 22px; }
  .sh-sub { font-size: 13.5px; }
  .sh-headings { min-width: 0; }                   /* 240px min-width forced the topbar to wrap */
  .sh-header { gap: 10px; align-items: center; }

  /* One row: [lang] 🔗 🌗 💬 [Sign out]. The labels are dropped, not the buttons —
     each keeps its title/aria-label, so the meaning survives for a screen reader. */
  .sh-topbar { flex-wrap: nowrap; gap: 6px; width: 100%; justify-content: flex-start; }
  /* height too: the select rendered 25px tall next to 40px buttons — under the tap-target
     minimum, and visibly misaligned in the row */
  .sh-topbar .sh-lang { min-width: 0; flex: 0 1 96px; font-size: 13px; height: 40px; }
  .sh-iconbtn { height: 40px; padding: 0 10px; flex: 0 0 auto; }
  /* Icon-only via font-size:0 + a pseudo-element, NOT by hiding a span. #sh-link has no
     span — its whole label is one text node — and every translation of btnMyLink embeds
     the 🔗 in the string itself, so there is no markup seam to hide and no way to keep the
     icon by hiding part of the text. Collapsing the type and drawing the icon in ::before
     works whatever language is loaded, and the text stays in the accessibility tree, so
     the button is still announced as "My sign-in link". */
  #sh-link, #sh-feedback, #sh-theme {
    padding: 0; width: 44px; justify-content: center; font-size: 0; gap: 0;
  }
  #sh-link::before     { content: "🔗"; font-size: 17px; }
  #sh-feedback::before { content: "💬"; font-size: 17px; }
  #sh-theme::before    { content: "🌗"; font-size: 17px; }
  .sh-signout { margin-left: auto; }               /* the one destructive action sits apart */

  /* Stats: keep all three, at a size that suits a glance rather than a dashboard. */
  .sh-stats { gap: 8px; }
  .sh-stat { padding: 10px 8px; border-radius: 12px; }
  .sh-stat b { font-size: 22px; margin-bottom: 2px; }
  .sh-stat span { font-size: 10px; }
  .options-grid { grid-template-columns: 1fr; }   /* one selector per row */
  .setup-actions { flex-direction: column; }
  .setup-actions .btn { width: 100%; }
  .library-panel { padding: 18px 14px 14px; }

  /* camera-first: on phones, lead with "Snap a photo" as the primary capture */
  .setup-card { display: flex; flex-direction: column; }
  .brand { order: -2; }
  #photo-btn {
    order: -1; width: 100%; justify-content: center; gap: 8px;
    padding: 15px; font-size: 15px; font-weight: 600; margin: 0 0 10px;
    background: var(--accent-soft); border-color: var(--accent); color: var(--text);
  }
  #photo-btn svg { width: 19px; height: 19px; }
  .drop-zone { padding: 18px 14px; }
  .drop-zone p { font-size: 13px; }

  /* Classroom header: ONE row — [←] title … [transcript] [print]
     It used to wrap onto three, because .header-spacer forced a full-width line break that
     pushed every icon button below the title. Measured on a 375x812 phone that header was
     159px tall for three buttons and a title, and with the step chips it spent 228px before
     the board even started — which is the "top of the chalkboard is buried" complaint.
     Collapsing it to a single row gives that back to the board. */
  .classroom-header { flex-wrap: nowrap; gap: 8px; padding: 8px 10px; }
  .header-spacer { display: none; }              /* was the line break; a nowrap row needs none */
  .lesson-meta { gap: 8px; flex-wrap: nowrap; flex: 1 1 auto; min-width: 0; align-items: center; }
  .lesson-meta h2 { font-size: 15px; min-width: 0; }   /* min-width:0 so the ellipsis can engage */
  /* The pills cost ~90px of a 375px row and repeat what the title and the class already say.
     The title is the one thing worth the width here. */
  .standards-row, .level-pill, .subject-pill, .concept-pill { display: none; }
  .classroom-header .icon-btn { flex: 0 0 auto; }

  /* board fills the width; controls become a tap-friendly two-row layout */
  .board-area { padding: 10px 8px 10px; }
  .controls-row { flex-wrap: wrap; justify-content: center; gap: 8px; }
  .ctl-btn { width: 42px; height: 42px; }       /* bigger tap targets */
  .ctl-play { width: 50px; height: 50px; }
  .ctl-spacer { display: none; }
  .speed-ctl span { display: none; }            /* labels hog space */
  .speed-ctl.voice-ctl { order: 3; flex: 1 1 100%; }
  .voice-ctl select { max-width: none; width: 100%; }
  .speed-ctl input[type="range"] { width: 90px; }

  /* caption + citation sit below the board (not overlaying it) so they never cover chalk */
  .board-footer {
    position: static;
    background: none;
    padding-bottom: 4px;
  }
  .caption {
    text-shadow: none;
    color: var(--text);
    font-size: 15px;      /* readability on small screens — was 13px */
    line-height: 1.55;
    padding: 10px 4px 0;
    min-height: calc(2 * 1.55em);   /* two lines at this line-height (clamp is global above) */
  }
  .source-cite { text-shadow: none; padding: 0 4px; }
}

/* Landscape phones / short viewports: reclaim vertical space for the board. The default
   chrome (header chips + roomy controls) leaves almost no height for the board on a
   ~375px-tall landscape screen, so the caption used to swallow it. Shrink the header,
   drop the standards chips, tighten the controls, and reduce the board's height reserve
   so the blackboard is as big as the screen allows. */
@media (min-width: 641px) and (max-height: 560px) {
  .classroom-header { padding: 6px 12px; }
  .lesson-meta h2 { font-size: 15px; }
  .standards-row, .level-pill, .concept-pill { display: none; }
  .board-area { padding: 6px 10px 4px; }
  .controls { width: min(100%, calc((100vh - 116px) * 1.6)); width: min(100%, calc((100dvh - 116px) * 1.6)); margin-top: 6px; }
  .caption { font-size: 13.5px; min-height: calc(2 * 1.45em); padding-top: 6px; }
}

/* "data saver" hint chip on the home screen */
.saver-row {
  display: flex; align-items: center; gap: 8px;
  margin-top: 14px;
  font-size: 12.5px; color: var(--text-dim);
}
.saver-row input { accent-color: var(--accent); width: 16px; height: 16px; }
.saver-row label { cursor: pointer; }

.privacy-note {
  margin-top: 14px;
  font-size: 11.5px; line-height: 1.5;
  color: #6b7682;
}
.privacy-note a { color: var(--text-dim); text-decoration: underline; }
.privacy-note a:hover { color: var(--text); }

/* ============ LANDING PAGE ============ */

.landing {
  background:
    radial-gradient(1100px 560px at 78% -12%, rgba(232, 176, 75, 0.07), transparent 60%),
    radial-gradient(920px 660px at -8% 110%, rgba(110, 140, 190, 0.06), transparent 60%),
    var(--bg);
  overflow-x: hidden;
}

/* nav */
.lp-nav {
  max-width: 1120px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px 32px;
  /* space-between alone lets the two sides TOUCH once the row runs out of slack — measured,
     the brand (170px) and the links (302px) plus 64px of padding collide at 536px wide,
     while the links only started hiding at 520. A gap keeps them apart at every width. */
  gap: 16px;
}
/* min-width:0 + ellipsis so a long BRAND_NAME can never push the nav apart. BRAND_NAME is
   configurable up to 40 characters, and at 40 this row would break at ANY viewport width. */
.lp-brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
.lp-brand .brand-mark { width: 40px; height: 40px; font-size: 21px; border-radius: 11px; }
.lp-brand-name { font-family: var(--font-display); font-weight: 600; font-size: 20px; letter-spacing: .2px;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the actions never shrink — the brand truncates instead, because a half-cut button is
   unusable while a truncated word is still readable */
.lp-nav-links { display: flex; align-items: center; gap: 26px; flex: 0 0 auto; }
.lp-navlink { color: var(--text-dim); text-decoration: none; font-size: 14.5px; transition: color .15s; }
.lp-navlink:hover { color: var(--text); }
.lp-link-btn { background: none; border: none; color: var(--text-dim); font-size: 14.5px; padding: 0; transition: color .15s; }
.lp-link-btn:hover { color: var(--text); }
.lp-nav-cta { padding: 9px 18px !important; font-size: 14px !important; }

/* hero */
.lp-hero {
  max-width: 1120px; margin: 0 auto;
  padding: 60px 32px 48px;
  display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 60px; align-items: center;
}
.lp-kicker {
  display: inline-block; font-size: 12px; letter-spacing: .15em; text-transform: uppercase;
  color: var(--accent); background: var(--accent-soft);
  padding: 6px 13px; border-radius: 999px; margin-bottom: 22px;
}
.lp-title {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(34px, 5vw, 50px); line-height: 1.06; letter-spacing: -0.6px;
  color: var(--text); margin-bottom: 20px;
  /* The headline now carries three clauses instead of one. At 56px it ran to six lines in
     the hero column and pushed the CTA below the fold on a 1280x800 laptop. balance stops
     the last line being one orphaned word. */
  text-wrap: balance;
}
.lp-sub { font-size: 17.5px; line-height: 1.6; color: var(--text-dim); max-width: 31em; margin-bottom: 30px; }
.lp-cta-row { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 24px; }
.lp-cta { padding: 13px 24px !important; font-size: 15.5px !important; display: inline-flex; align-items: center; gap: 9px; }
.lp-trust { font-size: 13px; color: var(--text-dim); letter-spacing: .015em; opacity: .85; }

/* hero board visual */
.lp-hero-visual { position: relative; display: flex; justify-content: center; }
.lp-board {
  position: relative; width: 100%; max-width: 430px; aspect-ratio: 4 / 3;
  border-radius: 16px; overflow: hidden;
  background:
    radial-gradient(120px 80px at 80% 18%, rgba(255,255,255,0.05), transparent 70%),
    radial-gradient(140px 90px at 15% 85%, rgba(255,255,255,0.04), transparent 70%),
    linear-gradient(158deg, #213328, #15231c);
  border: 9px solid #3a2d1f;
  box-shadow: 0 34px 64px -26px rgba(0,0,0,.65), inset 0 0 70px rgba(0,0,0,.4);
  animation: lp-float 7s ease-in-out infinite;
}
@keyframes lp-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
.lp-board-chalk {
  position: absolute; inset: 0; padding: 24px 28px;
  font-family: "Caveat", cursive; color: var(--chalk);
}
.lp-chalk-kicker { font-size: 20px; opacity: .8; }
.lp-chalk-formula { display: block; font-size: 42px; line-height: 1; margin-top: 6px; }
.lp-chalk-tri { position: absolute; left: 26px; bottom: 26px; width: 150px; height: 112px; color: var(--chalk); opacity: .92; }
.lp-chalk-note { position: absolute; right: 26px; bottom: 64px; font-size: 19px; opacity: .82; }
.lp-board-tray {
  position: absolute; left: 0; right: 0; bottom: 0; height: 12px;
  background: linear-gradient(#2a2017, #1c150e);
  display: flex; align-items: center; gap: 8px; padding-left: 18px;
}
.lp-board-tray i { display: block; width: 26px; height: 5px; border-radius: 3px; background: #d9d4c6; opacity: .85; }
.lp-board-tray i:last-child { width: 16px; background: #e8b04b; opacity: .7; }
.lp-caption-chip {
  position: absolute; bottom: -16px; left: 50%; transform: translateX(-50%);
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 999px;
  padding: 9px 17px; font-size: 13px; color: var(--text-dim); white-space: nowrap;
  box-shadow: 0 14px 28px -12px rgba(0,0,0,.55);
}
.lp-caption-chip em { color: var(--text); font-style: italic; }

/* feature + how sections */
.lp-section { max-width: 1120px; margin: 0 auto; padding: 72px 32px; }
.lp-h2 {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(26px, 3.2vw, 36px); letter-spacing: -0.3px;
  text-align: center; margin-bottom: 46px;
}
.lp-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.lp-card {
  background: linear-gradient(180deg, var(--bg-card), var(--bg-raised));
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 26px 24px; transition: transform .18s ease, border-color .18s ease;
}
.lp-card:hover { transform: translateY(-3px); border-color: #3c4450; }
.lp-card-ico {
  width: 42px; height: 42px; border-radius: 11px; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); margin-bottom: 16px;
}
.lp-card h3 { font-family: var(--font-display); font-weight: 600; font-size: 18px; margin-bottom: 8px; }
.lp-card p { font-size: 14.5px; line-height: 1.55; color: var(--text-dim); }

/* how it works */
.lp-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; list-style: none; }
.lp-step-n {
  display: grid; place-items: center; width: 36px; height: 36px;
  border: 1px solid var(--line); border-radius: 999px;
  font-family: var(--font-display); font-size: 16px; color: var(--accent);
  margin-bottom: 16px;
}
.lp-step h3 { font-family: var(--font-display); font-weight: 600; font-size: 17.5px; margin-bottom: 7px; }
.lp-step p { color: var(--text-dim); font-size: 14.5px; line-height: 1.55; }

/* final cta */
.lp-final { max-width: 760px; margin: 0 auto; padding: 56px 32px 24px; text-align: center; }
.lp-final h2 { font-family: var(--font-display); font-weight: 600; font-size: clamp(28px, 3.6vw, 40px); letter-spacing: -0.4px; margin-bottom: 13px; }
.lp-final p { color: var(--text-dim); font-size: 16.5px; margin-bottom: 26px; }
.lp-final-cta { justify-content: center; margin-bottom: 0; }

/* footer */
.lp-footer {
  max-width: 1120px; margin: 0 auto; padding: 40px 32px 48px;
  border-top: 1px solid var(--line); color: var(--text-dim); font-size: 13.5px;
}
.lp-footer-main { display: flex; align-items: flex-start; justify-content: space-between; gap: 40px; flex-wrap: wrap; }
.lp-footer-brand { display: flex; flex-direction: column; gap: 10px; max-width: 320px; }
.lp-foot-brand { display: inline-flex; align-items: center; gap: 9px; color: var(--text); font-weight: 600; }
.lp-foot-note { color: var(--text-dim); line-height: 1.5; }
.brand-mark-sm { width: 26px; height: 26px; font-size: 14px; border-radius: 8px; }
.lp-footer-cols { display: flex; gap: 56px; flex-wrap: wrap; }
.lp-footer-col { display: flex; flex-direction: column; gap: 10px; }
.lp-footer-col h4 { margin: 0 0 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text); }
.lp-footlink {
  display: inline-block; text-align: left; padding: 0; background: none; border: 0;
  color: var(--text-dim); text-decoration: none; font-family: inherit; font-size: 13.5px; cursor: pointer;
  transition: color 0.15s;
}
.lp-footlink:hover { color: var(--text); }
.lp-footer-bottom {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  margin-top: 32px; padding-top: 18px; border-top: 1px solid var(--line); font-size: 12.5px;
}

/* site content dialog (About / Contact / Terms) */
.site-overlay {
  position: fixed; inset: 0; z-index: 95;
  background: rgba(8, 10, 14, 0.72); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.site-modal {
  position: relative; width: min(640px, 100%); max-height: 84vh; overflow-y: auto;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 16px;
  padding: 30px 32px; box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
}
.site-close {
  position: absolute; top: 14px; right: 16px; width: 32px; height: 32px;
  background: none; border: 0; color: var(--text-dim); font-size: 24px; line-height: 1; cursor: pointer; border-radius: 8px;
}
.site-close:hover { color: var(--text); background: var(--bg-raised); }
.site-title { margin: 0 0 16px; font-family: var(--font-display); font-size: 24px; font-weight: 600; color: var(--text); }
.site-body { color: var(--text-dim); font-size: 15px; line-height: 1.65; white-space: pre-wrap; }

@media (max-width: 900px) {
  .lp-hero { grid-template-columns: 1fr; gap: 44px; padding-top: 32px; }
  .lp-hero-visual { order: -1; }
  .lp-board { max-width: 380px; }
  .lp-grid, .lp-steps { grid-template-columns: 1fr; }
  .lp-nav-links { gap: 16px; }
  .lp-navlink { display: none; }
}
/* Between 521 and 536px the brand and the nav actually overlapped: the anchor links go at
   900px, but "Ask the tutor" and "Sign in" survived to 520. Drop the marketing link first
   and keep Sign in — a teacher needs the way in far more than the demo hook, and "Open
   studio" is not obviously a sign-in door. */
@media (max-width: 700px) { #tutor-open-nav { display: none; } }
@media (max-width: 520px) {
  .lp-nav { padding: 16px 20px; }
  .lp-link-btn { display: none; }
  .lp-section { padding: 48px 20px; }
  .lp-hero { padding-left: 20px; padding-right: 20px; }
  .lp-cta { width: 100%; justify-content: center; }
  .lp-footer { flex-direction: column; align-items: flex-start; gap: 10px; }
}

/* ============ ACCESSIBLE TRANSCRIPT ============ */
.transcript-card { width: min(680px, 100%); max-height: 82vh; display: flex; flex-direction: column; }
.transcript-body { overflow-y: auto; margin-top: 8px; padding-right: 6px; }
.transcript-body .tr-step { padding: 10px 0; border-bottom: 1px solid var(--line); }
.transcript-body .tr-step h4 { font-size: 14px; margin: 0 0 6px; color: var(--text); }
.transcript-body .tr-narr { font-size: 13.5px; color: var(--text-dim); margin: 0 0 6px; line-height: 1.55; }
.transcript-body .w-h { font-weight: 600; margin: 4px 0; }
.transcript-body .w-em { font-style: italic; margin: 4px 0; }
.transcript-body .w-bullet { margin: 2px 0 2px 14px; }
.transcript-body .w-math { font-family: ui-monospace, "Cambria Math", serif; margin: 4px 0; }
.transcript-body .w-code { font-family: ui-monospace, monospace; font-size: 12.5px; background: var(--bg-raised); padding: 8px 10px; border-radius: 8px; white-space: pre-wrap; }
.transcript-body .w-cap { color: var(--text-dim); font-style: italic; margin: 4px 0; }
.transcript-body .w-table { border-collapse: collapse; margin: 6px 0; font-size: 13px; }
.transcript-body .w-table th, .transcript-body .w-table td { border: 1px solid var(--line); padding: 4px 9px; text-align: center; }
.transcript-body .w-table th { font-weight: 700; color: var(--accent); }
.editor-fig-tools { display: inline-flex; gap: 3px; align-items: center; }
.editor-fig-btn { min-width: 26px; height: 26px; padding: 0 6px; border: 1px solid var(--line); background: var(--bg-raised); color: var(--text); border-radius: 6px; cursor: pointer; font-size: 14px; line-height: 1; }
.editor-fig-btn:hover { border-color: var(--accent); }
.transcript-body .w-fig img { max-width: 100%; border-radius: 8px; margin: 6px 0; }
.transcript-body .w-q-text { font-weight: 600; margin: 8px 0 4px; }
.transcript-body .tr-opts { margin: 0 0 6px 18px; color: var(--text-dim); }

/* respect users who prefer reduced motion — quiet non-essential UI animation */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
}

/* ============ PRINTABLE WORKSHEET ============ */
/* the print container lives in the DOM only while printing; hidden on screen */
.print-root { display: none; }
@media print {
  @page { margin: 16mm 15mm; }
  html, body { background: #fff !important; }
  body > *:not(.print-root) { display: none !important; }
  .print-root {
    display: block !important;
    color: #111; background: #fff;
    font-family: Georgia, "Times New Roman", serif; font-size: 11.5pt; line-height: 1.5;
  }
  .print-root h1 { font-size: 20pt; margin: 0 0 2pt; }
  .print-root h2 { font-size: 14pt; margin: 16pt 0 6pt; border-bottom: 2px solid #000; padding-bottom: 3pt; }
  .print-root .w-meta { color: #555; margin: 0; font-size: 10.5pt; }
  .print-root .w-name { margin: 10pt 0 4pt; font-size: 11pt; }
  .print-root .w-top { border-bottom: 1.5px solid #000; padding-bottom: 8pt; margin-bottom: 6pt; }
  .print-root .w-step { margin: 0 0 10pt; break-inside: avoid; }
  .print-root .w-step h3 { font-size: 12pt; margin: 9pt 0 3pt; }
  .print-root .w-narr { margin: 2pt 0; }
  .print-root .w-h { font-weight: bold; margin: 3pt 0; }
  .print-root .w-em { font-style: italic; margin: 3pt 0; }
  .print-root .w-bullet { margin: 1pt 0 1pt 12pt; }
  .print-root .w-math { font-family: "Cambria Math", "Georgia", serif; margin: 3pt 0; font-size: 12pt; }
  .print-root .w-code { font-family: "Courier New", monospace; font-size: 9.5pt; background: #f3f3f3; padding: 6pt; white-space: pre-wrap; border-radius: 3pt; }
  .print-root .w-cap { color: #555; font-style: italic; margin: 3pt 0; }
  .print-root .w-table { border-collapse: collapse; margin: 4pt 0; font-size: 10pt; }
  .print-root .w-table th, .print-root .w-table td { border: 1px solid #888; padding: 3pt 6pt; text-align: center; }
  .print-root .w-table th { font-weight: 700; }
  .print-root .w-fig { margin: 4pt 0; }
  .print-root .w-fig img { max-width: 70%; max-height: 70mm; }
  .print-root .w-fig figcaption { color: #555; font-size: 10pt; font-style: italic; }
  .print-root .w-quiz, .print-root .w-key { break-before: page; }
  .print-root .w-teacher { font-size: 10pt; font-weight: normal; color: #555; }
  .print-root .w-q { margin: 0 0 12pt; break-inside: avoid; }
  .print-root .w-q-text { font-weight: bold; margin: 9pt 0 3pt; }
  .print-root .w-opts { margin: 0 0 4pt 20pt; }
  .print-root .w-opts li { margin: 2pt 0; }
  .print-root .w-ans { margin: 5pt 0; color: #333; }
  .print-root .w-key ol { margin-left: 18pt; }
  .print-root .w-key li { margin: 3pt 0; }
  .print-root .w-foot { margin-top: 16pt; color: #999; font-size: 9pt; text-align: center; }
  /* student login cards — two per row, cut along the borders */
  .print-root .rc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6mm; margin-top: 6mm; }
  .print-root .rc-card { border: 1.5px dashed #999; border-radius: 3mm; padding: 8mm 6mm; text-align: center; break-inside: avoid; }
  .print-root .rc-class { margin: 0 0 3mm; font-size: 9.5pt; color: #555; text-transform: uppercase; letter-spacing: 0.5pt; }
  .print-root .rc-name { margin: 0 0 6mm; font-size: 19pt; font-weight: 700; }
  .print-root .rc-label { margin: 0 0 1mm; font-size: 9.5pt; color: #555; }
  .print-root .rc-link { margin: 0 0 5mm; font-family: "Courier New", monospace; font-size: 10.5pt; word-break: break-all; }
  .print-root .rc-note { margin: 0; font-size: 9pt; color: #666; }
}

/* ============ SOCRATIC TUTOR (student's own problem) ============ */
.tutor-overlay {
  position: fixed; inset: 0; z-index: 150; display: flex; align-items: center; justify-content: center;
  padding: 20px; background: rgba(0, 0, 0, 0.6);
}
.tutor-overlay[hidden] { display: none; }
.tutor-panel {
  width: min(820px, 100%); height: min(880px, 94vh); display: flex; flex-direction: column;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 16px; overflow: hidden;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.tutor-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 14px 18px; border-bottom: 1px solid var(--line); }
.tutor-head strong { font-size: 16px; }
.tutor-head span { display: block; font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.tutor-close { background: none; border: none; color: var(--text-dim); font-size: 22px; line-height: 1; cursor: pointer; padding: 0 4px; }
.tutor-close:hover { color: var(--text); }
.tutor-messages { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.tutor-msg { max-width: 85%; padding: 10px 14px; border-radius: 14px; font-size: 14px; line-height: 1.5; white-space: pre-wrap; word-wrap: break-word; }
.tutor-user { align-self: flex-end; background: var(--accent); color: #1a1a1a; border-bottom-right-radius: 4px; }
.tutor-assistant { align-self: flex-start; background: var(--bg-raised); color: var(--text); border: 1px solid var(--line); border-bottom-left-radius: 4px; }
.tutor-muted { opacity: 0.85; font-style: italic; }
.tutor-input { display: flex; align-items: flex-end; gap: 8px; padding: 14px; border-top: 1px solid var(--line); }
.tutor-input textarea { flex: 1; resize: none; background: var(--bg); border: 1px solid var(--line); color: var(--text); border-radius: 12px; padding: 13px 15px; font: inherit; font-size: 15px; line-height: 1.4; min-height: 52px; max-height: 160px; }
.tutor-input textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.tutor-input .btn { flex-shrink: 0; }
#tutor-send { flex: 0 0 auto; padding: 13px 22px; }
@media (max-width: 640px) { .tutor-overlay { padding: 0; } .tutor-panel { height: 100vh; border-radius: 0; } }

/* tutor's own chalkboard (working sketched as it guides) */
.tutor-board-wrap { padding: 12px 14px 0; flex-shrink: 0; }
.tutor-board-wrap canvas {
  width: 100%; height: auto; display: block; border-radius: 10px;
  max-height: 46vh; object-fit: contain;          /* big board, but leave room for the chat */
  border: 1px solid var(--line); background: #1e2c1a;
}

/* tutor voice + photo controls */
.tutor-head-actions { display: flex; align-items: center; gap: 8px; }
.tutor-speak {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px;
  background: var(--bg); border: 1px solid var(--line); color: var(--text-dim);
  border-radius: 999px; font-size: 12px; cursor: pointer;
}
.tutor-speak:hover { border-color: var(--accent); color: var(--accent); }
.tutor-speak.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.tutor-iconbtn {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; background: var(--bg); border: 1px solid var(--line);
  color: var(--text-dim); border-radius: 10px; cursor: pointer;
}
.tutor-iconbtn:hover { border-color: var(--accent); color: var(--accent); }
.tutor-iconbtn.listening { border-color: #e0674f; color: #e0674f; animation: tutorPulse 1.1s ease-in-out infinite; }
@keyframes tutorPulse { 0%,100% { box-shadow: 0 0 0 0 rgba(224,103,79,0.5); } 50% { box-shadow: 0 0 0 6px rgba(224,103,79,0); } }

#setup-brand { cursor: pointer; border-radius: 10px; }
#setup-brand:hover .brand-text h1 { color: var(--accent); }

/* tutor's own interactive manipulative (live slider graph in the chat panel) */
.tutor-manip { padding: 10px 12px 0; }
.tutor-manip[hidden] { display: none; }
.tutor-manip canvas {
  width: 100%; height: auto; display: block; border-radius: 10px;
  max-height: 44vh; object-fit: contain;          /* bounded so the chat stays usable */
  border: 1px solid var(--line); background: #1e2c1a;
}
.tutor-manip .manip-title { font-size: 12px; color: var(--text-dim); margin: 0 2px 6px; }
.tutor-manip .manip-controls { margin-top: 8px; }
/* +/- stepper rows sit side-by-side (not stacked) so they don't crowd the chat */
.manip-controls.has-steppers { flex-direction: row; flex-wrap: wrap; gap: 8px 16px; }
.manip-controls.has-steppers .manip-stepper { flex: 0 0 auto; }
.manip-controls.has-steppers .manip-name { width: auto; min-width: 20px; }

/* dragging geometry vertices on touch shouldn't scroll the page */
#manip-canvas, #tutor-manip-canvas { touch-action: none; }

/* +/- steppers for block manipulatives (base-10, algebra tiles) */
.manip-stepper .manip-step {
  width: 30px; height: 28px; flex-shrink: 0;
  background: var(--bg); border: 1px solid var(--line); color: var(--accent);
  border-radius: 7px; font-size: 17px; line-height: 1; cursor: pointer;
}
.manip-stepper .manip-step:hover { border-color: var(--accent); }
.manip-stepper .manip-val { min-width: 26px; text-align: center; }

/* ✨ Add interactive — describe-a-visual input + live preview in the editor */
.editor-ai-add { display: flex; gap: 8px; margin: 8px 0 4px; flex-wrap: wrap; align-items: center; }
.editor-ai-add input {
  flex: 1; min-width: 220px; background: var(--bg); border: 1px solid var(--accent);
  color: var(--text); border-radius: 9px; padding: 10px 12px; font: inherit; font-size: 14px;
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.editor-ai-add .btn { flex-shrink: 0; padding: 9px 16px; }
.editor-board-col { flex-direction: column; align-items: stretch; }
.editor-kept-head { display: flex; align-items: center; gap: 8px; }
.editor-preview { margin: 8px 0 2px; }
.editor-preview .manip-title { font-size: 12px; color: var(--text-dim); margin: 0 2px 6px; }
.editor-preview-canvas {
  width: 100%; height: auto; max-height: 34vh; display: block; border-radius: 10px;
  border: 1px solid var(--line); background: #1e2c1a; touch-action: none;
}
/* static thumbnail of a chalk sketch — small, so the teacher can eyeball + cut it */
.editor-sketch-canvas {
  width: 240px; max-width: 100%; height: auto; display: block;
  border-radius: 10px; border: 1px solid var(--line);
}

/* ============ NATIVE APP (Capacitor) ============ */
/* `native-app` is set on <html> only inside the native WebView (native.js), so none
   of this affects the plain web. Small touches that make the WebView feel like a
   real app rather than a page in a browser. */
html.native-app {
  -webkit-tap-highlight-color: transparent;     /* no grey box flashing on every tap */
  overscroll-behavior: none;                     /* no rubber-band bounce revealing the bg */
}
/* app chrome isn't text — don't let long-presses select it; real content stays selectable */
html.native-app, html.native-app body { -webkit-user-select: none; user-select: none; }
html.native-app input, html.native-app textarea, html.native-app [contenteditable],
html.native-app .caption, html.native-app .tutor-msg, html.native-app .editor-board-text {
  -webkit-user-select: text; user-select: text;
}
/* keep top chrome + bottom controls clear of the status bar / gesture nav when the
   device reports safe-area insets (edge-to-edge displays, notches). 0 where absent. */
html.native-app .lp-nav { padding-top: max(16px, env(safe-area-inset-top)); }
html.native-app .classroom-header { padding-top: max(10px, env(safe-area-inset-top)); }
html.native-app .tutor-input { padding-bottom: max(10px, env(safe-area-inset-bottom)); }

/* first-run teacher checklist (auto-hides when every step is done or dismissed) */
.onboard-card {
  margin: 10px 12px;
  padding: 12px 14px;
  border: 1px solid rgba(232, 176, 75, 0.5);
  border-radius: 12px;
  background: rgba(232, 176, 75, 0.07);
}
.onboard-head { display: flex; justify-content: space-between; align-items: center; font-size: 14px; }
.onboard-dismiss { background: none; border: none; color: var(--muted); font-size: 17px; cursor: pointer; padding: 0 2px; }
.onboard-steps { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.onboard-steps button {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: none; padding: 5px 2px;
  color: var(--text); font-size: 13.5px; cursor: pointer; text-align: left; border-radius: 7px;
}
.onboard-steps button:hover { background: rgba(255, 255, 255, 0.05); }
.onboard-steps .ob-mark { flex: 0 0 18px; height: 18px; border-radius: 50%; border: 1.6px solid var(--muted); display: inline-flex; align-items: center; justify-content: center; font-size: 11px; }
.onboard-steps .done { color: var(--muted); text-decoration: line-through; }
.onboard-steps .done .ob-mark { border-color: var(--accent); background: var(--accent); color: var(--on-accent); text-decoration: none; }

/* 🌐 app-language picker (auth dialog + account bar) */
.ui-lang-select {
  background: var(--panel, #20242c);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 4px 8px;
  font-size: 12.5px;
  max-width: 110px;
}
.auth-dialog .ui-lang-select { position: absolute; top: 14px; left: 16px; }

/* figure strip: caption box under each thumbnail (steers step placement) */
.fig-cell { display: flex; flex-direction: column; gap: 4px; width: 66px; }
.fig-cap {
  width: 100%;
  padding: 3px 6px;
  font-size: 11px;
  color: var(--text);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  border-radius: 6px;
  outline: none;
}
.fig-cap:focus { border-color: var(--accent); }
.fig-cap::placeholder { color: var(--muted); font-size: 10px; }

/* ============ mock exam player ============ */
/* ===== Test player (practice + exam) — THEMEABLE, scoped to the overlay so it
   doesn't touch the dark-first rest of the app. LIGHT by default (what most testing
   platforms use); add .exam-dark on the overlay for the dark surface. ===== */
.exam-overlay {
  --ex-bg: #eef1f5; --ex-glow: rgba(232,176,75,0.07);
  --ex-card: #ffffff; --ex-line: #e2e6ec; --ex-text: #1b2230; --ex-muted: #667085;
  --ex-opt: #f7f9fb; --ex-opt-hover: rgba(176,125,18,0.08);
  --ex-chip-bg: #eef1f5; --ex-chip-border: #dce1e8; --ex-chip-color: #5a6472;
  --ex-accent: #a9760f; --ex-warn: #b8860b; --ex-danger: #c0392b; --ex-shadow: rgba(20,30,50,0.07);
  position: fixed; inset: 0; z-index: 1200; overflow-y: auto; display: flex;
  background: radial-gradient(1100px 620px at 50% -12%, var(--ex-glow), transparent 62%), var(--ex-bg);
}
.exam-overlay.exam-dark {
  --ex-bg: #101318; --ex-glow: rgba(232,176,75,0.05);
  --ex-card: var(--bg-card); --ex-line: var(--line); --ex-text: var(--text); --ex-muted: var(--muted);
  --ex-opt: rgba(255,255,255,0.015); --ex-opt-hover: rgba(245,215,110,0.06);
  --ex-chip-bg: rgba(255,255,255,0.03); --ex-chip-border: var(--line); --ex-chip-color: var(--muted);
  --ex-accent: var(--accent); --ex-warn: #f5d76e; --ex-danger: #f08a8a; --ex-shadow: rgba(0,0,0,0.2);
}
/* margin:auto vertically + horizontally centres the card, and (unlike align-items:center)
   scrolls gracefully instead of clipping the top when a long exam overflows */
.exam-sheet { margin: auto; width: 100%; max-width: 660px; padding: clamp(20px, 5vh, 56px) 22px;
  display: flex; flex-direction: column; gap: 20px; }
.exam-head { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  position: sticky; top: 0; padding: 12px 2px; z-index: 2;
  background: linear-gradient(var(--ex-bg) 72%, transparent); }
/* flex:1 matters as much as min-width:0. The tools side is flex:0 0 auto, so without a
   grow factor the title got only its own shrink-to-fit share and was crushed to ~29px on a
   phone — an exam title rendered two characters wide. */
.exam-title-wrap { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
.exam-title-wrap b { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; color: var(--ex-text);
  overflow-wrap: anywhere; }
#exam-progress { color: var(--ex-muted); font-size: 12px; }
/* mode eyebrow so students always know they're in a graded Mock exam vs untimed Practice */
.exam-kind { align-self: flex-start; font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.07em;
  padding: 2px 9px; border-radius: 999px; border: 1px solid var(--ex-line); color: var(--ex-muted); background: var(--ex-card); }
/* self-contained violet (the exam overlay has its own palette, so don't borrow the
   app's gold --accent-soft) — reads on both the light and dark exam sheet */
.exam-kind.is-exam { color: #7c3aed; border-color: rgba(124,58,237,0.5); background: rgba(124,58,237,0.12); }
.exam-headtools { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.exam-theme-btn { flex: 0 0 auto; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9px; border: 1px solid var(--ex-line); background: var(--ex-card); color: var(--ex-muted); cursor: pointer; font-size: 16px; }
.exam-theme-btn:hover { color: var(--ex-text); border-color: var(--ex-accent); }
/* leave-exam ✕ — same footprint as the theme button, sits at the far right of the header */
.exam-exit { flex: 0 0 auto; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9px; border: 1px solid var(--ex-line); background: var(--ex-card); color: var(--ex-muted); cursor: pointer; font-size: 15px; line-height: 1; }
.exam-exit:hover { color: var(--ex-text); border-color: var(--ex-accent); }
.exam-timer { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 16px; padding: 6px 14px; border-radius: 999px; border: 1px solid var(--ex-line); background: var(--ex-card); color: var(--ex-text); }
.exam-timer.amber { color: var(--ex-warn); border-color: var(--ex-warn); }
.exam-timer.red { color: var(--ex-danger); border-color: var(--ex-danger); animation: exam-pulse 1s infinite; }
@keyframes exam-pulse { 50% { opacity: 0.55; } }
/* the question + options live on a calm raised "test card" with generous padding */
.exam-qarea { background: var(--ex-card); border: 1px solid var(--ex-line); border-radius: 18px;
  padding: 30px 32px 28px; box-shadow: 0 1px 3px var(--ex-shadow); }
@media (max-width: 560px) { .exam-qarea { padding: 22px 18px 20px; } }
/* PHONES: the header cannot hold title + timer + two buttons on one 331px line. The tools
   are flex:0 0 auto, so the title absorbed the entire shortfall and rendered 29px wide —
   an exam title two characters across. Give each its own row instead of fighting over one.
   Also cap the timer: in preview it reads "not timed — preview", which is 198px on its own. */
@media (max-width: 640px) {
  .exam-head { flex-wrap: wrap; row-gap: 8px; padding: 10px 2px; }
  .exam-title-wrap { flex: 1 1 100%; }
  .exam-headtools { width: 100%; justify-content: space-between; }
  .exam-timer { font-size: 15px; padding: 6px 12px; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .exam-foot { flex-wrap: wrap; }
  .exam-foot .btn { flex: 1 1 auto; padding: 12px 14px; }
  .pr-exam-note { font-size: 14px; }
  .exam-section { font-size: 12px; }
  /* the nav grid is 38x34 — under the 44px minimum, on the control used to move between
     questions under time pressure */
  .exam-nav button { min-width: 44px; min-height: 44px; font-size: 14px; }
}
.exam-section { color: var(--ex-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; margin-bottom: 12px; }
.exam-q { font-size: 19px; line-height: 1.62; margin-bottom: 16px; font-weight: 500; color: var(--ex-text); }
/* "Play on board" — the alternative, watch-and-listen way to take a practice question */
.pr-actions { margin: 0 0 22px; }
.pr-playboard {
  display: inline-flex; align-items: baseline; gap: 8px; cursor: pointer;
  padding: 9px 16px; border-radius: 999px; font: inherit; font-size: 14px; font-weight: 600;
  color: var(--accent); background: var(--accent-soft, rgba(124,58,237,0.12));
  border: 1px solid var(--accent); transition: transform 0.12s, background 0.15s;
}
.pr-playboard:hover { transform: translateY(-1px); background: var(--accent); color: #fff; }
.pr-playboard-sub { font-size: 12px; font-weight: 500; opacity: 0.75; }
.exam-opts { display: flex; flex-direction: column; gap: 12px; }
.exam-opt { display: flex; gap: 14px; align-items: center; width: 100%; text-align: left;
  padding: 15px 18px; border: 1px solid var(--ex-line); border-radius: 13px; background: var(--ex-opt);
  color: var(--ex-text); font-size: 16px; line-height: 1.5; cursor: pointer;
  transition: border-color .15s, background .15s, transform .08s; }
.exam-opt:hover { border-color: var(--ex-accent); background: var(--ex-opt-hover); }
.exam-opt:active { transform: scale(0.995); }
.exam-opt.sel { border-color: var(--ex-accent); background: var(--ex-opt-hover); box-shadow: inset 0 0 0 1px var(--ex-accent); }
/* the A/B/C/D marker as a tidy chip — the professional test-platform look */
.exam-opt .opt-letter { flex: 0 0 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9px; border: 1px solid var(--ex-chip-border); background: var(--ex-chip-bg);
  color: var(--ex-chip-color); font-weight: 700; font-size: 13.5px; }
.exam-opt:hover .opt-letter, .exam-opt.sel .opt-letter { border-color: var(--ex-accent); color: var(--ex-accent); }
.exam-opt .opt-text { min-width: 0; }
/* footer buttons themed to the surface */
.exam-foot { display: flex; align-items: center; gap: 8px; margin-top: 6px; padding: 0 2px; }
.exam-foot .btn { padding: 12px 20px; font-size: 14px; border-radius: 11px; }
.exam-overlay .btn-ghost { color: var(--ex-muted); border: 1px solid var(--ex-line); background: var(--ex-card); }
.exam-overlay .btn-ghost:hover { color: var(--ex-text); border-color: var(--ex-accent); background: var(--ex-card); }
.exam-overlay .btn-ghost:disabled { opacity: .5; }
#exam-next { flex: 0 0 auto; margin-left: auto; min-width: 150px; justify-content: center; } /* override .btn-primary flex:1 so Next isn't full-width */
/* question navigator: compact, centered, evenly-sized cells */
.exam-nav { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; padding: 2px 0; }
.exam-nav button { width: 38px; height: 34px; border-radius: 8px; border: 1px solid var(--ex-line); background: var(--ex-card); color: var(--ex-text); font-size: 13px; cursor: pointer; }
.exam-nav button.answered { background: rgba(120,200,140,0.18); border-color: rgba(120,200,140,0.55); }
.exam-nav button.flagged { border-color: var(--ex-warn); }
.exam-nav button.cur { outline: 2px solid var(--ex-accent); outline-offset: 1px; }
/* submit: clearly available but secondary to Next — outline, capped width, set apart */
.exam-submitrow { display: flex; justify-content: center; padding-top: 12px; margin-top: 2px; border-top: 1px solid var(--ex-line); }
.exam-submitrow #exam-submit { width: 100%; max-width: 300px; padding: 12px 20px; font-size: 14px; box-shadow: none;
  background: var(--ex-opt-hover); color: var(--ex-accent); border: 1px solid var(--ex-accent); }
.exam-submitrow #exam-submit:hover { filter: brightness(1.04); border-color: var(--ex-accent); transform: none; box-shadow: none; }
.exam-result .exam-score { font-size: 30px; font-weight: 800; text-align: center; margin: 10px 0 2px; color: var(--ex-text); }
.exam-result .exam-score small { display: block; font-size: 13px; color: var(--ex-muted); font-weight: 400; margin-top: 4px; }
.exam-rev { border: 1px solid var(--ex-line); border-radius: 10px; padding: 12px 14px; margin-top: 10px; color: var(--ex-text); }
.exam-rev.good { border-color: rgba(70,160,110,0.55); background: rgba(70,160,110,0.06); }
.exam-rev.bad { border-color: rgba(200,80,80,0.5); background: rgba(200,80,80,0.05); }
.exam-rev .rev-q { font-weight: 600; margin-bottom: 6px; }
.exam-rev .rev-a { font-size: 14px; margin: 2px 0; }
.exam-rev .rev-x { color: var(--ex-muted); font-size: 13px; margin-top: 6px; }
/* teacher: exam rows + builder bits reuse class-card styles */
.exam-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; margin-bottom: 8px; }
.exam-row .ex-meta { color: var(--muted); font-size: 12px; }
/* release-mode badge on each teacher exam row */
.ex-titlerow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ex-rel { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); white-space: nowrap; }
.ex-rel.instant { color: var(--text-dim); }
.ex-rel.held { color: #7c3aed; border-color: rgba(124,58,237,0.5); background: rgba(124,58,237,0.12); }
.ex-rel.released { color: #2e7d5b; border-color: rgba(46,125,91,0.5); background: rgba(46,125,91,0.12); }
.exam-conf { display: flex; gap: 10px; align-items: flex-start; border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin-bottom: 8px; }
.exam-conf.ok { border-color: rgba(120,200,140,0.5); }
.exam-conf .conf-body { flex: 1; min-width: 0; font-size: 14px; }
.exam-conf .conf-opts { color: var(--muted); font-size: 13px; margin-top: 4px; }
.exam-short { width: 100%; min-height: 130px; padding: 12px 14px; border: 1px solid var(--ex-line); border-radius: 10px; background: var(--ex-card); color: var(--ex-text); font-size: 16px; font-family: inherit; resize: vertical; }
.exam-short:focus { border-color: var(--ex-accent); outline: none; }

/* --- assignment: obvious "where it belongs" (library pill + modal summary) --- */
.library-list .lib-assign .lib-assign-label {
  max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* live "Assigned to" summary at the top of the assign modal */
.assign-status {
  font-size: 12.5px; color: var(--text-dim); line-height: 1.5;
  margin: 0 0 12px; padding: 10px 12px; border-radius: 10px;
  background: var(--bg-raised); border: 1px dashed var(--line);
}
.assign-status.has {
  color: var(--text); border-style: solid; border-color: rgba(120, 160, 100, 0.45);
  background: rgba(63, 110, 49, 0.14);
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
}
.assign-status .as-label { font-weight: 600; color: #9fbe8f; }
.assign-status .as-chip {
  display: inline-block; font-size: 12px; font-weight: 600;
  padding: 3px 9px; border-radius: 999px;
  background: rgba(120, 160, 100, 0.22); color: #cfe3c2;
}
/* per-row state hint ("Assigned" / "Tap to assign") */
.assign-class-row .assign-state { font-size: 11.5px; color: var(--text-dim); flex-shrink: 0; }
.assign-class-row.on .assign-state { color: #9fbe8f; font-weight: 600; }
.assign-foot { display: flex; justify-content: flex-end; margin-top: 14px; }

/* ============ question bank + shared question editor + practice ============ */
/* ============ question bank — elegant, intuitive ============ */
/* toolbar: three clear action cards */
.qb-toolbar { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 14px; }
.qb-tool { display: flex; align-items: center; gap: 10px; text-align: left; padding: 12px 14px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--bg-raised); color: var(--text); cursor: pointer; transition: border-color .15s, background .15s, transform .1s; }
.qb-tool:hover { border-color: var(--accent); transform: translateY(-1px); }
.qb-tool-ic { font-size: 20px; line-height: 1; flex: 0 0 auto; }
.qb-tool span:last-child { display: flex; flex-direction: column; min-width: 0; }
.qb-tool b { font-size: 14px; font-weight: 700; }
.qb-tool small { font-size: 11px; color: var(--muted); }
.qb-tool-primary { background: linear-gradient(180deg, rgba(245,215,110,0.16), rgba(245,215,110,0.06)); border-color: rgba(245,215,110,0.5); }
.qb-tool-primary b { color: var(--accent); }
@media (max-width: 620px) { .qb-toolbar { grid-template-columns: 1fr; } }

/* hub: bank summary card + subject folders */
.qb-bankcard { border: 1px solid var(--line); border-radius: 14px; padding: 16px; background: var(--bg-raised); margin-top: 4px; }
.qb-bankhead { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.qb-banktitle { font-size: 15px; font-weight: 700; }
.qb-bankhint { font-size: 12.5px; color: var(--muted); margin: 6px 0 12px; }
.qb-bankhead-tools { display: inline-flex; align-items: center; gap: 14px; flex: 0 0 auto; }
/* "By grade" chips on the hub — pick a grade to filter the subject folders below */
.qb-gradechips { display: flex; flex-wrap: wrap; gap: 7px; margin: 2px 0 12px; }
.qb-gradechip { font-family: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  padding: 5px 12px; border-radius: 999px; color: var(--text-dim);
  background: var(--bg); border: 1px solid var(--line); transition: border-color .15s, color .15s, background .15s; }
.qb-gradechip:hover { border-color: var(--accent); color: var(--text); }
.qb-gradechip.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.qb-taggrades { white-space: nowrap; }
.qb-folders { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.qb-folder { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--bg); color: var(--text);
  cursor: pointer; font-family: inherit; transition: border-color .15s, transform .1s; }
.qb-folder:hover { border-color: var(--accent); transform: translateY(-1px); }
.qb-folder-name { font-size: 13.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qb-folder-n { flex: 0 0 auto; font-size: 12px; font-weight: 700; color: var(--accent);
  background: rgba(245,215,110,0.12); border-radius: 999px; padding: 2px 9px; }
/* browse: back / new-question bar */
.qb-browsebar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.qb-newbtn { padding: 7px 14px; font-size: 13px; }

/* filter bar */
.qb-filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.qb-search { position: relative; flex: 1 1 220px; }
.qb-search::before { content: "⌕"; position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 16px; pointer-events: none; }
.qb-search input { width: 100%; padding: 9px 12px 9px 30px; border: 1px solid var(--line); border-radius: 9px; background: var(--bg-raised); color: var(--text); font-size: 13px; }
.qb-search input:focus { outline: none; border-color: var(--accent); }
.qb-filter { flex: 0 1 auto; min-width: 120px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 9px; background: var(--bg-raised); color: var(--text); font-size: 13px; cursor: pointer; }
.qb-filter:focus { outline: none; border-color: var(--accent); }
.qb-filter:disabled { opacity: .5; cursor: default; }

/* count row */
.qb-countrow { display: flex; align-items: baseline; gap: 12px; margin: 12px 2px 8px; }
.qb-count { font-size: 12.5px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.qb-textbtn { background: none; border: none; color: var(--accent); font: inherit; font-size: 12.5px; cursor: pointer; padding: 0; }
/* names the lesson behind a "See them →" jump — the filter bar has no control for it,
   so without this the narrowed list would look like the whole bank */
.qb-srcchip {
  font-size: 12px; color: var(--accent);
  background: var(--accent-soft);
  border-radius: 999px; padding: 3px 10px;
  max-width: 42ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qb-textbtn:hover { text-decoration: underline; }

/* cards */
.qb-card { border: 1px solid var(--line); border-radius: 14px; padding: 15px 16px; margin-bottom: 11px;
  background: rgba(255,255,255,0.015); transition: border-color .15s, transform .1s, box-shadow .15s; }
.qb-card:hover { border-color: #414a56; box-shadow: 0 4px 18px rgba(0,0,0,.18); }
.qb-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.qb-q { font-size: 15.5px; font-weight: 600; line-height: 1.45; flex: 1; min-width: 0; }
.qb-actions { display: flex; gap: 4px; flex-shrink: 0; }
.qb-iconbtn { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 8px; border: 1px solid transparent;
  background: transparent; color: var(--muted); font-size: 14px; cursor: pointer; transition: background .12s, color .12s, border-color .12s; }
.qb-iconbtn:hover { background: rgba(255,255,255,0.05); color: var(--text); border-color: var(--line); }
.qb-iconbtn.qb-del:hover { color: #f0a0a0; border-color: rgba(240,138,138,0.4); }
.qb-chips { display: flex; gap: 6px; flex-wrap: wrap; margin: 9px 0 8px; }
.qb-chip { font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 999px; background: rgba(255,255,255,0.06); color: var(--text-dim); white-space: nowrap; }
.qb-chip.qb-grade { background: rgba(120,160,235,0.16); color: #a9c2ef; }

/* a data table shown with a bank question (card + practice player) — theme-agnostic
   colours so it reads on the dark card AND the light/dark test player */
.q-table-wrap { overflow-x: auto; margin: 9px 0 2px; }
.q-table { border-collapse: collapse; font-size: 12.5px; }
.q-table th, .q-table td { border: 1px solid rgba(128,128,128,0.34); padding: 5px 11px; text-align: left; white-space: nowrap; }
.q-table th { background: rgba(180,140,40,0.14); font-weight: 700; }
.q-table td { opacity: 0.92; }
/* exam-card actions (Preview · Publish/Results · ×). Was an inline flex:0 0 auto span, so
   on a phone the row ran 411px wide in a 375px viewport with nothing to scroll it — the
   delete × was simply unreachable. */
.ex-actions { display: flex; gap: 6px; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 640px) { .ex-actions { flex: 1 1 100%; justify-content: flex-start; } }

.exam-qtable { margin: 4px 0 2px; min-width: 0; max-width: 100%; }
.exam-qtable .q-table { font-size: 14px; }
.qe-tablefield { font-family: ui-monospace, "JetBrains Mono", "SF Mono", monospace; font-size: 12px; }

/* PHONES. A table is the one thing here that legitimately cannot always fit — cells hold
   numbers that must not wrap mid-value, so the table SCROLLS inside its own box rather
   than stretching the page sideways. The rules below make that scroll real (a flex/grid
   child will not shrink below its content without min-width:0) and make the figures
   legible: 12.5px cells and 11px axis labels are a desktop size, and this is the screen
   students actually sit the exam on. */
@media (max-width: 640px), (pointer: coarse) {
  .q-table-wrap {
    max-width: 100%; min-width: 0;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;        /* stop a table swipe pulling the whole page */
  }
  /* Only when it really overflows (set by markScrollableTables from a measurement).
     A clipped column in a timed exam is indistinguishable from missing data, so say so. */
  .q-table-wrap.is-scrollable { position: relative; }
  .q-table-wrap.is-scrollable::after {
    content: "swipe for more columns →";
    display: block; position: sticky; left: 0;
    /* clear of the table's bottom border, which otherwise reads as an underline on the hint */
    font-size: 12px; color: var(--ex-muted, #8a97a0); padding: 9px 1px 0; white-space: nowrap;
  }
  .q-table { font-size: 15px; }
  .exam-qtable .q-table { font-size: 15px; }
  .q-table th, .q-table td { padding: 7px 10px; }
  .q-graph { width: 100%; }
  .exam-qtable .q-graph { width: 100%; }
  .q-graph-tick { font-size: 13px; }
}

/* a function graph shown with a bank question (card + practice player) */
.q-graph-wrap { margin: 9px 0 2px; }
.q-graph { width: 320px; max-width: 100%; height: auto; display: block;
  background: rgba(128,128,128,0.06); border: 1px solid rgba(128,128,128,0.28); border-radius: 10px; }
.q-graph-axis { stroke: rgba(128,128,128,0.6); stroke-width: 1; }
.q-graph-tick { fill: rgba(128,128,128,0.85); font-size: 11px; font-family: var(--font-ui, sans-serif); }
.exam-qtable .q-graph { width: 380px; }
.qb-chip.qb-diff-easy { background: rgba(120,200,140,0.16); color: #9fd0a8; }
.qb-chip.qb-diff-medium { background: rgba(245,215,110,0.16); color: #e6cd7a; }
.qb-chip.qb-diff-hard { background: rgba(240,138,138,0.16); color: #f0a0a0; }
.qb-ans { font-size: 13.5px; color: var(--text); margin-bottom: 6px; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.qb-ans-lab { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted);
  background: rgba(255,255,255,0.05); padding: 2px 7px; border-radius: 5px; flex: 0 0 auto; }
.qb-ans-val { font-weight: 600; }
.qb-sol { margin-top: 2px; }
.qb-sol summary { font-size: 12.5px; color: var(--accent); cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 4px; }
.qb-sol summary::-webkit-details-marker { display: none; }
.qb-sol-chev { display: inline-block; transition: transform .15s; }
.qb-sol[open] .qb-sol-chev { transform: rotate(90deg); }
.qb-steps { margin: 8px 0 2px 18px; font-size: 13px; line-height: 1.65; color: var(--text-dim); }
.qb-steps .qb-final { color: var(--text); font-weight: 600; list-style: none; margin-left: -14px; }
.qb-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--line); flex-wrap: wrap; }
/* single-question editor */
.qedit-card { width: min(460px, 100%); max-height: 88vh; overflow-y: auto; }
.qedit-body { display: flex; flex-direction: column; gap: 10px; }
.qe-lab { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-dim); font-weight: 600; }
.qe-lab input, .qe-lab select, .qedit-body textarea { padding: 9px 11px; border: 1px solid var(--line); border-radius: 9px; background: var(--bg-raised); color: var(--text); font-size: 14px; font-family: inherit; font-weight: 400; }
.qe-row { display: flex; gap: 10px; } .qe-row .qe-lab { flex: 1; }
.qe-opt { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; }
.qe-opt input { flex: 1; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg-raised); color: var(--text); }
.qe-correct { flex: 0 0 auto; width: 34px; color: var(--text-dim); }
.qe-correct.on { color: #9fd0a8; }
.qe-rmopt { flex: 0 0 auto; color: var(--text-dim); }
/* student practice buttons + worked-solution reveal */
.sh-practice-subjects { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.sh-practice-btn { padding: 10px 16px; border: 1px solid var(--line); border-radius: 999px; background: var(--bg-raised); color: var(--text); font-size: 14px; font-weight: 600; cursor: pointer; }
.sh-practice-btn:hover { border-color: var(--accent); }
/* "Play all on the board" — watch every question worked out, back to back */
.sh-practice-playall {
  flex-basis: 100%; margin-top: 4px;
  display: inline-flex; align-items: baseline; gap: 10px; width: 100%;
  padding: 12px 18px; border-radius: 12px; cursor: pointer; font: inherit; font-size: 15px; font-weight: 700;
  color: #fff; background: linear-gradient(180deg, var(--accent), var(--accent-strong, var(--accent)));
  border: 1px solid var(--accent); transition: transform 0.12s, filter 0.15s;
}
.sh-practice-playall:hover { transform: translateY(-1px); filter: brightness(1.06); }
.sh-practice-playall-sub { font-size: 12.5px; font-weight: 500; opacity: 0.9; }
/* many questions → sequential "sets" so nothing is dropped */
.sh-practice-setshdr { flex-basis: 100%; margin: 6px 0 2px; font-size: 13.5px; color: var(--text-dim); }
.sh-practice-setshdr b { color: var(--text); }
.sh-practice-sets { flex-basis: 100%; display: flex; gap: 8px; flex-wrap: wrap; }
.sh-practice-set {
  padding: 10px 15px; border-radius: 999px; cursor: pointer; font: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--accent); background: var(--accent-soft, rgba(124,58,237,0.12)); border: 1px solid var(--accent);
  transition: transform 0.12s, background 0.15s;
}
.sh-practice-set:hover { transform: translateY(-1px); background: var(--accent); color: #fff; }
.exam-rev .rev-worked { margin-top: 8px; }
.exam-rev .rev-worked-h { font-size: 12px; font-weight: 700; color: var(--ex-accent); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }
.exam-rev .rev-worked ol { margin: 0 0 0 18px; font-size: 14px; line-height: 1.65; }
.exam-rev .rev-worked .rev-final { list-style: none; margin-left: -14px; font-weight: 700; color: var(--ex-text); margin-top: 4px; }

/* PHONES: the worked answer is what a student actually STUDIES, and it was the smallest
   text on the screen — 13-14px against a 19px question. A phone has the room; it just has
   to be spent on the right thing.
   This block sits AFTER the base rules deliberately. The same overrides written earlier in
   the file lost to `.exam-rev .rev-a` at equal specificity on source order alone, and read
   as applied while measuring 14px. */
@media (max-width: 640px), (pointer: coarse) {
  .exam-rev .rev-a { font-size: 16px; }
  .exam-rev .rev-x { font-size: 15px; line-height: 1.6; }
  .exam-rev .rev-worked ol { font-size: 15px; }
  .exam-rev .rev-worked-h { font-size: 13px; }
}
.conf-actions { display: flex; gap: 4px; flex-shrink: 0; }
.conf-ai { display: inline-block; font-size: 11px; color: #e6cd7a; margin-top: 4px; }
.qb-chip.qb-class { background: rgba(110,150,220,0.16); color: #a9c2ee; }
/* review lifecycle */
.qb-reviewbar { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap;
  background: linear-gradient(180deg, rgba(245,215,110,0.14), rgba(245,215,110,0.06)); border: 1px solid rgba(245,215,110,0.4);
  border-radius: 12px; padding: 12px 15px; margin-bottom: 14px; font-size: 13px; }
.qb-rev-msg { flex: 1 1 240px; }
.qb-rev-btns { display: flex; gap: 8px; flex: 0 0 auto; }
/* unreviewed: a clean left accent instead of a heavy tint */
.qb-card.unreviewed { border-color: var(--line); border-left: 3px solid rgba(245,215,110,0.7); background: rgba(245,215,110,0.035); }
.qb-chip.qb-needsrev { background: rgba(245,215,110,0.2); color: #e6cd7a; }
.qb-reviewcheck { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; color: var(--text-dim);
  cursor: pointer; padding: 6px 11px; border: 1px solid var(--line); border-radius: 8px; transition: border-color .12s, color .12s; }
.qb-reviewcheck input { width: 16px; height: 16px; accent-color: #9fd0a8; cursor: pointer; margin: 0; }
.qb-reviewcheck:hover { border-color: var(--accent); color: var(--text); }
.qb-card.unreviewed .qb-reviewcheck { border-color: rgba(245,215,110,0.5); color: #e6cd7a; }
.qb-card.unreviewed .qb-reviewcheck input { accent-color: #e6cd7a; }
/* Show-on-board button */
.qb-playbtn { display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 999px;
  border: 1px solid rgba(245,215,110,0.45); background: rgba(245,215,110,0.1); color: var(--accent);
  font-size: 12.5px; font-weight: 700; cursor: pointer; transition: background .12s, transform .1s; }
.qb-playbtn:hover { background: rgba(245,215,110,0.2); transform: translateY(-1px); }
/* the question text is also clickable to open on the board */
.qb-q.qb-q-open { cursor: pointer; }
.qb-q.qb-q-open:hover { color: var(--accent); }

/* bank panel: a bit wider for the cards; head lays out title + close */
.qbank-panel { width: min(860px, 100%); }
.qbank-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.qbank-head .auth-close { position: static; }

/* Question bank renders as a FLAT FULL-PAGE surface (not a floating pop-up): it
   fills the screen, with the content in a centred reading column — like the
   Lessons page, and easier to review. Overrides the shared modal styles for the
   bank only. */
#qbank-overlay {
  background: var(--bg); backdrop-filter: none; padding: 0;
  align-items: stretch; justify-content: center; z-index: 90;
}
#qbank-overlay .qbank-panel {
  width: 100%; max-width: 1060px; height: 100vh; max-height: 100vh;
  border: none; border-left: 1px solid var(--line); border-right: 1px solid var(--line);
  border-radius: 0; box-shadow: none;
}
#qbank-overlay .qbank-head { padding: 22px 26px 14px; }
#qbank-overlay .editor-body { padding: 18px 26px 40px; }
#qbank-overlay .qb-header { margin: 0 -26px; padding: 4px 26px 9px; }
@media (max-width: 620px) {
  #qbank-overlay .qbank-panel { border-left: none; border-right: none; }
}
/* keep the bank's actions + filters reachable while the list scrolls */
.qb-header { position: sticky; top: 0; z-index: 6; background: var(--bg-card);
  margin: 0 -22px; padding: 4px 22px 9px; border-bottom: 1px solid var(--line);
  box-shadow: 0 10px 16px -12px rgba(0,0,0,.6); }
.qb-header .qb-countrow { margin-bottom: 2px; }
.qb-countrow { justify-content: flex-start; }
.qb-playall { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; padding: 7px 15px; border-radius: 999px;
  border: 1px solid rgba(245,215,110,0.5); background: rgba(245,215,110,0.12); color: var(--accent); font-size: 12.5px; font-weight: 700; cursor: pointer; transition: background .12s, transform .1s; }
.qb-playall:hover { background: rgba(245,215,110,0.22); transform: translateY(-1px); }
.qi-progress { margin-top: 10px; padding: 9px 12px; border-radius: 9px; background: rgba(245,215,110,0.1); border: 1px solid rgba(245,215,110,0.35); color: var(--accent); font-size: 12.5px; font-weight: 600; }
/* question-bank guided empty state */
.qb-empty { text-align: center; padding: 22px 10px 8px; max-width: 460px; margin: 0 auto; }
.qb-empty-ic { font-size: 34px; }
.qb-empty h4 { font-size: 18px; margin: 8px 0 6px; }
.qb-empty > p { font-size: 13.5px; color: var(--text-dim); line-height: 1.55; }
.qb-empty-ways { list-style: none; counter-reset: qbw; display: flex; flex-direction: column; gap: 8px; margin: 16px 0 12px; text-align: left; }
.qb-empty-go { width: 100%; display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 11px; background: var(--bg-raised); color: var(--text); cursor: pointer; transition: border-color .15s, transform .1s; }
.qb-empty-go:hover { border-color: var(--accent); transform: translateY(-1px); }
.qb-empty-go b { font-size: 14px; }
.qb-empty-go span { font-size: 12px; color: var(--muted); }
.qb-empty-hint { font-size: 12px; color: var(--muted); font-style: italic; }

/* Touch devices: ensure the small header icon buttons meet the ~44px tap-target guideline
   (they were 38px). Placed late so it wins over the mobile size block above. */
@media (hover: none) and (pointer: coarse) {
  .icon-btn { width: 44px; height: 44px; }
  .ctl-btn { width: 44px; height: 44px; }
}

/* Mobile account bar: stack the identity above a horizontally-scrollable strip of
   action buttons (Create lesson · My classes · Question bank · Settings…) so every
   button stays reachable on a narrow screen instead of overflowing off the edge. */
@media (max-width: 640px) {
  .account-bar { flex-direction: column; align-items: stretch; gap: 10px; }
  /* WRAP, don't scroll. This strip used to scroll horizontally so that nothing overflowed
     the edge — but with six controls the last one (Settings) simply started off-screen, and
     a sideways-scrolling row nobody knows to swipe is a hidden button, not a reachable one.
     Measured at 375px: 429px of content in a 339px box, leaving Settings 72px past the right
     edge. Wrapping serves the original goal properly — every button visible, nothing to
     discover — and removes the clip that forced the Settings menu to be a fixed popover.
     (The fixed popover is kept: it works, and positionSettingsMenu already anchors it.) */
  .account-actions {
    flex-wrap: wrap;
    max-width: 100%;
    row-gap: 8px;
  }
  .account-actions > * { flex: 0 0 auto; }                /* keep size; never squish */
  .account-btn { white-space: nowrap; }

  /* the Settings menu sits inside the scroll strip, which clips overflow — make it a
     fixed popover so it escapes the clip. JS (positionSettingsMenu) anchors it right
     under the gear button; these are just the fixed defaults + on-screen fallback. */
  .settings-menu {
    position: fixed; top: 132px; left: auto; right: 12px; bottom: auto;
    min-width: 210px; z-index: 200;
    box-shadow: 0 10px 34px rgba(0, 0, 0, 0.5);
  }
}

/* Full-screen overlay panels on mobile: honour the iPhone status-bar / notch safe
   area so the close button and header aren't hidden underneath it, and give the
   close button a real tap target with contrast (it was a faint 13px ×). */
@media (max-width: 640px) {
  .editor-panel { padding-top: env(safe-area-inset-top, 0px); }
  /* A solid, obviously-tappable circular Close that clears the notch and can never
     blend into the content behind it (it was a faint 13px × that got lost under the
     status bar on real iPhones). */
  .editor-panel > .auth-close {
    position: absolute; z-index: 10;
    top: calc(8px + env(safe-area-inset-top, 0px)); right: 12px;
    width: 42px; height: 42px; font-size: 24px; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    color: var(--text); background: var(--bg-raised);
    border: 1px solid var(--line); border-radius: 999px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
  }
  .editor-panel > .auth-close:active { background: var(--line); }
  /* keep the header text clear of the floating close button */
  .editor-head { padding-right: 62px; }
}

/* ---- Horizontal-drift guard -------------------------------------------------
   A container with `overflow-y: auto` but no explicit `overflow-x` gets
   `overflow-x: auto` computed by the spec — which on touch means the whole
   panel can be dragged/rubber-banded side to side even when nothing overflows
   (the "wobbly, free-moving screen"). None of these vertical scrollers need a
   horizontal axis, so pin it hidden. Intentional horizontal scrollers
   (.account-actions, .class-tabs, .q-table-wrap, .gradebook-wrap) are NOT here
   and keep their overflow-x: auto. */
.setup-main,
.board-area,
.library-list,
.editor-body,
.transcript-body,
.tutor-messages,
.quiz-overlay,
.site-overlay,
.exam-overlay,
.qedit-card,
.assign-list-modal,
.ask-prior-list,
.annot-list,
.school-members,
.school-classes,
.ti-list,
.pdf-units-list,
.pdf-images {
  overflow-x: hidden;
  overscroll-behavior-x: none;   /* also kills the elastic left/right bounce */
}

/* Class-card action row: on phones give it the full card width and let the
   buttons wrap, so the last one (Remove) isn't pushed off the right edge. */
@media (max-width: 640px) {
  .cc-actions { flex: 1 1 100%; flex-wrap: wrap; }
}

/* ---------- foolproof offline: "Save all" button + student online nudge ---------- */
.lib-dl-all {
  margin-left: auto;                       /* push to the right of the Library head */
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--accent-soft); border: 1px solid var(--accent);
  color: var(--text); font: inherit; font-size: 12px; font-weight: 600;
  padding: 5px 11px; border-radius: 999px; cursor: pointer; white-space: nowrap;
  transition: filter 0.15s;
}
.lib-dl-all:hover { filter: brightness(1.06); }
.lib-dl-all:disabled { cursor: default; opacity: 0.75; }

.offline-nudge {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--accent-soft); border: 1px solid var(--accent);
  border-radius: 12px; padding: 11px 13px; margin: 0 0 12px;
}
.on-nudge-txt { flex: 1; min-width: 160px; font-size: 12.5px; line-height: 1.4; color: var(--text); }
.on-nudge-go {
  background: var(--accent); border: 1px solid var(--accent); color: #fff;
  font: inherit; font-size: 12.5px; font-weight: 700;
  padding: 7px 14px; border-radius: 8px; cursor: pointer; white-space: nowrap;
}
html[data-theme="light"] .on-nudge-go { color: #fff; }
.on-nudge-go:hover { filter: brightness(1.06); }
.on-nudge-x {
  background: none; border: none; color: var(--text-dim);
  font-size: 20px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.on-nudge-x:hover { color: var(--text); }

/* ---- material tools: organize into units + saved-materials library (author) ---- */
.material-tools { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
.material-tools .btn { flex: 0 1 auto; }
.materials-panel {
  margin: 10px 0; padding: 12px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--bg-raised);
}
.materials-panel-hdr { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.materials-panel-hdr b { font-size: 14px; }
/* A naked ✕ above a file list reads as "delete these" — and the row below it has a red
   Delete, which makes the guess worse. Word it, and keep it visually quiet so it can't
   compete with a genuinely destructive control. */
.panel-close {
  flex: none;
  background: none; border: 1px solid var(--line); border-radius: 999px;
  padding: 3px 11px;
  color: var(--text-dim); font: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer; opacity: 0.85;
}
.panel-close:hover { opacity: 1; color: var(--text); border-color: var(--text-dim); background: var(--bg); }
.materials-list { display: flex; flex-direction: column; gap: 6px; max-height: 320px; overflow-y: auto; }
.material-row {
  display: flex; align-items: center; gap: 10px; justify-content: space-between;
  padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-card);
}
.material-row-info { min-width: 0; }
/* the NAME truncates; the badge beside it must not — a textbook title is long enough
   to push the badge past the ellipsis, which hid it on every real material */
.material-row-title { display: flex; align-items: center; gap: 8px; min-width: 0; font-weight: 600; font-size: 14px; }
.material-row-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* has this material already been turned into lessons? (same signal as the question
   bank's "✓ 8 in bank" — generating is a metered call, so say so before it's spent) */
.material-used {
  flex: none;                       /* survives a long title instead of being clipped away */
  display: inline-block; vertical-align: 1px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.02em;
  border-radius: 999px; padding: 1px 8px;
  background: var(--accent-soft); color: var(--accent);
}
.material-used.is-unused { background: transparent; color: var(--text-dim); font-weight: 600; border: 1px solid var(--line); }
.material-row-meta { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.material-row-actions { display: flex; gap: 6px; flex: 0 0 auto; }
.material-row-actions .btn { padding: 5px 10px; font-size: 13px; }
/* Delete sits right beside Open and looked exactly like it — on a phone that's a
   mis-tap, and a confirm dialog you meet by surprise gets dismissed reflexively.
   Make it read as destructive BEFORE it's pressed, not only on hover. */
.material-del { color: #c9302c; border-color: rgba(201, 48, 44, 0.35); }
.material-del:hover { border-color: #d9534f; color: #fff; background: #c9302c; }
@media (prefers-color-scheme: dark) {
  .material-del { color: #ff9b97; border-color: rgba(255, 155, 151, 0.35); }
  .material-del:hover { border-color: #d9534f; color: #fff; background: #a02622; }
}

/* numbered badge on organized-unit chips */
.pdf-unit-num {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 6px;
  border-radius: 11px; background: var(--accent-soft); color: var(--accent);
  font-size: 12px; font-weight: 700;
}

/* selected organized-unit chip: persistent visual cue after tapping */
.pdf-unit-check { flex: 0 0 auto; font-size: 11.5px; font-weight: 700; color: var(--accent); display: none; }
.pdf-unit-btn.is-selected {
  border-color: var(--accent); background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.pdf-unit-btn.is-selected .pdf-unit-num { background: var(--accent); color: #14171c; }
.pdf-unit-btn.is-selected .pdf-unit-title { color: var(--text); }
.pdf-unit-btn.is-selected .pdf-unit-pages { display: none; }  /* swap the char count for the "selected" tag */
.pdf-unit-btn.is-selected .pdf-unit-check { display: inline; }

/* QBank transcript: coherent per-question block (correct option marked, worked steps) */
.tr-opts .tr-correct { font-weight: 700; color: var(--accent); }
.tr-solsteps { margin: 4px 0 8px; padding-left: 22px; }
.tr-solsteps li { margin: 3px 0; line-height: 1.5; }
.tr-solshow { font-family: ui-monospace, "SF Mono", Menlo, monospace; }
.tr-solsay { color: var(--text-dim); }
.tr-solshow + .tr-solsay { margin-left: 8px; }
.tr-solshow + .tr-solsay::before { content: "— "; }
.tr-answer { color: var(--accent); }

/* transcript print/download actions */
.transcript-actions { display: flex; gap: 8px; margin: 2px 0 12px; }
.transcript-actions .btn { padding: 6px 12px; font-size: 13px; }

/* transcript in the print worksheet path (Print button) */
@media print {
  .print-root .tr-step { margin: 0 0 10pt; break-inside: avoid; }
  .print-root .tr-step h4 { font-size: 12pt; margin: 9pt 0 3pt; }
  .print-root .tr-narr { margin: 2pt 0; }
  .print-root .tr-opts { margin: 2pt 0 4pt 14pt; }
  .print-root .tr-correct { font-weight: bold; }
  .print-root .tr-solsteps { margin: 2pt 0 4pt 16pt; }
  .print-root .tr-solshow { font-family: "Cambria Math", serif; font-weight: bold; }
  .print-root .tr-solsay { color: #333; }
  .print-root .tr-solshow + .tr-solsay::before { content: "— "; }
  .print-root .tr-answer { font-weight: bold; margin: 3pt 0 0; }
}

/* Student "save for offline" — previously only reachable from #library, which is
   display:none for students, so the whole offline feature was invisible to them. */
.sh-lesson-row { display: flex; align-items: stretch; gap: 8px; }
.sh-lesson-row .sh-lesson { flex: 1; min-width: 0; }
.sh-dl {
  flex: 0 0 auto; width: 44px;                      /* 44px = the minimum comfortable touch target */
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  color: var(--text-dim); font-size: 17px; cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.sh-dl:hover { border-color: var(--accent); color: var(--accent); }
.sh-dl.on { color: var(--ok, #2e7d54); border-color: var(--ok, #2e7d54); background: transparent; cursor: default; }
.sh-dl.busy { opacity: .6; cursor: progress; }
.sh-offline-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin-bottom: 10px; padding: 9px 12px;
  background: var(--accent-soft); border-radius: 9px;
  font-size: 13px; color: var(--text-dim);
}
.sh-dl-all {
  margin-left: auto; padding: 6px 12px;
  background: var(--accent); color: #fff; border: 0; border-radius: 8px;
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.sh-dl-all:disabled { opacity: .6; cursor: progress; }

/* Landing: the student door. Quiet next to the primary CTAs — a student who has been
   given a code is looking for it, and a teacher evaluating the product isn't. */
.lp-student-line {
  margin-top: 14px;
  font-size: 14px;
  color: var(--muted);
}
.lp-studentlink {
  background: none; border: none; padding: 0;
  font: inherit; font-weight: 600; color: var(--accent);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.lp-studentlink:hover { color: var(--text); }

/* Breadcrumb back into the class a teacher opened the question bank from. Only rendered
   in that case — the bank reached from the account bar has nowhere to go back to. */
.qb-crumb {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--accent-soft); border: 1px solid var(--line); color: var(--text);
  border-radius: 999px; padding: 6px 13px; margin-bottom: 12px;
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.qb-crumb:hover { border-color: var(--accent); color: var(--accent); }

/* Exam builder: where the questions come from. Two radio cards rather than a bare
   dropdown, because the choice changes what the rest of the form means. */
.ex-source { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 10px; }
.ex-source label {
  display: flex; align-items: flex-start; gap: 9px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px;
}
.ex-source label:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.ex-source label:has(input:disabled) { opacity: 0.55; cursor: not-allowed; }
.ex-source input { margin-top: 3px; flex: 0 0 auto; }
.ex-source span { display: flex; flex-direction: column; gap: 1px; font-size: 13.5px; font-weight: 600; }
.ex-source small { font-weight: 400; font-size: 11.5px; color: var(--text-dim); }
.ex-bankfilters { display: flex; flex-wrap: wrap; gap: 8px 12px; margin: 6px 0 2px; }
.ex-bankfilters label { display: flex; align-items: center; gap: 6px; }
.ex-bankfilters select {
  background: var(--bg-raised); border: 1px solid var(--line); color: var(--text);
  border-radius: 8px; font: inherit; font-size: 12.5px; padding: 5px 8px;
}
@media (max-width: 560px) {
  .ex-bankfilters { flex-direction: column; align-items: stretch; gap: 6px; }
  .ex-bankfilters label { justify-content: space-between; }
}

/* A dangling assignment (its lesson was deleted) gets a remove control instead of the
   share button — there is nothing left to share, and nowhere else to reach it from. */
.class-lesson-row .cl-unassign { color: var(--text-dim); }
.class-lesson-row .cl-unassign:hover { color: #f08a8a; border-color: #f08a8a; }

/* Quiet secondary actions inside the auth card ("Forgot your password?", "← Back"). */
.auth-link {
  background: none; border: none; color: var(--text-dim); font: inherit; font-size: 12.5px;
  padding: 4px; margin-top: 2px; cursor: pointer; text-decoration: underline; align-self: center;
}
.auth-link:hover { color: var(--accent); }
.auth-hint { margin: 4px 0 0; font-size: 12px; color: var(--text-dim); line-height: 1.45; text-align: center; }

/* "Never signed in" is the one roster value that means "act on this", so it is the one
   thing coloured. Idle-but-active students stay quiet; over two weeks just dims. */
.rs-never {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  background: rgba(240, 138, 138, 0.14); border: 1px solid rgba(240, 138, 138, 0.45);
  color: #f08a8a; font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
.rs-seen { font-size: 12px; color: var(--text); white-space: nowrap; }
.rs-seen.stale { color: var(--text-dim); }
.roster-never-note {
  margin: 0 0 10px; padding: 9px 13px; border-radius: 10px; font-size: 13px; line-height: 1.45;
  background: var(--accent-soft); border: 1px solid var(--line); color: var(--text);
}
.roster-never-note.ok { background: none; color: var(--text-dim); border-color: transparent; padding-left: 0; }

/* ── Feedback dialog ── */
.fb-title { margin: 0 0 4px; font-family: var(--font-display); font-size: 20px; }
.fb-kinds { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 4px; }
.fb-kind { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 999px; padding: 6px 12px; font-size: 12.5px; }
.fb-kind:has(input:checked) { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.fb-kind input { accent-color: var(--accent); }
.fb-message { resize: vertical; min-height: 96px; line-height: 1.5; font-family: inherit; }
.fb-replies { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 12px; max-height: 40vh; overflow-y: auto; }
.fb-past-title { margin: 0 0 8px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-dim); }
.fb-past { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin-bottom: 8px; background: var(--bg-raised); }
.fb-past.unread { border-color: var(--accent); }
.fb-past-msg { margin: 0 0 6px; font-size: 13px; white-space: pre-wrap; }
.fb-past-meta { margin: 0; font-size: 11.5px; color: var(--text-dim); }
.fb-status { text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700; }
.fb-status.fb-resolved { color: #7fce9b; }
.fb-reply { margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: var(--accent-soft); font-size: 13px; }
.fb-reply b { display: block; font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent); margin-bottom: 3px; }
.fb-reply-text { margin: 0; white-space: pre-wrap; }

/* Set-a-PIN prompt on the student home. Deliberately prominent while it applies: without
   a PIN the student can only ever sign in from their personal link. */
.sh-setpin {
  display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; justify-content: space-between;
  margin: 0 0 14px; padding: 12px 15px; border-radius: 12px;
  background: var(--accent-soft); border: 1px solid var(--accent);
}
.sh-setpin-text { display: flex; flex-direction: column; gap: 2px; min-width: 220px; flex: 1; }
.sh-setpin-text b { font-size: 14px; }
.sh-setpin-text span { font-size: 12.5px; color: var(--text-dim); line-height: 1.45; }
.sh-setpin-row { display: flex; gap: 8px; align-items: center; }
.sh-pin-input {
  width: 92px; text-align: center; letter-spacing: 0.32em; font: 600 18px/1 var(--font-ui);
  background: var(--bg-card); border: 1px solid var(--line); color: var(--text);
  border-radius: 10px; padding: 9px 10px; outline: none;
}
.sh-pin-input:focus { border-color: var(--accent); }

/* "on loan from ReasonBoard" — explains why a teacher can edit a colleague's lesson but
   not this one, before they click and get a 403. */
.lib-platform {
  flex: 0 0 auto; font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
  background: var(--accent-soft); border: 1px solid rgba(232, 176, 75, 0.4); color: var(--accent);
}

.lib-scope {
  flex: 0 0 auto; background: none; border: 1px solid var(--line); color: var(--text-dim);
  border-radius: 999px; padding: 4px 11px; font: 600 11px/1 inherit; cursor: pointer; white-space: nowrap;
}
.lib-scope:hover { border-color: var(--accent); color: var(--accent); }
.lib-scope.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

/* One sentence of orientation at the top of an exam preview/review — the badge alone
   wasn't enough to stop the preview being read as the student exam. */
.pr-exam-note {
  margin: 0 0 14px; padding: 9px 13px; border-radius: 10px; font-size: 12.5px; line-height: 1.5;
  background: var(--accent-soft); border: 1px solid var(--line); color: var(--text-dim);
}
.pr-exam-note b { color: var(--text); }

/* Worked steps under an exam answer. A student who got it wrong needs the route to the
   answer, not the answer restated — that was the whole complaint about mock exams. */
.rev-work { margin-top: 10px; padding-top: 9px; border-top: 1px dashed var(--line); }
.rev-work > b {
  display: block; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-dim); margin-bottom: 6px;
}
.rev-work ol { margin: 0; padding-left: 20px; }
.rev-work li { font-size: 13px; line-height: 1.6; margin-bottom: 4px; }
.rev-work li::marker { color: var(--accent); font-weight: 700; }
