/* ═══════════════════════════════════════════════════════════
   Board DOM — Chalk-style board rendered with DOM elements
   Replaces canvas-based board with identical visual feel.
   ═══════════════════════════════════════════════════════════ */

@font-face {
  font-family: 'ChalkBoard';
  src: url('/fonts/ChalkBoard.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'CoalhandLuke';
  src: url('/fonts/CoalhandLuke.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* ─── Custom Properties (Color Palette) ─────────────────── */

:root {
  --bd-bg: #060e11;
  --bd-bg-dark: rgba(0, 0, 0, 0.25);
  --bd-grid-line: rgba(255, 255, 255, 0.025);
  --bd-grid-spacing: 40px;

  /* Fonts: Lexend for prose, JetBrains Mono for math/data/equations */
  --bd-font: 'Lexend', -apple-system, BlinkMacSystemFont, sans-serif;
  --bd-font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Three-color palette: headers / body / math */
  --bd-header: #e8c872;      /* h1/h2/h3 — warm gold tone */
  --bd-h2-color: #e8c872;    /* same as h1 */
  --bd-white: #E0E0E0;       /* body text + bullets + everything else */
  --bd-math: #A8E6CF;        /* numbers, equations, data, symbols */
  --bd-accent: #E0E0E0;
  --bd-yellow: #E0E0E0;
  --bd-gold: #E0E0E0;
  --bd-green: #E0E0E0;
  --bd-green-alt: #E0E0E0;
  --bd-cyan: #A8E6CF;        /* equations/data lean on cyan slot */
  --bd-red: #ff6b6b;         /* kept only for actual error/warning */
  --bd-dim: #E0E0E0;

  /* No chalk glow — Lexend reads better without text-shadow */
  --bd-glow: none;

  /* Sizing scale — larger for board readability */
  --bd-h1: 38px;
  --bd-h2: 30px;
  --bd-h3: 24px;
  --bd-text: 20px;
  --bd-small: 18px;
  --bd-label: 14px;

  /* Spacing */
  --bd-margin: 56px;
  --bd-el-gap: 24px;
  --bd-row-gap: 24px;
}


/* ═══════════════════════════════════════════════════════════
   1. Board Container and Scene Structure
   ═══════════════════════════════════════════════════════════ */

/* Scene — each scene is a full board state (current or past) */
.bd-scene {
  position: relative;
  background: var(--bd-bg);
  padding: 30px var(--bd-margin) 50px;
  font-family: var(--bd-font);
  font-size: var(--bd-text);
  color: var(--bd-white);
  line-height: 1.6;
  min-height: 100px;
  width: 100%;
}

/* Drawing canvas — fixed coordinate space for x,y positioned elements.
   Transparent: no border, no background, no chrome. The student should
   never see a "container" around free-positioned text — just the text. */
.bd-draw-canvas {
  position: relative;
  background: transparent;
  border: none;
  overflow: visible;
}
.bd-draw-canvas .bd-positioned {
  font-family: var(--bd-font);
  font-size: var(--bd-text);
  color: var(--bd-white);
  line-height: 1.5;
}

/* Frozen scenes — past content, subtle bottom border for separation */
.bd-scene-frozen {
  border-bottom: 1px solid rgba(255,255,255,0.05);
  padding-bottom: 30px;
  margin-bottom: 0;
}

/* Subtle grid overlay — repeating lines every 40px */
.bd-grid-bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    repeating-linear-gradient(
      90deg,
      var(--bd-grid-line) 0px,
      var(--bd-grid-line) 0.5px,
      transparent 0.5px,
      transparent var(--bd-grid-spacing)
    ),
    repeating-linear-gradient(
      0deg,
      var(--bd-grid-line) 0px,
      var(--bd-grid-line) 0.5px,
      transparent 0.5px,
      transparent var(--bd-grid-spacing)
    );
}

/* Scene content sits above the grid */
.bd-scene > *:not(.bd-grid-bg) {
  position: relative;
  z-index: 1;
}

/* Frozen past scenes — no pointer events, dimmed slightly */
.bd-scene-frozen {
  pointer-events: none;
  opacity: 0.85;
  border-bottom: 1px solid rgba(255, 255, 255, 0.03);
}

/* Zoom wrapper — scales all board content via JS transform */
#bd-board-content {
  position: relative;
  transform-origin: top left;
  /* Large bottom padding so content is never hidden behind fixed subtitle + input bars */
  padding-bottom: 200px;
  /* Minimum height ensures the board is always scrollable (like Excel adding empty rows) */
  min-height: calc(100vh + 200px);
}


/* ═══════════════════════════════════════════════════════════
   2. Element Base
   ═══════════════════════════════════════════════════════════ */

/* Base class for every board element (text, equation, step, etc.) */
.bd-el {
  margin-top: var(--bd-el-gap);
  font-family: var(--bd-font);
  line-height: 1.6;
  text-shadow: var(--bd-glow);
  max-width: 100%;
  overflow-x: auto;
  overflow-y: visible;
}

/* First element in a scene has no top margin */
.bd-el:first-child {
  margin-top: 0;
}

/* KaTeX rendered math — use JetBrains Mono for symbols + mint color */
.bd-el .katex {
  font-size: 1.1em;
  color: var(--bd-math);
}
.bd-el .katex .mathnormal,
.bd-el .katex .mord,
.bd-el .katex .mbin,
.bd-el .katex .mrel,
.bd-el .katex .mopen,
.bd-el .katex .mclose,
.bd-el .katex .mpunct,
.bd-el .katex .minner,
.bd-el .katex .mop {
  color: var(--bd-math);
}

.bd-el .katex-display {
  margin: 4px 0;
  padding: 0;
}


/* ═══════════════════════════════════════════════════════════
   3. Placement Classes
   ═══════════════════════════════════════════════════════════ */

/* Center-aligned text */
.bd-placement-center {
  text-align: center;
}

/* Right-aligned — pushes element to the right */
.bd-placement-right {
  margin-left: auto;
  text-align: right;
  width: fit-content;
}

/* Indented — offset from left margin */
.bd-placement-indent {
  padding-left: 20px;
}

/* ── Percentage-positioned elements — free-form spatial placement ── */
.bd-positioned {
  transition: none; /* no animation on placement — appears instantly */
  word-wrap: break-word;
  overflow-wrap: break-word;
}
/* Mobile fallback: revert to flow layout on small screens */
@media (max-width: 600px) {
  .bd-positioned {
    position: static !important;
    left: auto !important;
    top: auto !important;
    max-width: 100% !important;
    margin-top: var(--bd-el-gap);
  }
}

/* ── Zone-based placement — spatial positioning like a real board ── */
.bd-zone-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--bd-row-gap) var(--bd-el-gap);
  width: 100%;
  margin-top: var(--bd-el-gap);
}
.bd-zone-left { grid-column: 1; }
.bd-zone-right { grid-column: 2; }
.bd-zone-full { grid-column: 1 / -1; }
.bd-zone-right { text-align: left; } /* right zone, left-aligned text */

/* ── Connection arrows between elements ── */
.bd-connect-svg {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  z-index: 5;
  overflow: visible;
}
.bd-connect-label {
  font-family: var(--bd-font);
  font-size: var(--bd-small);
  fill: var(--bd-dim);
}

/* Flex row — elements placed side by side, FULL WIDTH */
.bd-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bd-row-gap);
  align-items: flex-start;
  width: 100%;
}
/* Each item in a row takes roughly half the width */
.bd-row > .bd-el, .bd-row > .bd-annotation {
  flex: 1 1 40%;
  min-width: 200px;
}

/* Columns grid — AI-specified multi-column layout zone */
.bd-columns {
  display: grid;
  gap: var(--bd-row-gap) var(--bd-row-gap);
  width: 100%;
  align-items: start;
}
.bd-columns > .bd-el {
  min-width: 0;
}

/* Annotations — small labels relative to elements */
.bd-annotation {
  font-family: var(--bd-font);
  font-size: var(--bd-small);
  line-height: 1.4;
  text-shadow: var(--bd-glow);
  opacity: 0.8;
}
.bd-ann-right { margin-left: 12px; align-self: center; flex: 0 0 auto !important; min-width: auto !important; }
.bd-ann-beside { margin-left: 12px; align-self: center; flex: 0 0 auto !important; min-width: auto !important; }
.bd-ann-below { margin-top: 4px; display: block; }
.bd-ann-below-right { margin-top: 4px; margin-left: auto; display: block; text-align: right; }

/* Vertical column inside a row — for stacking items (e.g., legend beside animation) */
.bd-column {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

/* Items inside a column don't need top margin (parent handles gap) */
.bd-column > .bd-el {
  margin-top: 0;
}


/* ═══════════════════════════════════════════════════════════
   4. Chalk Color Classes
   ═══════════════════════════════════════════════════════════ */

.bd-chalk-white {
  color: var(--bd-white);
  text-shadow: var(--bd-glow);
}

.bd-chalk-yellow {
  color: var(--bd-yellow);
  text-shadow: var(--bd-glow);
}

.bd-chalk-gold {
  color: var(--bd-gold);
  text-shadow: var(--bd-glow);
}

.bd-chalk-green {
  color: var(--bd-green);
  text-shadow: var(--bd-glow);
}

.bd-chalk-cyan {
  color: var(--bd-cyan);
  text-shadow: var(--bd-glow);
}

.bd-chalk-red {
  color: var(--bd-red);
  text-shadow: var(--bd-glow);
}

.bd-chalk-dim {
  color: var(--bd-dim);
  text-shadow: var(--bd-glow);
}


/* ═══════════════════════════════════════════════════════════
   5. Size Classes
   ═══════════════════════════════════════════════════════════ */

.bd-size-h1 {
  font-size: var(--bd-h1);
  font-weight: 400;
  line-height: 1.4;
  color: var(--bd-header);
}

.bd-size-h2 {
  font-size: var(--bd-h2);
  font-weight: 400;
  line-height: 1.5;
  color: var(--bd-h2-color); /* #EBF5ED */
}

.bd-size-h3 {
  font-size: var(--bd-h3);
  font-weight: 400;
  line-height: 1.5;
  color: var(--bd-h2-color); /* #EBF5ED — same as H2 */
}

.bd-size-text {
  font-size: var(--bd-text);
}

.bd-size-small {
  font-size: var(--bd-small);
}

.bd-size-label {
  font-size: var(--bd-label);
  text-transform: uppercase;
  letter-spacing: 1px;
}


/* ═══════════════════════════════════════════════════════════
   6. Compound Command Styles
   ═══════════════════════════════════════════════════════════ */

/* ── Equation: math expression with note RIGHT BESIDE it ── */
.bd-equation {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: nowrap;
  font-family: var(--bd-font-mono);
  color: var(--bd-math);
}

.bd-equation .bd-eq-main {
  flex-shrink: 0;
  font-family: var(--bd-font-mono);
  color: var(--bd-math);
}

.bd-equation .bd-eq-note {
  color: var(--bd-dim);
  font-family: var(--bd-font);
  font-style: italic;
  font-size: 0.8em;
  text-shadow: none;
  opacity: 0.85;
  white-space: nowrap;
  border-left: 1.5px solid rgba(176, 190, 197, 0.4);
  padding-left: 8px;
}

/* ── Step: numbered step with circled number ── */
.bd-step {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.bd-step-num {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--bd-small);
  font-weight: 500;
  line-height: 1;
  margin-top: 2px;
  opacity: 0.7;
}

.bd-step-content {
  flex: 1;
  min-width: 0;
}

/* ── Check / Cross: status markers ── */
.bd-check,
.bd-cross {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.bd-check::before {
  content: '\2713';  /* checkmark */
  color: var(--bd-green);
  font-weight: 600;
  font-size: 1.1em;
  flex-shrink: 0;
  text-shadow: 0 0 4px var(--bd-green);
}

.bd-cross::before {
  content: '\2717';  /* ballot X */
  color: var(--bd-red);
  font-weight: 600;
  font-size: 1.1em;
  flex-shrink: 0;
  text-shadow: 0 0 4px var(--bd-red);
}

/* ── Callout: accent border on the left, FULL WIDTH ── */
.bd-callout {
  border-left: 3px solid var(--bd-gold);
  padding-left: 14px;
  margin-left: 4px;
  width: 100%;
}

.bd-callout.bd-chalk-green {
  border-left-color: var(--bd-green);
}

.bd-callout.bd-chalk-cyan {
  border-left-color: var(--bd-cyan);
}

.bd-callout.bd-chalk-red {
  border-left-color: var(--bd-red);
}

.bd-callout.bd-chalk-dim {
  border-left-color: var(--bd-dim);
}

/* Callout variants — subtle variations */
/* V1 — default left bar (no extra styles) */
/* V2 — no bar, indented, slightly larger text */
.bd-cv-2 {
  border-left: none;
  padding-left: 0;
  margin-left: 20px;
}
.bd-cv-2 .bd-callout-text { font-size: 1.05em; }
/* V3 — centered, dot accent above instead of bar */
.bd-cv-3 {
  border-left: none;
  padding-left: 0;
  text-align: center;
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}
.bd-cv-3::before {
  content: '';
  display: block;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
  margin: 0 auto 12px;
}

/* ═══════════════════════════════════════════════════════════
   Board Blocks — split, flow, diff, question
   Controlled layout components. No x,y. System handles WHERE.
   ═══════════════════════════════════════════════════════════ */

/* ── SPLIT — thing left, meaning right ── */
.bd-split {
  display: flex;
  align-items: baseline;
  gap: 32px;
  margin-top: var(--bd-el-gap);
}
.bd-split-l {
  flex: 0 0 auto;
  font-family: var(--bd-font-mono);
  font-size: 20px;
  font-weight: 400;
  color: var(--bd-math);
}
/* KaTeX inside split left — inherit mint color, no extra margin */
.bd-split-l .katex,
.bd-split-l .katex-display {
  color: var(--bd-math);
  font-size: 1em;
  margin: 0; padding: 0;
  text-align: left;
  display: inline;
}
.bd-split-l .katex-display > .katex { display: inline; }
.bd-split-r {
  flex: 1;
  font-family: var(--bd-font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--bd-white);
  opacity: 0.75;
}
.bd-split-lg .bd-split-l { font-size: 28px; }
.bd-split-lg .bd-split-r { font-size: 17px; }
.bd-split-sm .bd-split-l { font-size: 16px; }
.bd-split-sm .bd-split-r { font-size: 14px; opacity: 0.55; }

/* Split variants — subtle variations to break monotony */
/* V1 — default baseline (no extra styles) */
/* V2 — left side has a subtle bottom accent */
.bd-sv-2 .bd-split-l {
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(168,230,207,0.2);
}
/* V3 — indented, tighter gap, right side brighter */
.bd-sv-3 {
  margin-left: 24px;
  gap: 24px;
}
.bd-sv-3 .bd-split-r { opacity: 0.85; }

/* ── FLOW — process chain with glowing dots ── */
.bd-flow {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  margin-top: var(--bd-el-gap);
  flex-wrap: wrap;
}
.bd-flow-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  min-width: 72px;
}
.bd-flow-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-bottom: 10px;
}
.bd-flow-name {
  font-family: var(--bd-font);
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 4px;
}
.bd-flow-sub {
  font-family: var(--bd-font);
  font-size: 11px;
  color: var(--bd-dim);
  max-width: 100px;
  line-height: 1.35;
}
.bd-flow-edge {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 2px 14px 0;
}
.bd-flow-line {
  width: 48px;
  height: 1px;
  background: rgba(255,255,255,0.08);
}
.bd-flow-verb {
  font-family: var(--bd-font);
  font-size: 9px;
  color: var(--bd-dim);
  letter-spacing: 0.5px;
  margin-top: 6px;
  white-space: nowrap;
}
.bd-flow-compact .bd-flow-node { min-width: 56px; }
.bd-flow-compact .bd-flow-name { font-size: 14px; }
.bd-flow-compact .bd-flow-edge { padding: 2px 8px 0; }
.bd-flow-compact .bd-flow-line { width: 28px; }

/* ── DIFF — before/after or side-by-side compare ── */
.bd-diff {
  display: flex;
  gap: 0;
  margin-top: var(--bd-el-gap);
  max-width: 780px;
}
.bd-diff-side { flex: 1; padding: 16px 24px; }
.bd-diff-label {
  font-family: var(--bd-font);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  margin-bottom: 14px;
  font-weight: 400;
}
.bd-diff-body {
  font-family: var(--bd-font-mono);
  font-size: 14px;
  line-height: 1.8;
  white-space: pre;
}
.bd-diff-bar {
  width: 1px;
  background: rgba(255,255,255,0.05);
  flex-shrink: 0;
}
/* Fix mode */
.bd-diff-fix .bd-diff-before { opacity: 0.35; }
.bd-diff-fix .bd-diff-before .bd-diff-label { color: var(--bd-red); }
.bd-diff-fix .bd-diff-before .bd-diff-body {
  text-decoration: line-through;
  text-decoration-color: rgba(255,107,107,0.25);
}
.bd-diff-fix .bd-diff-after .bd-diff-label { color: var(--bd-green); }
.bd-diff-fix .bd-diff-after .bd-diff-body { color: var(--bd-white); }
/* Compare mode */
.bd-diff-compare .bd-diff-side { opacity: 1; }
.bd-diff-compare .bd-diff-body {
  font-family: var(--bd-font);
  font-size: 15px;
  white-space: normal;
  line-height: 1.55;
}
.bd-diff-items {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.bd-diff-item {
  font-family: var(--bd-font);
  font-size: 14px;
  padding-left: 14px;
  position: relative;
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.bd-diff-item-enter {
  opacity: 0;
  transform: translateY(8px);
}
.bd-diff-item::before {
  content: '·';
  position: absolute;
  left: 0;
  color: var(--bd-dim);
  font-size: 18px;
  line-height: 1.1;
}
.bd-diff-note {
  font-family: var(--bd-font);
  font-size: 14px;
  color: var(--bd-white);
  opacity: 0.65;
  margin-top: 12px;
  line-height: 1.5;
  max-width: 500px;
}

/* ── QUESTION — 4 visual variants, picked by the renderer ──
   Prevents the board from looking templated when multiple questions
   appear in one session. Each variant has a different layout/accent. */

/* Shared base */
.bd-question-block {
  margin: 28px 0;
  max-width: 680px;
}
.bd-question-ctx {
  font-family: var(--bd-font);
  font-size: 14px;
  color: var(--bd-dim);
  margin-bottom: 14px;
  line-height: 1.5;
}
.bd-question-text {
  font-family: var(--bd-font);
  font-size: 20px;
  font-weight: 400;
  color: var(--bd-white);
  line-height: 1.5;
}
.bd-question-hint {
  font-family: var(--bd-font);
  font-size: 13px;
  color: var(--bd-dim);
  margin-top: 14px;
  font-style: italic;
}

/* V1 — Centered with cyan dot beacon */
.bd-qv-1 {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}
.bd-qv-1::before {
  content: '';
  display: block;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--bd-cyan);
  box-shadow: 0 0 12px var(--bd-cyan);
  margin: 0 auto 18px;
}

/* V2 — Left-aligned with cyan accent bar */
.bd-qv-2 {
  text-align: left;
  padding-left: 20px;
  border-left: 2px solid rgba(83,216,251,0.35);
}
.bd-qv-2 .bd-question-text { font-size: 19px; }

/* V3 — Right-aligned, italic question, gold accent */
.bd-qv-3 {
  text-align: right;
  margin-left: auto;
  padding-right: 20px;
  border-right: 2px solid rgba(251,191,36,0.3);
}
.bd-qv-3 .bd-question-text {
  font-size: 19px;
  font-style: italic;
  color: var(--bd-gold);
  font-weight: 300;
}
.bd-qv-3 .bd-question-ctx { text-align: right; }
.bd-qv-3 .bd-question-hint { text-align: right; }

/* V4 — Full-width top/bottom rule, centered, smaller text */
.bd-qv-4 {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
  max-width: 600px;
  padding: 20px 0;
  border-top: 1px solid rgba(255,255,255,0.06);
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.bd-qv-4 .bd-question-text { font-size: 18px; }
.bd-qv-4 .bd-question-ctx { font-size: 13px; }

/* ── List: styled items with markers ── */
.bd-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.bd-list li {
  position: relative;
  padding-left: 20px;
  margin-top: 6px;
}

.bd-list li:first-child {
  margin-top: 0;
}

.bd-list li::before {
  content: '\2022';  /* bullet */
  position: absolute;
  left: 4px;
  color: var(--bd-dim);
  text-shadow: var(--bd-glow);
}

/* Numbered list variant */
.bd-list-numbered {
  counter-reset: bd-list-counter;
}

.bd-list-numbered li {
  counter-increment: bd-list-counter;
}

.bd-list-numbered li::before {
  content: counter(bd-list-counter) '.';
  font-size: 0.9em;
}

/* ── Divider: horizontal chalk line ── */
.bd-divider {
  height: 1px;
  margin: 14px 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.08) 15%,
    rgba(255, 255, 255, 0.06) 85%,
    transparent 100%
  );
  border: none;
}


/* ── Mermaid diagrams ── */
.bd-mermaid {
  margin-top: var(--bd-el-gap);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  overflow: hidden;
  background: rgba(10, 14, 12, 0.5);
}
.bd-mermaid-title {
  padding: 6px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-style: italic;
}
.bd-mermaid-container { min-height: 60px; }
.bd-mermaid-container svg { display: block; margin: 0 auto; max-width: 100%; height: auto; }
.bd-mermaid .nodeLabel, .bd-mermaid .edgeLabel, .bd-mermaid .label {
  font-family: var(--bd-font) !important;
}

/* SVG shape primitives — inline SVG elements for lines, circles, arrows, rects */
.bd-svg-shape { margin-top: var(--bd-el-gap); }
.bd-svg-shape svg { filter: drop-shadow(0 0 2px rgba(255,255,255,0.1)); }

/* ═══════════════════════════════════════════════════════════
   6.5. Figure (animation + narration column)

   Layout: animation on the LEFT (60%), narration column on the
   RIGHT (40%). The narration column is filled by cmd:"narrate" or
   any content command with placement="figure:<id>" — text, h3,
   list, callout, equation all work. The whole row is a single
   bd-el that fills the available width and reserves enough height
   for the animation to actually breathe.
   ═══════════════════════════════════════════════════════════ */
.bd-figure {
  display: flex;
  align-items: stretch;
  gap: 32px;
  width: 100%;
  min-height: 420px;
  margin-top: var(--bd-el-gap);
}
.bd-figure-anim {
  flex: 1 1 65%;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
/* If the animation slot is empty (no animation code), hide it so
   narration takes full width. CSS-only safety net. */
.bd-figure-anim:empty { display: none; }
.bd-figure-anim:empty + .bd-figure-narration { flex: 1 1 100%; }

/* Override the standalone .bd-anim-figure sizing — inside a figure the
   animation should grow to fill the entire left slot, not sit in a
   220px-tall box anchored to the top. */
.bd-figure-anim > .bd-anim-figure {
  margin-top: 0;
  width: 100%;
  height: 100%;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}
.bd-figure-anim > .bd-anim-figure > .bd-anim-box {
  flex: 1 1 auto;
  min-height: 360px;
  aspect-ratio: auto;
  width: 100%;
}
.bd-figure-narration {
  flex: 1 1 35%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* Vertically center the key points beside the animation, so the right
     column reads as a balanced caption rather than top-anchored notes. */
  justify-content: center;
  gap: 14px;
  padding: 8px 4px 8px 24px;
  border-left: none;
  background: transparent;
  overflow-y: auto;
  max-height: 100%;
}
/* The optional column header is suppressed — the figure already has its
   own title in the animation panel; a second header here is redundant
   noise and breaks the uniform-bullet feel of the column. */
.bd-figure-narration-title {
  display: none;
}
/* Content nested inside the narration column reads as a uniform bulleted
   note — same font size everywhere, bullet markers in front of every line,
   consistent rhythm. No mix of big titles and tiny body. No huge callouts.
   The look should feel like a teacher's chalk-side notes column. */
.bd-figure-narration > .bd-el {
  margin-top: 0;
  position: relative;
  padding-left: 18px;
  font-size: 15px;
  line-height: 1.55;
  font-family: var(--bd-font);
  color: var(--bd-white);
  text-shadow: var(--bd-glow);
}
/* Bullet marker — small dim dot, sits at the same baseline as the text */
.bd-figure-narration > .bd-el::before {
  content: '•';
  position: absolute;
  left: 0;
  top: 0;
  font-size: 15px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.45);
}
/* Force every text-style child to the same uniform size — even if the model
   passes size:"h3" or size:"h2", we override it inside the narration column
   so the column reads as a balanced list rather than headings + body. */
.bd-figure-narration .bd-text,
.bd-figure-narration .bd-text.bd-size-h1,
.bd-figure-narration .bd-text.bd-size-h2,
.bd-figure-narration .bd-text.bd-size-h3,
.bd-figure-narration .bd-text.bd-size-text,
.bd-figure-narration .bd-text.bd-size-small {
  font-size: 15px;
  font-weight: 400;
  line-height: 1.55;
  margin: 0;
}
/* Callouts inside the narration collapse to a plain bullet too — same
   font size as text, no gold border bar, no extra padding. The model is
   instructed not to use callouts here, but if one slips through it
   shouldn't visually dominate the column. */
.bd-figure-narration .bd-callout {
  border-left: none;
  padding-left: 0;
  margin-left: 0;
  width: auto;
}
.bd-figure-narration .bd-callout .bd-callout-text,
.bd-figure-narration .bd-callout .bd-callout-text.bd-size-text,
.bd-figure-narration .bd-callout .bd-callout-text.bd-size-h1,
.bd-figure-narration .bd-callout .bd-callout-text.bd-size-h2,
.bd-figure-narration .bd-callout .bd-callout-text.bd-size-h3 {
  font-size: 15px;
  font-weight: 400;
  line-height: 1.55;
}
/* Lists inside the narration use the column's own bullet markers, not
   the default list bullets — we suppress the inner ones. */
.bd-figure-narration .bd-list {
  padding-left: 0;
}
.bd-figure-narration .bd-list li::before {
  content: '';
}

.bd-figure-narration-line {
  font-family: var(--bd-font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--bd-white);
  text-shadow: var(--bd-glow);
}

/* When the narration column has no real content (no children, or only the
   optional title), hide it entirely so the animation gets the full row.
   The flex: 1 1 58% on the anim slot lets it grow to fill the freed space. */
.bd-figure-narration:empty,
.bd-figure-narration:not(:has(> *:not(.bd-figure-narration-title))) {
  display: none;
}

/* Stack vertically on narrow viewports */
@media (max-width: 900px) {
  .bd-figure {
    flex-direction: column;
    gap: 16px;
    min-height: 0;
  }
  .bd-figure-anim,
  .bd-figure-narration {
    flex: 1 1 auto;
    width: 100%;
  }
  .bd-figure-anim > .bd-anim-figure > .bd-anim-box {
    min-height: 280px;
  }
  .bd-figure-narration {
    border: none;
    padding: 16px 0 0 0;
    max-height: none;
    justify-content: flex-start;
  }
}

/* ═══════════════════════════════════════════════════════════
   7. Animation Figure (self-contained: title + canvas + legend)
   ═══════════════════════════════════════════════════════════ */

/* Figure container — wraps title + canvas + legend; blends into board */
.bd-anim-figure {
  border: none;
  border-radius: 0;
  overflow: visible;
  background: transparent;
  margin-top: var(--bd-el-gap);
}

/* Figure title bar — sans-serif (not board chalk font) */
.bd-anim-title {
  padding: 8px 14px;
  border-bottom: none;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.2px;
  color: var(--bd-cyan);
  display: flex;
  align-items: center;
  gap: 8px;
  background: transparent;
}

/* Legend bar — sans-serif, inside the figure frame */
.bd-anim-legend-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  padding: 8px 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 11px;
  font-weight: 400;
  color: rgba(255,255,255,0.55);
  background: transparent;
}
.bd-anim-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
}
.bd-anim-legend-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 6px currentColor;
}

/* Canvas area inside figure — matches board bg so animation blends */
.bd-anim-box {
  display: block;
  overflow: visible;
  background: var(--bd-bg);
  position: relative;
  min-height: 220px;
  aspect-ratio: 4 / 3;
  padding: 8px;
}
/* p5 canvas — board bg, p.background(6,14,17) fills the pixel buffer */
.bd-anim-box canvas {
  display: block;
  background: var(--bd-bg);
  width: 100% !important;
  height: 100% !important;
}

/* Figure inside a row */
.bd-row > .bd-anim-figure {
  flex: 0 0 55%;
  max-width: 600px;
}

/* Standalone figure — responsive, fill available space */
.bd-anim-figure:not(.bd-row *) {
  width: 90%;
  max-width: min(900px, 100%);
}

/* Fullscreen mode — fixed overlay */
.bd-anim-fullscreen {
  position: fixed !important;
  inset: 40px !important;
  z-index: 500 !important;
  width: auto !important;
  max-width: none !important;
  margin: 0 !important;
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
  background: var(--bd-bg) !important;
}
.bd-anim-fullscreen .bd-anim-box {
  min-height: 0;
  height: calc(100% - 60px);
  aspect-ratio: auto;
}
/* Backdrop overlay — click to close */
.bd-anim-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.75);
  z-index: -1;
  backdrop-filter: blur(6px);
}
/* Close button — top-right corner of fullscreen figure */
.bd-anim-close-btn {
  position: absolute;
  top: -4px;
  right: -4px;
  z-index: 510;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.2);
  background: rgba(0,0,0,0.6);
  color: rgba(255,255,255,0.8);
  cursor: pointer;
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(6px);
  transition: all 0.15s;
}
.bd-anim-close-btn:hover {
  background: rgba(248,113,113,0.3);
  border-color: rgba(248,113,113,0.5);
}

/* (Removed duplicate — consolidated into .bd-anim-box canvas rule above) */

.bd-anim-canvas-wrap {
  width: 100%;
  height: 100%;
}

/* ── Drawing shimmer — shown on board while content is being generated ── */
.bd-drawing-shimmer {
  position: absolute;
  bottom: 24px;
  left: 24px;
  right: 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
  z-index: 5;
  transition: opacity .3s;
}
.bd-shimmer-bar {
  height: 10px;
  width: 80%;
  border-radius: 5px;
  background: linear-gradient(90deg, rgba(52,211,153,.04) 25%, rgba(52,211,153,.12) 50%, rgba(52,211,153,.04) 75%);
  background-size: 400% 100%;
  animation: bdShimmer 1.8s ease-in-out infinite;
}
.bd-shimmer-label {
  font-size: 11px;
  color: rgba(52,211,153,.35);
  font-weight: 400;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  animation: bdShimmerPulse 2s ease-in-out infinite;
}
@keyframes bdShimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@keyframes bdShimmerPulse {
  0%, 100% { opacity: .3; }
  50% { opacity: .7; }
}

/* Expand button overlay */
.bd-anim-controls {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 5;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.bd-anim-box:hover .bd-anim-controls {
  opacity: 1;
}

.bd-anim-controls button {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(0, 0, 0, 0.5);
  color: rgba(255, 255, 255, 0.8);
  cursor: pointer;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(6px);
  transition: all 0.15s;
}

.bd-anim-controls button:hover {
  background: rgba(255, 255, 255, 0.15);
}


/* ═══════════════════════════════════════════════════════════
   8. Character-by-Character Animation
   ═══════════════════════════════════════════════════════════ */

/* Individual character — hidden by default for typewriter effect */
.bd-char {
  opacity: 0;
  transition: opacity 0.04s ease;
}

/* Character revealed — set by JS during animation */
.bd-char-visible {
  opacity: 1;
}

/* Bulk reveal — when element animation completes, all chars visible */
.bd-chars-visible .bd-char {
  opacity: 1;
}


/* ═══════════════════════════════════════════════════════════
   9. Board Editing (strikeout, delete)
   ═══════════════════════════════════════════════════════════ */

/* Strikeout — red line-through for corrections */
.bd-strikeout {
  text-decoration: line-through;
  text-decoration-color: var(--bd-red);
  text-decoration-thickness: 2px;
  opacity: 0.6;
}

/* Deleted — completely hidden */
.bd-deleted {
  display: none;
}


/* ═══════════════════════════════════════════════════════════
   10. Highlighting / Referencing
   ═══════════════════════════════════════════════════════════ */

/* Highlight glow — pulsing animation for referenced elements */
.bd-highlight {
  animation: bd-highlight-glow 4.3s ease-in-out;
}

@keyframes bd-highlight-glow {
  0% {
    text-shadow: var(--bd-glow);
    background-color: transparent;
  }
  8% {
    text-shadow: 0 0 8px var(--bd-green-alt), 0 0 16px var(--bd-green-alt);
    background-color: rgba(52, 211, 153, 0.08);
    border-radius: 3px;
  }
  30% {
    text-shadow: 0 0 8px var(--bd-green-alt), 0 0 16px var(--bd-green-alt);
    background-color: rgba(52, 211, 153, 0.08);
  }
  100% {
    text-shadow: var(--bd-glow);
    background-color: transparent;
  }
}


/* ═══════════════════════════════════════════════════════════
   11. Responsive Considerations
   ═══════════════════════════════════════════════════════════ */

/* Board content wrapper — scrollable with max-width */
.bd-canvas-wrap {
  flex: 1;
  overflow-x: hidden;
  overflow-y: scroll !important;
  position: relative;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x pan-y pinch-zoom;
  background: var(--bd-bg);
  scroll-behavior: smooth;
}

/* Scale down spacing and fonts on narrow screens */
@media (max-width: 600px) {
  :root {
    --bd-margin: 16px;
    --bd-h1: 22px;
    --bd-h2: 18px;
    --bd-h3: 16px;
    --bd-text: 14px;
    --bd-small: 12px;
    --bd-label: 11px;
  }

  .bd-row {
    gap: 8px;
  }

  .bd-row > .bd-anim-box {
    flex: 0 0 100%;
    max-width: 100%;
  }

  .bd-anim-box:not(.bd-row *) {
    width: 80%;
    max-width: 100%;
  }

  .bd-equation {
    gap: 10px;
  }
}

@media (max-width: 400px) {
  :root {
    --bd-margin: 12px;
    --bd-el-gap: 8px;
  }
}


/* ═══════════════════════════════════════════════════════════
   Board-Native Assessment Elements
   ═══════════════════════════════════════════════════════════ */

.bd-assess-card {
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 14px;
  padding: 24px 28px;
  max-width: 90%;
  backdrop-filter: blur(4px);
  animation: bd-fadeUp 0.4s ease;
  overflow-wrap: break-word;
  word-wrap: break-word;
}

@keyframes bd-fadeUp {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.bd-assess-prompt {
  font-family: var(--bd-font);
  font-size: var(--bd-text);
  color: var(--bd-white);
  line-height: 1.5;
  margin-bottom: 18px;
  text-shadow: var(--bd-glow);
}

/* MCQ options */
.bd-mcq-options { display: flex; flex-direction: column; gap: 6px; }

.bd-mcq-opt {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border-radius: 10px;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid rgba(255, 255, 255, 0.04);
  cursor: pointer; transition: all 0.15s;
  font-family: var(--bd-font);
  font-size: 18px;
  color: var(--bd-white);
}

.bd-mcq-opt:hover { background: rgba(255, 255, 255, 0.05); border-color: rgba(255, 255, 255, 0.08); }
.bd-mcq-opt.bd-selected { background: rgba(52, 211, 153, 0.06); border-color: rgba(52, 211, 153, 0.2); }
.bd-mcq-opt.bd-correct { background: rgba(52, 211, 153, 0.1); border-color: var(--bd-green); }
.bd-mcq-opt.bd-wrong { background: rgba(255, 107, 107, 0.06); border-color: rgba(255, 107, 107, 0.2); }

.bd-mcq-radio {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.2);
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  transition: all 0.15s;
}

.bd-mcq-opt.bd-selected .bd-mcq-radio { border-color: var(--bd-green); }
.bd-mcq-opt.bd-selected .bd-mcq-radio::after { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--bd-green); }
.bd-mcq-opt.bd-correct .bd-mcq-radio { border-color: var(--bd-green); }
.bd-mcq-opt.bd-correct .bd-mcq-radio::after { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--bd-green); }

/* Free text input */
.bd-free-input {
  width: 100%; min-height: 70px; padding: 12px 14px;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px; color: var(--bd-white);
  font-family: var(--bd-font); font-size: 18px;
  outline: none; resize: vertical; transition: border-color 0.2s;
}
.bd-free-input:focus { border-color: rgba(255, 255, 255, 0.12); }
.bd-free-input::placeholder { color: rgba(255, 255, 255, 0.2); }

/* Spot the error */
.bd-spot-error-eq {
  font-family: var(--bd-font); font-size: 28px; color: var(--bd-cyan);
  padding: 16px 20px; background: rgba(0, 0, 0, 0.2);
  border-radius: 10px; margin: 10px 0; display: inline-block;
}

.bd-assess-hint {
  font-family: var(--bd-font); font-size: 16px;
  color: rgba(255, 255, 255, 0.3); margin: 8px 0;
}

/* Teach-back label */
.bd-teachback-label {
  font-family: var(--bd-font); font-size: var(--bd-h3);
  color: var(--bd-yellow); margin-bottom: 8px;
  text-shadow: var(--bd-glow);
}

/* Confidence scale */
.bd-confidence-scale { display: flex; gap: 6px; margin-top: 8px; }

.bd-conf-btn {
  flex: 1; padding: 12px 8px; border-radius: 10px;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid rgba(255, 255, 255, 0.04);
  font-family: var(--bd-font); font-size: 16px;
  color: rgba(255, 255, 255, 0.5); text-align: center;
  cursor: pointer; transition: all 0.15s;
}
.bd-conf-btn:hover { background: rgba(255, 255, 255, 0.05); color: var(--bd-white); }
.bd-conf-btn.bd-conf-selected { background: rgba(52, 211, 153, 0.08); border-color: rgba(52, 211, 153, 0.2); color: var(--bd-green); }

/* Submit */
.bd-assess-submit { display: flex; justify-content: flex-end; margin-top: 14px; }

.bd-submit-btn {
  padding: 10px 26px; border-radius: 10px;
  background: var(--bd-green); color: #0a0d0b;
  font-family: 'Inter', sans-serif; font-size: 13px; font-weight: 500;
  border: none; cursor: pointer; transition: all 0.15s;
}
.bd-submit-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(52, 211, 153, 0.2); }

/* Progress dots */
.bd-assess-progress { display: flex; gap: 5px; justify-content: center; margin: 14px 0 0; }
.bd-prog-dot { width: 5px; height: 5px; border-radius: 50%; background: rgba(255, 255, 255, 0.08); }
.bd-prog-dot.bd-prog-done { background: var(--bd-green); }
.bd-prog-dot.bd-prog-active { background: rgba(255, 255, 255, 0.3); }

/* ── Mixed text + code (markdown fences inside cmd:"text") ─── */
.bd-text-mixed {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: var(--bd-el-gap);
}
.bd-text-mixed > .bd-text-segment {
  margin: 0;
}
.bd-text-mixed > .bd-text-code-segment {
  margin: 4px 0;
}

/* ── Code block — read-only OR editable OR runnable ─── */
.bd-code-block {
  background: #0d1117;
  border: 1px solid #1e2733;
  border-radius: 10px;
  margin: 14px 0;
  overflow: hidden;
  width: 100%;
  max-width: 820px;
}
.bd-code-block.bd-code-runner {
  box-shadow: 0 0 0 1px rgba(168,230,207,0.04);
  border-color: rgba(168,230,207,0.15);
}
.bd-code-header {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px;
  background: rgba(255,255,255,.025);
  border-bottom: 1px solid #1e2733;
}
.bd-code-block.bd-code-runner .bd-code-header {
  background: rgba(168,230,207,0.04);
}
.bd-code-lang {
  font-size: 10px; font-weight: 600;
  color: #A8E6CF;
  text-transform: uppercase;
  letter-spacing: .8px;
  font-family: 'Lexend', system-ui, sans-serif;
}
.bd-code-file {
  font-size: 11px; color: #94a3b8;
  font-family: 'JetBrains Mono', monospace;
}
.bd-code-prompt {
  font-size: 11px;
  color: #A8E6CF;
  font-weight: 500;
}
.bd-code-prompt::before { content: '✎ '; margin-right: 2px; }
.bd-code-actions {
  margin-left: auto;
  display: flex; gap: 8px;
}
.bd-code-btn {
  font-family: 'Lexend', system-ui, sans-serif;
  font-size: 11px;
  padding: 5px 12px;
  border-radius: 6px;
  border: 1px solid rgba(255,255,255,0.1);
  background: transparent;
  color: #E0E0E0;
  cursor: pointer;
  font-weight: 500;
}
.bd-code-btn:hover { background: rgba(255,255,255,0.05); }
.bd-code-btn-run {
  background: rgba(52,211,153,0.12);
  color: #34d399;
  border-color: rgba(52,211,153,0.3);
}
.bd-code-btn-run:hover { background: rgba(52,211,153,0.2); }
.bd-code-btn-run:disabled { opacity: 0.4; cursor: not-allowed; }

/* Body — same shell for read-only <pre> and editable <pre contenteditable>.
   max-height + overflow-y: auto makes the body scroll internally when
   code grows beyond the visible area — the header stays pinned at the
   top (it's a sibling above the body, not inside it). New lines type
   in at the bottom and the body auto-scrolls to keep them visible. */
.bd-code-body {
  padding: 12px 16px;
  overflow-x: auto;
  overflow-y: auto;
  max-height: 420px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  line-height: 1.7;
  color: #e6edf3;
  white-space: pre;
  outline: none;
  tab-size: 4;
  -moz-tab-size: 4;
  min-height: 1.7em;
}
.bd-code-body[contenteditable="true"] {
  cursor: text;
  caret-color: #A8E6CF;
}
.bd-code-body[contenteditable="true"]:focus {
  background: rgba(168,230,207,0.015);
}

/* Line numbers + line highlighting — applied after highlight.js runs.
   Each line of code is wrapped in a <span class="bd-code-line"> with
   data-ln="N" for the line number (shown via ::before) and an optional
   bd-code-line-hi class for a transparent mint background highlight
   that the tutor can use to draw attention while speaking. */
.bd-code-line {
  display: block;
  position: relative;
  padding-left: 44px;
  min-height: 1.7em;
}
.bd-code-line::before {
  content: attr(data-ln);
  position: absolute;
  left: 0;
  width: 30px;
  text-align: right;
  color: #484f58;
  font-size: 11px;
  user-select: none;
  pointer-events: none;
}
.bd-code-line-hi {
  background: rgba(168, 230, 207, 0.08);
  border-left: 2px solid #A8E6CF;
  padding-left: 42px;
  margin-left: -2px;
}
.bd-code-line-hi::before {
  color: #A8E6CF;
}

/* Old line-number markup — kept for back-compat with legacy code blocks */
.bd-cl { display: block; padding: 1px 0; }
.bd-cl-hi {
  background: rgba(52,211,153,.07);
  border-left: 3px solid #34d399;
  padding-left: 11px;
  margin-left: -14px;
  margin-right: -14px;
  padding-right: 14px;
}
.bd-ln {
  display: inline-block;
  width: 24px;
  text-align: right;
  margin-right: 14px;
  color: #484f58;
  user-select: none;
  font-size: 11px;
}

/* Test cases panel */
.bd-code-tests {
  border-top: 1px solid #1e2733;
  background: rgba(255,255,255,0.015);
  padding: 12px 16px;
}
.bd-code-tests-header {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: #94a3b8;
  margin-bottom: 8px;
  font-weight: 500;
  font-family: 'Lexend', system-ui, sans-serif;
  display: flex; align-items: center; gap: 8px;
}
.bd-code-tests-summary {
  margin-left: auto;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
  font-size: 11px;
}
.bd-code-tests-summary.idle { color: #94a3b8; font-weight: 400; font-style: italic; }
.bd-code-tests-summary.ok { color: #34d399; }
.bd-code-tests-summary.err { color: #ff6b6b; }
.bd-code-tests-table {
  width: 100%;
  border-collapse: collapse;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
}
.bd-code-tests-table th,
.bd-code-tests-table td {
  padding: 5px 10px;
  text-align: left;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  color: #E0E0E0;
}
.bd-code-tests-table th {
  font-family: 'Lexend', system-ui, sans-serif;
  font-weight: 500;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: #94a3b8;
}
.bd-code-tests-table tr:last-child td { border-bottom: none; }
.bd-code-tests-table .bd-code-tests-status { width: 18px; color: #94a3b8; }
.bd-code-tests-table tr.pass-row { background: rgba(52,211,153,0.03); }
.bd-code-tests-table tr.pass-row .bd-code-tests-status { color: #34d399; }
.bd-code-tests-table tr.pass-row .bd-code-tests-actual { color: #34d399; }
.bd-code-tests-table tr.fail-row { background: rgba(255,107,107,0.04); }
.bd-code-tests-table tr.fail-row .bd-code-tests-status { color: #ff6b6b; }
.bd-code-tests-table tr.fail-row .bd-code-tests-actual { color: #ff6b6b; }

/* Output panel */
.bd-code-output {
  border-top: 1px solid #1e2733;
  background: rgba(0,0,0,0.3);
  padding: 12px 16px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  line-height: 1.6;
  white-space: pre-wrap;
  max-height: 220px;
  overflow-y: auto;
}
.bd-code-output-header {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 6px;
  font-family: 'Lexend', system-ui, sans-serif;
  font-weight: 500;
  display: flex; align-items: center; gap: 8px;
}
.bd-code-output.bd-code-output-empty {
  background: transparent;
  padding: 12px 16px;
  font-style: italic;
  color: #94a3b8;
  font-family: 'Lexend', system-ui, sans-serif;
  font-size: 11px;
}
.bd-code-output-empty-text { font-style: italic; }
.bd-code-output.bd-code-output-ok { color: #c8e6c9; }
.bd-code-output.bd-code-output-err { color: #ffcdd2; }
.bd-code-output.bd-code-output-ok .bd-code-output-header { color: #34d399; }
.bd-code-output.bd-code-output-err .bd-code-output-header { color: #ff6b6b; }
.bd-code-output-status-dot {
  width: 7px; height: 7px; border-radius: 50%;
  display: inline-block;
}
.bd-code-output-status-dot.ok { background: #34d399; box-shadow: 0 0 8px rgba(52,211,153,.6); }
.bd-code-output-status-dot.err { background: #ff6b6b; box-shadow: 0 0 8px rgba(255,107,107,.6); }
.bd-code-output-status-dot.running { background: #fbbf24; animation: bdRunningPulse 1s infinite; }
@keyframes bdRunningPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* ── Three.js 3D scene on board ─── */
.bd-scene3d {
  margin: 10px 0;
  position: relative;
  /* Override .bd-el overflow-x:auto which intercepts drag gestures */
  overflow: visible !important;
  touch-action: none;
  user-select: none;
}
.bd-scene3d canvas {
  display: block;
  border-radius: 10px;
  pointer-events: auto !important;
  touch-action: none;
  cursor: grab;
  user-select: none;
  /* Prevent canvas from being a scroll target */
  overflow: visible;
}
.bd-scene3d canvas:active { cursor: grabbing; }

/* 3D controls bar — Pause/Speed/Title */
.bd-3d-controls {
  display: flex; align-items: center; gap: 14px;
  padding: 8px 14px;
  background: rgba(255,255,255,0.04);
  border-bottom: 1px solid rgba(255,255,255,0.06);
  font-family: var(--bd-font); font-size: 12px;
  position: relative; z-index: 2; pointer-events: auto;
}
.bd-3d-ctrl-btn {
  font-family: var(--bd-font); font-size: 12px;
  padding: 4px 14px; border-radius: 5px;
  border: 1px solid rgba(255,255,255,0.12);
  background: rgba(255,255,255,0.06);
  color: #e0e0e0; cursor: pointer; pointer-events: auto;
}
.bd-3d-ctrl-btn:hover { background: rgba(255,255,255,0.1); }
.bd-3d-ctrl-label { color: #94a3b8; display: flex; align-items: center; gap: 8px; }
.bd-3d-speed { width: 80px; cursor: pointer; }
.bd-3d-ctrl-title { margin-left: auto; color: #94a3b8; font-size: 11px; }

/* 3D legend bar */
.bd-3d-legend {
  display: flex; gap: 16px; flex-wrap: wrap;
  padding: 6px 14px;
  font-size: 12px; color: #b0b0ac;
  background: rgba(0,0,0,0.2);
}
.bd-3d-legend-item { display: flex; align-items: center; gap: 6px; }
.bd-3d-legend-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}

/* 3D skeleton loading */
.bd-3d-skeleton { display: flex; flex-direction: column; align-items: center; justify-content: center;
  height: 100%; gap: 12px; color: #52525b; font-size: 12px; font-family: Inter, sans-serif; }
.bd-3d-skeleton-orb { width: 48px; height: 48px; border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(52,211,153,.15), rgba(52,211,153,.03));
  border: 1px solid rgba(52,211,153,.1);
  animation: bd3dPulse 2s ease-in-out infinite; }
@keyframes bd3dPulse {
  0%, 100% { transform: scale(1); opacity: 0.6; box-shadow: 0 0 20px rgba(52,211,153,.05); }
  50% { transform: scale(1.1); opacity: 1; box-shadow: 0 0 40px rgba(52,211,153,.15); }
}

/* 3D fallback (when Three.js unavailable) */
.bd-3d-fallback { display: flex; flex-direction: column; align-items: center; justify-content: center;
  height: 100%; gap: 8px; color: #52525b; font-size: 12px; font-family: Inter, sans-serif; }
.bd-3d-fallback-icon { font-size: 36px; opacity: 0.3; }
.bd-3d-fallback-sub { font-size: 10px; color: #3f3f46; }

/* ─── Drawing-in-progress skeleton ──────────────────────────
   Shown while the LLM is mid-stream of a <vb> draw command —
   gives the student feedback that something is being prepared
   before the parsed beat actually arrives.

   Pinned with position:fixed so it stays at the bottom of the
   visible viewport regardless of board scroll position. Sits
   above the voice bar (which lives at bottom: ~80px in voice mode).
*/
.bd-drawing-skeleton {
  position: fixed;
  bottom: 140px;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 18px 28px;
  background: rgba(6, 14, 17, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(168, 230, 207, 0.22);
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
  pointer-events: none;
  z-index: 950;
  opacity: 0;
  transition: opacity 0.2s ease, transform 0.25s ease;
}
.bd-drawing-skeleton.bd-drawing-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.bd-drawing-bars {
  display: flex;
  flex-direction: column;
  gap: 9px;
  align-items: stretch;
  width: 240px;
}
.bd-drawing-bar {
  height: 11px;
  border-radius: 4px;
  background: linear-gradient(
    90deg,
    rgba(168, 230, 207, 0.06) 0%,
    rgba(168, 230, 207, 0.28) 50%,
    rgba(168, 230, 207, 0.06) 100%
  );
  background-size: 200% 100%;
  animation: bd-drawing-shimmer 1.4s ease-in-out infinite;
}
.bd-drawing-bar:nth-child(1) { width: 100%; }
.bd-drawing-bar:nth-child(2) { width: 78%; animation-delay: 0.18s; }
.bd-drawing-bar:nth-child(3) { width: 92%; animation-delay: 0.36s; }
.bd-drawing-text {
  font-family: var(--bd-font);
  font-size: 13px;
  color: var(--bd-white);
  opacity: 0.55;
  letter-spacing: 0.4px;
}
.bd-drawing-text::after {
  content: '';
  display: inline-block;
  width: 1ch;
  text-align: left;
  animation: bd-drawing-dots 1.4s steps(4, end) infinite;
}
@keyframes bd-drawing-shimmer {
  0%   { background-position: 200% 0;  opacity: 0.55; }
  50%  { opacity: 1; }
  100% { background-position: -200% 0; opacity: 0.55; }
}
@keyframes bd-drawing-dots {
  0%   { content: ''; }
  25%  { content: '.'; }
  50%  { content: '..'; }
  75%  { content: '...'; }
  100% { content: ''; }
}

/* ── Board streaming indicator — shown while LLM generates ── */
#bd-streaming-indicator {
  position: fixed;
  bottom: 130px;
  left: 50%;
  transform: translateX(-50%) translateY(10px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 16px 32px;
  background: rgba(6, 14, 17, 0.85);
  border: 1px solid rgba(52, 211, 153, 0.12);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  z-index: 900;
  opacity: 0;
  transition: opacity 0.3s ease, transform 0.3s ease;
  pointer-events: none;
}
#bd-streaming-indicator.bd-stream-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.bd-stream-pulse {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(52, 211, 153, 0.3), transparent 70%);
  border: 2px solid rgba(52, 211, 153, 0.2);
  animation: bd-stream-breathe 2s ease-in-out infinite;
}
@keyframes bd-stream-breathe {
  0%, 100% { transform: scale(0.85); opacity: 0.5; border-color: rgba(52, 211, 153, 0.15); }
  50% { transform: scale(1.1); opacity: 1; border-color: rgba(52, 211, 153, 0.4); }
}
.bd-stream-text {
  font-family: var(--bd-font, 'Inter', sans-serif);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.45);
  letter-spacing: 0.3px;
}
