/* Shared styling for the four "concept" scenes: Trajectory, Objective,
 * π*-from-Q, why-not-DP. KaTeX-heavy, minimal text. */

.concept-scene {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.concept-heading {
  font-family: 'Press Start 2P', monospace;
  font-size: 14px;
  letter-spacing: 0.08em;
  margin: 6px 0 4px;
  color: var(--ink);
}

.concept-formula-card {
  background: var(--bg-strong);
  border: 4px solid var(--rule);
  padding: 18px 22px;
  box-shadow:
    inset 0 0 0 2px var(--bg-strong),
    inset 0 0 0 4px var(--inner-highlight),
    inset 0 0 0 6px var(--bg-strong);
  color: var(--ink-on-box);
  text-align: center;
  /* A long KaTeX line (e.g. τ = (S₁,A₁,R₁, …) on the Trajectory scene) can be
     wider than a 390px viewport. Cap the card to its container and let the
     formula scroll INSIDE the card rather than widening the whole page, which
     would shift and clip every sibling. Desktop is unaffected: the formulas
     fit, so no scrollbar appears and the box-shadow inset frame is unchanged. */
  max-width: 100%;
  overflow-x: auto;
}
.concept-formula-card .katex-display {
  margin: 0;
}
.concept-formula-card.compact { padding: 12px 16px; }
.concept-formula-card .concept-formula-label {
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--ink-secondary);
  margin-bottom: 10px;
}
.concept-formula-card .concept-formula-foot {
  font-family: 'Press Start 2P', monospace;
  font-size: 8px;
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
  margin-top: 10px;
}

.concept-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

.concept-key-question {
  font-family: 'Press Start 2P', monospace;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-align: center;
  padding: 14px;
  color: var(--pikachu-cheek, #C62828);
  border: 3px solid var(--pikachu-cheek, #C62828);
  background: var(--bg-strong);
}

/* ---- Trajectory scene ---- */

.traj-rollout {
  display: flex;
  align-items: stretch;
  overflow-x: auto;
  /* Larger gap between turn-groups than within a group (.traj-group
     keeps its three boxes tight) — clusters each (s,a,r) triple
     visually without losing the box-per-symbol mapping. */
  gap: 22px;
  padding: 14px 12px;
  background: var(--bg-strong);
  border: 4px solid var(--rule);
  min-height: 180px;
}

/* One turn = a .traj-group of three boxes (sᵢ, aᵢ, rᵢ) so the eye
   can trace each subscripted symbol from the formula above into its
   own box. Within a group the inter-box gap is tight; between groups
   the .traj-rollout `gap` provides breathing room. */
.traj-group {
  display: flex;
  align-items: stretch;
  gap: 4px;
  flex-shrink: 0;
}

.traj-box {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  padding: 6px 8px 8px;
  background: var(--bg);
  border: 2px solid var(--ink);
  border-left-width: 5px;
  font-family: 'Press Start 2P', monospace;
  color: var(--ink-on-box);
  animation: traj-box-pop 280ms ease-out backwards;
}

/* Per-component border-left colour — echoes the cross-viz hue
   identity used in scene-5 recap (MDP red / Casino blue / Bellman
   purple). Box-label text gives the redundant non-colour cue. */
.traj-box-state  { border-left-color: var(--hue-anymal); min-width: 100px; }
.traj-box-action { border-left-color: var(--hue-casino); min-width: 88px;  }
.traj-box-reward { border-left-color: var(--hue-ghost);  min-width: 60px; align-items: center; }

/* Final-state box (s_{N+1}) — only appears after a terminal turn so
   the trajectory visibly closes. Whichever side fainted is rendered
   with the .fainted sprite + a 0%-width HP bar + "FAINT" bucket. The
   border uses the colour-blind-safe win/loss tokens (blue/vermillion). */
.traj-box-state-final.win {
  border-color: var(--cb-blue);
  border-left-color: var(--cb-blue);
  background: rgba(0, 114, 178, 0.08);
}
.traj-box-state-final.loss {
  border-color: var(--cb-vermillion);
  border-left-color: var(--cb-vermillion);
  background: rgba(213, 94, 0, 0.08);
}
.traj-box-terminal-mini {
  font-size: 6px;
  color: var(--ink-secondary);
  letter-spacing: 0.04em;
  margin-left: 4px;
}
.traj-box-sprite.fainted {
  opacity: 0.32;
  filter: grayscale(0.7);
  transform: rotate(-22deg);
}

.traj-box-label {
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
  margin-bottom: 6px;
}
.traj-box-label sub {
  font-size: 7px;
  vertical-align: baseline;
}

/* sᵢ box content: two mini-Pokemons + HP bars + bucket labels. */
.traj-box-state-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  flex: 1;
  align-items: end;
}
.traj-box-side {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.traj-box-sprite {
  width: 28px;
  height: 28px;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}
.traj-box-hp {
  width: 100%;
  height: 4px;
  background: rgba(0,0,0,0.2);
  border: 1px solid var(--ink);
  box-sizing: border-box;
}
.traj-box-hp-fill { height: 100%; background: #48C848; }
.traj-box-hp-fill.b1 { background: #88D848; }
.traj-box-hp-fill.b2 { background: #E8C828; }
.traj-box-hp-fill.b3 { background: #E89028; }
.traj-box-hp-fill.b4 { background: #E84828; }
.traj-box-bucket { font-size: 7px; }

/* aᵢ box content: just the move name. */
.traj-box-action-body {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 8.5px;
  color: var(--hue-casino);
  text-align: center;
  letter-spacing: 0.04em;
  line-height: 1.4;
}

/* rᵢ box content: big signed number, centred. Terminal turns swap the
   border colour to colour-blind blue/vermillion and add a ✓/✗ tag. */
.traj-box-reward-body {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--hue-ghost);
  letter-spacing: 0.04em;
}
.traj-box-reward.win {
  border-color: var(--cb-blue);
  border-left-color: var(--cb-blue);
  background: rgba(0, 114, 178, 0.10);
}
.traj-box-reward.win  .traj-box-reward-body { color: var(--cb-blue); font-size: 16px; }
.traj-box-reward.loss {
  border-color: var(--cb-vermillion);
  border-left-color: var(--cb-vermillion);
  background: rgba(213, 94, 0, 0.10);
}
.traj-box-reward.loss .traj-box-reward-body { color: var(--cb-vermillion); font-size: 16px; }
.traj-box-terminal-tag {
  font-size: 8px;
  margin-top: 4px;
  letter-spacing: 0.06em;
}
.traj-box-reward.win  .traj-box-terminal-tag { color: var(--cb-blue); }
.traj-box-reward.loss .traj-box-terminal-tag { color: var(--cb-vermillion); }

@keyframes traj-box-pop {
  0%   { opacity: 0; transform: translateY(-6px) scale(0.95); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* Used by sceneObjective: dim state + action boxes so G_t illustration
   focuses the eye on the reward boxes alone. */
.traj-box.muted {
  opacity: 0.30;
  filter: grayscale(0.55);
}

/* Reward boxes in sceneObjective are clickable to pick a new t. */
.traj-box-reward.clickable { cursor: pointer; transition: transform 100ms ease-out; }
.traj-box-reward.clickable:hover { transform: scale(1.04); }
.traj-box-reward.selected {
  outline: 3px solid var(--pikachu-yellow);
  outline-offset: 3px;
  position: relative;
  z-index: 2;
}

/* ----- G_t illustration block in sceneObjective ----- */
.g-illus {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px 14px 14px;
  background: var(--bg-strong);
  border: 4px solid var(--rule);
  box-shadow:
    inset 0 0 0 2px var(--bg-strong),
    inset 0 0 0 4px var(--inner-highlight),
    inset 0 0 0 6px var(--bg-strong);
}
.g-illus-label {
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  letter-spacing: 0.06em;
  color: var(--ink-secondary);
  text-align: center;
}
.g-illus-rollout {
  background: transparent;
  border: none;
  padding: 4px 0;
  min-height: 0;
}

.g-expansion {
  font-family: 'Press Start 2P', monospace;
  font-size: 10px;
  line-height: 1.9;
  color: var(--ink-on-box);
  padding: 8px 14px;
  background: var(--bg);
  border: 2px solid var(--rule);
}
.g-expansion .g-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}
.g-expansion .g-lhs {
  font-size: 12px;
  letter-spacing: 0.04em;
}
.g-expansion .g-eq {
  margin-left: 28px;       /* indent continuation lines under "= " of line 1 */
  color: var(--ink-secondary);
}
.g-expansion .g-gamma { color: var(--hue-star); }
.g-expansion .g-r     { color: var(--hue-ghost); }
.g-expansion .g-prod  { color: var(--ink-on-box); font-variant-numeric: tabular-nums; }
.g-expansion .g-final { padding-top: 6px; border-top: 2px solid var(--rule); margin-top: 4px; }
.g-expansion .g-result {
  font-size: 16px;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}
.g-expansion .g-result.pos { color: var(--cb-blue); }
.g-expansion .g-result.neg { color: var(--cb-vermillion); }

.traj-controls {
  display: flex;
  gap: 10px;
  align-items: center;
}
.traj-status {
  font-family: 'Press Start 2P', monospace;
  font-size: 8px;
  color: var(--ink-secondary);
  margin-left: auto;
}

/* ---- Q* demo battle (sceneQstar) ----
   Looping demo where PIKACHU plays argmax_a Q(s,a) each turn against
   CHARMANDER; the right-hand Q-panel updates per state with the
   argmax row highlighted. */

.qstar-premise {
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  line-height: 1.7;
  color: var(--ink-secondary);
  margin: 8px 4px 12px;
  max-width: 88ch;
}
.qstar-q-star { color: var(--hue-anymal); }

.qstar-demo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: 18px;
  margin: 0;
  align-items: stretch;
}

.qstar-stage {
  position: relative;
  height: 300px !important;
  min-height: 300px;
  max-width: none;
}
.qstar-stage .sprite-host img { transition: transform 240ms ease-out; }

/* Attack animation (PIKACHU lunges right, CHARM shakes). */
@keyframes qstar-attack-pika {
  0%   { transform: translate(0, 0); }
  35%  { transform: translate(70px, -22px); }
  60%  { transform: translate(70px, -22px); }
  100% { transform: translate(0, 0); }
}
@keyframes qstar-shake-opp {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}
.qstar-stage.qstar-attack .sprite-host.player img  { animation: qstar-attack-pika 1.1s ease-out; }
.qstar-stage.qstar-attack .sprite-host.opponent img { animation: qstar-shake-opp 0.5s ease-in-out 0.4s; }

/* Counter (CHARM lunges left, PIKA shakes). */
@keyframes qstar-counter-charm {
  0%   { transform: translate(0, 0); }
  35%  { transform: translate(-70px, 22px); }
  60%  { transform: translate(-70px, 22px); }
  100% { transform: translate(0, 0); }
}
@keyframes qstar-shake-pika {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}
.qstar-stage.qstar-counter .sprite-host.opponent img { animation: qstar-counter-charm 1.1s ease-out; }
.qstar-stage.qstar-counter .sprite-host.player img   { animation: qstar-shake-pika 0.5s ease-in-out 0.4s; }

/* Damage flash. */
@keyframes qstar-flash-rise {
  0%   { opacity: 0; transform: translate(-50%, 12px); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -44px); }
}
.qstar-flash {
  position: absolute;
  top: 30%;
  transform: translate(-50%, 12px);
  font-family: 'Press Start 2P', monospace;
  font-size: 13px;
  pointer-events: none;
  animation: qstar-flash-rise 1.05s ease-out forwards;
  text-shadow: 2px 2px 0 #FFF, -2px -2px 0 #FFF, 2px -2px 0 #FFF, -2px 2px 0 #FFF;
  z-index: 6;
}
.qstar-flash.opp  { right: 18%; }
.qstar-flash.pika { left:  30%; top: 60%; }

/* WIN / LOSS banner overlay on the stage. */
.qstar-banner {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) scale(0.9);
  font-family: 'Press Start 2P', monospace;
  font-size: 22px;
  letter-spacing: 0.08em;
  padding: 12px 20px;
  border: 4px solid var(--rule);
  background: var(--bg-strong);
  pointer-events: none;
  opacity: 0;
  transition: opacity 220ms, transform 220ms;
  z-index: 10;
}
.qstar-banner.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
.qstar-banner.win  { color: var(--cb-blue);      border-color: var(--cb-blue); }
.qstar-banner.loss { color: var(--cb-vermillion); border-color: var(--cb-vermillion); }

/* Q-panel — state icon on top, two-column (action a | Q*(s, a)) table below.
   Mirrors the q-cell layout students will see in scenes 7 and 9. */
.qstar-q-panel {
  background: var(--bg-strong);
  border: 4px solid var(--rule);
  padding: 12px 14px;
  box-shadow:
    inset 0 0 0 2px var(--bg-strong),
    inset 0 0 0 4px var(--inner-highlight),
    inset 0 0 0 6px var(--bg-strong);
  font-family: 'Press Start 2P', monospace;
  color: var(--ink-on-box);
}

/* State icon — two stacked sprite + HP-bar slices, "state s" caption. */
.qstar-state-icon {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin-bottom: 12px;
  padding: 8px 10px;
  background: var(--bg);
  border: 2px solid var(--ink);
}
.qstar-state-label {
  font-size: 10px;
  letter-spacing: 0.05em;
  color: var(--ink-secondary);
  text-transform: lowercase;
}
.qstar-state-thumb {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}
.qstar-state-side {
  display: grid;
  grid-template-columns: 28px 1fr 56px;
  gap: 8px;
  align-items: center;
}
.qstar-state-sprite {
  width: 28px;
  height: 28px;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}
.qstar-state-hp {
  height: 8px;
  background: rgba(0,0,0,0.18);
  border: 2px solid var(--ink);
  box-sizing: border-box;
  position: relative;
}
.qstar-state-hp-fill {
  height: 100%;
  background: #48C848;
}
.qstar-state-hp-fill.b1 { background: #88D848; }
.qstar-state-hp-fill.b2 { background: #E8C828; }
.qstar-state-hp-fill.b3 { background: #E89028; }
.qstar-state-hp-fill.b4 { background: #E84828; }
.qstar-state-bucket {
  font-size: 7px;
  letter-spacing: 0.05em;
  text-align: right;
}

/* Two-column Q-table (action a | Q*(s, a)). */
.qstar-table {
  width: 100%;
  border-collapse: collapse;
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  color: var(--ink-on-box);
}
.qstar-table th {
  font-weight: normal;
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
  padding: 6px 8px;
  border-bottom: 2px solid var(--ink);
  text-align: left;
}
.qstar-table th.qstar-table-q {
  text-align: right;
}
.qstar-table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--rule);
}
.qstar-table tr:last-child td { border-bottom: none; }
.qstar-table-action {
  font-size: 9px;
}
.qstar-table-q {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 10px;
}
.qstar-table-row.argmax td {
  background: rgba(248, 208, 40, 0.32);
  box-shadow: inset 0 0 0 2px var(--accent, #F8D028);
}
.qstar-cell-mark {
  color: var(--pikachu-cheek, #C62828);
}

.qstar-status {
  display: flex;
  gap: 18px;
  justify-content: center;
  margin: 10px 0 0;
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
}
.qstar-status b { color: var(--pikachu-cheek); }

/* ---- Why-not-DP scene ---- */

.why-stat-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
.why-stat-card {
  background: var(--bg-strong);
  border: 4px solid var(--rule);
  padding: 16px 14px;
  text-align: center;
  font-family: 'Press Start 2P', monospace;
  color: var(--ink-on-box);
}
.why-stat-title {
  font-size: 8px;
  letter-spacing: 0.06em;
  color: var(--ink-secondary);
  margin-bottom: 10px;
}
.why-stat-value {
  font-size: 18px;
  color: var(--pikachu-cheek, #C62828);
  letter-spacing: 0.04em;
}
.why-stat-value sup {
  /* Force the exponent into the same pixel font and lift it cleanly above
     the baseline. The default browser <sup> styling drops in a fallback
     font that doesn't match — and Unicode superscripts (¹⁵) only have
     ¹ in our pixel font, so the rest fall back and misalign. */
  font: inherit;
  font-size: 0.62em;
  vertical-align: super;
  line-height: 0;
  margin-left: 0.06em;
  letter-spacing: 0.02em;
}
.why-stat-detail {
  font-size: 7px;
  margin-top: 6px;
  color: var(--ink-secondary);
}

/* ============================================================
   Variance illustration in the Objective scene
   ----------------------------------------------------------------
   "Q* is the EXPECTED G — variance lives in one trajectory."  20
   sampled G_1 values rendered as horizontal bars; mean drawn as a
   dashed vertical line.  Sits below the Q* formula card.
   ============================================================ */
.g-variance {
  background: var(--bg-strong);
  border: 4px solid var(--rule);
  box-shadow:
    inset 0 0 0 2px var(--bg-strong),
    inset 0 0 0 4px var(--inner-highlight),
    inset 0 0 0 6px var(--bg-strong);
  margin-top: 14px;
  padding: 14px 18px;
  color: var(--ink-on-box);
}
.g-variance-title {
  font-family: 'Press Start 2P', monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--pikachu-cheek);
  text-align: center;
  margin-bottom: 10px;
  cursor: pointer;
  user-select: none;
}
.g-variance-caret {
  display: inline-block;
  margin-right: 6px;
  color: var(--pikachu-cheek);
}
.g-variance-hint {
  font-size: 7px;
  color: var(--ink-secondary);
  margin-left: 8px;
  letter-spacing: 0.04em;
}
.g-variance.collapsed { padding: 10px 18px; }
.g-variance.collapsed .g-variance-title { margin-bottom: 0; }
.g-variance.collapsed .g-variance-body { display: none; }
.g-variance:not(.collapsed) .g-variance-hint { display: none; }
.g-variance-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: 16px;
  align-items: start;
}
.g-variance-explainer {
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  line-height: 1.8;
  color: var(--ink-on-box);
}
.g-variance-explainer em { color: var(--cb-blue); font-style: normal; }
.g-variance-explainer b  { color: var(--pikachu-cheek); }
.g-variance-explainer .g-r { color: var(--hue-ghost); }

.g-variance-right {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.g-variance-stats {
  font-family: 'Press Start 2P', monospace;
  font-size: 8.5px;
  color: var(--ink-on-box);
  text-align: center;
}
.g-variance-stats b { color: var(--pikachu-cheek); }
.g-variance-chart {
  position: relative;
  background: var(--bg);
  border: 2px solid var(--rule);
  min-height: 200px;
  padding: 4px 0;
  overflow: hidden;
}
.g-variance-empty {
  font-family: 'Press Start 2P', monospace;
  font-size: 8px;
  color: var(--ink-secondary);
  text-align: center;
  padding: 30px 10px;
}
.g-variance-zero {
  position: absolute;
  top: 0; bottom: 0;
  left: 50%;
  width: 1px;
  background: var(--ink);
  opacity: 0.25;
  z-index: 1;
}
.g-variance-mean {
  position: absolute;
  top: 0; bottom: 0;
  width: 2px;
  background: var(--pikachu-cheek);
  z-index: 3;
  border-left: 2px dashed var(--pikachu-cheek);
  background: transparent;
}
.g-variance-mean span {
  position: absolute;
  top: -2px;
  left: 4px;
  font-family: 'Press Start 2P', monospace;
  font-size: 7.5px;
  color: var(--pikachu-cheek);
  background: var(--bg);
  padding: 1px 4px;
  white-space: nowrap;
}
.g-variance-bar {
  position: relative;
  height: 8px;
  margin: 2px 0;
  display: flex;
  align-items: center;
  animation: g-variance-bar-grow 280ms ease-out;
}
.g-variance-bar.pos { background: var(--cb-blue); }
.g-variance-bar.neg { background: var(--cb-vermillion); }
.g-variance-bar-label {
  font-family: 'Press Start 2P', monospace;
  font-size: 6.5px;
  color: var(--ink-on-box);
  padding: 0 4px;
  position: absolute;
  white-space: nowrap;
}
.g-variance-bar.pos .g-variance-bar-label { right: -28px; }
.g-variance-bar.neg .g-variance-bar-label { left:  -28px; }
@keyframes g-variance-bar-grow {
  0%   { transform: scaleX(0); transform-origin: 0 50%; }
  100% { transform: scaleX(1); transform-origin: 0 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .g-variance-bar { animation: none; }
}

#g-variance-sample {
  align-self: center;
  margin-top: 6px;
}

.g-variance-policy-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'Press Start 2P', monospace;
  font-size: 8px;
  color: var(--ink-secondary);
  letter-spacing: 0.04em;
  margin-bottom: 4px;
}
.g-variance-policy {
  font-family: 'Press Start 2P', monospace;
  font-size: 8px;
  padding: 4px 8px;
  border: 2px solid var(--rule);
  background: var(--bg);
  color: var(--ink-on-box);
  cursor: pointer;
  letter-spacing: 0.04em;
  transition: background 120ms, color 120ms;
}
.g-variance-policy:hover { background: var(--pikachu-yellow); }
.g-variance-policy.active {
  background: var(--pikachu-cheek);
  color: #fff;
  box-shadow: inset 0 0 0 1px var(--inner-highlight);
}

/* ---------------------------------------------------------------------------
   Mobile (≤ 720px). Every two-column layout in the concept scenes
   (Q* demo, G-variance side-by-side, concept-grid-2) becomes a single
   column. The policy-row inside the G-variance card already uses
   `flex-wrap: wrap`, but we allow it to overflow horizontally if the
   four policy buttons can't fit on one row.
   --------------------------------------------------------------------------- */
@media (max-width: 720px) {
  .concept-grid-2,
  .qstar-demo,
  .g-variance-body {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }
  .qstar-demo .qstar-side,
  .g-variance-right { max-width: none; }
  .g-variance-policy-row { flex-wrap: wrap; }
}

/* =====================================================================
   Trajectory-as-TREE additions (window.TrajTree host wrappers).
   The tree + ledger themselves are styled in css/trajTree.css; these
   rules style the scene-level scaffolding around them and the compact
   node icon the scenes render via renderNode. Retro-pixel, theme tokens
   only, no inline categorical colors.
   ===================================================================== */

/* Foot line on the tau formula card: the tree reframe. */
.traj-tree-foot { color: var(--pikachu-cheek); display: inline-block; margin-top: 4px; }

/* Caption naming the fixed root + action. */
.traj-tree-caption {
  font-family: 'Press Start 2P', monospace;
  font-size: 8.5px;
  line-height: 1.7;
  color: var(--ink-on-box);
  background: var(--bg-strong);
  border: 2px solid var(--rule);
  border-left: 6px solid var(--hue-anymal);
  padding: 8px 12px;
  margin: 2px 0 4px;
}
.traj-tree-caption b { color: var(--pikachu-cheek); }

/* The TrajTree mount host (tree panel + ledger stack inside). */
.traj-tree-host, .obj-tree-host { width: 100%; }

/* ---- compact node icon rendered into .tt-node-icon by renderNode ---- */
/* Descendant sprites at desktop: a touch smaller than the 28px root so the
   tree reads as shrinking with depth. The mobile rule in trajTree.css
   shrinks .tt-mini-sprite further to 22px. */
.tt-node-icon .tt-mini-sprite { width: 24px; height: 24px; }
.tt-node-icon .tt-root-sprite { width: 28px; height: 28px; }
.tt-state-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  align-items: end;
}
.tt-state-body .traj-box-bucket { font-size: 6px; text-align: center; }
.tt-node-tag {
  font-family: 'Press Start 2P', monospace;
  font-size: 7px;
  color: var(--ink-secondary);
  margin-bottom: 3px;
}
.tt-node-tag sub { font-size: 5px; vertical-align: baseline; }

/* Terminal-leaf body: a glyph + WIN/LOSS word (color-blind safe). */
.tt-leaf-final {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 4px;
  font-family: 'Press Start 2P', monospace;
}
.tt-leaf-glyph { font-size: 16px; line-height: 1; }
.tt-leaf-word { font-size: 8px; letter-spacing: 0.04em; }
.tt-leaf-final.win .tt-leaf-glyph, .tt-leaf-final.win .tt-leaf-word { color: var(--cb-blue); }
.tt-leaf-final.loss .tt-leaf-glyph, .tt-leaf-final.loss .tt-leaf-word { color: var(--cb-vermillion); }

/* ---- derived tape strip (the lit path as the old S/A/R tape) ---- */
.traj-derived {
  margin-top: 4px;
  background: var(--bg-strong);
  border: 2px dashed var(--rule);
  padding: 8px 10px 10px;
}
.traj-derived-label {
  font-family: 'Press Start 2P', monospace;
  font-size: 7.5px;
  color: var(--ink-secondary);
  letter-spacing: 0.05em;
  margin-bottom: 6px;
}
.traj-derived-tape { min-height: 64px; align-items: center; }
.traj-derived-empty {
  font-family: 'Press Start 2P', monospace;
  font-size: 8px;
  color: var(--ink-secondary);
  opacity: 0.8;
  padding: 14px 4px;
}
.traj-derived-g {
  flex: 0 0 auto;
  align-self: center;
  margin-left: 10px;
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  color: var(--ink-on-box);
  border: 2px solid var(--rule);
  border-left: 5px solid var(--hue-ghost);
  background: var(--bg);
  padding: 6px 9px;
  white-space: nowrap;
}
.traj-derived-g b { color: var(--hue-ghost); }

/* ---- objective scene: E[G_t] ledger label + the "= Q*" callout ---- */
.obj-eg-label {
  font-family: 'Press Start 2P', monospace;
  font-size: 8.5px;
  line-height: 1.7;
  color: var(--ink-on-box);
  background: var(--bg-strong);
  border: 2px solid var(--rule);
  border-left: 6px solid var(--hue-ghost);
  padding: 8px 12px;
  margin: 4px 0;
}
.obj-eg-label b { color: var(--hue-ghost); }
.obj-eg-tie {
  font-family: 'Press Start 2P', monospace;
  font-size: 9px;
  line-height: 1.8;
  color: var(--ink-on-box);
  background: var(--bg-strong);
  border: 3px solid var(--cb-blue);
  box-shadow: inset 0 0 0 2px var(--bg-strong), inset 0 0 0 4px var(--inner-highlight);
  padding: 10px 14px;
  margin: 6px 0 2px;
}
.obj-eg-tie b { color: var(--cb-blue); }

/* ---- variance widget: the target line (tree-computed E[G]) ---- */
/* Distinct from the dashed cheek-colored mean line: a dotted ghost-purple
   line, so the two are never confused. The mean walks toward it. */
.g-variance-target {
  position: absolute;
  top: 0; bottom: 0;
  width: 0;
  border-left: 2px dotted var(--hue-ghost);
  z-index: 2;
}
.g-variance-target span {
  position: absolute;
  bottom: -2px;
  left: 4px;
  font-family: 'Press Start 2P', monospace;
  font-size: 7.5px;
  color: var(--hue-ghost);
  background: var(--bg);
  padding: 1px 4px;
  white-space: nowrap;
}
