/* GENERATED FILE. Do not edit this bundle directly.
   Run npm run css:generate after editing a file in app/styles/. */

/* Source: styles/base.css */
/* Tokens follow the aliensbrain OMR exam-sheet system: paper/ink + one yellow accent,
   scoped green/red only for correct/wrong feedback. */

:root {
  --paper: #faf7f0;
  --ink: #1f1d1a;
  --ink-soft: #6b6659;
  --accent: #ffd935;
  --card: #ffffff;
  --line: #e5dfd2;
  --correct: #2e9e44;
  --correct-bg: #e8f7ec;
  --wrong: #d64545;
  --wrong-bg: #fdecec;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: -apple-system, "Segoe UI", Roboto, "Noto Sans", sans-serif;
  min-height: 100vh;
}

header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 2px solid var(--line);
}

.icon-btn {
  font-size: 24px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  min-width: 48px;
  min-height: 48px;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.icon-btn[aria-pressed="true"] { background: var(--accent); }

main { max-width: 640px; margin: 0 auto; padding: 16px; }

/* progress dots */
.dots { display: flex; gap: 8px; }
.dot { width: 14px; height: 14px; border-radius: 50%; background: var(--line); }
.dot.done { background: var(--correct); }
.dot.missed { background: var(--wrong); }
.dot.now { background: var(--accent); transform: scale(1.25); }

/* question card */
/* Prompt row: prompt text plus the question-only mic (reads the stem, never
   the options). The row owns the vertical spacing the bare .prompt used to
   carry; .omr-q overrides below keep the exam player's tighter rhythm. */
.prompt-row { display: flex; align-items: flex-start; gap: 10px; margin: 16px 0; }
.prompt-row .prompt { flex: 1 1 auto; margin: 0; }
.prompt-mic {
  flex: 0 0 auto;
  min-width: 48px;
  min-height: 48px;
  font-size: 22px;
  background: #e8f0fe;
  border: 2px solid #9db8e8;
  border-radius: 12px;
  cursor: pointer;
}
.prompt-mic:active { transform: scale(0.94); }
.prompt-mic:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55); }
.prompt { font-size: 26px; font-weight: 700; text-align: center; margin: 16px 0; }

/* Powers print as real superscripts and chemical indexes as real subscripts
   (see engine/math-text.js). line-height: 0 keeps the shifted digit inside its
   own line box, so a prompt with x^2 or H2O does not sit taller than the one
   beside it. */
sup,
sub { font-size: 0.68em; line-height: 0; font-weight: inherit; }
sup { vertical-align: super; }
sub { vertical-align: sub; }

.q-visual {
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 16px;
  padding: 20px;
  margin-bottom: 20px;
  display: flex;
  justify-content: center;
}

/* Shared frame for maps and interactive answer surfaces. The component keeps
   owning its diagram while the player supplies one consistent ready/retry/
   checked state and a small keyboard affordance. */
.q-visual[data-a11y-ready="true"] {
  display: block;
  padding: 0;
  overflow: hidden;
  border-color: #d8d0c1;
  box-shadow: 0 8px 24px rgba(31, 29, 26, 0.08);
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.interactive-surface-bar {
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 12px;
  background: #fffdf3;
  border-bottom: 1px solid var(--line);
}
.interactive-surface-identity,
.interactive-surface-help {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}
.interactive-surface-mark {
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  display: grid;
  place-items: center;
  border: 2px solid var(--ink);
  border-radius: 9px;
  background: var(--accent);
  color: var(--ink);
  font-size: 14px;
  line-height: 1;
  box-shadow: 2px 2px 0 var(--ink);
}
.interactive-surface-label {
  overflow: hidden;
  color: var(--ink);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.035em;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.interactive-surface-status {
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 750;
  white-space: nowrap;
}
.interactive-keyboard-tip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: var(--ink-soft);
  font-size: 9px;
}
.interactive-keyboard-tip kbd {
  min-width: 25px;
  padding: 3px 5px;
  border: 1px solid #cfc6b7;
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--card);
  color: var(--ink-soft);
  font: 700 9px/1 ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  text-align: center;
}
.interactive-surface-stage {
  min-width: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(12px, 3vw, 20px);
  overflow-x: auto;
  overscroll-behavior-inline: contain;
}
.interactive-surface-stage > * { max-width: 100%; }

.q-visual[data-interactive-state="retry"] {
  border-color: #c99c15;
  box-shadow: 0 8px 24px rgba(201, 156, 21, 0.12);
}
.q-visual[data-interactive-state="retry"] .interactive-surface-status {
  color: #805f00;
}
.q-visual[data-interactive-state="correct"] {
  border-color: var(--correct);
  box-shadow: 0 8px 24px rgba(46, 158, 68, 0.14);
}
.q-visual[data-interactive-state="correct"] .interactive-surface-mark {
  color: #fff;
  border-color: var(--correct);
  background: var(--correct);
  box-shadow: none;
}
.q-visual[data-interactive-state="correct"] .interactive-surface-mark::before { content: "✓"; }
.q-visual[data-interactive-state="correct"] .interactive-surface-mark { font-size: 0; }
.q-visual[data-interactive-state="correct"] .interactive-surface-mark::before { font-size: 16px; }
.q-visual[data-interactive-state="correct"] .interactive-surface-status { color: var(--correct); }
.q-visual[data-interactive-state="incorrect"] {
  border-color: var(--wrong);
  box-shadow: 0 8px 24px rgba(214, 69, 69, 0.12);
}
.q-visual[data-interactive-state="incorrect"] .interactive-surface-mark {
  color: #fff;
  border-color: var(--wrong);
  background: var(--wrong);
  box-shadow: none;
}
.q-visual[data-interactive-state="incorrect"] .interactive-surface-mark::before { content: "×"; }
.q-visual[data-interactive-state="incorrect"] .interactive-surface-mark { font-size: 0; }
.q-visual[data-interactive-state="incorrect"] .interactive-surface-mark::before { font-size: 18px; }
.q-visual[data-interactive-state="incorrect"] .interactive-surface-status { color: var(--wrong); }

@media (max-width: 520px) {
  .q-visual[data-a11y-ready="true"] { margin-inline: -4px; border-radius: 14px; }
  .interactive-surface-bar { min-height: 44px; padding: 7px 9px; }
  .interactive-surface-stage { padding: 10px; }
  .interactive-keyboard-tip { display: none; }
  .interactive-surface-label,
  .interactive-surface-status { font-size: 11px; }
}

.objects-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  max-width: 420px;
  font-size: 34px;
}

/* compare-groups: two labelled groups side by side (Left vs Right) */
.compare-groups {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  justify-content: center;
  align-items: flex-start;
}
.compare-groups .group {
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  padding: 12px;
  min-width: 120px;
}
.compare-groups .group-label {
  font-size: 16px;
  font-weight: 700;
  text-align: center;
  margin-bottom: 8px;
  color: var(--ink-soft);
}
.compare-groups .group-items {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  max-width: 180px;
  font-size: 30px;
  line-height: 1.1;
}

/* options: kid mode needs >= 64px tap targets */
.options { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.opt {
  min-height: 72px;
  font-size: 28px;
  font-weight: 700;
  color: var(--ink);
  background: var(--card);
  border: 3px solid var(--line);
  border-radius: 16px;
  cursor: pointer;
  transition: transform 0.1s;
}
.opt:active { transform: scale(0.97); }
.opt:disabled { cursor: default; opacity: 0.9; }
.opt.correct { background: var(--correct-bg); border-color: var(--correct); animation: pop 0.4s; }
.opt.wrong { background: var(--wrong-bg); border-color: var(--wrong); animation: shake 0.4s; }

/* Read-aloud controls for the class 1-3 band (W5): a big hear-the-question
   button plus one speaker per option. A tap only speaks, never answers. */
.hear-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 52px;
  padding: 8px 18px;
  margin: 2px 0 12px;
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
  background: #e8f0fe;
  border: 3px solid #9db8e8;
  border-radius: 999px;
  cursor: pointer;
}
.hear-btn:active { transform: scale(0.97); }
.opt-row { display: flex; gap: 8px; align-items: stretch; }
.opt-row .opt { flex: 1; }
.opt-row .bubble { flex: 1; }
.opt-hear {
  min-width: 56px;
  font-size: 22px;
  background: #e8f0fe;
  border: 3px solid #9db8e8;
  border-radius: 16px;
  cursor: pointer;
}
.opt-hear:active { transform: scale(0.94); }

@keyframes pop { 40% { transform: scale(1.08); } }
@keyframes shake {
  20%, 60% { transform: translateX(-8px); }
  40%, 80% { transform: translateX(8px); }
}

.explain-card {
  margin-top: 18px;
  background: var(--card);
  border-left: 6px solid var(--accent);
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 20px;
}

/* worked solution steps (teaches the method, not just the answer) */
.worked-head {
  margin: 12px 0 4px;
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}
ol.worked {
  margin: 0;
  padding-left: 22px;
  font-size: 17px;
  line-height: 1.5;
  counter-reset: worked;
}
ol.worked li {
  margin: 6px 0;
  padding-left: 4px;
}

/* hint lifeline */
.hint-row { margin-top: 12px; text-align: center; }
.hint-btn {
  min-height: 44px;
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  background: var(--card);
  border: 2px dashed var(--line);
  border-radius: 999px;
  padding: 8px 18px;
  cursor: pointer;
  transition: border-color 0.1s, background 0.1s;
}
.hint-btn:hover { border-color: var(--accent); }
.hint-btn.used { opacity: 0.5; cursor: default; border-style: solid; }
.hint-card {
  margin: 10px auto 0;
  max-width: 480px;
  background: #fffdf3;
  border: 1px dashed var(--line);
  border-radius: 12px;
  padding: 10px 14px;
  font-size: 16px;
  line-height: 1.45;
  color: var(--ink);
  text-align: center;
}
.hint-card[hidden] { display: none; }

/* retired interactive target (first-miss retry in kid player) */
.is-retired { opacity: 0.4; pointer-events: none; }

.next-btn, .big-btn {
  display: block;
  margin: 20px auto 0;
  min-height: 64px;
  min-width: 200px;
  font-size: 24px;
  font-weight: 700;
  background: var(--accent);
  color: var(--ink);
  border: none;
  border-radius: 16px;
  cursor: pointer;
}

/* retry toast (kid player) */
.toast {
  position: fixed;
  top: 14px;
  left: 50%;
  transform: translate(-50%, -12px);
  background: var(--ink);
  color: var(--paper);
  font-size: 17px;
  font-weight: 700;
  padding: 10px 22px;
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(31, 29, 26, 0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 50;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.warn { background: var(--wrong); }

/* a retired option (wrong on first try) stays visible but out of play */
.opt.retired { opacity: 0.45; }

/* secondary big button (Next topic on end screens) */
.ghost-btn {
  display: block;
  margin: 14px auto 0;
  background: var(--card);
  border: 3px solid var(--ink);
  color: var(--ink);
  text-decoration: none;
  text-align: center;
  line-height: 58px;
  min-height: 58px;
}
.ghost-btn:hover { background: var(--accent); border-color: var(--accent); }

/* end screen */
.end { text-align: center; padding: 40px 0; }
.end a.big-btn { text-decoration: none; text-align: center; line-height: 58px; }
.end .stars { font-size: 52px; letter-spacing: 6px; margin: 16px 0; }
.end h2 { font-size: 30px; margin: 0; }
.end p { color: var(--ink-soft); font-size: 20px; }

.focus-panel {
  max-width: 440px;
  margin: 18px auto 8px;
  padding: 12px 14px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  text-align: left;
}
.scorecard .focus-panel, .end .focus-panel { margin-bottom: 18px; }
.focus-panel .focus-head {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.focus-panel .focus-list { display: flex; flex-direction: column; gap: 8px; }
.focus-panel .focus-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  border: 2px solid var(--line);
  border-radius: 10px;
  color: var(--ink);
  text-decoration: none;
  font-size: 15px;
  font-weight: 700;
}
.focus-panel .focus-row:hover { border-color: var(--accent); }
.focus-panel .focus-row:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55); }
.focus-panel .focus-copy { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.focus-panel .focus-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.focus-panel .focus-reason { color: var(--ink-soft); font-size: 12px; font-weight: 600; text-transform: none; letter-spacing: 0; }
.focus-panel .focus-go { font-size: 13px; font-weight: 800; color: var(--ink-soft); white-space: nowrap; }

.celebrate {
  position: fixed;
  inset: 0;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 90px;
  animation: burst 0.9s ease-out forwards;
}
@keyframes burst {
  from { transform: scale(0.3); opacity: 1; }
  to { transform: scale(2); opacity: 0; }
}

/* gallery + home */
.tpl-card {
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 20px;
}
.tpl-card h3 { margin: 0 0 4px; font-family: monospace; }
.tpl-card .meta-line { color: var(--ink-soft); font-size: 14px; margin-bottom: 12px; }
.variant { border-top: 1px dashed var(--line); padding: 12px 0; }
.variant .opts { margin-top: 8px; font-size: 15px; }
.variant .opts .right { background: var(--correct-bg); border: 1px solid var(--correct); border-radius: 6px; padding: 2px 8px; }
.variant .opts span { margin-right: 8px; padding: 2px 8px; }
.home-list a {
  display: block;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 12px;
  font-size: 20px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
}
.home-list a:hover { border-color: var(--accent); }

/* home page section headings */
.home-section { margin-top: 8px; }
.home-section h2 { font-size: 24px; margin: 24px 0 4px; }
.home-section h3 {
  font-size: 14px;
  color: var(--ink-soft);
  margin: 16px 0 8px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* exam player (OMR-flavoured) */
.exam-meta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  font-size: 13px;
  color: var(--ink-soft);
}
.exam-meta .q-count { font-weight: 700; color: var(--ink); font-size: 14px; }
.exam-meta .score-pill {
  background: var(--ink);
  color: var(--paper);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 12px;
  font-weight: 700;
}

.omr-q {
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 16px;
  padding: 18px 18px 22px;
}
.mock-notice {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 12px;
  padding: 11px 14px;
  background: #fff8df;
  border: 1px solid #d9bd68;
  border-radius: 12px;
  color: var(--ink);
  font-size: 14px;
  line-height: 1.4;
}
.mock-notice strong { font-size: 15px; }
.q-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--ink);
  font-weight: 800;
  font-size: 16px;
  margin-bottom: 8px;
}
.omr-q .prompt { text-align: left; font-size: 21px; margin: 4px 0 14px; }
.omr-q .prompt-row { margin: 4px 0 14px; }
.omr-q .prompt-mic { min-width: 44px; min-height: 44px; font-size: 19px; }

.passage {
  background: #fffdf3;
  border: 1px dashed var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  font-size: 17px;
  line-height: 1.5;
  margin-bottom: 14px;
  color: var(--ink);
}
.passage-tag {
  display: inline-block;
  background: var(--accent);
  color: var(--ink);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-radius: 6px;
  padding: 2px 8px;
  margin-right: 6px;
  vertical-align: middle;
}

/* Achievers items carry double weight on real papers; surface that in
   chapter practice too so a child learns the section is special. */
.q-marks-badge {
  display: inline-block;
  background: #ffe0b2;
  border: 1px solid #ffb74d;
  color: #7a4a00;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  border-radius: 999px;
  padding: 3px 10px;
  margin-bottom: 8px;
}

.bubbles { display: flex; flex-direction: column; gap: 10px; }
.bubble {
  display: flex;
  align-items: center;
  gap: 14px;
  text-align: left;
  min-height: 60px;
  font-size: 20px;
  font-weight: 600;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: 14px;
  padding: 10px 16px;
  cursor: pointer;
  transition: transform 0.1s, border-color 0.1s, background 0.1s;
}
.bubble:active { transform: scale(0.99); }
.bubble .bub { font-size: 24px; line-height: 1; color: var(--ink-soft); width: 26px; text-align: center; }
.bubble .blet { font-weight: 800; color: var(--ink-soft); width: 18px; }
.bubble .btext { flex: 1; }
.bubble.picked-correct { border-color: var(--correct); background: var(--correct-bg); }
.bubble.picked-correct .bub, .bubble.picked-correct .blet { color: var(--correct); }
.bubble.picked-wrong { border-color: var(--wrong); background: var(--wrong-bg); }
.bubble.picked-wrong .bub, .bubble.picked-wrong .blet { color: var(--wrong); animation: shake 0.4s; }
.bubble.reveal-correct { border-color: var(--correct); }
.bubble.reveal-correct .bub, .bubble.reveal-correct .blet { color: var(--correct); }
.bubble:disabled { cursor: default; }

/* scorecard */
.scorecard { text-align: center; padding: 30px 0; }
.scorecard h2 { font-size: 26px; margin: 0 0 6px; }
.score-big { font-size: 64px; font-weight: 800; line-height: 1; }
.score-big span { font-size: 30px; color: var(--ink-soft); font-weight: 700; }
.score-pct { font-size: 22px; font-weight: 700; color: var(--correct); margin: 4px 0 10px; }
.scorecard .remark { color: var(--ink-soft); font-size: 18px; margin-bottom: 20px; }
.link-btn { display: inline-block; margin-top: 14px; color: var(--ink-soft); font-size: 16px; text-decoration: underline; }

/* Source: styles/interactive-map.css */
/* interactive India map (tap-the-state) - framed map panel with depth */
.map-card { margin: 0 auto; max-width: 420px; width: 100%; }
.india-map {
  width: 100%; height: auto; display: block; margin: 0 auto;
  touch-action: manipulation;
  animation: map-in 0.45s ease-out both;
}
@keyframes map-in { from { opacity: 0; } to { opacity: 1; } }
.india-map .map-sea { stroke: #b6d3e8; stroke-width: 1.5; }

.india-map .regions .region {
  stroke: #ffffff; stroke-width: 1.1; stroke-linejoin: round;
  transition: fill 0.18s ease, fill-opacity 0.18s ease, stroke-width 0.14s ease, filter 0.14s ease;
}
.india-map .regions .region.dim { fill: #e7dfca; stroke: #f8f4e9; pointer-events: none; }

/* interactive states: four Okabe-Ito categorical fills (colour-blind safe;
   green/red reserved for feedback) so adjacent choices read as distinct */
.india-map .regions .region.tap { cursor: pointer; animation: tap-breathe 2.8s ease-in-out infinite; }
.india-map .regions .region.tap.c0 { fill: #56b4e9; }
.india-map .regions .region.tap.c1 { fill: #e69f00; }
.india-map .regions .region.tap.c2 { fill: #cc79a7; }
.india-map .regions .region.tap.c3 { fill: #f0d442; }
@keyframes tap-breathe { 0%, 100% { fill-opacity: 1; } 50% { fill-opacity: 0.86; } }
.india-map:not(.locked) .regions .region.tap:hover,
.india-map:not(.locked) .regions .region.tap:focus-visible {
  filter: brightness(1.08) saturate(1.15); stroke: #ffffff; stroke-width: 2.2; outline: none;
}
.india-map.locked .regions .region.tap { cursor: default; animation: none; }
/* after the answer: quieten the choices that are out of play */
.india-map.locked .regions .region.tap:not(.map-correct):not(.map-wrong):not(.map-reveal) {
  fill-opacity: 0.35;
}

.india-map .regions .region.map-correct {
  fill: var(--correct) !important; stroke: #1c6b2a; stroke-width: 2.2;
  filter: url(#map-glow); animation: pop 0.4s;
}
.india-map .regions .region.map-wrong {
  fill: var(--wrong) !important; stroke: #7a2222; stroke-width: 2.2; stroke-dasharray: 4 2;
  animation: shake 0.4s;
}
.india-map .regions .region.map-reveal {
  fill: var(--correct) !important; stroke: #1c6b2a; stroke-width: 2.6;
  filter: url(#map-glow);
}

/* code chips on tappable states: white pill + 2-letter code, taps fall through */
.india-map .map-labels { pointer-events: none; }
.india-map .map-label rect {
  fill: rgba(255, 255, 255, 0.92); stroke: rgba(40, 64, 90, 0.25); stroke-width: 1;
}
.india-map .map-label text {
  font-family: inherit; font-size: 13px; font-weight: 800; letter-spacing: 0.04em;
  fill: #2f3540; text-anchor: middle;
}
.india-map .map-label { transition: opacity 0.25s ease; }
.india-map .map-label.faded { opacity: 0.25; }

.map-readout {
  text-align: center; margin-top: 10px; min-height: 22px;
  font-size: 15px; font-weight: 700; letter-spacing: 0.06em;
  color: var(--ink-soft); text-transform: uppercase;
}
@media (prefers-reduced-motion: reduce) {
  .india-map { animation: none; }
  .india-map .regions .region.tap { animation: none; }
}

/* Source: styles/interactive-solar.css */
/* Interactive Solar System orbital diagram (tap-the-planet) */
.solar-card { margin: 0 auto; max-width: 480px; width: 100%; }
.solar-diagram {
  width: 100%; height: auto; display: block; margin: 0 auto;
  touch-action: manipulation;
  animation: solar-in 0.45s ease-out both;
}
@keyframes solar-in { from { opacity: 0; transform: scale(0.985); } to { opacity: 1; transform: none; } }

.solar-diagram .solar-panel { stroke: #e2dccd; stroke-width: 1.5; }
.solar-diagram .orbits .orbit {
  fill: none; stroke: #d9d2c2; stroke-width: 1; stroke-dasharray: 2 3; opacity: 0.7;
}
.solar-diagram .sun circle { stroke: #f0b41c; stroke-width: 1; }

.solar-diagram .planets .planet { transition: opacity 0.2s ease, filter 0.14s ease; }
/* dim context planets: faded, no labels, never a target (like map dim regions) */
.solar-diagram .planets .planet.dim .body { opacity: 0.42; }
.solar-diagram .planets .planet.dim { pointer-events: none; }

/* tappable planets: canonical colour kept; a dashed accent ring signals interactive */
.solar-diagram .planets .planet.tap { cursor: pointer; animation: solar-breathe 2.8s ease-in-out infinite; }
@keyframes solar-breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.85; } }
/* inner wrapper holds pop/shake transforms so the outer translate is never lost */
.solar-diagram .planets .planet-inner { transform-box: fill-box; transform-origin: center; }
.solar-diagram .planets .planet.tap .tap-ring {
  fill: none; stroke: #ffd935; stroke-width: 1.4; stroke-dasharray: 3 2.5; opacity: 0.7;
}
.solar-diagram .planets .planet.tap .hit { fill: transparent; pointer-events: all; }
.solar-diagram:not(.solar-locked) .planets .planet.tap:hover .tap-ring,
.solar-diagram:not(.solar-locked) .planets .planet.tap:focus-visible .tap-ring {
  stroke: #1f1d1a; opacity: 1; stroke-width: 2;
}
.solar-diagram:not(.solar-locked) .planets .planet.tap:hover .body,
.solar-diagram:not(.solar-locked) .planets .planet.tap:focus-visible .body {
  filter: brightness(1.08) saturate(1.12);
}
.solar-diagram .planets .planet.tap:focus-visible { outline: none; }

/* locked state: stop the breathe, quiet the choices that are out of play */
.solar-diagram.solar-locked .planets .planet.tap { cursor: default; animation: none; }
.solar-diagram.solar-locked .planets .planet.tap.faded { opacity: 0.3; }
.solar-diagram.solar-locked .planets .planet.tap:not(.solar-correct):not(.solar-wrong):not(.solar-reveal) {
  opacity: 0.4;
}

/* feedback - green/red reserved strictly for correct/wrong/reveal */
.solar-diagram .planets .planet.solar-correct .body,
.solar-diagram .planets .planet.solar-reveal .body {
  fill: var(--correct) !important; filter: url(#solar-glow);
}
.solar-diagram .planets .planet.solar-correct .detail,
.solar-diagram .planets .planet.solar-reveal .detail { display: none; }
.solar-diagram .planets .planet.solar-correct .tap-ring,
.solar-diagram .planets .planet.solar-reveal .tap-ring {
  stroke: var(--correct); opacity: 1; stroke-dasharray: none;
}
.solar-diagram .planets .planet.solar-correct .planet-inner { animation: solar-pop 0.4s; }
@keyframes solar-pop { 40% { transform: scale(1.14); } }
.solar-diagram .planets .planet.solar-wrong .body { fill: var(--wrong) !important; }
.solar-diagram .planets .planet.solar-wrong .detail { display: none; }
.solar-diagram .planets .planet.solar-wrong .tap-ring {
  stroke: var(--wrong); stroke-dasharray: none; opacity: 1;
}
.solar-diagram .planets .planet.solar-wrong .planet-inner { animation: solar-shake 0.4s; }
@keyframes solar-shake {
  20%, 60% { transform: translateX(-3px); }
  40%, 80% { transform: translateX(3px); }
}

/* name chips on tappable planets: white pill, taps resolve to the planet group */
.solar-diagram .solar-chip rect {
  fill: rgba(255, 255, 255, 0.95); stroke: rgba(40, 38, 32, 0.22); stroke-width: 1;
}
.solar-diagram .solar-chip text {
  font-family: inherit; font-size: 12px; font-weight: 800; fill: #1f1d1a; text-anchor: middle;
}

.solar-readout {
  text-align: center; margin-top: 10px; min-height: 22px;
  font-size: 15px; font-weight: 700; letter-spacing: 0.06em;
  color: var(--ink-soft); text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .solar-diagram { animation: none; }
  .solar-diagram .planets .planet.tap { animation: none; }
  .solar-diagram .planets .planet-inner { animation: none !important; }
}

/* Source: styles/interactive-timeline.css */
/* Interactive horizontal timeline (tap-the-event). Greens/reds are reserved
   for correct/wrong feedback only; event chips use four colour-blind-safe
   Okabe-Ito categorical tints (blue, orange, purple, sky). */
.timeline-card { margin: 0 auto; max-width: 460px; width: 100%; }

.timeline-svg {
  width: 100%;
  height: auto;
  display: block;
  margin: 0 auto;
  touch-action: manipulation;
  animation: timeline-in 0.45s ease-out both;
}
@keyframes timeline-in { from { opacity: 0; } to { opacity: 1; } }

.timeline-svg .tl-bg { fill: #fffdf6; stroke: var(--line); stroke-width: 1.5; }
.timeline-svg .tl-baseline { stroke: #c4bba4; stroke-width: 2.5; stroke-linecap: round; }
.timeline-svg .tl-arrow { fill: #c4bba4; }
.timeline-svg .tl-tick { stroke: #c4bba4; stroke-width: 1.5; }
.timeline-svg .tl-tick-label {
  font-family: inherit; font-size: 10.5px; font-weight: 700;
  fill: var(--ink-soft); text-anchor: middle; letter-spacing: 0.02em;
}

/* tappable event group */
.timeline-svg .timeline-event { cursor: pointer; outline: none; }
.timeline-svg .timeline-event .tl-card {
  stroke-width: 2;
  transition: fill 0.18s ease, stroke 0.18s ease, stroke-width 0.14s ease, filter 0.14s ease;
}
.timeline-svg .timeline-event .tl-title {
  font-family: inherit; font-size: 12px; font-weight: 800;
  fill: var(--ink); text-anchor: middle; pointer-events: none;
}
.timeline-svg .timeline-event .tl-year {
  font-family: inherit; font-size: 10.5px; font-weight: 700;
  fill: var(--ink-soft); text-anchor: middle; letter-spacing: 0.03em; pointer-events: none;
}
.timeline-svg .timeline-event .tl-connector { stroke-width: 2; stroke-dasharray: 3 3; }
.timeline-svg .timeline-event .tl-dot {
  stroke: #ffffff; stroke-width: 1.5;
  transform-box: fill-box; transform-origin: center;
}

/* idle attention: gentle dot pulse, disabled on answer */
.timeline-svg:not(.timeline-locked) .timeline-event .tl-dot {
  animation: timeline-pulse 2.4s ease-in-out infinite;
}
@keyframes timeline-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.18); }
}

/* categorical tints (colour-blind safe; never green/red) */
.timeline-svg .timeline-event.tl-c0 .tl-card { fill: #d6e8f5; stroke: #0072b2; }
.timeline-svg .timeline-event.tl-c0 .tl-dot { fill: #0072b2; }
.timeline-svg .timeline-event.tl-c0 .tl-connector { stroke: #0072b2; }

.timeline-svg .timeline-event.tl-c1 .tl-card { fill: #fbe7c8; stroke: #e69f00; }
.timeline-svg .timeline-event.tl-c1 .tl-dot { fill: #e69f00; }
.timeline-svg .timeline-event.tl-c1 .tl-connector { stroke: #e69f00; }

.timeline-svg .timeline-event.tl-c2 .tl-card { fill: #f0d8e6; stroke: #cc79a7; }
.timeline-svg .timeline-event.tl-c2 .tl-dot { fill: #cc79a7; }
.timeline-svg .timeline-event.tl-c2 .tl-connector { stroke: #cc79a7; }

.timeline-svg .timeline-event.tl-c3 .tl-card { fill: #d9eff8; stroke: #56b4e9; }
.timeline-svg .timeline-event.tl-c3 .tl-dot { fill: #56b4e9; }
.timeline-svg .timeline-event.tl-c3 .tl-connector { stroke: #56b4e9; }

/* hover / keyboard focus */
.timeline-svg:not(.timeline-locked) .timeline-event:hover .tl-card,
.timeline-svg:not(.timeline-locked) .timeline-event:focus-visible .tl-card {
  stroke-width: 3;
  filter: brightness(1.05);
}
.timeline-svg:not(.timeline-locked) .timeline-event:focus-visible .tl-card {
  stroke: var(--ink);
}

/* locked: quieten the cards that are out of play */
.timeline-svg.timeline-locked .timeline-event { cursor: default; }
.timeline-svg.timeline-locked .timeline-event .tl-dot { animation: none; }
.timeline-svg.timeline-locked .timeline-event:not(.timeline-correct):not(.timeline-wrong):not(.timeline-reveal) .tl-card { fill-opacity: 0.42; }
.timeline-svg.timeline-locked .timeline-event:not(.timeline-correct):not(.timeline-wrong):not(.timeline-reveal) .tl-title { fill-opacity: 0.5; }
.timeline-svg.timeline-locked .timeline-event:not(.timeline-correct):not(.timeline-wrong):not(.timeline-reveal) .tl-year { fill-opacity: 0.5; }
.timeline-svg.timeline-locked .timeline-event:not(.timeline-correct):not(.timeline-wrong):not(.timeline-reveal) .tl-connector { stroke-opacity: 0.4; }
.timeline-svg.timeline-locked .timeline-event:not(.timeline-correct):not(.timeline-wrong):not(.timeline-reveal) .tl-dot { fill-opacity: 0.4; }

/* feedback: green/red reserved for correct/wrong/reveal only */
.timeline-svg .timeline-event.timeline-correct .tl-card,
.timeline-svg .timeline-event.timeline-wrong .tl-card,
.timeline-svg .timeline-event.timeline-reveal .tl-card {
  transform-box: fill-box; transform-origin: center;
}
.timeline-svg .timeline-event.timeline-correct .tl-card {
  fill: var(--correct-bg) !important; stroke: var(--correct) !important; stroke-width: 2.5;
  filter: url(#tl-glow);
  animation: timeline-pop 0.4s ease-out;
}
.timeline-svg .timeline-event.timeline-correct .tl-dot { fill: var(--correct) !important; }
.timeline-svg .timeline-event.timeline-correct .tl-connector { stroke: var(--correct) !important; }

.timeline-svg .timeline-event.timeline-wrong .tl-card {
  fill: var(--wrong-bg) !important; stroke: var(--wrong) !important; stroke-width: 2.5;
  stroke-dasharray: 4 2;
  animation: timeline-shake 0.4s ease-out;
}
.timeline-svg .timeline-event.timeline-wrong .tl-dot { fill: var(--wrong) !important; }
.timeline-svg .timeline-event.timeline-wrong .tl-connector { stroke: var(--wrong) !important; }

.timeline-svg .timeline-event.timeline-reveal .tl-card {
  fill: var(--correct-bg) !important; stroke: var(--correct) !important; stroke-width: 2.5;
  filter: url(#tl-glow);
}
.timeline-svg .timeline-event.timeline-reveal .tl-dot { fill: var(--correct) !important; }
.timeline-svg .timeline-event.timeline-reveal .tl-connector { stroke: var(--correct) !important; }

@keyframes timeline-pop { 40% { transform: scale(1.06); } }
@keyframes timeline-shake {
  20%, 60% { transform: translateX(-3px); }
  40%, 80% { transform: translateX(3px); }
}

.timeline-readout {
  text-align: center; margin-top: 10px; min-height: 22px;
  font-size: 15px; font-weight: 700; letter-spacing: 0.06em;
  color: var(--ink-soft); text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .timeline-svg { animation: none; }
  .timeline-svg:not(.timeline-locked) .timeline-event .tl-dot { animation: none; }
  .timeline-svg .timeline-event.timeline-correct .tl-card,
  .timeline-svg .timeline-event.timeline-wrong .tl-card { animation: none; }
}

/* Source: styles/interactive-spotting.css */
/* Interactive spotting-errors widget (tap-the-wrong-part).
   Mirrors the India-map system: soft depth, rounded panels, Okabe-Ito
   categorical chip tints cycled per part; green and red stay reserved for
   correct/wrong feedback only. Reuses the global pop/shake keyframes. */
.spotting-card { margin: 0 auto; max-width: 460px; width: 100%; animation: spotting-in 0.4s ease-out both; }
@keyframes spotting-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

.spotting-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.spotting-icon { width: 20px; height: 20px; color: var(--ink-soft); flex-shrink: 0; }
.spotting-title { font-size: 13px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-soft); }

/* Category badge: Okabe-Ito tinted pill (driven by --cat-hue/--cat-tint set inline), never green/red. */
.spotting-cat { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; background: var(--cat-tint); color: var(--cat-hue); font-size: 12px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; padding: 4px 10px; border-radius: 999px; }
.spotting-cat-dot { width: 9px; height: 9px; }
.spotting-cat-dot circle { fill: var(--cat-hue); }

/* Sentence panel: a soft warm "worksheet" surface the chips sit on. */
.spotting-sentence { display: flex; flex-wrap: wrap; gap: 8px 7px; justify-content: center; align-items: center; background: var(--paper); border: 1px solid var(--line); border-radius: 14px; padding: 16px 14px; box-shadow: inset 0 1px 2px rgba(31, 29, 26, 0.04); }

/* Tappable segment chip. Tint comes from --chip-ink/--chip-border/--chip-bg set inline per part. */
.spotting-chip { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; min-height: 44px; padding: 7px 14px 7px 7px; background: var(--chip-bg); border: 2px solid var(--chip-border); color: var(--chip-ink); border-radius: 999px; font-size: 17px; font-weight: 600; line-height: 1.2; cursor: pointer; user-select: none; transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease, background 0.12s ease, color 0.12s ease; }
.spotting-chip-mark { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; flex-shrink: 0; border-radius: 50%; background: var(--chip-ink); color: #fff; font-size: 12px; font-weight: 800; letter-spacing: 0.02em; }
.spotting-chip-text { white-space: nowrap; }

/* Hover/active/focus only while unlocked. */
.spotting-card:not(.spotting-locked) .spotting-chip:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(31, 29, 26, 0.10); border-color: var(--chip-ink); }
.spotting-card:not(.spotting-locked) .spotting-chip:active { transform: scale(0.97); }
.spotting-card:not(.spotting-locked) .spotting-chip:focus-visible { outline: none; border-color: var(--chip-ink); box-shadow: 0 0 0 3px var(--accent); }

/* Feedback states: green/red reserved for correct/wrong only. */
.spotting-chip.spotting-correct { background: var(--correct-bg) !important; border-color: var(--correct) !important; color: var(--correct) !important; animation: pop 0.4s; }
.spotting-chip.spotting-correct .spotting-chip-mark { background: var(--correct); color: #fff; }
.spotting-chip.spotting-wrong { background: var(--wrong-bg) !important; border-color: var(--wrong) !important; color: var(--wrong) !important; animation: shake 0.4s; }
.spotting-chip.spotting-wrong .spotting-chip-mark { background: var(--wrong); color: #fff; }
.spotting-chip.spotting-reveal { background: var(--correct-bg) !important; border-color: var(--correct) !important; color: var(--correct) !important; box-shadow: 0 0 0 2px rgba(46, 158, 68, 0.25); }
.spotting-chip.spotting-reveal .spotting-chip-mark { background: var(--correct); color: #fff; }

/* Lock: quieten chips that are out of play so the result pops. */
.spotting-card.spotting-locked .spotting-chip { cursor: default; }
.spotting-card.spotting-locked .spotting-chip:not(.spotting-correct):not(.spotting-wrong):not(.spotting-reveal) { opacity: 0.42; }

.spotting-readout { text-align: center; margin-top: 12px; min-height: 22px; font-size: 15px; font-weight: 700; letter-spacing: 0.06em; color: var(--ink-soft); text-transform: uppercase; }

@media (prefers-reduced-motion: reduce) {
  .spotting-card { animation: none; }
  .spotting-chip,
  .spotting-card:not(.spotting-locked) .spotting-chip:hover,
  .spotting-card:not(.spotting-locked) .spotting-chip:active { transition: none; transform: none; }
  .spotting-chip.spotting-correct,
  .spotting-chip.spotting-wrong { animation: none; }
}

/* Source: styles/interactive-circuit.css */
/* ===== Interactive series circuit (tap-the-part) - Option B pick-one =====
   Tappable components carry data-name; a tap resolves to
   options.indexOf(name) === answerIndex. Green/red are reserved for
   correct/wrong feedback; four Okabe-Ito categorical shades distinguish the
   four choices so adjacent parts read as distinct. `color` on each category
   class is the shade the active glyph parts pick up via currentColor, which is
   also how the feedback colour overrides a part on answer. */

.circuit-card { margin: 0 auto; max-width: 440px; width: 100%; }

.circuit-svg {
  width: 100%;
  height: auto;
  display: block;
  margin: 0 auto;
  touch-action: manipulation;
  animation: circuit-in 0.45s ease-out both;
}
@keyframes circuit-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

/* board panel + the non-tappable connecting wire loop (context only) */
.circuit-board {
  fill: #fbf4e2;
  stroke: var(--line);
  stroke-width: 2;
  filter: drop-shadow(0 3px 5px rgba(58, 53, 43, 0.12));
}
.circuit-ctx-loop {
  fill: none;
  stroke: #9c9486;
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* a tappable component. `color` is the categorical shade (Okabe-Ito, none are
   green or red) consumed by the active glyph parts through currentColor. */
.circuit-comp { cursor: pointer; }
.circuit-comp.circuit-c0 { color: #1f7fb8; } /* sky blue */
.circuit-comp.circuit-c1 { color: #b37400; } /* orange */
.circuit-comp.circuit-c2 { color: #9a4f7c; } /* reddish-purple */
.circuit-comp.circuit-c3 { color: #807012; } /* dark yellow */

/* soft tinted halo behind each part; the visible "card" of the choice */
.circuit-inner { transform-box: fill-box; transform-origin: center; }
.circuit-pad {
  fill: currentColor;
  fill-opacity: 0.10;
  stroke: currentColor;
  stroke-opacity: 0.42;
  stroke-width: 1.5;
  filter: drop-shadow(0 2px 3px rgba(58, 53, 43, 0.14));
  transition: fill-opacity 0.18s ease, stroke-opacity 0.18s ease, stroke-width 0.18s ease;
}

/* neutral metal leads entering each part (stay constant, never feedback-coloured) */
.circuit-lead { stroke: #6f6a5e; stroke-width: 3; stroke-linecap: round; }

/* --- cell / battery --- */
.circuit-plate { stroke: currentColor; stroke-width: 3.4; stroke-linecap: round; }
.circuit-mark { font-family: inherit; font-size: 16px; font-weight: 800; fill: currentColor; }

/* --- bulb --- */
.circuit-glass { fill: rgba(255, 248, 224, 0.55); stroke: currentColor; stroke-width: 1.8; }
.circuit-base { fill: #8a8273; stroke: currentColor; stroke-width: 1.4; stroke-linejoin: round; }
.circuit-filament { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.circuit-glow-core { fill: #ffb627; fill-opacity: 0.85; transform-box: fill-box; transform-origin: center; }
.circuit-rays line { stroke: #ffb627; stroke-width: 2.2; stroke-linecap: round; opacity: 0.9; }
.circuit-comp.circuit-on .circuit-glow-core { animation: circuit-glow 2.6s ease-in-out infinite; }
@keyframes circuit-glow { 0%, 100% { fill-opacity: 0.65; } 50% { fill-opacity: 1; } }

/* --- buzzer --- */
.circuit-body { fill: #efe9d8; stroke: currentColor; stroke-width: 1.8; }
.circuit-hole { fill: #6f6a5e; }
.circuit-wave path { fill: none; stroke: #d98a00; stroke-width: 2; stroke-linecap: round; opacity: 0.85; }

/* --- switch --- */
.circuit-post { fill: currentColor; }
.circuit-lever { stroke: currentColor; stroke-width: 3.6; stroke-linecap: round; }

/* --- wire --- */
.circuit-wire-seg { stroke: #6f6a5e; stroke-width: 4; stroke-linecap: round; }
.circuit-electron { fill: currentColor; }
/* gentle current-flow cue when the circuit is closed (educational, not feedback) */
.circuit-wire-seg.circuit-flow { stroke-dasharray: 7 6; animation: circuit-current 1.2s linear infinite; }
@keyframes circuit-current { to { stroke-dashoffset: -26; } }

/* hover + keyboard focus (active only while the widget is interactive) */
.circuit-comp:focus-visible { outline: none; }
.circuit-svg:not(.circuit-locked) .circuit-comp:hover .circuit-pad {
  fill-opacity: 0.22;
  stroke-opacity: 1;
  stroke-width: 2.6;
}
.circuit-svg:not(.circuit-locked) .circuit-comp:focus-visible .circuit-pad {
  fill-opacity: 0.24;
  stroke-opacity: 1;
  stroke-width: 3;
}

/* locked after answering: stop input, quieten the parts no longer in play */
.circuit-svg.circuit-locked .circuit-comp { cursor: default; }
.circuit-svg.circuit-locked .circuit-comp:not(.circuit-correct):not(.circuit-wrong):not(.circuit-reveal) {
  opacity: 0.4;
  transition: opacity 0.25s ease;
}

/* feedback: override `color` so every active (currentColor) part turns green or
   red, and the halo pad becomes a solid result chip. Animations reuse the
   global pop/shake keyframes (same as app/map.js). */
.circuit-comp.circuit-correct { color: var(--correct); }
.circuit-comp.circuit-correct .circuit-pad {
  fill: var(--correct-bg);
  stroke: var(--correct);
  stroke-width: 2.6;
  stroke-dasharray: none;
}
.circuit-comp.circuit-correct .circuit-inner { animation: pop 0.4s; }

.circuit-comp.circuit-wrong { color: var(--wrong); }
.circuit-comp.circuit-wrong .circuit-pad {
  fill: var(--wrong-bg);
  stroke: var(--wrong);
  stroke-width: 2.6;
  stroke-dasharray: 5 2.5;
}
.circuit-comp.circuit-wrong .circuit-inner { animation: shake 0.4s; }

.circuit-comp.circuit-reveal { color: var(--correct); }
.circuit-comp.circuit-reveal .circuit-pad {
  fill: var(--correct-bg);
  fill-opacity: 0.9;
  stroke: var(--correct);
  stroke-width: 2.8;
  stroke-dasharray: none;
}

/* readout caption (hint / hovered name / answer) */
.circuit-readout {
  text-align: center;
  margin-top: 10px;
  min-height: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .circuit-svg { animation: none; }
  .circuit-comp.circuit-on .circuit-glow-core,
  .circuit-wire-seg.circuit-flow { animation: none; }
  .circuit-comp.circuit-correct .circuit-inner,
  .circuit-comp.circuit-wrong .circuit-inner { animation: none; }
  .circuit-pad { transition: none; }
}

/* Source: styles/interactive-plantbody.css */
/* interactive plant / human-body figure (tap-the-part) - framed cross-section
   panels with soft depth. Green/red stay reserved for correct/wrong feedback;
   the four tappable parts use colour-blind-safe Okabe-Ito fills. */
.plantbody-card {
  margin: 0 auto;
  max-width: 420px;
  width: 100%;
  text-align: center;
}

.plantbody-tag {
  display: inline-block;
  margin: 0 auto 10px;
  padding: 4px 14px;
  background: var(--paper);
  border: 1.5px solid var(--line);
  border-radius: 999px;
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.plantbody-svg {
  display: block;
  width: 100%;
  height: auto;
  margin: 0 auto;
  touch-action: manipulation;
  animation: plantbody-in 0.45s ease-out both;
}
@keyframes plantbody-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* transparent hit areas: invisible but always catch the pointer so every part
   has a comfortable tap target regardless of its stroke thickness. */
.plantbody-hit {
  fill: transparent;
  stroke: none;
  pointer-events: all;
}
/* Only the transparent hit areas receive pointer events; all painted art is
   pointer-events:none so a tap in an overlap always lands on the intended
   part's hit zone (drawn last, on top), never on a sibling's painted shape. */
.plantbody-part.tap *,
.plantbody-part.dim,
.plantbody-part.dim * {
  pointer-events: none;
}
.plantbody-part.tap .plantbody-hit {
  pointer-events: all;
}

/* parts: smooth colour/opacity transitions; transform-box lets pop/shake animate
   from each part's own centre rather than the SVG origin. */
.plantbody-part {
  transform-box: fill-box;
  transform-origin: center;
  transition: fill 0.18s ease, stroke 0.18s ease, opacity 0.18s ease, filter 0.14s ease;
}

/* non-option parts render as quiet sand context and never register taps. */
.plantbody-part.dim {
  fill: #e2d8c2;
  stroke: #c9bd9f;
  opacity: 0.6;
  pointer-events: none;
}

/* four colour-blind-safe categorical fills (Okabe-Ito blue / orange / magenta /
   yellow). None is green or red, so feedback colours stay unambiguous. */
.plantbody-part.tap { cursor: pointer; animation: plantbody-breathe 2.8s ease-in-out infinite; }
.plantbody-part.tap.c0 { fill: #56b4e9; stroke: #2a8fc9; }
.plantbody-part.tap.c1 { fill: #e69f00; stroke: #b67800; }
.plantbody-part.tap.c2 { fill: #cc79a7; stroke: #a05782; }
.plantbody-part.tap.c3 { fill: #f0d442; stroke: #c4a519; }
@keyframes plantbody-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.84; }
}

/* gentle lift + soft shadow on hover and keyboard focus (pre-answer only). */
.plantbody-svg:not(.plantbody-locked) .plantbody-part.tap:hover,
.plantbody-svg:not(.plantbody-locked) .plantbody-part.tap:focus-visible {
  filter: brightness(1.06) saturate(1.12) drop-shadow(0 3px 5px rgba(31, 29, 26, 0.18));
  outline: none;
}

/* once locked: stop the breathing and quiet the parts that are out of play. */
.plantbody-svg.plantbody-locked .plantbody-part.tap { animation: none; cursor: default; }
.plantbody-svg.plantbody-locked
  .plantbody-part.tap:not(.plantbody-correct):not(.plantbody-wrong):not(.plantbody-reveal) {
  opacity: 0.32;
}

/* feedback: repaint every art shape of the part (excluding the transparent hit
   area) so the whole part reads as correct/wrong. Presentation attributes on the
   detail shapes are overridden by these rules. */
.plantbody-part.plantbody-correct > :not(.plantbody-hit),
.plantbody-part.plantbody-reveal > :not(.plantbody-hit) {
  fill: var(--correct) !important;
  stroke: #1c6b2a !important;
}
.plantbody-part.plantbody-wrong > :not(.plantbody-hit) {
  fill: var(--wrong) !important;
  stroke: #7a2222 !important;
}

/* chosen correct part pops and glows; revealed-correct glows; wrong shakes. */
.plantbody-svg.plantbody-locked .plantbody-part.plantbody-correct {
  animation: plantbody-pop 0.42s ease-out;
  filter: url(#plantbody-glow);
}
.plantbody-svg.plantbody-locked .plantbody-part.plantbody-reveal {
  filter: url(#plantbody-glow);
}
.plantbody-svg.plantbody-locked .plantbody-part.plantbody-wrong {
  animation: plantbody-shake 0.42s ease-out;
}
@keyframes plantbody-pop { 40% { transform: scale(1.06); } }
@keyframes plantbody-shake {
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}

/* body figure: soft depth on the stage panel; connective context never interactive. */
.plantbody-stage { filter: drop-shadow(0 2px 5px rgba(31, 29, 26, 0.07)); }
.plantbody-context { pointer-events: none; }

.plantbody-readout {
  text-align: center;
  margin-top: 12px;
  min-height: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: reduce) {
  .plantbody-svg { animation: none; }
  .plantbody-part.tap,
  .plantbody-svg.plantbody-locked .plantbody-part.plantbody-correct,
  .plantbody-svg.plantbody-locked .plantbody-part.plantbody-wrong { animation: none !important; }
}

/* Source: styles/interactive-money.css */
/* Money interactive: four trays of coins/notes; tap the tray that makes the target.
   Scoped under .money-card. Categorical tray accents use Okabe-Ito
   blue/orange/pink/yellow; green/red stay reserved for correct/wrong feedback.
   Denomination fills (silver coins, brass 5, violet 10, teal 20) are cues only -
   the numeral/value text is the real identifier. */
.money-card {
  margin: 0 auto;
  max-width: 440px;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Target badge: the "Make X" goal at the top */
.money-target {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  background: linear-gradient(180deg, #fffdf3 0%, #fff6d8 100%);
  border: 2px solid #f0d442;
  border-radius: 14px;
  padding: 8px 20px;
  box-shadow: 0 2px 6px rgba(60, 50, 0, 0.08);
  align-self: center;
}
.money-target-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.money-target-value {
  font-size: 26px;
  font-weight: 800;
  color: var(--ink);
  line-height: 1;
}

/* 2x2 grid of trays */
.money-board {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  animation: money-fade 0.4s ease-out both;
}
@keyframes money-fade {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Each tray: a tappable card (role=button, tabindex=0 in markup). */
.money-tray {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 84px;
  padding: 16px 12px 12px;
  background: var(--card);
  border: 2.5px solid var(--line);
  border-top-width: 6px;
  border-radius: 16px;
  cursor: pointer;
  outline: none;
  box-shadow: 0 2px 8px rgba(40, 35, 20, 0.06);
  transition: transform 0.12s ease, box-shadow 0.16s ease, border-color 0.16s ease, background 0.16s ease;
  -webkit-tap-highlight-color: transparent;
}
/* Categorical top stripes (Okabe-Ito; green/red reserved for feedback) */
.money-tray.c0 { border-top-color: #56b4e9; }
.money-tray.c1 { border-top-color: #e69f00; }
.money-tray.c2 { border-top-color: #cc79a7; }
.money-tray.c3 { border-top-color: #f0d442; }

/* Letter chip (A/B/C/D) in the top-left corner - the option identifier */
.money-tray-tag {
  position: absolute;
  top: 7px;
  left: 8px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 800;
  background: rgba(255, 255, 255, 0.9);
  border: 1.5px solid currentColor;
}
.money-tray.c0 .money-tray-tag { color: #1f6fa6; }
.money-tray.c1 .money-tray-tag { color: #b06f00; }
.money-tray.c2 .money-tray-tag { color: #9c4f7e; }
.money-tray.c3 .money-tray-tag { color: #8a7300; }

/* The loot row (coins + notes) */
.money-tray-loot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px;
  max-width: 160px;
}

.money-tray:not(.money-locked):hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(40, 35, 20, 0.14);
  border-color: #b8ad94;
}
.money-tray:not(.money-locked):focus-visible {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.5), 0 6px 16px rgba(40, 35, 20, 0.14);
}
.money-tray:not(.money-locked):active { transform: scale(0.98); }

/* Coins: labelled circles; metallic face + rim + sheen. Numeral is the ID. */
.money-coin {
  width: 38px;
  height: 38px;
  display: block;
  filter: drop-shadow(0 1px 1.5px rgba(40, 35, 20, 0.22));
}
.money-coin .money-rim { fill: #9aa0a8; }
.money-coin .money-face { fill: #e9ecf1; }
.money-coin .money-sheen { fill: rgba(255, 255, 255, 0.55); }
.money-coin .money-coin-text {
  font-family: inherit;
  font-size: 17px;
  font-weight: 800;
  fill: #2f3540;
}
.money-coin-1 .money-rim { fill: #aab0b8; }
.money-coin-1 .money-face { fill: #eef0f3; }
.money-coin-2 .money-rim { fill: #8f959e; }
.money-coin-2 .money-face { fill: #dde2ea; }
.money-coin-5 .money-rim { fill: #b8861f; }
.money-coin-5 .money-face { fill: #f2cf6b; }
.money-coin-5 .money-coin-text { fill: #4a3208; }

/* Notes: small rounded rects with value text */
.money-note {
  width: 54px;
  height: 30.6px;
  display: block;
  filter: drop-shadow(0 1px 1.5px rgba(40, 35, 20, 0.22));
}
.money-note .money-note-body { fill: #b9a3e0; }
.money-note .money-note-inner { fill: none; stroke: rgba(255, 255, 255, 0.6); stroke-width: 1; }
.money-note .money-note-border { fill: none; stroke: rgba(40, 25, 70, 0.35); stroke-width: 1; }
.money-note .money-note-text {
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  fill: #ffffff;
}
.money-note-10 .money-note-body { fill: #9b6dd4; }
.money-note-20 .money-note-body { fill: #3aa6a0; }

/* Readout caption (hint / feedback) */
.money-readout {
  text-align: center;
  min-height: 22px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

/* Locked state: freeze all trays, quiet the out-of-play ones */
.money-card.money-locked .money-tray { cursor: default; }
.money-card.money-locked .money-tray:not(.money-correct):not(.money-wrong):not(.money-reveal) {
  opacity: 0.4;
}

/* Feedback - green/red reserved ONLY here */
.money-tray.money-correct {
  border-color: var(--correct) !important;
  border-top-color: var(--correct) !important;
  background: var(--correct-bg);
  animation: money-pop 0.4s ease;
}
.money-tray.money-wrong {
  border-color: var(--wrong) !important;
  border-top-color: var(--wrong) !important;
  background: var(--wrong-bg);
  animation: money-shake 0.4s ease;
}
.money-tray.money-reveal {
  border-color: var(--correct) !important;
  border-top-color: var(--correct) !important;
  background: var(--correct-bg);
  box-shadow: 0 0 0 3px rgba(46, 158, 68, 0.35);
}

@keyframes money-pop { 40% { transform: scale(1.05); } }
@keyframes money-shake {
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}

@media (prefers-reduced-motion: reduce) {
  .money-tray,
  .money-board,
  .money-tray.money-correct,
  .money-tray.money-wrong {
    animation: none !important;
    transition: none !important;
  }
}

/* Source: styles/interactive-worldmap.css */
/* Interactive world map (tap-the-continent) - framed sea panel with depth.
   Mirrors .india-map/.map-card. All classes prefixed worldmap-; green/red
   reserved for correct/wrong feedback; categorical fills are Okabe-Ito. */
.worldmap-card { margin: 0 auto; max-width: 520px; width: 100%; }
.worldmap-map {
  width: 100%; height: auto; display: block; margin: 0 auto;
  touch-action: manipulation;
  animation: worldmap-in 0.45s ease-out both;
}
@keyframes worldmap-in { from { opacity: 0; } to { opacity: 1; } }

.worldmap-map .worldmap-sea { stroke: #b6d3e8; stroke-width: 1.5; }
.worldmap-map .worldmap-grid {
  stroke: #9cc3e0; stroke-width: 1; stroke-dasharray: 4 5; opacity: 0.22;
}

.worldmap-map .worldmap-regions .worldmap-region {
  stroke: #ffffff; stroke-width: 1.1; stroke-linejoin: round;
  transition: fill 0.18s ease, fill-opacity 0.18s ease, stroke-width 0.14s ease, filter 0.14s ease;
}
.worldmap-map .worldmap-regions .worldmap-region.worldmap-dim {
  fill: #e7dfca; stroke: #f3ecdb; pointer-events: none;
}

.worldmap-map .worldmap-regions .worldmap-region.worldmap-tap {
  cursor: pointer; animation: worldmap-breathe 2.8s ease-in-out infinite;
}
.worldmap-map .worldmap-regions .worldmap-region.worldmap-tap.worldmap-c0 { fill: #56b4e9; }
.worldmap-map .worldmap-regions .worldmap-region.worldmap-tap.worldmap-c1 { fill: #e69f00; }
.worldmap-map .worldmap-regions .worldmap-region.worldmap-tap.worldmap-c2 { fill: #cc79a7; }
.worldmap-map .worldmap-regions .worldmap-region.worldmap-tap.worldmap-c3 { fill: #f0d442; }
@keyframes worldmap-breathe { 0%, 100% { fill-opacity: 1; } 50% { fill-opacity: 0.86; } }

.worldmap-map:not(.worldmap-locked) .worldmap-regions .worldmap-region.worldmap-tap:hover,
.worldmap-map:not(.worldmap-locked) .worldmap-regions .worldmap-region.worldmap-tap:focus-visible {
  filter: brightness(1.08) saturate(1.15); stroke: #ffffff; stroke-width: 2.2; outline: none;
}
.worldmap-map.worldmap-locked .worldmap-regions .worldmap-region.worldmap-tap { cursor: default; animation: none; }
.worldmap-map.worldmap-locked .worldmap-regions .worldmap-region.worldmap-tap:not(.worldmap-correct):not(.worldmap-wrong):not(.worldmap-reveal) {
  fill-opacity: 0.35;
}

.worldmap-map .worldmap-regions .worldmap-region.worldmap-correct {
  fill: var(--correct) !important; stroke: #1c6b2a; stroke-width: 2.2;
  filter: url(#worldmap-glow); animation: worldmap-pop 0.4s ease-out;
  transform-box: fill-box; transform-origin: center center;
}
.worldmap-map .worldmap-regions .worldmap-region.worldmap-wrong {
  fill: var(--wrong) !important; stroke: #7a2222; stroke-width: 2.2; stroke-dasharray: 4 2;
  animation: worldmap-shake 0.4s ease-out;
}
.worldmap-map .worldmap-regions .worldmap-region.worldmap-reveal {
  fill: var(--correct) !important; stroke: #1c6b2a; stroke-width: 2.6;
  filter: url(#worldmap-glow);
}
@keyframes worldmap-pop { 0% { transform: scale(1); } 40% { transform: scale(1.08); } 100% { transform: scale(1); } }
@keyframes worldmap-shake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-8px); }
  40%, 80% { transform: translateX(8px); }
}

.worldmap-map .worldmap-labels { pointer-events: none; }
.worldmap-map .worldmap-label rect {
  fill: rgba(255, 255, 255, 0.92); stroke: rgba(40, 64, 90, 0.25); stroke-width: 1;
}
.worldmap-map .worldmap-label text {
  font-family: inherit; font-size: 15px; font-weight: 800; letter-spacing: 0.04em;
  fill: #2f3540; text-anchor: middle;
}
.worldmap-map .worldmap-label { transition: opacity 0.25s ease; }
.worldmap-map .worldmap-label.worldmap-faded { opacity: 0.25; }

.worldmap-readout {
  text-align: center; margin-top: 10px; min-height: 22px;
  font-size: 15px; font-weight: 700; letter-spacing: 0.06em;
  color: var(--ink-soft); text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .worldmap-map { animation: none; }
  .worldmap-map .worldmap-regions .worldmap-region.worldmap-tap,
  .worldmap-map .worldmap-regions .worldmap-region.worldmap-correct,
  .worldmap-map .worldmap-regions .worldmap-region.worldmap-wrong { animation: none; }
}

/* Source: styles/interactive-binary.css */
/* interactive binary cards (tap-the-value) - four bit cards with soft depth */
.binary-card { margin: 0 auto; max-width: 440px; width: 100%; }
.binary-target {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 12px;
}
.binary-target-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.binary-target-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 40px;
  padding: 0 10px;
  border-radius: 12px;
  background: var(--accent);
  color: var(--ink);
  font-size: 22px;
  font-weight: 800;
  box-shadow: 0 2px 6px rgba(31, 29, 26, 0.12);
}
.binary-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  animation: binary-in 0.45s ease-out both;
}
@keyframes binary-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.binary-tile {
  display: block;
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 12px 10px 10px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 16px;
  cursor: pointer;
  touch-action: manipulation;
  color: var(--ink);
  font: inherit;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05), 0 5px 14px rgba(31, 29, 26, 0.06);
  transition: transform 0.12s ease, box-shadow 0.16s ease, border-color 0.16s ease, background 0.16s ease, opacity 0.25s ease;
}
.binary-card:not(.binary-locked) .binary-tile:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 2px 5px rgba(31, 29, 26, 0.07), 0 10px 22px rgba(31, 29, 26, 0.10);
}
.binary-tile:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55), 0 6px 16px rgba(31, 29, 26, 0.10);
}
.binary-card:not(.binary-locked) .binary-tile:active { transform: scale(0.98); }
.binary-card.binary-locked .binary-tile { cursor: default; }
/* dim the choices that are out of play so the result pops */
.binary-card.binary-locked .binary-tile:not(.binary-correct):not(.binary-wrong):not(.binary-reveal) {
  opacity: 0.4;
}

.binary-tile.binary-correct {
  border-color: var(--correct);
  background: var(--correct-bg);
  animation: binary-pop 0.42s ease;
}
.binary-tile.binary-wrong {
  border-color: var(--wrong);
  background: var(--wrong-bg);
  animation: binary-shake 0.42s ease;
}
.binary-tile.binary-reveal {
  border-color: var(--correct);
  background: var(--correct-bg);
  box-shadow: 0 0 0 3px rgba(46, 158, 68, 0.22), 0 6px 16px rgba(46, 158, 68, 0.20);
}
@keyframes binary-pop { 40% { transform: scale(1.06); } }
@keyframes binary-shake {
  20%, 60% { transform: translateX(-7px); }
  40%, 80% { transform: translateX(7px); }
}

/* the bit-card svg: place-value headers, lit/unlit cells, binary string */
.binary-svg { display: block; width: 100%; height: auto; max-width: 156px; margin: 0 auto; }
.binary-svg .binary-pv {
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  fill: var(--ink-soft);
}
.binary-svg .binary-pv.binary-pv-on { fill: var(--ink); font-weight: 800; }
.binary-svg .binary-rule { stroke: var(--line); stroke-width: 1; }
.binary-svg .binary-cell { stroke-width: 2; transition: fill 0.2s ease; }
.binary-svg .binary-cell.binary-dim { fill: #f4efe3; stroke: #e5dfd2; }
.binary-svg .binary-cell.binary-lit { stroke: rgba(0, 0, 0, 0.05); }
/* Okabe-Ito categorical fills for lit cells (colour-blind safe; green/red reserved for feedback) */
.binary-svg .binary-cell.binary-c0 { fill: #56b4e9; }
.binary-svg .binary-cell.binary-c1 { fill: #e69f00; }
.binary-svg .binary-cell.binary-c2 { fill: #cc79a7; }
.binary-svg .binary-cell.binary-c3 { fill: #f0d442; }
.binary-svg .binary-digit {
  font-family: inherit;
  font-size: 16px;
  font-weight: 800;
  fill: var(--ink);
}
.binary-svg .binary-digit.binary-on { fill: var(--ink); }
.binary-svg .binary-digit.binary-off { fill: var(--ink-soft); }
.binary-svg .binary-str {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 0.12em;
  fill: var(--ink);
}

.binary-readout {
  text-align: center;
  margin-top: 12px;
  min-height: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: reduce) {
  .binary-grid { animation: none; }
  .binary-tile, .binary-svg .binary-cell { transition: none; }
  .binary-tile.binary-correct, .binary-tile.binary-wrong { animation: none; }
}

/* Source: styles/interactive-jumbled.css */
/* Interactive jumbled-words (tap-the-word) - dictionary-order chips with depth.
   Colour-blind-safe categorical badge tints (Okabe-Ito blue/orange/teal/purple);
   green and red stay reserved for correct/wrong feedback only. Mirrors the
   India-map widget's depth, restraint and OMR paper-ink aesthetic. */
.jumbled-card {
  margin: 0 auto;
  max-width: 440px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  animation: jumbled-in 0.45s ease-out both;
}
@keyframes jumbled-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* A-to-Z ruler strip - decorative dictionary-order cue (aria-hidden in markup). */
.jumbled-ruler {
  width: 100%;
  max-width: 288px;
  height: auto;
  display: block;
}
.jumbled-ruler-line {
  stroke: var(--line);
  stroke-width: 1.5;
  stroke-linecap: round;
}
.jumbled-ruler-letter {
  font-family: inherit;
  font-size: 7px;
  font-weight: 700;
  fill: var(--ink-soft);
  opacity: 0.6;
}

/* chip row - wraps to 2x2 on narrow viewports, one row when words are short. */
.jumbled-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;
  gap: 12px;
  width: 100%;
}

/* a chip is a real <button>: white card + categorical badge + the word.
   Native button covers mouse, touch and Enter/Space in one click handler. */
.jumbled-chip {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 64px;
  padding: 10px 18px 10px 10px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.06), 0 4px 10px rgba(31, 29, 26, 0.05);
  cursor: pointer;
  font-family: inherit;
  color: var(--ink);
  transition: transform 0.12s ease, border-color 0.15s ease,
              box-shadow 0.15s ease, background 0.15s ease;
  touch-action: manipulation;
}
.jumbled-chip:hover {
  border-color: var(--jumbled-tone, #0072b2);
  box-shadow: 0 2px 4px rgba(31, 29, 26, 0.08), 0 8px 18px rgba(31, 29, 26, 0.08);
}
.jumbled-chip:active { transform: scale(0.97); }
.jumbled-chip:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* categorical tone per chip drives its hover ring (never green/red). */
.jumbled-chip.jumbled-c0 { --jumbled-tone: #0072b2; }
.jumbled-chip.jumbled-c1 { --jumbled-tone: #e69f00; }
.jumbled-chip.jumbled-c2 { --jumbled-tone: #cc79a7; }
.jumbled-chip.jumbled-c3 { --jumbled-tone: #17a2ac; }

/* circular first-letter badge (>=44px, contributes to tap target). */
.jumbled-badge {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  display: block;
}
.jumbled-badge-ring {
  stroke: rgba(255, 255, 255, 0.65);
  stroke-width: 1.5;
}
.jumbled-chip.jumbled-c0 .jumbled-badge-ring { fill: #0072b2; }
.jumbled-chip.jumbled-c1 .jumbled-badge-ring { fill: #e69f00; }
.jumbled-chip.jumbled-c2 .jumbled-badge-ring { fill: #cc79a7; }
.jumbled-chip.jumbled-c3 .jumbled-badge-ring { fill: #17a2ac; }
.jumbled-badge-letter {
  font-family: inherit;
  font-size: 22px;
  font-weight: 800;
  fill: #ffffff;
  letter-spacing: 0.02em;
  paint-order: stroke;
  stroke: rgba(31, 29, 26, 0.18);
  stroke-width: 0.4;
}

.jumbled-word {
  font-size: 22px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.01em;
}

/* locked after answering: quieten chips that are out of play. */
.jumbled-card.jumbled-locked .jumbled-chip { cursor: default; }
.jumbled-card.jumbled-locked
  .jumbled-chip:not(.jumbled-correct):not(.jumbled-wrong):not(.jumbled-reveal) {
  opacity: 0.42;
}
.jumbled-card.jumbled-locked .jumbled-chip:hover {
  border-color: var(--line);
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.06), 0 4px 10px rgba(31, 29, 26, 0.05);
}

/* feedback - green/red reserved for correctness only. */
.jumbled-chip.jumbled-correct {
  border-color: var(--correct);
  background: var(--correct-bg);
  animation: jumbled-pop 0.4s ease;
}
.jumbled-chip.jumbled-wrong {
  border-color: var(--wrong);
  background: var(--wrong-bg);
  animation: jumbled-shake 0.4s ease;
}
.jumbled-chip.jumbled-reveal {
  border-color: var(--correct);
  background: var(--correct-bg);
  box-shadow: 0 0 0 3px rgba(46, 158, 68, 0.25), 0 4px 12px rgba(46, 158, 68, 0.18);
}
@keyframes jumbled-pop { 40% { transform: scale(1.06); } }
@keyframes jumbled-shake {
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}

.jumbled-readout {
  text-align: center;
  margin-top: 4px;
  min-height: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .jumbled-card { animation: none; }
  .jumbled-chip { transition: none; }
  .jumbled-chip:active { transform: none; }
  .jumbled-chip.jumbled-correct,
  .jumbled-chip.jumbled-wrong { animation: none; }
}

/* Source: styles/interactive-pictograph.css */
/* Interactive pictograph (tap-the-row) - framed panel with soft depth.
   Green/red stay reserved for correct/wrong feedback only; the four row
   categories use a colour-blind-safe Okabe-Ito set (sky blue, orange,
   reddish purple, deep blue) so adjacent rows read as distinct. */
.pictograph-card {
  margin: 0 auto;
  max-width: 440px;
  width: 100%;
  display: flex;
  flex-direction: column;
}

/* Key chip: "[KEY] [symbol] = [N]" in a soft pill, centred above the rows. */
.pictograph-key {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  padding: 8px 14px;
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05);
}
.pictograph-key-label {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.pictograph-key .pictograph-symbol {
  width: 22px;
  height: 22px;
  color: var(--ink);
}
.pictograph-key-eq {
  color: var(--ink-soft);
  font-weight: 700;
  font-size: 15px;
}
.pictograph-key-value {
  display: inline-block;
  min-width: 24px;
  text-align: center;
  font-size: 17px;
  font-weight: 800;
  color: var(--ink);
  background: var(--accent);
  border-radius: 8px;
  padding: 1px 8px;
}

/* Board: vertical stack of tappable rows. */
.pictograph-board {
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: pictograph-in 0.45s ease-out both;
}
@keyframes pictograph-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* A tappable row: colour swatch + label on the left, symbols flowing right.
   The whole row is the tap target (>=44px: min-height 56px). */
.pictograph-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 10px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform 0.12s ease, border-color 0.14s ease,
    background 0.14s ease, box-shadow 0.14s ease, opacity 0.25s ease;
}
.pictograph-row:focus-visible {
  outline: none;
  border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(31, 29, 26, 0.14);
}
/* Categorical row colours drive the symbol fill via currentColor. */
.pictograph-row.c0 { color: #56b4e9; } /* sky blue */
.pictograph-row.c1 { color: #e69f00; } /* orange */
.pictograph-row.c2 { color: #cc79a7; } /* reddish purple */
.pictograph-row.c3 { color: #0072b2; } /* deep blue */
.pictograph-card:not(.pictograph-locked) .pictograph-row:hover {
  transform: translateY(-1px);
  border-color: var(--ink-soft);
  box-shadow: 0 4px 12px rgba(31, 29, 26, 0.09);
}

/* Category swatch (sits left of the label). */
.pictograph-row-chip {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border-radius: 5px;
  background: currentColor;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.6);
}

.pictograph-row-label {
  flex: 0 0 92px;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.15;
  color: var(--ink);
}

.pictograph-row-symbols {
  flex: 1 1 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 5px;
}
.pictograph-row-empty {
  font-size: 13px;
  font-style: italic;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

/* Symbols inherit the row's category colour through currentColor.
   Detail inks (eyes, mouth, seams, stems) stay fixed for legibility. */
.pictograph-symbol {
  width: 24px;
  height: 24px;
  display: block;
}
.pictograph-fill { fill: currentColor; }
.pictograph-eye { fill: #1f1d1a; }
.pictograph-mouth {
  fill: none;
  stroke: #1f1d1a;
  stroke-width: 1.5;
  stroke-linecap: round;
}
.pictograph-rays {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
}
.pictograph-spine {
  fill: none;
  stroke: rgba(255, 255, 255, 0.92);
  stroke-width: 1.6;
}
.pictograph-seam {
  fill: none;
  stroke: rgba(255, 255, 255, 0.92);
  stroke-width: 1.4;
  stroke-linecap: round;
}
.pictograph-stem {
  fill: none;
  stroke: #7a5230;
  stroke-width: 1.7;
  stroke-linecap: round;
}
.pictograph-leaf { fill: #7a5230; } /* warm brown, not feedback-green */
.pictograph-center { fill: var(--accent); }

/* Locked state: no further taps; quieten the rows that are out of play. */
.pictograph-card.pictograph-locked .pictograph-row { cursor: default; }
.pictograph-card.pictograph-locked
  .pictograph-row:not(.pictograph-correct):not(.pictograph-wrong):not(.pictograph-reveal) {
  opacity: 0.38;
}

/* Feedback - green/red reserved for correct/wrong only. */
.pictograph-row.pictograph-correct {
  background: var(--correct-bg) !important;
  border-color: var(--correct) !important;
  box-shadow: 0 0 0 3px rgba(46, 158, 68, 0.18);
  animation: pictograph-pop 0.4s ease;
}
.pictograph-row.pictograph-correct .pictograph-row-chip { background: var(--correct); }

.pictograph-row.pictograph-wrong {
  background: var(--wrong-bg) !important;
  border-color: var(--wrong) !important;
  box-shadow: 0 0 0 3px rgba(214, 69, 69, 0.18);
  animation: pictograph-shake 0.4s ease;
}
.pictograph-row.pictograph-wrong .pictograph-row-chip { background: var(--wrong); }

.pictograph-row.pictograph-reveal {
  border-color: var(--correct) !important;
  border-style: dashed;
  box-shadow: 0 0 0 3px rgba(46, 158, 68, 0.14);
}
.pictograph-row.pictograph-reveal .pictograph-row-chip { background: var(--correct); }

@keyframes pictograph-pop { 40% { transform: scale(1.03); } }
@keyframes pictograph-shake {
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}

/* Readout caption (mirrors .map-readout). */
.pictograph-readout {
  text-align: center;
  margin-top: 12px;
  min-height: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: reduce) {
  .pictograph-board { animation: none; }
  .pictograph-row,
  .pictograph-row.pictograph-correct,
  .pictograph-row.pictograph-wrong { animation: none; transition: none; }
}

/* Source: styles/interactive-shapes.css */
/* Interactive 3D shapes (tap-the-solid) - four isometric-solid cards in a 2x2
   grid. Option B pick-one: tapping a card resolves to options.indexOf(name).
   Green/red stay reserved for correct/wrong feedback; tiles are neutral warm
   white so each solid's own Okabe-Ito-safe hue reads cleanly. */

.shapes-card { margin: 0 auto; max-width: 460px; width: 100%; }

.shapes-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* Button reset + soft-depth card. min-height well past the 44px tap minimum. */
.shapes-tile {
  -webkit-appearance: none;
  appearance: none;
  font: inherit;
  color: inherit;
  margin: 0;
  padding: 14px;
  border: 2px solid var(--line);
  background: var(--card);
  border-radius: 16px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 132px;
  cursor: pointer;
  touch-action: manipulation;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.04), 0 6px 14px rgba(31, 29, 26, 0.06);
  transition: transform 0.14s ease, box-shadow 0.14s ease, border-color 0.14s ease, background 0.14s ease;
  animation: shapes-in 0.4s ease-out both;
}
.shapes-tile.c0 { animation-delay: 0.02s; }
.shapes-tile.c1 { animation-delay: 0.08s; }
.shapes-tile.c2 { animation-delay: 0.14s; }
.shapes-tile.c3 { animation-delay: 0.20s; }

@keyframes shapes-in {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: none; }
}

.shapes-tile:hover {
  transform: translateY(-2px);
  border-color: #d8d0bf;
  box-shadow: 0 2px 4px rgba(31, 29, 26, 0.06), 0 10px 22px rgba(31, 29, 26, 0.10);
}
.shapes-tile:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px rgba(255, 217, 53, 0.45), 0 10px 22px rgba(31, 29, 26, 0.10);
}
.shapes-tile:active { transform: translateY(0) scale(0.985); }

/* Position chip A/B/C/D - never the solid's name (the child picks by form). */
.shapes-tag {
  position: absolute;
  top: 8px;
  left: 8px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--paper);
  color: var(--ink-soft);
  border: 1px solid var(--line);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.shapes-solid { width: 104px; height: 96px; display: block; overflow: visible; }

/* Ground shadow under each solid. The SVG ellipses carry no fill attribute,
   so this rule is load-bearing - without it they render solid black. */
.shapes-shadow { fill: rgba(31, 29, 26, 0.16); }

/* Locked: answer resolved - disable hover/cursor so the result settles. */
.shapes-card.shapes-locked .shapes-tile { cursor: default; }
.shapes-card.shapes-locked .shapes-tile:hover {
  transform: none;
  border-color: var(--line);
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.04), 0 6px 14px rgba(31, 29, 26, 0.06);
}

/* Out-of-play cards quiet down so the tapped + revealed pair pops. */
.shapes-tile.shapes-faded { opacity: 0.42; }

/* Feedback - the only place green/red appear. */
.shapes-tile.shapes-correct {
  border-color: var(--correct);
  background: var(--correct-bg);
  box-shadow: 0 0 0 3px rgba(46, 158, 68, 0.22), 0 10px 22px rgba(31, 29, 26, 0.10);
  animation: shapes-pop 0.42s ease;
}
.shapes-tile.shapes-wrong {
  border-color: var(--wrong);
  background: var(--wrong-bg);
  box-shadow: 0 0 0 3px rgba(214, 69, 69, 0.20);
  animation: shapes-shake 0.42s ease;
}
.shapes-tile.shapes-reveal {
  border-color: var(--correct);
  background: var(--correct-bg);
  box-shadow: 0 0 0 3px rgba(46, 158, 68, 0.22);
}

@keyframes shapes-pop { 40% { transform: scale(1.05); } }
@keyframes shapes-shake {
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}

.shapes-readout {
  text-align: center;
  margin-top: 12px;
  min-height: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .shapes-tile,
  .shapes-tile.shapes-correct,
  .shapes-tile.shapes-wrong {
    animation: none !important;
    transition: none !important;
  }
}

/* Source: styles/interactive-fractionline.css */
/* interactive fraction number line - tappable points over a ruled axis */
.fl-card { margin: 0 auto; max-width: 560px; width: 100%; }

.fl-target {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 6px;
  animation: fl-in 0.4s ease-out both;
}
.fl-target-label {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.fl-frac {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
  font-weight: 800;
  font-size: 20px;
  background: var(--accent);
  border-radius: 10px;
  padding: 6px 12px;
  box-shadow: 0 2px 6px rgba(31, 29, 26, 0.12);
}
.fl-frac .fl-num { padding-bottom: 2px; }
.fl-frac .fl-den { border-top: 2px solid var(--ink); padding-top: 2px; }
.fl-whole {
  font-weight: 800;
  font-size: 22px;
  background: var(--accent);
  border-radius: 10px;
  padding: 4px 12px;
}

.fl-board {
  position: relative;
  animation: fl-in 0.5s ease-out both;
}
@keyframes fl-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
.fl-line { display: block; width: 100%; height: auto; }
.fl-axis { stroke: var(--ink); stroke-width: 2.5; stroke-linecap: round; }
.fl-arrow { fill: var(--ink); }
.fl-tick { stroke: #cfc7b4; stroke-width: 1.5; }
.fl-tick-whole { stroke: var(--ink-soft); stroke-width: 2; }
.fl-endlabel {
  font-family: inherit;
  font-size: 15px;
  font-weight: 800;
  fill: var(--ink);
}

/* The axis sits at 62/110 of the SVG viewBox height; the dot's centre is
   41px below the button's top (30px letter + 4px gap + 7px radius), so this
   keeps every dot pinned to the axis at any rendered width. */
.fl-point {
  position: absolute;
  top: calc(56.36% - 41px);
  transform: translateX(-50%);
  display: flex;
  min-width: 44px;
  min-height: 48px;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
}
.fl-letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--card);
  border: 2px solid var(--ink);
  font-size: 15px;
  font-weight: 800;
  color: var(--ink);
  transition: transform 0.12s ease, background 0.15s ease, box-shadow 0.15s ease;
  box-shadow: 0 2px 5px rgba(31, 29, 26, 0.12);
}
.fl-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--ink);
  border: 3px solid var(--paper);
  box-shadow: 0 0 0 2px var(--ink);
  transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.fl-card:not(.fl-locked) .fl-point:hover .fl-letter,
.fl-point:focus-visible .fl-letter {
  background: var(--accent);
  transform: scale(1.12);
  box-shadow: 0 4px 10px rgba(31, 29, 26, 0.18);
}
.fl-point:focus-visible { outline: none; }
.fl-card:not(.fl-locked) .fl-point:active .fl-dot { transform: scale(1.25); }
.fl-card.fl-locked .fl-point { cursor: default; }
.fl-card.fl-locked .fl-point:not(.fl-correct):not(.fl-wrong):not(.fl-reveal) { opacity: 0.35; }

.fl-point.fl-correct .fl-letter { background: var(--correct); border-color: var(--correct); color: #fff; animation: fl-pop 0.42s ease; }
.fl-point.fl-correct .fl-dot { background: var(--correct); box-shadow: 0 0 0 2px var(--correct), 0 0 0 7px rgba(46, 158, 68, 0.22); }
.fl-point.fl-wrong .fl-letter { background: var(--wrong); border-color: var(--wrong); color: #fff; animation: fl-shake 0.42s ease; }
.fl-point.fl-wrong .fl-dot { background: var(--wrong); box-shadow: 0 0 0 2px var(--wrong); }
.fl-point.fl-reveal .fl-letter { background: var(--correct-bg); border-color: var(--correct); color: var(--correct); }
.fl-point.fl-reveal .fl-dot { background: var(--correct); box-shadow: 0 0 0 2px var(--correct), 0 0 0 7px rgba(46, 158, 68, 0.22); }
@keyframes fl-pop { 40% { transform: scale(1.25); } }
@keyframes fl-shake {
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}

.fl-readout {
  text-align: center;
  margin-top: 10px;
  min-height: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: reduce) {
  .fl-target, .fl-board { animation: none; }
  .fl-letter, .fl-dot { transition: none; }
  .fl-point.fl-correct .fl-letter, .fl-point.fl-wrong .fl-letter { animation: none; }
}

/* Source: styles/interactive-periodic.css */
/* interactive periodic table tiles - element cards with hidden names */
.el-card { margin: 0 auto; max-width: 480px; width: 100%; }

.el-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(86px, 1fr));
  gap: 12px;
  animation: el-in 0.45s ease-out both;
}
@keyframes el-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.el-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 96px;
  padding: 10px 6px 8px;
  background: var(--card);
  border: 2px solid var(--line);
  border-top: 6px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
  touch-action: manipulation;
  color: var(--ink);
  font: inherit;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05), 0 5px 14px rgba(31, 29, 26, 0.06);
  transition: transform 0.12s ease, box-shadow 0.16s ease, border-color 0.16s ease, background 0.16s ease, opacity 0.25s ease;
}
.el-card:not(.el-locked) .el-tile:hover {
  transform: translateY(-3px);
  box-shadow: 0 2px 5px rgba(31, 29, 26, 0.07), 0 12px 24px rgba(31, 29, 26, 0.11);
}
.el-tile:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55), 0 6px 16px rgba(31, 29, 26, 0.10);
}
.el-card:not(.el-locked) .el-tile:active { transform: scale(0.97); }
.el-card.el-locked .el-tile { cursor: default; }
.el-card.el-locked .el-tile:not(.el-correct):not(.el-wrong):not(.el-reveal):not(.el-peeked) { opacity: 0.4; }

.el-n {
  position: absolute;
  top: 5px;
  left: 8px;
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-soft);
}
.el-sym {
  font-size: 30px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.01em;
}
.el-name {
  min-height: 15px;
  margin-top: 5px;
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-soft);
  letter-spacing: 0.02em;
}
.el-tile.el-peeked .el-name { color: var(--ink); }

/* Okabe-Ito category tints (colour-blind safe; green/red reserved for feedback) */
.el-cat-alkali { border-top-color: #e69f00; }
.el-cat-alkaline { border-top-color: #56b4e9; }
.el-cat-metal { border-top-color: #999999; }
.el-cat-metalloid { border-top-color: #cc79a7; }
.el-cat-nonmetal { border-top-color: #009e73; }
.el-cat-halogen { border-top-color: #f0d442; }
.el-cat-noble { border-top-color: #0072b2; }

.el-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  justify-content: center;
  margin-top: 12px;
}
.el-legend-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-soft);
  letter-spacing: 0.03em;
}
.el-legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--line);
  border-top: 3px solid var(--line);
}
.el-legend-dot.el-cat-alkali { background: #e69f00; }
.el-legend-dot.el-cat-alkaline { background: #56b4e9; }
.el-legend-dot.el-cat-metal { background: #999999; }
.el-legend-dot.el-cat-metalloid { background: #cc79a7; }
.el-legend-dot.el-cat-nonmetal { background: #009e73; }
.el-legend-dot.el-cat-halogen { background: #f0d442; }
.el-legend-dot.el-cat-noble { background: #0072b2; }

.el-tile.el-correct {
  border-color: var(--correct);
  border-top-color: var(--correct);
  background: var(--correct-bg);
  animation: el-pop 0.42s ease;
}
.el-tile.el-wrong {
  border-color: var(--wrong);
  border-top-color: var(--wrong);
  background: var(--wrong-bg);
  animation: el-shake 0.42s ease;
}
.el-tile.el-reveal {
  border-color: var(--correct);
  border-top-color: var(--correct);
  background: var(--correct-bg);
  box-shadow: 0 0 0 3px rgba(46, 158, 68, 0.22), 0 6px 16px rgba(46, 158, 68, 0.20);
}
@keyframes el-pop { 40% { transform: scale(1.07); } }
@keyframes el-shake {
  20%, 60% { transform: translateX(-7px); }
  40%, 80% { transform: translateX(7px); }
}

.el-readout {
  text-align: center;
  margin-top: 10px;
  min-height: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: reduce) {
  .el-grid { animation: none; }
  .el-tile { transition: none; }
  .el-tile.el-correct, .el-tile.el-wrong { animation: none; }
}

/* Source: styles/interactive-gates.css */
/* interactive logic gate cards - symbols, input switches, output LED */
.gate-card { margin: 0 auto; max-width: 520px; width: 100%; }

.gate-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  animation: gate-in 0.45s ease-out both;
}
@keyframes gate-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.gate-tile {
  display: block;
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 10px 8px 6px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 16px;
  cursor: pointer;
  touch-action: manipulation;
  color: var(--ink);
  font: inherit;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05), 0 5px 14px rgba(31, 29, 26, 0.06);
  transition: transform 0.12s ease, box-shadow 0.16s ease, border-color 0.16s ease, background 0.16s ease, opacity 0.25s ease;
}
.gate-card:not(.gate-locked) .gate-tile:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 2px 5px rgba(31, 29, 26, 0.07), 0 10px 22px rgba(31, 29, 26, 0.10);
}
.gate-tile:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55), 0 6px 16px rgba(31, 29, 26, 0.10);
}
.gate-card:not(.gate-locked) .gate-tile:active { transform: scale(0.98); }
.gate-card.gate-locked .gate-tile { cursor: default; }
.gate-card.gate-locked .gate-tile:not(.gate-correct):not(.gate-wrong):not(.gate-reveal) { opacity: 0.4; }

.gate-svg { display: block; width: 100%; height: auto; }
.gate-wire { stroke: var(--ink-soft); stroke-width: 2.5; }
.gate-body {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 2.5;
  stroke-linejoin: round;
}
.gate-bubble { fill: var(--paper); stroke: var(--ink); stroke-width: 2.5; }
.gate-in-label {
  font-family: inherit;
  font-size: 13px;
  font-weight: 800;
  fill: var(--ink-soft);
  dominant-baseline: central;
}
.gate-chip { stroke-width: 1.5; }
.gate-chip-on { fill: var(--accent); stroke: #d9b400; }
.gate-chip-off { fill: #f4efe3; stroke: var(--line); }
.gate-chip-text {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 13px;
  font-weight: 800;
  fill: var(--ink);
  text-anchor: middle;
  dominant-baseline: central;
}
.gate-led {
  fill: #f4efe3;
  stroke: var(--line);
  stroke-width: 2.5;
  transition: fill 0.2s ease, stroke 0.2s ease;
}
.gate-led-text {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 13px;
  font-weight: 800;
  fill: var(--ink-soft);
  text-anchor: middle;
  dominant-baseline: central;
}
.gate-led.gate-led-on { fill: var(--correct-bg); stroke: var(--correct); }
.gate-led.gate-led-off { fill: var(--wrong-bg); stroke: var(--wrong); }
.gate-led-on + .gate-led-text, .gate-led-off + .gate-led-text { fill: var(--ink); }

.gate-tile.gate-correct {
  border-color: var(--correct);
  background: var(--correct-bg);
  animation: gate-pop 0.42s ease;
}
.gate-tile.gate-wrong {
  border-color: var(--wrong);
  background: var(--wrong-bg);
  animation: gate-shake 0.42s ease;
}
.gate-tile.gate-reveal {
  border-color: var(--correct);
  background: var(--correct-bg);
  box-shadow: 0 0 0 3px rgba(46, 158, 68, 0.22), 0 6px 16px rgba(46, 158, 68, 0.20);
}
@keyframes gate-pop { 40% { transform: scale(1.05); } }
@keyframes gate-shake {
  20%, 60% { transform: translateX(-7px); }
  40%, 80% { transform: translateX(7px); }
}

.gate-readout {
  text-align: center;
  margin-top: 12px;
  min-height: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

@media (max-width: 420px) {
  .gate-grid { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .gate-grid { animation: none; }
  .gate-tile, .gate-led { transition: none; }
  .gate-tile.gate-correct, .gate-tile.gate-wrong { animation: none; }
}

/* ==========================================================================
   Logic Gates V2 Interactive Component (.v2-gates)
   ========================================================================== */

.v2-gates {
  margin: 0 auto;
  max-width: 520px;
  width: 100%;
}

.v2-gates-target {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-soft);
}

.v2-gates-target-label {
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 12px;
}

.v2-gates-target-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: 8px;
  background: var(--accent);
  color: var(--ink);
  font-size: 14px;
  font-weight: 800;
}

.v2-gates-circuit {
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 16px;
  padding: 16px 12px;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05), 0 5px 14px rgba(31, 29, 26, 0.06);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}

.v2-gates.v2-correct .v2-gates-circuit {
  border-color: var(--correct);
  background: var(--correct-bg);
  animation: gate-pop 0.42s ease;
}

.v2-gates.v2-wrong .v2-gates-circuit {
  border-color: var(--wrong);
  background: var(--wrong-bg);
  animation: gate-shake 0.42s ease;
}

.v2-gates.v2-retry .v2-gates-circuit {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.4);
}

.v2-gates-svg {
  display: block;
  width: 100%;
  height: auto;
}

.v2-wire {
  fill: none;
  stroke: var(--ink-soft);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke 0.2s ease, stroke-width 0.2s ease, filter 0.2s ease;
}

.v2-wire.is-high {
  stroke: #d9b400;
  stroke-width: 3.5;
  filter: drop-shadow(0 0 3px rgba(217, 180, 0, 0.45));
}

.v2-wire.is-low {
  stroke: #c8c0b3;
  stroke-width: 2.5;
}

.v2-gate-body {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 2.5;
  stroke-linejoin: round;
}

.v2-gate-extra {
  stroke: var(--ink);
  stroke-width: 2.5;
  stroke-linejoin: round;
}

.v2-gate-bubble {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 2.5;
}

.v2-gate-type-label {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 13px;
  font-weight: 800;
  fill: var(--ink);
  text-anchor: middle;
  dominant-baseline: central;
}

.v2-gate-in-label {
  font-family: inherit;
  font-size: 14px;
  font-weight: 800;
  fill: var(--ink);
  dominant-baseline: central;
}

.v2-gate-out-label {
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  fill: var(--ink-soft);
  text-anchor: middle;
}

.v2-gate-chip {
  stroke-width: 1.5;
  transition: fill 0.2s ease, stroke 0.2s ease;
}

.v2-gate-chip.is-high {
  fill: var(--accent);
  stroke: #d9b400;
}

.v2-gate-chip.is-low {
  fill: #f4efe3;
  stroke: var(--line);
}

.v2-gate-chip-text {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 13px;
  font-weight: 800;
  fill: var(--ink);
  text-anchor: middle;
  dominant-baseline: central;
}

.v2-gate-led-glow {
  fill: #2e9e44;
  opacity: 0;
  transition: opacity 0.25s ease;
}

.v2-gate-led-glow.is-high {
  opacity: 0.28;
}

.v2-gate-led {
  stroke-width: 2.5;
  transition: fill 0.2s ease, stroke 0.2s ease;
}

.v2-gate-led.is-high {
  fill: var(--correct-bg);
  stroke: var(--correct);
}

.v2-gate-led.is-low {
  fill: #f4efe3;
  stroke: var(--line);
}

.v2-gate-led-text {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 14px;
  font-weight: 800;
  fill: var(--ink);
  text-anchor: middle;
  dominant-baseline: central;
}

.v2-gate-controls {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
}

.v2-gate-toggles {
  display: flex;
  justify-content: center;
  gap: 12px;
  width: 100%;
}

.v2-gate-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 44px;
  padding: 8px 16px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
  touch-action: manipulation;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05);
  transition: transform 0.12s ease, border-color 0.16s ease, background 0.16s ease;
  -webkit-appearance: none;
  appearance: none;
}

.v2-gate-toggle:hover:not(:disabled) {
  transform: translateY(-1px);
  border-color: var(--accent);
}

.v2-gate-toggle:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-gate-toggle.is-high {
  border-color: #d9b400;
  background: #fffbe6;
}

.v2-gate-toggle:disabled {
  cursor: default;
  opacity: 0.6;
}

.v2-gate-toggle-val {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-weight: 800;
  background: #f4efe3;
  color: var(--ink);
  transition: background 0.15s ease;
}

.v2-gate-toggle.is-high .v2-gate-toggle-val {
  background: var(--accent);
}

.v2-gates .v2-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 28px;
  border-radius: 12px;
  border: 2px solid var(--ink);
  background: var(--accent);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  box-shadow: 0 2px 6px rgba(31, 29, 26, 0.12);
  transition: transform 0.12s ease, opacity 0.16s ease;
}

.v2-gates .v2-check:hover:not(:disabled) {
  transform: translateY(-1px);
}

.v2-gates .v2-check:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55), 0 2px 6px rgba(31, 29, 26, 0.12);
}

.v2-gates .v2-check:disabled {
  opacity: 0.5;
  cursor: default;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .v2-wire, .v2-gate-chip, .v2-gate-led, .v2-gate-toggle {
    transition: none;
  }
  .v2-gates.v2-correct .v2-gates-circuit,
  .v2-gates.v2-wrong .v2-gates-circuit {
    animation: none;
  }
}

/* Source: styles/interactive-clockpick.css */
/* Interactive clock picker (tap the clock that matches the time). */

.clock-card { margin: 0; }
.clock-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  justify-items: center;
}
.clock-tile {
  position: relative;
  width: 100%;
  max-width: 200px;
  background: var(--card);
  border: 3px solid var(--line);
  border-radius: 16px;
  padding: 14px 10px 10px;
  cursor: pointer;
  transition: transform 0.1s, border-color 0.1s, background 0.1s, opacity 0.15s;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.clock-tile:active { transform: scale(0.97); }
.clock-tile.c0 { border-color: #2a87c2; }
.clock-tile.c1 { border-color: #b37400; }
.clock-tile.c2 { border-color: #9a4f7c; }
.clock-tile.c3 { border-color: #4f60aa; }

.clock-tag {
  position: absolute;
  top: 6px;
  left: 8px;
  font-size: 12px;
  font-weight: 800;
  color: var(--ink-soft);
  background: var(--paper);
  border-radius: 6px;
  padding: 1px 6px;
}
.clock-face { width: 100%; height: auto; max-width: 150px; display: block; }
.clock-hour, .clock-min { transition: none; }

.clock-readout {
  margin-top: 12px;
  text-align: center;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink-soft);
  min-height: 1.2em;
}

.clock-tile.clock-correct {
  border-color: var(--correct) !important;
  background: var(--correct-bg);
  animation: pop 0.4s;
}
.clock-tile.clock-wrong {
  border-color: var(--wrong);
  background: var(--wrong-bg);
  animation: shake 0.4s;
}
.clock-tile.clock-reveal {
  border-color: var(--correct) !important;
  background: var(--correct-bg);
}
.clock-tile.clock-faded { opacity: 0.45; }
.clock-card.clock-locked .clock-tile { cursor: default; }
.clock-tile.clock-wrong .clock-face { opacity: 0.7; }

@media (prefers-reduced-motion: reduce) {
  .clock-tile.clock-correct, .clock-tile.clock-wrong { animation: none; }
}

/* Source: styles/interactive-builder.css */
.builder-card {
  margin: 12px 0 4px;
  padding: 14px;
  border: 2px solid var(--line);
  border-radius: 16px;
  background: var(--card);
}
.builder-progress, .builder-readout { color: var(--ink-soft); font-size: 14px; }
.builder-steps { display: grid; gap: 10px; margin: 12px 0; }
.builder-step { padding: 12px; border-radius: 12px; background: #fffdf7; border: 1px solid var(--line); }
.builder-step.is-locked { opacity: .52; }
.builder-step.is-complete { border-color: #4f9e6e; }
.builder-step h3 { display: flex; gap: 8px; align-items: center; font-size: 15px; margin: 0 0 9px; }
.builder-step-number { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--accent); }
.builder-choices { display: flex; flex-wrap: wrap; gap: 8px; }
.builder-choice { border: 2px solid var(--line); border-radius: 9px; padding: 8px 11px; background: white; color: var(--ink); font: inherit; cursor: pointer; }
.builder-choice:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.builder-choice.builder-correct { background: #dff4e6; border-color: #4f9e6e; }
.builder-choice.builder-wrong { background: #ffe6e3; border-color: #c95c52; }
.builder-choice.builder-reveal { box-shadow: 0 0 0 3px #b9e1c4 inset; }
.builder-choice.is-retired { opacity: .45; text-decoration: line-through; }

/* Source: styles/interactive-balance.css */
/* interactive pan balance scale (v2) - physics-inspired balance puzzle */
.v2-balance {
  margin: 12px auto;
  max-width: 480px;
  width: 100%;
}

.v2-balance-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  margin-bottom: 12px;
  box-shadow: 0 1px 3px rgba(31, 29, 26, 0.05);
  transition: border-color 0.2s ease, background 0.2s ease;
}

.v2-balance.is-correct .v2-balance-status {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-balance.is-wrong .v2-balance-status {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-balance-pan-tag {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
}

.v2-balance-pan-tag strong {
  color: var(--ink);
  font-size: 16px;
  font-weight: 800;
}

.v2-balance-indicator {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  background: #f4efe3;
  padding: 4px 10px;
  border-radius: 999px;
}

.v2-balance.is-correct .v2-balance-indicator {
  background: var(--correct);
  color: #ffffff;
}

/* SVG scale container */
.v2-balance-stage {
  padding: 10px 8px 6px;
  background: #fffdf8;
  border: 2px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 2px 8px rgba(31, 29, 26, 0.06);
  margin-bottom: 14px;
}

.v2-balance-svg {
  display: block;
  width: 100%;
  height: auto;
  max-width: 400px;
  margin: 0 auto;
  overflow: visible;
}

/* SVG mechanical elements */
.v2-beam-group,
.v2-pan-group-left,
.v2-pan-group-right {
  transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.v2-balance-base {
  fill: #8c8273;
}

.v2-balance-pillar {
  fill: #b3a898;
}

.v2-dial-arc {
  stroke: var(--line);
}

.v2-dial-tick-center {
  stroke: var(--ink);
}

.v2-dial-tick {
  stroke: var(--ink-soft);
}

.v2-balance-bar {
  fill: #595247;
}

.v2-beam-pointer {
  fill: #d64545;
}

.v2-balance-pin {
  fill: var(--accent);
  stroke: #595247;
}

.v2-balance-hook {
  fill: #595247;
}

.v2-pan-dish {
  fill: #e8e3d8;
  stroke: #8c8273;
}

.v2-pan-rim {
  stroke: #736b5e;
}

.v2-pan-string {
  stroke: #a0988a;
}

/* SVG weight blocks */
.v2-svg-weight {
  fill: #4385be;
  stroke: #2a5f8a;
  stroke-width: 1.5px;
}

.v2-svg-weight-1 { fill: #48a999; stroke: #2e7d70; }
.v2-svg-weight-2 { fill: #5c93c4; stroke: #3a6891; }
.v2-svg-weight-3 { fill: #d97736; stroke: #aa5218; }
.v2-svg-weight-5 { fill: #8a65b8; stroke: #613e8d; }
.v2-svg-weight-10 { fill: #c94c4c; stroke: #992828; }

.v2-svg-weight-knob {
  fill: #ffd935;
  stroke: #8c8273;
  stroke-width: 1px;
}

.v2-svg-weight-text {
  fill: #ffffff;
  font-weight: 800;
  font-family: inherit;
  dominant-baseline: central;
}

/* Weight bank controls */
.v2-balance-bank-section {
  margin-bottom: 12px;
}

.v2-balance-bank-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 8px;
  text-align: center;
}

.v2-balance-bank {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}

.v2-weight-btn {
  min-height: 44px;
  padding: 8px 18px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05), 0 3px 8px rgba(31, 29, 26, 0.04);
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.v2-weight-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: #fffdf5;
  box-shadow: 0 4px 12px rgba(31, 29, 26, 0.08);
}

.v2-weight-btn:active:not(:disabled) {
  transform: scale(0.97);
}

.v2-weight-btn:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55), 0 4px 10px rgba(31, 29, 26, 0.10);
}

.v2-weight-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Placed weights tray */
.v2-balance-tray-section {
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #faf7f0;
  margin-bottom: 14px;
}

.v2-balance-tray-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
}

.v2-balance-placed {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 40px;
  align-items: center;
}

.v2-empty-note {
  font-size: 13px;
  font-style: italic;
  color: var(--ink-soft);
  opacity: 0.75;
}

.v2-placed-chip {
  min-height: 44px;
  padding: 6px 14px;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}

.v2-placed-chip:hover:not(:disabled) {
  transform: translateY(-1px);
  border-color: var(--wrong);
  background: var(--wrong-bg);
  color: var(--wrong);
}

.v2-placed-chip:active:not(:disabled) {
  transform: scale(0.97);
}

.v2-placed-chip:focus-visible {
  outline: none;
  border-color: var(--wrong);
  box-shadow: 0 0 0 3px rgba(214, 69, 69, 0.35);
}

.v2-placed-chip:disabled {
  opacity: 0.6;
  cursor: default;
}

.v2-balance-clear {
  min-height: 44px;
  padding: 4px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.12s ease, color 0.12s ease;
}

.v2-balance-clear:hover:not(:disabled) {
  background: #efebe2;
  color: var(--ink);
}

.v2-balance-clear:disabled {
  opacity: 0.35;
  cursor: default;
}

/* Check balance button */
.v2-balance-actions {
  text-align: center;
  margin-bottom: 12px;
}

.v2-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 28px;
  border: 2px solid #595247;
  border-radius: 14px;
  background: var(--accent);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 2px 6px rgba(31, 29, 26, 0.12);
  transition: transform 0.12s ease, box-shadow 0.15s ease, opacity 0.2s ease;
}

.v2-check:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(31, 29, 26, 0.16);
}

.v2-check:active:not(:disabled) {
  transform: scale(0.98);
}

.v2-check:focus-visible {
  outline: none;
  border-color: #1f1d1a;
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.7), 0 4px 10px rgba(31, 29, 26, 0.12);
}

.v2-check:disabled {
  opacity: 0.45;
  cursor: default;
}

/* Readout feedback */
.v2-readout {
  text-align: center;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-soft);
  min-height: 24px;
  line-height: 1.4;
}

@media (prefers-reduced-motion: reduce) {
  .v2-beam-group,
  .v2-pan-group-left,
  .v2-pan-group-right {
    transition: none;
  }
  .v2-weight-btn,
  .v2-placed-chip,
  .v2-check {
    transition: none;
  }
}

/* Source: styles/interactive-clockset.css */
/* Interactive set-the-clock face (v2). The child moves the hands with native
   buttons and can tap an hour numeral on the dial. */

.v2-clockset {
  margin: 12px auto;
  max-width: 480px;
  width: 100%;
}

.v2-clockset-status {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  margin-bottom: 12px;
}

.v2-clockset.is-correct .v2-clockset-status {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-clockset.is-wrong .v2-clockset-status {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-clockset-tag {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
}

.v2-clockset-tag strong {
  color: var(--ink);
  font-size: 16px;
  font-weight: 800;
}

.v2-clockset-goal {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  background: #f4efe3;
  padding: 4px 10px;
  border-radius: 999px;
}

.v2-clockset-digital {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* Dial */
.v2-clockset-stage {
  padding: 10px 8px 6px;
  background: #fffdf8;
  border: 2px solid var(--line);
  border-radius: 18px;
  margin-bottom: 14px;
}

.v2-clockset-face {
  display: block;
  width: 100%;
  height: auto;
  max-width: 320px;
  margin: 0 auto;
  overflow: visible;
}

.v2-clockset-rim {
  fill: #e8eff6;
  stroke: #2a87c2;
  stroke-width: 2px;
}

.v2-clockset-dial {
  fill: #ffffff;
  stroke: #2a87c2;
  stroke-width: 2.5px;
}

.v2-clockset-tick {
  stroke: #8fb4cc;
  stroke-width: 1.2px;
  stroke-linecap: round;
}

.v2-clockset-tick-hour {
  stroke: #2a87c2;
  stroke-width: 2.6px;
}

.v2-clockset-numeral-hit {
  fill: transparent;
}

.v2-clockset-numeral-text {
  fill: var(--ink);
  font-family: inherit;
  font-size: 20px;
  font-weight: 800;
}

.v2-clockset-numeral.is-tappable {
  cursor: pointer;
  touch-action: manipulation;
  transition: opacity 0.15s ease;
}

.v2-clockset-numeral.is-tappable:hover .v2-clockset-numeral-hit,
.v2-clockset-numeral.is-tappable:focus-visible .v2-clockset-numeral-hit {
  fill: rgba(255, 217, 53, 0.45);
}

.v2-clockset-numeral.is-tappable:focus-visible {
  outline: none;
}

.v2-clockset-numeral.is-tappable:focus-visible .v2-clockset-numeral-hit {
  stroke: #1f1d1a;
  stroke-width: 2px;
}

.v2-clockset-numeral[aria-disabled="true"] {
  cursor: default;
  opacity: 0.55;
}

.v2-clockset-hand-hour line {
  stroke: #1f1d1a;
  stroke-width: 8px;
  stroke-linecap: round;
}

.v2-clockset-hand-minute line {
  stroke: #d64545;
  stroke-width: 5px;
  stroke-linecap: round;
}

.v2-clockset-hand-hour,
.v2-clockset-hand-minute {
  transition: transform 0.35s cubic-bezier(0.34, 1.2, 0.64, 1);
}

.v2-clockset-pin {
  fill: var(--accent, #ffd935);
  stroke: #1f1d1a;
  stroke-width: 2px;
}

/* Hand controls */
.v2-clockset-controls {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-bottom: 10px;
}

.v2-clockset-step {
  min-height: 44px;
  min-width: 44px;
  padding: 8px 18px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
}

.v2-clockset-step:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: #fffdf5;
}

.v2-clockset-step:active:not(:disabled) {
  transform: scale(0.97);
}

.v2-clockset-step:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-clockset-step:disabled {
  opacity: 0.5;
  cursor: default;
}

.v2-clockset-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.v2-clockset-reset {
  min-height: 44px;
  min-width: 44px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.12s ease, color 0.12s ease;
}

.v2-clockset-reset:hover:not(:disabled) {
  background: #efebe2;
  color: var(--ink);
}

.v2-clockset-reset:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-clockset-reset:disabled {
  opacity: 0.35;
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .v2-clockset-hand-hour,
  .v2-clockset-hand-minute,
  .v2-clockset-numeral.is-tappable,
  .v2-clockset-step,
  .v2-clockset-reset {
    transition: none;
  }
}

/* Source: styles/interactive-numberline.css */
/* interactive number line (v2) - tap or arrow a mark onto a tick */
.v2-numberline {
  margin: 12px auto;
  max-width: 480px;
  width: 100%;
}

.v2-nl-status {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
  transition: border-color 0.2s ease, background 0.2s ease;
}

.v2-nl-status-value {
  color: var(--ink);
  font-size: 16px;
  font-weight: 800;
}

.v2-numberline.is-correct .v2-nl-status {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-numberline.is-wrong .v2-nl-status {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

/* The stage scrolls sideways when a long line cannot keep 44px per tick. */
.v2-nl-stage {
  padding: 10px 8px 6px;
  background: #fffdf8;
  border: 2px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 2px 8px rgba(31, 29, 26, 0.06);
  margin-bottom: 14px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.v2-nl-track {
  position: relative;
  width: 100%;
}

.v2-nl-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.v2-nl-axis {
  stroke: #595247;
  stroke-width: 3;
  stroke-linecap: round;
}

.v2-nl-arrow {
  fill: #595247;
}

.v2-nl-tick-line {
  stroke: #a0988a;
  stroke-width: 2;
  stroke-linecap: round;
}

.v2-nl-tick-line.is-major {
  stroke: #595247;
  stroke-width: 3;
}

.v2-nl-label {
  fill: var(--ink, #1f1d1a);
  font-size: 12px;
  font-weight: 700;
}

.v2-nl-band {
  fill: var(--accent, #ffd935);
  opacity: 0.55;
}

.v2-nl-marker-stem {
  stroke: #d64545;
  stroke-width: 2;
  stroke-linecap: round;
}

.v2-nl-marker-dot {
  fill: #d64545;
  stroke: #ffffff;
  stroke-width: 2;
}

.v2-nl-marker-text {
  fill: #d64545;
  font-size: 12px;
  font-weight: 800;
}

.v2-numberline.is-correct .v2-nl-marker-dot {
  fill: var(--correct, #2e8b57);
}

.v2-numberline.is-correct .v2-nl-marker-stem {
  stroke: var(--correct, #2e8b57);
}

.v2-numberline.is-correct .v2-nl-marker-text {
  fill: var(--correct, #2e8b57);
}

.v2-nl-marker {
  transition: transform 0.18s ease;
}

/* One button per tick, laid out over the line. Each cell keeps a 44px touch
   target, and the track scrolls when the ticks need more room. */
.v2-nl-ticks {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
}

.v2-nl-tick {
  flex: 1 0 44px;
  min-width: 44px;
  min-height: 44px;
  align-self: stretch;
  padding: 0;
  margin: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  transition: background 0.15s ease;
}

.v2-nl-tick-face {
  display: block;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px dashed transparent;
}

.v2-nl-tick:hover:not(:disabled) .v2-nl-tick-face {
  border-color: #b3a898;
}

.v2-nl-tick:focus-visible {
  outline: none;
  background: rgba(255, 217, 53, 0.35);
  box-shadow: inset 0 0 0 2px #595247;
}

.v2-nl-tick[aria-pressed="true"] .v2-nl-tick-face {
  border-color: transparent;
}

.v2-nl-tick:disabled {
  cursor: default;
}

.v2-nl-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 12px;
}

.v2-nl-clear {
  min-height: 44px;
  min-width: 44px;
  padding: 4px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.12s ease, color 0.12s ease;
}

.v2-nl-clear:hover:not(:disabled) {
  background: #efebe2;
  color: var(--ink);
}

.v2-nl-clear:disabled {
  opacity: 0.35;
  cursor: default;
}

.v2-numberline .v2-check {
  min-height: 44px;
  min-width: 44px;
}

@media (prefers-reduced-motion: reduce) {
  .v2-nl-status,
  .v2-nl-marker,
  .v2-nl-tick,
  .v2-nl-clear,
  .v2-numberline .v2-check {
    transition: none;
  }
}

/* Source: styles/interactive-abacus.css */
/* interactive place-value abacus (v2) - build a number bead by bead */
.v2-abacus {
  margin: 12px auto;
  max-width: 480px;
  width: 100%;
}

.v2-abacus-stage {
  padding: 10px 8px 4px;
  background: #fffdf8;
  border: 2px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 2px 8px rgba(31, 29, 26, 0.06);
  margin-bottom: 12px;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.v2-abacus.is-correct .v2-abacus-stage {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-abacus.is-wrong .v2-abacus-stage {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-abacus-svg {
  display: block;
  width: 100%;
  height: auto;
  max-width: 380px;
  margin: 0 auto;
  overflow: visible;
}

/* Frame, base and rods */
.v2-abacus-frame {
  fill: #fdf8ec;
  stroke: #b3a898;
  stroke-width: 2px;
}

.v2-abacus-base {
  fill: #8d6e63;
  stroke: #5d4037;
  stroke-width: 2px;
}

.v2-abacus-rod {
  stroke: #78909c;
  stroke-width: 3px;
  stroke-linecap: round;
}

.v2-abacus-rod-cap {
  fill: #546e7a;
}

.v2-abacus-rod-label {
  fill: #ffffff;
  font-weight: 800;
  font-family: inherit;
}

/* Beads, one colour per place so the rods stay easy to tell apart */
.v2-abacus-bead {
  fill: #5c93c4;
  stroke: #263238;
  stroke-width: 1.2px;
  transition: transform 0.18s ease;
}

.v2-abacus-bead-ones { fill: #ffa726; stroke: #b26a00; }
.v2-abacus-bead-tens { fill: #26a69a; stroke: #12726a; }
.v2-abacus-bead-hundreds { fill: #42a5f5; stroke: #1668ad; }
.v2-abacus-bead-thousands { fill: #ab47bc; stroke: #71257f; }
.v2-abacus-bead-ten-thousands { fill: #ef5350; stroke: #a92c29; }

.v2-abacus-bead-shine {
  fill: #ffffff;
  fill-opacity: 0.45;
}

/* Digital readout */
.v2-abacus-display {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  margin-bottom: 14px;
  box-shadow: 0 1px 3px rgba(31, 29, 26, 0.05);
}

.v2-abacus.is-correct .v2-abacus-display {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-abacus-display-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.v2-abacus-number {
  font-size: 26px;
  font-weight: 800;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* One control column per rod */
.v2-abacus-controls {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-bottom: 14px;
}

.v2-abacus-rod-control {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px 6px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #faf7f0;
  min-width: 84px;
}

.v2-abacus-rod-name {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}

.v2-abacus-rod-steps {
  display: flex;
  align-items: center;
  gap: 4px;
}

.v2-abacus-rod-count {
  min-width: 24px;
  text-align: center;
  font-size: 18px;
  font-weight: 800;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.v2-abacus-step {
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 22px;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05);
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
}

.v2-abacus-step:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: #fffdf5;
}

.v2-abacus-step:active:not(:disabled) {
  transform: scale(0.96);
}

.v2-abacus-step:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-abacus-step:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Actions */
.v2-abacus-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 12px;
}

.v2-abacus-clear {
  min-height: 44px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.12s ease, color 0.12s ease;
}

.v2-abacus-clear:hover:not(:disabled) {
  background: #efebe2;
  color: var(--ink);
}

.v2-abacus-clear:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-abacus-clear:disabled {
  opacity: 0.35;
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .v2-abacus-stage,
  .v2-abacus-bead,
  .v2-abacus-step {
    transition: none;
  }
}

/* Source: styles/interactive-sorter.css */
/* interactive sorter (v2) - tap a thing, then tap a labelled bin */
.v2-sorter {
  margin: 12px auto;
  max-width: 520px;
  width: 100%;
}

.v2-sorter-heading {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 8px;
  text-align: center;
}

.v2-sorter-tray-section {
  padding: 10px 12px;
  border: 2px solid var(--line);
  border-radius: 16px;
  background: #fffdf8;
  margin-bottom: 14px;
}

.v2-sorter-tray {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  min-height: 52px;
  align-items: center;
}

.v2-sorter-empty {
  display: none;
  font-size: 13px;
  font-style: italic;
  color: var(--ink-soft);
  opacity: 0.75;
}

.v2-sorter-tray.is-empty .v2-sorter-empty {
  display: inline;
}

/* Item buttons */
.v2-sorter-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  min-width: 44px;
  padding: 8px 14px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05), 0 3px 8px rgba(31, 29, 26, 0.04);
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.v2-sorter-emoji {
  font-size: 20px;
  line-height: 1;
}

.v2-sorter-item:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: #fffdf5;
  box-shadow: 0 4px 12px rgba(31, 29, 26, 0.08);
}

.v2-sorter-item:active:not(:disabled) {
  transform: scale(0.97);
}

.v2-sorter-item:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55), 0 4px 10px rgba(31, 29, 26, 0.10);
}

.v2-sorter-item.is-selected {
  border-color: var(--accent);
  background: #fff8d9;
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
  transform: translateY(-2px);
}

.v2-sorter-item.is-placed {
  display: none;
}

.v2-sorter-item:disabled:not(.is-placed) {
  opacity: 0.5;
  cursor: default;
}

/* Bins */
.v2-sorter-bins {
  display: grid;
  gap: 12px;
  margin-bottom: 14px;
}

.v2-sorter-bins-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.v2-sorter-bins-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 480px) {
  .v2-sorter-bins-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.v2-sorter-bin {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border: 2px solid var(--line);
  border-radius: 16px;
  background: #faf7f0;
  min-width: 0;
}

.v2-sorter-bin-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 100%;
  min-height: 64px;
  padding: 10px 8px;
  border: 2px dashed #a0988a;
  border-radius: 14px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
}

.v2-sorter-bin-emoji {
  font-size: 24px;
  line-height: 1;
}

.v2-sorter-bin-label {
  line-height: 1.2;
  text-align: center;
}

.v2-sorter-bin-count {
  display: inline-grid;
  place-items: center;
  min-width: 24px;
  height: 24px;
  border-radius: 999px;
  background: #f0ebe0;
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 800;
}

.v2-sorter-bin-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: #fffdf5;
}

.v2-sorter-bin-btn:active:not(:disabled) {
  transform: scale(0.98);
}

.v2-sorter-bin-btn:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-sorter-bin-btn.is-filled {
  border-style: solid;
  border-color: #8c8273;
}

.v2-sorter-bin-btn.is-filled .v2-sorter-bin-count {
  background: var(--accent);
  color: var(--ink);
}

.v2-sorter-bin-items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  min-height: 34px;
}

.v2-sorter-placed {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--card);
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
}

.v2-sorter.is-correct .v2-sorter-bin {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-sorter.is-wrong .v2-sorter-bin {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

/* Actions */
.v2-sorter-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.v2-sorter-undo {
  min-height: 44px;
  min-width: 44px;
  padding: 8px 18px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.15s ease;
}

.v2-sorter-undo:hover:not(:disabled) {
  background: #efebe2;
  color: var(--ink);
  border-color: #a0988a;
}

.v2-sorter-undo:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-sorter-undo:disabled {
  opacity: 0.4;
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .v2-sorter-item,
  .v2-sorter-bin-btn,
  .v2-sorter-undo {
    transition: none;
  }
  .v2-sorter-item:hover:not(:disabled),
  .v2-sorter-item.is-selected,
  .v2-sorter-bin-btn:hover:not(:disabled) {
    transform: none;
  }
  .v2-sorter-item:active:not(:disabled),
  .v2-sorter-bin-btn:active:not(:disabled) {
    transform: none;
  }
}

/* Source: styles/interactive-angle.css */
/* interactive angle setter (v2) - fixed ray, movable ray, faint protractor */
.v2-angle {
  margin: 12px auto;
  max-width: 480px;
  width: 100%;
}

.v2-angle-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  margin-bottom: 12px;
  box-shadow: 0 1px 3px rgba(31, 29, 26, 0.05);
  transition: border-color 0.2s ease, background 0.2s ease;
}

.v2-angle.is-correct .v2-angle-status {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-angle.is-wrong .v2-angle-status {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-angle-tag {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
}

.v2-angle-tag strong {
  color: var(--ink);
  font-size: 16px;
  font-weight: 800;
}

.v2-angle-type {
  display: inline-flex;
  align-items: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  background: #f4efe3;
  padding: 4px 10px;
  border-radius: 999px;
}

.v2-angle.is-correct .v2-angle-type {
  background: var(--correct);
  color: #ffffff;
}

.v2-angle-stage {
  display: flex;
  justify-content: center;
  margin-bottom: 12px;
}

.v2-angle-svg {
  width: 100%;
  max-width: 400px;
  height: auto;
}

/* Protractor: present but quiet, so the two rays stay the loudest marks. */
.v2-angle-protractor-arc {
  stroke: var(--line, #e5dfd2);
  stroke-width: 2;
}

.v2-angle-tick {
  stroke: var(--line, #e5dfd2);
  stroke-width: 1.5;
}

.v2-angle-tick-major {
  stroke: var(--ink-soft, #6b6659);
  stroke-width: 2;
}

.v2-angle-tick-label {
  fill: var(--ink-soft, #6b6659);
  font-weight: 600;
}

.v2-angle-ray {
  stroke-linecap: round;
}

.v2-angle-ray-fixed {
  stroke: var(--ink-soft, #6b6659);
  stroke-width: 4;
}

.v2-angle-ray-movable {
  stroke: #d64545;
  stroke-width: 5;
  transition: none;
}

.v2-angle-arc {
  stroke: #d64545;
  stroke-width: 2.5;
}

.v2-angle-square {
  stroke: #d64545;
  stroke-width: 2.5;
}

.v2-angle-vertex {
  fill: var(--accent, #ffd935);
  stroke: #595247;
  stroke-width: 2;
}

.v2-angle-arc-label {
  fill: var(--ink, #1f1d1a);
  font-weight: 800;
}

.v2-angle.is-correct .v2-angle-ray-movable,
.v2-angle.is-correct .v2-angle-arc {
  stroke: var(--correct, #2f7a44);
}

.v2-angle-controls-section {
  margin-bottom: 12px;
}

.v2-angle-controls-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
  margin-bottom: 6px;
}

.v2-angle-controls {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}

/* Touch target: 44px is the smallest comfortable tap area for a child. */
.v2-angle-step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 64px;
  min-height: 44px;
  padding: 10px 16px;
  border: 2px solid #595247;
  border-radius: 14px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 17px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  transition: transform 0.12s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.v2-angle-step:hover:not(:disabled) {
  background: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 4px 10px rgba(31, 29, 26, 0.14);
}

.v2-angle-step:active:not(:disabled) {
  transform: scale(0.97);
}

.v2-angle-step:focus-visible {
  outline: none;
  border-color: #1f1d1a;
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.7);
}

.v2-angle-step:disabled {
  opacity: 0.4;
  cursor: default;
}

.v2-angle-actions {
  display: flex;
  justify-content: center;
  margin-bottom: 8px;
}

@media (max-width: 420px) {
  .v2-angle-status {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    text-align: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .v2-angle-status,
  .v2-angle-ray-movable,
  .v2-angle-step {
    transition: none;
  }

  .v2-angle-step:hover:not(:disabled),
  .v2-angle-step:active:not(:disabled) {
    transform: none;
  }
}

/* Source: styles/interactive-counter.css */
/* interactive counter (v2) - a tappable grid of emoji objects for classes 1-3 */
.v2-counter {
  margin: 12px auto;
  max-width: 460px;
  width: 100%;
}

.v2-counter-instruction {
  text-align: center;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 10px;
}

.v2-counter-grid {
  display: grid;
  grid-template-columns: repeat(var(--v2-counter-cols, 5), minmax(48px, 1fr));
  gap: 8px;
  justify-content: center;
  padding: 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 16px;
}

.v2-counter-object {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  min-height: 48px;
  padding: 4px;
  border: 2px solid transparent;
  border-radius: 14px;
  background: transparent;
  font: inherit;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.v2-counter-emoji {
  font-size: 1.7rem;
  line-height: 1.2;
  pointer-events: none;
}

.v2-counter-object:hover:not(:disabled) {
  background: #f4efe3;
}

.v2-counter-object:focus-visible {
  outline: 3px solid var(--accent, #ffd935);
  outline-offset: 2px;
}

/* The ring is the whole feedback for a tap, so it stays a solid colour plus a
   halo rather than a colour change an emoji would drown out. */
.v2-counter-object.is-selected {
  border-color: var(--accent, #ffd935);
  background: #fff8d6;
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.35);
  transform: scale(1.06);
}

.v2-counter-object:disabled {
  cursor: default;
  opacity: 0.85;
}

.v2-counter.is-correct .v2-counter-object.is-selected {
  border-color: var(--correct);
  background: var(--correct-bg);
  box-shadow: none;
}

.v2-counter.is-wrong .v2-counter-object.is-selected {
  border-color: var(--wrong);
  background: var(--wrong-bg);
  box-shadow: none;
}

.v2-counter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 12px;
}

.v2-counter-tally {
  font-size: 16px;
  font-weight: 800;
  color: var(--ink);
  padding: 6px 14px;
  border-radius: 999px;
  background: #f4efe3;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
}

.v2-counter-buttons {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 10px;
}

.v2-counter-clear,
.v2-counter .v2-check {
  min-height: 44px;
  min-width: 88px;
  padding: 8px 18px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
}

.v2-counter .v2-check {
  border-color: var(--accent, #ffd935);
  background: var(--accent, #ffd935);
}

.v2-counter-clear:hover:not(:disabled),
.v2-counter .v2-check:hover:not(:disabled) {
  transform: translateY(-1px);
}

.v2-counter-clear:disabled,
.v2-counter .v2-check:disabled {
  cursor: default;
  opacity: 0.55;
  transform: none;
}

.v2-counter .v2-readout {
  margin-top: 10px;
  text-align: center;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-soft);
  min-height: 24px;
  line-height: 1.4;
}

@media (max-width: 420px) {
  .v2-counter-grid {
    gap: 6px;
    padding: 8px;
  }
  .v2-counter-bar {
    justify-content: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .v2-counter-object,
  .v2-counter-clear,
  .v2-counter .v2-check {
    transition: none;
  }
  .v2-counter-object.is-selected,
  .v2-counter-clear:hover:not(:disabled),
  .v2-counter .v2-check:hover:not(:disabled) {
    transform: none;
  }
}

/* Source: styles/interactive-shade.css */
/* interactive shade (v2) - tap the parts of a partitioned shape to shade them.
   The SVG draws the shape. A native button sits over every part, so the
   keyboard path and the focus ring stay the browser's own. */
.v2-shade {
  margin: 12px auto;
  max-width: 480px;
  width: 100%;
}

.v2-shade-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  margin-bottom: 12px;
  box-shadow: 0 1px 3px rgba(31, 29, 26, 0.05);
  transition: border-color 0.2s ease, background 0.2s ease;
}

.v2-shade.is-correct .v2-shade-status {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-shade.is-wrong .v2-shade-status {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-shade-tag {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
}

.v2-shade-tag strong {
  color: var(--ink);
  font-size: 16px;
  font-weight: 800;
}

.v2-shade-value {
  display: inline-flex;
  align-items: center;
  font-size: 15px;
  font-weight: 800;
  color: var(--ink);
  background: #f4efe3;
  padding: 4px 12px;
  border-radius: 999px;
}

.v2-shade.is-correct .v2-shade-value {
  background: var(--correct);
  color: #ffffff;
}

/* Stage: the SVG shape and the button layer share one box, so a part button
   can be placed over its own piece with percentages. */
.v2-shade-stage {
  padding: 10px 8px;
  background: #fffdf8;
  border: 2px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 2px 8px rgba(31, 29, 26, 0.06);
  margin-bottom: 14px;
  overflow-x: auto;
}

.v2-shade-frame {
  position: relative;
  width: 100%;
  margin: 0 auto;
}

.v2-shade-svg {
  display: block;
  width: 100%;
  height: auto;
}

.v2-shade-piece {
  fill: #ffffff;
  stroke: #33312c;
  stroke-width: 2;
  transition: fill 0.15s ease;
}

.v2-shade-piece.is-shaded {
  fill: #4a90d9;
}

.v2-shade-parts {
  position: absolute;
  inset: 0;
}

/* Every part is a real button. Rectangular parts cover their own cell; the
   wedges of a circle get a round target at the middle of the wedge. */
.v2-shade-part {
  position: absolute;
  min-width: 44px;
  min-height: 44px;
  margin: 0;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.12s ease;
}

.v2-shade-part-dot {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

.v2-shade-part:hover:not(:disabled) {
  border-color: var(--accent);
}

.v2-shade-part:active:not(:disabled) {
  transform: scale(0.96);
}

.v2-shade-part-dot:active:not(:disabled) {
  transform: translate(-50%, -50%) scale(0.96);
}

.v2-shade-part:focus-visible {
  outline: none;
  border-color: #1f1d1a;
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.7);
}

.v2-shade-part:disabled {
  cursor: default;
}

.v2-shade-actions {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.v2-shade-clear {
  min-height: 44px;
  min-width: 44px;
  padding: 4px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.12s ease, color 0.12s ease;
}

.v2-shade-clear:hover:not(:disabled) {
  background: #efebe2;
  color: var(--ink);
}

.v2-shade-clear:disabled {
  opacity: 0.35;
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .v2-shade-status,
  .v2-shade-piece,
  .v2-shade-part {
    transition: none;
  }

  .v2-shade-part:active:not(:disabled) {
    transform: none;
  }

  .v2-shade-part-dot:active:not(:disabled) {
    transform: translate(-50%, -50%);
  }
}

/* Source: styles/interactive-gridplot.css */
/* interactive coordinate grid (v2) - the child taps grid intersections.
   The SVG grid and the button layer share one box. The box keeps a gutter of
   one grid unit on the left and one at the bottom for the axis numbers, and
   render() sets the inset of the button layer as a percentage, so a button
   always sits exactly on its intersection. */
.v2-gridplot {
  margin: 12px auto;
  max-width: 520px;
  width: 100%;
}

.v2-gridplot-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  margin-bottom: 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
}

.v2-gridplot.is-correct .v2-gridplot-head {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-gridplot.is-wrong .v2-gridplot-head {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-gridplot-tag strong {
  color: var(--ink);
  font-weight: 800;
}

.v2-gridplot-list {
  text-align: right;
  max-width: 60%;
  overflow-wrap: anywhere;
}

/* A wide four-quadrant grid can be wider than a phone. The scroller keeps the
   buttons at full size instead of shrinking them below the touch minimum. */
.v2-gridplot-scroll {
  overflow-x: auto;
  padding: 6px 2px 10px;
  margin-bottom: 12px;
}

.v2-gridplot-stage {
  position: relative;
  width: 100%;
  min-width: var(--gp-minw, 352px);
  max-width: var(--gp-maxw, 460px);
  aspect-ratio: var(--gp-ar, 1 / 1);
  margin: 0 auto;
  background: #fffdf8;
  border: 2px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 2px 8px rgba(31, 29, 26, 0.06);
}

.v2-gridplot-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

.v2-gp-line {
  stroke: #ddd6c7;
  stroke-width: 1px;
  fill: none;
}

.v2-gp-axis {
  stroke: var(--ink, #1f1d1a);
  stroke-width: 2px;
  fill: none;
}

.v2-gp-tick {
  fill: var(--ink-soft, #6b6659);
  font-family: inherit;
  font-size: 0.34px;
  font-weight: 700;
}

.v2-gp-axis-name {
  fill: var(--ink, #1f1d1a);
  font-family: inherit;
  font-size: 0.38px;
  font-style: italic;
  font-weight: 700;
}

.v2-gp-pre-dot {
  fill: #8c8273;
  stroke: #595247;
  stroke-width: 0.03px;
}

/* Button layer, inset by the label gutter so each cell centre is a lattice point. */
.v2-gridplot-cells {
  position: absolute;
  left: var(--gp-left, 0%);
  top: 0;
  width: var(--gp-width, 100%);
  height: var(--gp-height, 100%);
  display: grid;
  grid-template-columns: var(--gp-colt, repeat(1, 1fr));
  grid-template-rows: var(--gp-rowt, repeat(1, 1fr));
}

.v2-gp-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
}

.v2-gp-mark {
  display: block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #c9c2b2;
  transition: transform 0.14s ease, background 0.14s ease, box-shadow 0.14s ease;
}

.v2-gp-cell:hover:not(:disabled) .v2-gp-mark {
  background: var(--accent, #ffd935);
  transform: scale(1.5);
}

.v2-gp-cell:focus-visible {
  outline: none;
}

.v2-gp-cell:focus-visible .v2-gp-mark {
  background: var(--accent, #ffd935);
  transform: scale(1.6);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.6);
}

.v2-gp-cell.is-plotted .v2-gp-mark {
  width: 16px;
  height: 16px;
  background: #1b5e20;
  transform: scale(1);
  box-shadow: 0 0 0 3px rgba(27, 94, 32, 0.18);
}

.v2-gp-cell.is-fixed {
  cursor: default;
}

.v2-gp-cell.is-fixed .v2-gp-mark {
  background: transparent;
}

.v2-gridplot.is-correct .v2-gp-cell.is-plotted .v2-gp-mark {
  background: var(--correct, #1b5e20);
}

.v2-gridplot.is-wrong .v2-gp-cell.is-plotted .v2-gp-mark {
  background: var(--wrong, #d64545);
  box-shadow: 0 0 0 3px rgba(214, 69, 69, 0.2);
}

.v2-gridplot-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.v2-gridplot-undo {
  min-height: 44px;
  min-width: 44px;
  padding: 8px 18px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
}

.v2-gridplot-undo:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: #fffdf5;
}

.v2-gridplot-undo:active:not(:disabled) {
  transform: scale(0.97);
}

.v2-gridplot-undo:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-gridplot-undo:disabled {
  opacity: 0.45;
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .v2-gp-mark,
  .v2-gridplot-undo {
    transition: none;
  }
  .v2-gp-cell:hover:not(:disabled) .v2-gp-mark,
  .v2-gp-cell:focus-visible .v2-gp-mark {
    transform: none;
  }
}

/* Source: styles/interactive-wordbuild.css */
/* interactive word builder (v2) - letter and word tiles for English 1-4 */
.v2-wordbuild {
  margin: 12px auto;
  max-width: 480px;
  width: 100%;
  text-align: center;
}

.v2-wb-picture {
  font-size: 52px;
  line-height: 1.1;
  margin-bottom: 6px;
}

.v2-wb-task {
  margin: 0 0 10px;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-soft);
}

/* Answer row: the tiles the child has placed, in tap order. */
.v2-wb-answer {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 8px;
  min-height: 60px;
  padding: 8px 10px;
  border: 2px dashed var(--line);
  border-radius: 14px;
  background: #fffdf8;
}

.v2-wordbuild.is-correct .v2-wb-answer {
  border-style: solid;
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-wordbuild.is-wrong .v2-wb-answer {
  border-style: solid;
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-wb-made {
  margin: 8px 0 12px;
  font-size: 15px;
  font-weight: 800;
  color: var(--ink);
  min-height: 22px;
}

/* Tray: the authored tile order, never shuffled at run time. */
.v2-wb-tray {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #faf7f0;
  margin-bottom: 12px;
}

.v2-wb-tile,
.v2-wb-answer-tile {
  min-width: 44px;
  min-height: 44px;
  padding: 6px 12px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 18px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
}

.v2-wb-answer-tile {
  border-color: var(--accent);
  background: #fffdf5;
}

.v2-wb-tile:hover:not(:disabled),
.v2-wb-answer-tile:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: #fffdf5;
}

.v2-wb-tile:active:not(:disabled),
.v2-wb-answer-tile:active:not(:disabled) {
  transform: scale(0.97);
}

.v2-wb-tile:focus-visible,
.v2-wb-answer-tile:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-wb-tile:disabled {
  opacity: 0.3;
  cursor: default;
  transform: none;
}

.v2-wb-answer-tile:disabled {
  opacity: 0.75;
  cursor: default;
}

.v2-wb-actions {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.v2-wb-clear {
  min-height: 44px;
  min-width: 44px;
  padding: 6px 18px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.12s ease, color 0.12s ease;
}

.v2-wb-clear:hover:not(:disabled) {
  background: #efebe2;
  color: var(--ink);
}

.v2-wb-clear:disabled {
  opacity: 0.35;
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .v2-wb-tile,
  .v2-wb-answer-tile,
  .v2-wb-clear {
    transition: none;
  }

  .v2-wb-tile:hover:not(:disabled),
  .v2-wb-answer-tile:hover:not(:disabled),
  .v2-wb-tile:active:not(:disabled),
  .v2-wb-answer-tile:active:not(:disabled) {
    transform: none;
  }
}

/* Source: styles/interactive-chart.css */
/* interactive bar chart builder (v2) - the child grows each bar to match a table */
.v2-chart {
  margin: 12px auto;
  max-width: 480px;
  width: 100%;
}

.v2-chart-title {
  text-align: center;
  font-size: 16px;
  font-weight: 800;
  color: var(--ink);
  margin-bottom: 10px;
}

/* Data table */
.v2-chart-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}

.v2-chart-table-caption {
  caption-side: top;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-bottom: 6px;
}

.v2-chart-table th,
.v2-chart-table td {
  border: 1px solid var(--line);
  padding: 6px 8px;
  text-align: center;
  font-size: 15px;
}

.v2-chart-table th {
  background: #f4efe3;
  font-weight: 700;
  color: var(--ink);
}

.v2-chart-table td {
  font-weight: 800;
  color: var(--ink);
}

/* Chart stage */
.v2-chart-stage {
  padding: 10px 8px 6px;
  background: #fffdf8;
  border: 2px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 2px 8px rgba(31, 29, 26, 0.06);
  margin-bottom: 12px;
}

.v2-chart.is-correct .v2-chart-stage {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-chart.is-wrong .v2-chart-stage {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-chart-svg {
  display: block;
  width: 100%;
  height: auto;
  max-width: 420px;
  margin: 0 auto;
}

.v2-chart-axis {
  stroke: #595247;
  stroke-width: 2;
}

.v2-chart-grid {
  stroke: #e6e0d3;
  stroke-width: 1;
}

.v2-chart-ynum {
  fill: var(--ink-soft);
  font-size: 11px;
  font-family: inherit;
}

.v2-chart-xlab {
  fill: var(--ink);
  font-size: 12px;
  font-weight: 700;
  font-family: inherit;
}

.v2-chart-emoji {
  font-size: 16px;
}

.v2-chart-bar {
  stroke: #595247;
  stroke-width: 1;
  transition: height 0.25s ease, y 0.25s ease;
}

.v2-chart-bar-0 { fill: #48a999; }
.v2-chart-bar-1 { fill: #5c93c4; }
.v2-chart-bar-2 { fill: #d97736; }
.v2-chart-bar-3 { fill: #8a65b8; }
.v2-chart-bar-4 { fill: #c94c4c; }
.v2-chart-bar-5 { fill: #7a9a3b; }

.v2-chart-bar-value {
  fill: var(--ink);
  font-size: 12px;
  font-weight: 800;
  font-family: inherit;
}

/* Plus and minus controls, one row per category */
.v2-chart-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}

.v2-chart-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #faf7f0;
}

.v2-chart-row-label {
  flex: 1 1 auto;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}

.v2-chart-row-value {
  min-width: 44px;
  text-align: center;
  font-size: 17px;
  font-weight: 800;
  color: var(--ink);
}

.v2-chart-step {
  min-width: 44px;
  min-height: 44px;
  padding: 0 10px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 22px;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 1px 2px rgba(31, 29, 26, 0.05);
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
}

.v2-chart-step:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--accent);
  background: #fffdf5;
}

.v2-chart-step:active:not(:disabled) {
  transform: scale(0.97);
}

.v2-chart-step:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.v2-chart-step:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Actions */
.v2-chart-actions {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.v2-chart .v2-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 24px;
  border: 2px solid #595247;
  border-radius: 14px;
  background: var(--accent);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 2px 6px rgba(31, 29, 26, 0.12);
  transition: transform 0.12s ease, box-shadow 0.15s ease;
}

.v2-chart .v2-check:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(31, 29, 26, 0.16);
}

.v2-chart .v2-check:focus-visible {
  outline: none;
  border-color: #1f1d1a;
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.7);
}

.v2-chart .v2-check:disabled {
  opacity: 0.45;
  cursor: default;
}

.v2-chart-reset {
  min-height: 44px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.12s ease, color 0.12s ease;
}

.v2-chart-reset:hover:not(:disabled) {
  background: #efebe2;
  color: var(--ink);
}

.v2-chart-reset:disabled {
  opacity: 0.35;
  cursor: default;
}

.v2-chart .v2-readout {
  text-align: center;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-soft);
  min-height: 24px;
  line-height: 1.4;
}

@media (max-width: 420px) {
  .v2-chart-table th,
  .v2-chart-table td {
    padding: 5px 4px;
    font-size: 13px;
  }
  .v2-chart-row-label {
    font-size: 14px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .v2-chart-bar,
  .v2-chart-step,
  .v2-chart-reset,
  .v2-chart .v2-check {
    transition: none;
  }
  .v2-chart-step:hover:not(:disabled),
  .v2-chart .v2-check:hover:not(:disabled) {
    transform: none;
  }
}

/* Source: styles/interactive-appwindow.css */
/* interactive app window (v2) - a generic mock app for the cyber tree.
   Every control is a native button, so the keyboard path is the browser's. */
.v2-appwindow {
  margin: 12px auto;
  max-width: 480px;
  width: 100%;
}

.v2-aw-window {
  border: 2px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: #fffdf8;
  box-shadow: 0 2px 8px rgba(31, 29, 26, 0.08);
}

.v2-appwindow.is-correct .v2-aw-window {
  border-color: var(--correct);
}

.v2-appwindow.is-wrong .v2-aw-window {
  border-color: var(--wrong);
}

/* title bar */
.v2-aw-titlebar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 8px 6px 14px;
  background: #e8e2d4;
  border-bottom: 2px solid var(--line);
}

.v2-aw-title {
  font-size: 15px;
  font-weight: 800;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.v2-aw-winbtns {
  display: inline-flex;
  gap: 6px;
  flex: none;
}

.v2-aw-winbtn {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: #fffdf8;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.v2-aw-winbtn-close {
  color: #b3261e;
}

/* menu bar */
.v2-aw-menubar {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px 8px;
  background: #f4efe3;
  border-bottom: 1px solid var(--line);
}

.v2-aw-menu {
  min-height: 44px;
  min-width: 44px;
  padding: 4px 14px;
  border: 2px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

/* toolbar */
.v2-aw-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px;
  background: #fdfaf2;
  border-bottom: 1px solid var(--line);
}

.v2-aw-tool {
  min-width: 56px;
  min-height: 56px;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 6px 8px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: #fffdf8;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.v2-aw-toollabel {
  font-size: 12px;
  font-weight: 700;
  line-height: 1.1;
}

.v2-aw-glyph {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* body and text area */
.v2-aw-body {
  padding: 10px;
  background: #ffffff;
}

.v2-aw-textarea {
  display: block;
  width: 100%;
  min-height: 88px;
  text-align: left;
  padding: 10px 12px;
  border: 2px dashed var(--line);
  border-radius: 12px;
  background: #ffffff;
  color: var(--ink);
  font-size: 15px;
  line-height: 1.4;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.v2-aw-text {
  display: block;
}

/* hover, focus and chosen states */
.v2-aw-winbtn:hover:not(:disabled),
.v2-aw-menu:hover:not(:disabled),
.v2-aw-tool:hover:not(:disabled),
.v2-aw-textarea:hover:not(:disabled) {
  background: #f4efe3;
  border-color: var(--accent, #ffd935);
}

.v2-aw-winbtn:focus-visible,
.v2-aw-menu:focus-visible,
.v2-aw-tool:focus-visible,
.v2-aw-textarea:focus-visible,
.v2-aw-undo:focus-visible,
.v2-appwindow .v2-check:focus-visible {
  outline: 3px solid var(--accent, #ffd935);
  outline-offset: 2px;
}

.v2-aw-winbtn.is-picked,
.v2-aw-menu.is-picked,
.v2-aw-tool.is-picked,
.v2-aw-textarea.is-picked {
  border-color: var(--accent, #ffd935);
  background: #fff6cc;
}

.v2-appwindow.is-correct .is-picked {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-appwindow.is-wrong .is-picked {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-appwindow button:disabled {
  opacity: 0.75;
  cursor: default;
}

/* step tray for sequence mode */
.v2-aw-stepsbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding: 8px 12px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
}

.v2-aw-stepslabel {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
}

.v2-aw-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.v2-aw-step {
  padding: 4px 10px;
  border-radius: 999px;
  background: #f4efe3;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
}

.v2-aw-empty {
  font-size: 13px;
  color: var(--ink-soft);
}

.v2-aw-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.v2-aw-undo,
.v2-appwindow .v2-check {
  min-height: 44px;
  min-width: 44px;
  padding: 8px 18px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: #fffdf8;
  color: var(--ink);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.v2-appwindow .v2-check {
  background: var(--accent, #ffd935);
  border-color: var(--accent, #ffd935);
}

.v2-appwindow .v2-readout {
  margin-top: 10px;
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink-soft);
  text-align: center;
}

@media (max-width: 420px) {
  .v2-aw-tool {
    min-width: 48px;
  }
  .v2-aw-toollabel {
    font-size: 11px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .v2-aw-winbtn,
  .v2-aw-menu,
  .v2-aw-tool,
  .v2-aw-textarea,
  .v2-aw-undo,
  .v2-appwindow .v2-check {
    transition: none;
  }
}

/* Source: styles/interactive-label.css */
/* label the diagram (v2) - word bank plus numbered hotspots over an SVG */
.v2-label {
  margin: 12px auto;
  max-width: 520px;
  width: 100%;
}

.v2-label-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  margin-bottom: 12px;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.v2-label.is-correct .v2-label-head {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-label.is-wrong .v2-label-head {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

.v2-label-title {
  font-size: 15px;
  font-weight: 800;
  color: var(--ink);
}

.v2-label-progress {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
}

/* stage: the SVG sits in flow, the hotspot buttons float over it */
.v2-label-stage {
  position: relative;
  padding: 8px;
  background: #fffdf8;
  border: 2px solid var(--line);
  border-radius: 18px;
  margin-bottom: 14px;
}

.v2-label-svg {
  display: block;
  width: 100%;
  height: auto;
}

.v2-label-hotspots {
  position: absolute;
  inset: 8px;
}

.v2-label-hotspot {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 44px;
  min-height: 44px;
  padding: 2px;
  background: transparent;
  border: 0;
  cursor: pointer;
  font: inherit;
  color: var(--ink);
  transition: transform 0.15s ease;
}

.v2-label-pin {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--card);
  border: 2px solid var(--ink-soft);
  font-size: 15px;
  font-weight: 800;
  line-height: 1;
  box-shadow: 0 1px 3px rgba(31, 29, 26, 0.18);
}

.v2-label-hotspot.is-chosen .v2-label-pin {
  background: var(--accent);
  border-color: var(--ink);
}

.v2-label-hotspot.is-filled .v2-label-pin {
  background: var(--ink);
  color: var(--card);
  border-color: var(--ink);
}

.v2-label-chip {
  max-width: 92px;
  padding: 2px 6px;
  border-radius: 8px;
  background: var(--card);
  border: 2px solid var(--ink);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  overflow-wrap: break-word;
}

.v2-label.is-correct .v2-label-chip {
  border-color: var(--correct);
  background: var(--correct-bg);
}

.v2-label.is-wrong .v2-label-chip {
  border-color: var(--wrong);
  background: var(--wrong-bg);
}

/* word bank */
.v2-label-bank-section {
  margin-bottom: 12px;
}

.v2-label-bank-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
  margin-bottom: 6px;
}

.v2-label-bank {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.v2-label-word {
  min-height: 44px;
  min-width: 44px;
  padding: 8px 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.v2-label-word.is-chosen {
  background: var(--accent);
  border-color: var(--ink);
}

.v2-label-word.is-used {
  opacity: 0.45;
  cursor: default;
  text-decoration: line-through;
}

/* actions */
.v2-label-actions {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}

.v2-label-clear,
.v2-label .v2-check {
  min-height: 44px;
  min-width: 44px;
  padding: 10px 18px;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.v2-label-clear {
  background: var(--card);
  border: 2px solid var(--line);
  color: var(--ink-soft);
}

.v2-label .v2-check {
  background: var(--accent);
  border: 2px solid var(--ink);
  color: var(--ink);
}

.v2-label-clear:disabled,
.v2-label .v2-check:disabled,
.v2-label-word:disabled {
  cursor: default;
}

.v2-label .v2-readout {
  margin-top: 10px;
  font-size: 14px;
  color: var(--ink-soft);
  text-align: center;
}

/* diagram paint */
.v2-label-bg { fill: #fdfaf3; stroke: var(--line); stroke-width: 2; }
.v2-label-sky { fill: #eaf4fd; stroke: var(--line); stroke-width: 2; }
.v2-label-body { fill: #f4ece0; stroke: #d8cbb6; stroke-width: 2; }
.v2-label-detail { fill: none; stroke: #8c8273; stroke-width: 2; stroke-linecap: round; }
.v2-label-organ { fill: #e8a7a0; stroke: #b8756d; stroke-width: 2; }
.v2-label-tube { fill: none; stroke: #d8a49c; stroke-width: 12; stroke-linecap: round; }
.v2-label-gut { fill: none; stroke: #c9a173; stroke-width: 18; stroke-linecap: round; stroke-linejoin: round; }
.v2-label-coil { fill: none; stroke: #e0b98f; stroke-width: 11; stroke-linecap: round; }
.v2-label-stalk { fill: none; stroke: #4f9d52; stroke-width: 10; stroke-linecap: round; }
.v2-label-stalk-knob { fill: #4f9d52; }
.v2-label-leaf { fill: #6bbd6e; stroke: #3f7f43; stroke-width: 2; }
.v2-label-bloom { fill: #f2a7c3; stroke: #c9718f; stroke-width: 2; }
.v2-label-guard { fill: #7cbf7f; stroke: #3f7f43; stroke-width: 2; }
.v2-label-thread { fill: none; stroke: #b98500; stroke-width: 4; stroke-linecap: round; }
.v2-label-tip { fill: #ffd935; stroke: #b98500; stroke-width: 2; }
.v2-label-column { fill: none; stroke: #8c6fb1; stroke-width: 7; stroke-linecap: round; }
.v2-label-sun { fill: #ffd935; stroke: #e0b000; stroke-width: 2; }
.v2-label-ray { fill: none; stroke: #e0b000; stroke-width: 3; stroke-linecap: round; }
.v2-label-water { fill: #8fc7ea; stroke: #5a97bd; stroke-width: 2; }
.v2-label-land { fill: #b9d99a; stroke: #7fa864; stroke-width: 2; }
.v2-label-cloud { fill: #ffffff; stroke: #9fb3c4; stroke-width: 2; }
.v2-label-rain { fill: none; stroke: #4f8fbf; stroke-width: 3; stroke-linecap: round; }
.v2-label-arrow { fill: none; stroke: #4f8fbf; stroke-width: 3; stroke-linecap: round; }
.v2-label-arrowhead { fill: #4f8fbf; }
.v2-label-river { fill: none; stroke: #5aa7dd; stroke-width: 9; stroke-linecap: round; }

@media (max-width: 420px) {
  .v2-label-chip { max-width: 74px; font-size: 10px; }
  .v2-label-pin { width: 30px; height: 30px; font-size: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .v2-label-hotspot,
  .v2-label-word,
  .v2-label-clear,
  .v2-label-head,
  .v2-label .v2-check {
    transition: none;
  }
}

/* Source: styles/home.css */
/* Home page: exam-hall paper. Ruled sheet, notebook margin, OMR dot grid,
   rubber-stamp accent. Display voice is a rounded heavy stack; metadata is
   monospace like a question-paper header. */

body.home { position: relative; min-height: 100vh; }

.paper-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(circle, rgba(31, 29, 26, 0.055) 1px, transparent 1.6px) 0 0 / 26px 26px,
    repeating-linear-gradient(0deg, transparent 0 31px, rgba(31, 29, 26, 0.04) 31px 32px),
    var(--paper);
}
.paper-bg::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 58px;
  width: 2px;
  background: rgba(214, 69, 69, 0.28);
  box-shadow: 5px 0 0 rgba(214, 69, 69, 0.14);
}
@media (max-width: 760px) {
  .paper-bg::after { display: none; }
}

/* ---------- masthead: question-paper header ---------- */

.home-masthead {
  max-width: 900px;
  margin: 0 auto;
  padding: 22px 22px 4px;
  position: relative;
}

.mast-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 26px;
  padding: 9px 2px;
  border-top: 3px solid var(--ink);
  border-bottom: 1px solid var(--line);
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.mast-main {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 26px;
  flex-wrap: wrap;
  padding: 30px 0 20px;
}

.mast-title {
  margin: 0 0 12px;
  font-family: ui-rounded, "SF Pro Rounded", "Hiragino Maru Gothic ProN", "Nunito", "Segoe UI", system-ui, sans-serif;
  font-size: clamp(42px, 7.5vw, 68px);
  font-weight: 900;
  line-height: 1.02;
  letter-spacing: -0.015em;
  text-transform: uppercase;
}
.mast-title .hl {
  display: inline-block;
  background: var(--accent);
  padding: 0 12px 2px;
  transform: rotate(-1.2deg);
  box-shadow: 3px 3px 0 rgba(31, 29, 26, 0.85);
}

.mast-sub {
  margin: 0 0 10px;
  font-size: 18px;
  font-weight: 700;
}
.mast-modes {
  margin: 0;
  max-width: 52ch;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-soft);
}
.mast-modes strong { color: var(--ink); }

.mast-stats {
  display: flex;
  gap: 24px;
  padding: 16px 22px;
  background: var(--card);
  border: 2px solid var(--ink);
  border-radius: 14px;
  box-shadow: 5px 5px 0 rgba(31, 29, 26, 0.85);
  animation: stat-in 0.5s ease-out both;
}
@keyframes stat-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
.stat { text-align: center; }
.stat-num {
  font-family: ui-rounded, "SF Pro Rounded", "Nunito", "Segoe UI", system-ui, sans-serif;
  font-size: 32px;
  font-weight: 900;
  line-height: 1;
}
.stat-den { font-size: 16px; color: var(--ink-soft); font-weight: 800; }
.stat-label {
  margin-top: 5px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.mast-who {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 0 0;
}
.who-active {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.who-avatar {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: #fff5d8;
  font-size: 24px;
}
.who-copy { min-width: 0; display: flex; flex-direction: column; }
.who-copy strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 42vw;
  font-size: 16px;
}
.who-copy small { color: var(--ink-soft); font-size: 12px; font-weight: 700; }
.who-switch {
  display: flex;
  gap: 6px;
  max-width: 100%;
  overflow-x: auto;
  padding: 2px 0;
  scrollbar-width: thin;
}
.who-chip {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 148px;
  padding: 6px 10px;
  border: 2px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.who-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who-chip.active { border-color: var(--ink); background: #fff5d8; box-shadow: 2px 2px 0 var(--accent); }
.who-chip:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55); }

.today-wrap { max-width: 760px; margin: 16px auto 0; padding: 0 16px; }
.today-card {
  display: block;
  padding: 16px 18px;
  border: 2px solid var(--ink);
  border-radius: 16px;
  background: var(--card);
  box-shadow: 4px 4px 0 rgba(31, 29, 26, 0.85);
  text-decoration: none;
  color: var(--ink);
}
.today-go:hover { background: #fffef5; }
.today-go:focus-visible { outline: none; box-shadow: 4px 4px 0 rgba(31, 29, 26, 0.85), 0 0 0 3px rgba(255, 217, 53, 0.55); }
.today-caught { border-style: dashed; box-shadow: none; background: #fffdf3; }
.today-kicker {
  display: block;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 4px;
}
.today-title { display: block; font-size: 22px; font-weight: 900; line-height: 1.2; }
.today-lede { display: block; margin: 6px 0 0; color: var(--ink-soft); font-size: 14px; line-height: 1.45; }
.week-notes { margin: 12px 0 0; font-size: 14px; line-height: 1.45; }
.week-notes p { margin: 0 0 6px; }
.week-print { margin-top: 14px; }
.week-print-lede { color: var(--ink-soft); font-size: 13px; }
.week-print-list { margin: 0; padding-left: 18px; }

.mast-stamp {
  position: absolute;
  top: 52px;
  right: 20px;
  width: 96px;
  height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  border: 3px dashed rgba(214, 69, 69, 0.55);
  border-radius: 50%;
  color: rgba(214, 69, 69, 0.62);
  font-family: ui-rounded, "SF Pro Rounded", "Nunito", "Segoe UI", system-ui, sans-serif;
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transform: rotate(12deg);
  animation: stamp-in 0.4s 0.35s ease-out both;
}
@keyframes stamp-in {
  from { opacity: 0; transform: rotate(12deg) scale(1.6); }
  to { opacity: 1; transform: rotate(12deg) scale(1); }
}
@media (max-width: 940px) {
  .mast-stamp { display: none; }
}

/* ---------- class tabs ---------- */

.class-tabs {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  gap: 8px;
  max-width: 900px;
  margin: 0 auto;
  padding: 10px 22px;
  overflow-x: auto;
  background: var(--paper);
  border-bottom: 2px solid var(--line);
  scrollbar-width: thin;
}
.class-tab {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 62px;
  padding: 7px 12px 6px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
  font: inherit;
  color: var(--ink);
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.class-tab:hover { transform: translateY(-2px); border-color: var(--ink); }
.class-tab:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55); }
.class-tab .tab-num {
  font-family: ui-rounded, "SF Pro Rounded", "Nunito", "Segoe UI", system-ui, sans-serif;
  font-size: 20px;
  font-weight: 900;
  line-height: 1;
}
.class-tab .tab-stars {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 10px;
  font-weight: 700;
  color: var(--ink-soft);
}
.class-tab.active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
  box-shadow: 3px 3px 0 var(--accent);
  transform: translateY(-2px);
}
.class-tab.active .tab-stars { color: var(--accent); }

/* ---------- subject sections ---------- */

.home-main {
  max-width: 900px;
  margin: 0 auto;
  padding: 10px 22px 44px;
}

.subj-section {
  margin: 30px 0;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.subj-section.revealed { opacity: 1; transform: none; }

.subj-head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 12px;
}
.subj-icon {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  font-size: 23px;
  background: var(--card);
  border: 2px solid var(--ink);
  border-radius: 13px;
  box-shadow: 3px 3px 0 rgba(31, 29, 26, 0.16);
}
.subj-title { flex: 0 1 auto; min-width: 0; }
.subj-name {
  font-family: ui-rounded, "SF Pro Rounded", "Nunito", "Segoe UI", system-ui, sans-serif;
  font-size: 21px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.1;
}
.subj-count {
  margin-top: 2px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
}
.subj-bar {
  flex: 1 1 90px;
  height: 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.subj-bar i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--accent), #ffc400);
  border-radius: 999px;
  transition: width 0.6s ease;
}

/* ---------- topic rows ---------- */

.topic {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 9px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  color: var(--ink);
  text-decoration: none;
  transition: transform 0.12s ease, border-color 0.15s ease, box-shadow 0.15s ease;
  animation: row-in 0.4s ease-out both;
  animation-delay: calc(var(--i) * 30ms);
}
@keyframes row-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
.topic:hover {
  transform: translateX(5px);
  border-color: var(--ink);
  box-shadow: -5px 5px 0 rgba(255, 217, 53, 0.75);
}
.topic:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55);
}

.topic-num {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
}
.topic-title {
  font-size: 17px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.topic-badges {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.topic-stars { letter-spacing: 2px; font-size: 14px; white-space: nowrap; }
.star-on { color: #e0a400; }
.star-off { color: var(--line); }
.topic-go {
  color: var(--ink-soft);
  font-weight: 800;
  transition: transform 0.15s ease, color 0.15s ease;
}
.topic:hover .topic-go { transform: translateX(4px); color: var(--ink); }

.chip {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 999px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.chip-ix { background: var(--accent); color: var(--ink); }
.chip-ach { background: var(--ink); color: var(--paper); }
.chip-mode { border: 1.5px solid var(--line); color: var(--ink-soft); }
.chip-new { border: 1.5px dashed var(--correct); color: var(--correct); }

@media (max-width: 620px) {
  .topic { grid-template-columns: auto minmax(0, 1fr) auto; }
  .topic-badges, .topic-go { display: none; }
  .mast-stats { gap: 16px; padding: 12px 16px; }
  .stat-num { font-size: 26px; }
}

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

.home-footer {
  max-width: 900px;
  margin: 0 auto;
  padding: 18px 22px 46px;
  border-top: 2px solid var(--line);
  text-align: center;
  color: var(--ink-soft);
  font-size: 13px;
}
.home-footer code {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1px 6px;
  font-size: 12px;
}
.footer-links {
  display: flex;
  gap: 22px;
  justify-content: center;
  margin-bottom: 10px;
}
.footer-links a {
  color: var(--ink);
  font-weight: 700;
  text-decoration: none;
  border-bottom: 3px solid var(--accent);
  padding-bottom: 1px;
  transition: background 0.15s ease;
}
.footer-links a:hover { background: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .mast-stats, .mast-stamp, .topic, .subj-section { animation: none; transition: none; }
  .subj-section { opacity: 1; transform: none; }
}

/* Focus card: what to practise next, under the class tabs. */
#focus { max-width: 760px; margin: 14px auto 0; padding: 0 16px; }
.focus-card {
  background: #fffdf3;
  border: 1px dashed var(--line);
  border-left: 6px solid var(--accent);
  border-radius: 14px;
  padding: 12px 16px;
}
.focus-head {
  font-size: 15px;
  font-weight: 800;
  color: var(--ink);
  margin: 0 0 4px;
}
.focus-lede {
  margin: 0 0 10px;
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1.4;
}
.focus-list { display: flex; flex-direction: column; gap: 8px; }
.focus-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 10px;
  padding: 10px 14px;
  text-decoration: none;
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  transition: border-color 0.1s, background 0.1s, box-shadow 0.1s;
}
.focus-row:hover { border-color: var(--accent); background: #fffef5; }
.focus-row:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(255, 217, 53, 0.55); }
.focus-copy { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.focus-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.focus-reason { color: var(--ink-soft); font-size: 12px; font-weight: 600; }
.focus-go { font-size: 13px; font-weight: 800; color: var(--ink-soft); white-space: nowrap; }
.chip-tried { border: 1.5px solid var(--ink); color: var(--ink); }
.review-hub-link { display: inline-block; margin-top: 12px; color: var(--ink); font-weight: 800; }

/* Review desk */
.review-main { max-width: 760px; margin: 0 auto; padding: 10px 22px 56px; }
.review-card { margin: 18px 0; padding: 16px; background: var(--card); border: 2px solid var(--line); border-radius: 14px; }
.review-card h2 { display: flex; justify-content: space-between; margin: 0 0 12px; font-size: 20px; }
.review-card h2 span { color: var(--ink-soft); font-size: 15px; }
.review-list, .skill-list, .missed-list { display: grid; gap: 8px; }
.review-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 13px; border: 2px solid var(--line); border-radius: 10px; color: var(--ink); text-decoration: none; }
.review-row:hover { border-color: var(--accent); }
.review-row small { display: block; margin-top: 3px; color: var(--ink-soft); }
.review-action { white-space: nowrap; font-weight: 800; }
.skill-row { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.skill-row span:last-child { color: var(--ink-soft); text-align: right; }
.missed-link { color: var(--ink); font-weight: 700; }
.review-empty { color: var(--ink-soft); margin: 4px 0; }

/* Parent view */
.parent-section-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.parent-section-heading h2 { margin-bottom: 4px; }
.parent-section-heading h2 span { color: var(--ink-soft); font-size: 14px; font-weight: 600; }
.parent-note, .profile-storage-note { color: var(--ink-soft); font-size: 13px; line-height: 1.45; margin: 0 0 12px; }
.profile-count { color: var(--ink-soft); font-size: 13px; white-space: nowrap; }
.parent-profile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
.parent-profile { min-width: 0; border: 2px solid var(--line); border-radius: 12px; padding: 10px; background: var(--card); }
.parent-profile.selected { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(216, 126, 50, 0.12); }
.profile-select { display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto; column-gap: 9px; width: 100%; padding: 0; border: 0; background: transparent; color: var(--ink); text-align: left; cursor: pointer; }
.profile-select:hover .profile-name, .profile-select:focus-visible .profile-name { text-decoration: underline; }
.profile-avatar { grid-row: span 2; display: grid; place-items: center; width: 42px; height: 42px; border-radius: 50%; background: #fff5d8; font-size: 25px; }
.profile-name { align-self: end; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.profile-class, .profile-summary { color: var(--ink-soft); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.profile-summary { grid-column: 1 / -1; margin-top: 9px; }
.profile-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line); }
.profile-current { color: var(--ink-soft); font-size: 12px; font-weight: 800; }
.danger-link { color: #a24b3a; }
.add-profile { margin-top: 13px; }
.add-profile summary { display: inline-block; color: var(--ink); cursor: pointer; font-weight: 800; }
#add-profile-form { display: grid; grid-template-columns: 1fr 120px; gap: 10px; margin-top: 12px; }
#add-profile-form label { display: grid; gap: 5px; color: var(--ink-soft); font-size: 12px; font-weight: 700; }
#add-profile-form input, #add-profile-form select { min-width: 0; padding: 9px 10px; border: 2px solid var(--line); border-radius: 8px; background: var(--card); color: var(--ink); font: inherit; }
#add-profile-form fieldset { grid-column: 1 / -1; border: 0; padding: 0; margin: 2px 0 0; }
#add-profile-form legend { color: var(--ink-soft); font-size: 12px; font-weight: 700; margin-bottom: 5px; }
.avatar-picker { display: flex; flex-wrap: wrap; gap: 6px; }
.avatar-picker label { position: relative; }
.avatar-picker input { position: absolute; opacity: 0; }
.avatar-picker span { display: grid; place-items: center; width: 36px; height: 36px; border: 2px solid var(--line); border-radius: 9px; background: var(--card); font-size: 22px; cursor: pointer; }
.avatar-picker input:checked + span { border-color: var(--accent); background: #fff5d8; }
.avatar-picker input:focus-visible + span { outline: 3px solid var(--accent); outline-offset: 2px; }
#add-profile-form .big-btn { grid-column: 1 / -1; justify-self: start; }
.compact-btn { padding: 8px 12px; font-size: 13px; }
.profile-storage-note { margin: 13px 0 0; }
.subject-mastery-row > span:first-child { display: flex; align-items: center; gap: 7px; }
.mastery-icon { display: inline-block; width: 20px; }
.skill-details { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 10px; }
.skill-details summary { color: var(--ink); cursor: pointer; font-size: 14px; font-weight: 800; }
.skill-detail-row { font-size: 13px; }
.parent-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.parent-stat { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 6px; border: 2px solid var(--line); border-radius: 10px; text-align: center; }
.parent-stat span { font-size: 20px; font-weight: 800; }
.parent-stat small { color: var(--ink-soft); font-size: 12px; }
@media (max-width: 520px) { .parent-stats { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) {
  .parent-section-heading { display: block; }
  .parent-section-heading .compact-btn { margin-top: 8px; }
  #add-profile-form { grid-template-columns: 1fr; }
}
.sheet-print { margin-top: 14px; }
.sheet-print h3 { display: flex; align-items: center; justify-content: space-between; font-size: 16px; margin: 0 0 10px; }
.sheet-q { padding: 10px 0; border-bottom: 1px dashed var(--line); }
.sheet-q-head { font-size: 12px; color: var(--ink-soft); margin-bottom: 4px; }
.sheet-q-prompt { font-weight: 700; margin-bottom: 6px; }
.sheet-q-opts { display: flex; flex-wrap: wrap; gap: 12px; font-size: 14px; }
.sheet-key { margin-top: 12px; padding-top: 10px; border-top: 2px solid var(--line); font-size: 13px; color: var(--ink-soft); }

@media print {
  .home-masthead, .home-footer, .parent-stats, #make-sheet, #print-week-card { display: none; }
  body.review-page { background: #fff; }
  .review-card:not(:has(.sheet-print)):not(:has(.week-print)) { display: none; }
}

/* Source: styles/interactives-gallery.css */
/* Interactive activity browser. It borrows the paper-and-ink language from the
   practice hall while giving the activity cards a brighter laboratory feel. */

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

body.ix-page { position: relative; overflow-x: hidden; }
.ix-paper-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(circle at 12% 8%, rgba(255, 217, 53, 0.22), transparent 24%),
    radial-gradient(circle at 88% 22%, rgba(81, 175, 219, 0.13), transparent 22%),
    radial-gradient(circle, rgba(31, 29, 26, 0.045) 1px, transparent 1.5px) 0 0 / 26px 26px,
    var(--paper);
}

.ix-topbar {
  max-width: 1120px;
  margin: 0 auto;
  padding: 18px 24px;
  border: 0;
}
.ix-home {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  color: var(--ink);
  font-size: 14px;
  font-weight: 850;
  text-decoration: none;
}
.ix-home > span:first-child {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  background: var(--card);
  border: 2px solid var(--ink);
  border-radius: 50%;
  transition: transform 0.15s ease, background 0.15s ease;
}
.ix-home:hover > span:first-child { transform: translateX(-3px); background: var(--accent); }
.ix-topbar-mark {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.13em;
  color: var(--ink-soft);
}

.ix-main { max-width: 1120px; padding: 0 24px 72px; }
.ix-hero {
  min-height: 410px;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(320px, 0.85fr);
  gap: 64px;
  align-items: center;
  padding: 46px 56px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 30px;
  box-shadow: 9px 9px 0 var(--accent);
  overflow: hidden;
  position: relative;
}
.ix-hero::before {
  content: "";
  position: absolute;
  width: 230px;
  height: 230px;
  left: -120px;
  bottom: -130px;
  border: 42px solid rgba(255, 255, 255, 0.055);
  border-radius: 50%;
}
.ix-eyebrow,
.ix-section-kicker {
  margin: 0 0 10px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  font-weight: 850;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.ix-hero h1 {
  margin: 0;
  font-family: ui-rounded, "SF Pro Rounded", "Nunito", "Segoe UI", system-ui, sans-serif;
  font-size: clamp(52px, 7vw, 86px);
  font-weight: 950;
  line-height: 0.92;
  letter-spacing: -0.045em;
  text-transform: uppercase;
}
.ix-hero h1 span {
  display: inline-block;
  color: var(--ink);
  background: var(--accent);
  padding: 1px 12px 7px;
  margin-top: 8px;
  transform: rotate(-1.5deg);
}
.ix-lede {
  max-width: 52ch;
  margin: 24px 0 0;
  color: rgba(250, 247, 240, 0.76);
  font-size: 17px;
  line-height: 1.62;
}
.ix-hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.ix-surprise,
.ix-secondary-action {
  min-height: 50px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 0 20px;
  border-radius: 13px;
  font: inherit;
  font-size: 14px;
  font-weight: 850;
  text-decoration: none;
  cursor: pointer;
}
.ix-surprise { color: var(--ink); background: var(--accent); border: 2px solid var(--accent); }
.ix-surprise:hover { background: #ffe56d; transform: translateY(-2px); }
.ix-secondary-action { color: var(--paper); border: 2px solid rgba(255,255,255,0.3); }
.ix-secondary-action:hover { border-color: var(--paper); }

.ix-hero-demo {
  width: 330px;
  aspect-ratio: 1;
  justify-self: center;
  position: relative;
  border: 2px solid rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,217,53,0.14), transparent 58%);
}
.ix-orbit { position: absolute; inset: 18%; border: 1px dashed rgba(255,255,255,0.2); border-radius: 50%; }
.ix-orbit-two { inset: 5%; }
.ix-demo-sun { position: absolute; inset: 0; display: grid; place-items: center; font-size: 58px; filter: drop-shadow(0 0 24px rgba(255,217,53,0.35)); }
.ix-demo-item {
  position: absolute;
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  background: var(--card);
  border: 3px solid var(--accent);
  border-radius: 19px;
  font-size: 31px;
  box-shadow: 5px 5px 0 rgba(255, 217, 53, 0.28);
}
.ix-demo-planet { top: 10px; right: 38px; transform: rotate(7deg); }
.ix-demo-ruler { left: -2px; bottom: 66px; transform: rotate(-8deg); }
.ix-demo-bulb { right: 16px; bottom: 40px; transform: rotate(5deg); }
.ix-demo-cursor {
  position: absolute;
  right: 76px;
  top: 92px;
  color: var(--accent);
  font-size: 44px;
  transform: rotate(-16deg);
  animation: ix-tap 2.2s ease-in-out infinite;
}
.ix-demo-note {
  position: absolute;
  left: 50%;
  bottom: -24px;
  transform: translateX(-50%) rotate(2deg);
  width: max-content;
  padding: 9px 15px;
  color: var(--ink);
  background: var(--card);
  border: 2px solid var(--ink);
  box-shadow: 4px 4px 0 var(--accent);
  font-size: 13px;
  font-weight: 900;
  text-transform: uppercase;
}
@keyframes ix-tap {
  0%, 55%, 100% { transform: translate(0, 0) rotate(-16deg); }
  67% { transform: translate(-8px, 8px) rotate(-16deg) scale(0.9); }
}

.ix-browser { padding-top: 72px; scroll-margin-top: 16px; }
.ix-browser-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px;
  padding-bottom: 22px;
}
.ix-section-kicker { color: var(--ink-soft); }
.ix-browser h2 {
  margin: 0;
  font-family: ui-rounded, "SF Pro Rounded", "Nunito", "Segoe UI", system-ui, sans-serif;
  font-size: clamp(28px, 4vw, 40px);
  line-height: 1.08;
}
.ix-mode { min-width: 300px; margin: 0; padding: 5px; border: 2px solid var(--ink); border-radius: 14px; display: flex; background: var(--card); }
.ix-mode legend { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }
.ix-mode button {
  flex: 1;
  min-height: 42px;
  padding: 0 14px;
  border: 0;
  border-radius: 9px;
  color: var(--ink-soft);
  background: transparent;
  font: inherit;
  font-size: 13px;
  font-weight: 850;
  cursor: pointer;
}
.ix-mode button[aria-pressed="true"] { color: var(--paper); background: var(--ink); box-shadow: 2px 2px 0 var(--accent); }

.ix-tools {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px;
  background: rgba(255,255,255,0.72);
  border: 2px solid var(--line);
  border-radius: 18px;
}
.ix-search {
  min-width: 280px;
  flex: 1 1 340px;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.ix-search:focus-within { border-color: var(--ink); box-shadow: 3px 3px 0 var(--accent); }
.ix-search > span:first-child { font-size: 25px; line-height: 1; transform: rotate(-12deg); }
.ix-search input { min-width: 0; width: 100%; border: 0; outline: 0; background: transparent; color: var(--ink); font: inherit; font-size: 15px; }
.ix-search input::placeholder { color: #918b7f; }
.ix-search kbd { padding: 2px 7px; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 6px; color: var(--ink-soft); background: var(--paper); font-size: 11px; }
.ix-filters { display: flex; gap: 7px; overflow-x: auto; scrollbar-width: thin; }
.ix-filters button {
  min-height: 42px;
  white-space: nowrap;
  padding: 0 13px;
  border: 2px solid transparent;
  border-radius: 999px;
  color: var(--ink-soft);
  background: transparent;
  font: inherit;
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
}
.ix-filters button:hover { color: var(--ink); background: var(--paper); }
.ix-filters button[aria-pressed="true"] { color: var(--ink); background: var(--accent); border-color: var(--ink); }
.ix-filters button span { margin-left: 3px; opacity: 0.65; }

.ix-results-line { min-height: 58px; display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.ix-results-line p { margin: 0; color: var(--ink-soft); font-size: 13px; }
.ix-results-line #ix-result-count { color: var(--ink); font-weight: 850; }
.ix-mode-hint { text-align: right; }

.ix-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.ix-card {
  --subject: #ffd935;
  min-height: 236px;
  display: grid;
  grid-template-columns: 74px minmax(0, 1fr);
  gap: 18px;
  padding: 22px;
  position: relative;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 20px;
  box-shadow: 0 1px 0 rgba(31,29,26,0.04);
  animation: ix-card-in 0.35s calc(var(--card-order) * 22ms) ease-out both;
  transition: transform 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease;
}
.ix-card::after { content: ""; position: absolute; left: 26px; right: 26px; bottom: -2px; height: 4px; border-radius: 4px 4px 0 0; background: var(--subject); opacity: 0; transition: opacity 0.16s ease; }
.ix-card:hover { transform: translateY(-4px); border-color: var(--ink); box-shadow: 5px 6px 0 rgba(31,29,26,0.12); }
.ix-card:hover::after { opacity: 1; }
.ix-subject-math { --subject: #ffca28; }
.ix-subject-science { --subject: #67c58b; }
.ix-subject-english { --subject: #e38bb9; }
.ix-subject-gk { --subject: #62b6e0; }
.ix-subject-cyber { --subject: #9d8ae7; }
.ix-card-icon {
  width: 68px;
  height: 68px;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--subject) 20%, white);
  border: 2px solid var(--ink);
  border-radius: 18px;
  box-shadow: 4px 4px 0 var(--subject);
  font-size: 33px;
}
.ix-card-body { min-width: 0; display: flex; flex-direction: column; }
.ix-card-meta { display: flex; align-items: center; gap: 8px; color: var(--ink-soft); font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 10px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; }
.ix-subject-pill { padding: 4px 7px; color: var(--ink); background: color-mix(in srgb, var(--subject) 26%, white); border-radius: 6px; }
.ix-card h3 { margin: 12px 0 7px; font-family: ui-rounded, "SF Pro Rounded", "Nunito", "Segoe UI", system-ui, sans-serif; font-size: 23px; line-height: 1.08; }
.ix-card p { margin: 0; color: var(--ink-soft); font-size: 14px; line-height: 1.48; }
.ix-card-foot { margin-top: auto; padding-top: 18px; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ix-action-label { color: var(--ink-soft); font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 10px; font-weight: 850; letter-spacing: 0.08em; text-transform: uppercase; }
.ix-launch { min-height: 44px; display: inline-flex; align-items: center; gap: 11px; padding: 0 14px 0 16px; color: var(--ink); background: var(--subject); border: 2px solid var(--ink); border-radius: 11px; font-size: 13px; font-weight: 900; text-decoration: none; box-shadow: 2px 2px 0 var(--ink); transition: transform 0.12s ease, box-shadow 0.12s ease; }
.ix-launch:hover { transform: translate(2px, 2px); box-shadow: none; }
.ix-launch span:last-child { font-size: 18px; }
@keyframes ix-card-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.ix-empty { padding: 54px 20px; text-align: center; background: var(--card); border: 2px dashed var(--line); border-radius: 20px; }
.ix-empty > span { font-size: 44px; }
.ix-empty h3 { margin: 10px 0 4px; font-size: 22px; }
.ix-empty p { margin: 0 0 18px; color: var(--ink-soft); }
.ix-empty button { min-height: 44px; padding: 0 16px; border: 2px solid var(--ink); border-radius: 10px; background: var(--accent); color: var(--ink); font: inherit; font-weight: 850; cursor: pointer; }

.ix-footer { max-width: 1072px; margin: 0 auto 36px; padding: 22px 0; display: flex; align-items: center; justify-content: space-between; gap: 20px; border-top: 2px solid var(--ink); }
.ix-footer p { margin: 0; color: var(--ink-soft); font-size: 13px; }
.ix-footer p strong { color: var(--ink); }
.ix-footer a { color: var(--ink); font-size: 13px; font-weight: 850; }

.ix-page :is(a, button, input):focus-visible { outline: 3px solid #2f78c4; outline-offset: 3px; }

@media (max-width: 880px) {
  .ix-hero { grid-template-columns: 1fr; min-height: auto; padding: 44px; }
  .ix-hero-demo { display: none; }
  .ix-tools { align-items: stretch; flex-direction: column; }
  .ix-search { flex-basis: auto; }
  .ix-filters { padding-bottom: 3px; }
}
@media (max-width: 680px) {
  .ix-topbar { padding: 12px 16px; }
  .ix-topbar-mark { display: none; }
  .ix-main { padding: 0 16px 52px; }
  .ix-hero { padding: 36px 26px; border-radius: 22px; box-shadow: 6px 6px 0 var(--accent); }
  .ix-hero h1 { font-size: clamp(38px, 11.5vw, 50px); }
  .ix-lede { font-size: 15px; }
  .ix-hero-actions { align-items: stretch; flex-direction: column; }
  .ix-browser { padding-top: 58px; }
  .ix-browser-head { align-items: stretch; flex-direction: column; }
  .ix-mode { min-width: 0; width: 100%; }
  .ix-tools { margin-left: -4px; margin-right: -4px; padding: 10px; }
  .ix-search { min-width: 0; }
  .ix-search kbd { display: none; }
  .ix-results-line { align-items: flex-start; flex-direction: column; gap: 4px; padding: 15px 2px; }
  .ix-mode-hint { text-align: left; }
  .ix-grid { grid-template-columns: 1fr; }
  .ix-card { min-height: 218px; grid-template-columns: 58px minmax(0, 1fr); gap: 14px; padding: 18px; }
  .ix-card-icon { width: 54px; height: 54px; border-radius: 15px; font-size: 27px; box-shadow: 3px 3px 0 var(--subject); }
  .ix-card h3 { font-size: 21px; }
  .ix-footer { margin: 0 16px 28px; align-items: flex-start; flex-direction: column; }
}
@media (prefers-reduced-motion: reduce) {
  .ix-demo-cursor,
  .ix-card { animation: none; }
  .ix-card,
  .ix-home > span:first-child,
  .ix-surprise { transition: none; }
}
