:root {
  --cream-50: #FBF4E8;
  --cream-100: #F3E6CF;
  --cream-200: #E6D3B3;
  --orange-500: #E36A24;
  --orange-700: #B04A17;
  --rust-700: #8E3A1E;
  --brass-400: #D49A33;
  --stone-500: #8C7E73;
  --charcoal-700: #4A403B;
  --charcoal-800: #322B28;
  --charcoal-900: #241F1D;
  --ink-muted: #6B5B50;
  --cyan-300: #5CE1E6;
  --cyan-700: #0E7C86;

  --color-bg-page: var(--cream-50);
  --color-bg-panel: var(--cream-100);
  --color-text: var(--charcoal-900);
  --color-text-secondary: var(--ink-muted);
  --color-border: var(--charcoal-700);
  --color-accent-solid: var(--orange-500);
  --color-accent-on: var(--charcoal-900);
  --color-accent-pressed: var(--orange-700);
  --color-screen-bg: var(--charcoal-900);
  --color-screen-text: var(--cream-100);
  --color-diagnostic: var(--cyan-300);
  --color-focus: var(--charcoal-900);

  --font-ui: ui-rounded, "SF Pro Rounded", system-ui, sans-serif;
  --font-key: ui-monospace, "SF Mono", Menlo, monospace;
  --text-caption: 0.8125rem;
  --text-ui: 1rem;
  --text-title: 1.375rem;

  --radius-key: 10px;
  --radius-panel: 18px;
  --edge: 0 4px 0 var(--charcoal-700);
  --edge-pressed: 0 1px 0 var(--charcoal-700);
  --gutter: max(16px, env(safe-area-inset-left));
  --gutter-end: max(16px, env(safe-area-inset-right));

  color-scheme: light;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

body {
  margin: 0;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--color-bg-page);
  color: var(--color-text);
  font: 500 var(--text-ui)/1.4 var(--font-ui);
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

button, a { font: inherit; color: inherit; }
button { cursor: pointer; touch-action: manipulation; user-select: none; -webkit-user-select: none; }
button:disabled { cursor: default; opacity: 0.45; }
p, h1, h2 { margin: 0; }
svg { fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }

:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 2px; }
.done :focus-visible { outline-color: var(--color-diagnostic); }

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

.skip {
  position: absolute; inset-inline-start: var(--gutter); top: 8px; z-index: 2;
  padding: 10px 14px; border-radius: var(--radius-key);
  background: var(--color-bg-panel); border: 2px solid var(--color-border);
  translate: 0 -200%;
}
.skip:focus-visible { translate: 0 0; }

/* Header */

.bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px;
  padding: max(10px, env(safe-area-inset-top)) var(--gutter-end) 10px var(--gutter);
}
.brand { line-height: 0; }
.brand img { display: block; height: 44px; width: auto; }

.levels { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.groups { display: flex; gap: 4px; }
.group {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 10px;
  border: 2px solid transparent; border-radius: 12px; background: none;
  color: var(--color-text-secondary); font-weight: 700;
}
.group[aria-expanded="true"] { color: var(--color-text); border-color: var(--cream-200); background: var(--color-bg-panel); }
.group-count {
  padding: 1px 6px; border-radius: 6px; background: var(--cream-200);
  font-size: var(--text-caption); font-variant-numeric: tabular-nums;
}
.group[aria-expanded="true"] .group-count { background: var(--charcoal-800); color: var(--cream-100); }
.group-lock { display: grid; }
.group-lock svg { width: 15px; height: 15px; }

.levels ol { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.level {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 12px 0 8px;
  border: 2px solid transparent; border-radius: 12px;
  font-weight: 600; text-decoration: none; white-space: nowrap;
}
.level svg { width: 18px; height: 18px; }
.level-state { display: grid; }
.level-num {
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 7px;
  background: var(--charcoal-800); color: var(--cream-100);
  font-weight: 800; font-size: var(--text-caption); font-variant-numeric: tabular-nums;
}
.level[aria-current="page"] {
  background: var(--color-bg-panel); border-color: var(--color-border); box-shadow: var(--edge);
}
.level.is-mastered .level-num { background: var(--orange-500); color: var(--charcoal-900); }
.level.is-locked { color: var(--color-text-secondary); }
.level.is-locked .level-num { background: var(--cream-200); color: var(--color-text-secondary); }

.quiet {
  margin-inline-start: auto; min-height: 44px; padding: 0 12px;
  border: 2px solid transparent; border-radius: 12px; background: none;
  color: var(--color-text-secondary); font-weight: 600;
}

.test-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  margin: 0 var(--gutter-end) 8px var(--gutter); padding: 8px 12px;
  border: 2px dashed var(--color-border); border-radius: var(--radius-key);
  background: var(--color-bg-panel); font-size: 0.9375rem;
}
.test-bar label { font-weight: 700; }
.test-bar select {
  flex: 1 1 14rem; min-width: 0; max-width: 24rem; min-height: 44px; padding: 0 8px;
  border: 2px solid var(--color-border); border-radius: 10px; background: var(--color-bg-page);
  font: inherit; color: inherit;
}
.test-bar button {
  min-height: 44px; padding: 0 16px; border: 2px solid var(--color-border); border-radius: 10px;
  background: var(--color-accent-solid); color: var(--color-accent-on); font-weight: 700;
}
.test-bar p { margin: 0; color: var(--color-text-secondary); }
.test-bar a { display: inline-flex; align-items: center; min-height: 44px; margin-inline-start: auto; font-weight: 600; }

.notice {
  margin: 0 var(--gutter-end) 8px var(--gutter);
  padding: 8px 12px; border-radius: var(--radius-key);
  background: var(--color-bg-panel); font-size: 0.9375rem;
}

/* Play area */

.play {
  flex: 1; display: flex; flex-direction: column; gap: 16px;
  padding: 4px var(--gutter-end) max(16px, env(safe-area-inset-bottom)) var(--gutter);
}

.stage { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.stage-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.stage h2 { font-size: var(--text-title); font-weight: 800; line-height: 1.15; text-wrap: balance; }
.stage h2:focus { outline: none; }
.stage h2:focus-visible { outline: 3px solid var(--color-focus); }
.help { flex: none; padding-inline: 10px; }
.docked {
  flex: none; padding: 4px 10px; border-radius: 8px;
  background: var(--color-screen-bg); color: var(--color-diagnostic);
  font-weight: 700; font-variant-numeric: tabular-nums;
}

/* Score: strokes readout, three-ceiling rail, technique chip. */

.score {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px;
  max-width: 32rem; margin-top: 6px;
}
.strokes {
  display: flex; flex-direction: column; align-items: center; min-width: 4.25rem; padding: 4px 10px;
  border-radius: 8px; background: var(--color-screen-bg); line-height: 1;
}
.strokes-num { color: var(--color-diagnostic); font-size: 1.5rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.strokes.is-over .strokes-num { color: var(--orange-500); }
.strokes-label { margin-top: 2px; color: var(--cream-100); font-size: 0.75rem; font-weight: 600; }

.track { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.rail { display: grid; grid-template-columns: repeat(3, 1fr); align-items: center; gap: 3px; height: 10px; }
.rail span { height: 100%; overflow: hidden; border-radius: 3px; background: var(--cream-200); }
.rail i { display: block; height: 100%; inline-size: 0; margin-inline-start: auto; background: var(--charcoal-700); }
.rail .is-live i { background: var(--orange-500); }
.rail .is-lost { height: 4px; background: var(--stone-500); }
.notches { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; margin: 0; padding: 0; list-style: none; }
.notch {
  position: relative; display: flex; align-items: center; justify-content: flex-end; gap: 3px;
  font-weight: 700; font-size: 0.875rem; font-variant-numeric: tabular-nums;
}
.badge {
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid var(--charcoal-700); background: var(--cream-50); color: var(--charcoal-900);
}
.badge svg { width: 13px; height: 13px; stroke-width: 2.5; }
.tier-2 .badge { width: 28px; height: 28px; border-color: var(--orange-500); }
.tier-2 .badge svg { width: 16px; height: 16px; }
.notch.is-earned .badge { background: var(--color-screen-bg); border-color: var(--color-screen-bg); color: var(--color-diagnostic); }
.notch.is-live .badge { outline: 2px solid var(--orange-500); outline-offset: 2px; }
.notch.is-live .ceiling { color: var(--orange-700); }
.notch.is-passed .ceiling { color: var(--ink-muted); text-decoration: line-through; text-decoration-thickness: 2px; }
.notch.is-passed .badge { opacity: 0.45; }
.notch.needs-technique::after {
  content: ""; position: absolute; inset-inline-end: -3px; top: -2px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--orange-700);
}

.chip {
  display: flex; align-items: center; gap: 4px; min-height: 32px; padding: 0 8px;
  border: 2px solid var(--color-border); border-radius: 8px; background: var(--color-bg-panel);
  font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.chip kbd { font: 700 0.9375rem/1 var(--font-key); }
.chip svg { width: 16px; height: 16px; stroke-width: 3; }
.chip.is-broken { border-color: var(--orange-700); background: var(--cream-50); color: var(--orange-700); }

@media (prefers-reduced-motion: no-preference) {
  .rail i { transition: inline-size 160ms ease-out; }
}
@media (forced-colors: active) {
  .rail span, .rail i { forced-color-adjust: none; }
  .rail span { outline: 1px solid CanvasText; background: Canvas; }
  .rail i { background: CanvasText; }
  .rail .is-live i { background: Highlight; }
  .rail .is-lost { outline-style: dashed; }
  .notch.is-live .badge { outline-color: Highlight; }
}

.world {
  position: relative; width: 100%; margin-top: 8px;
  aspect-ratio: var(--scene-aspect, 1.4); max-height: 60svh;
  background: radial-gradient(ellipse 70% 60% at 50% 45%, #FFF9EE, transparent 75%);
}
.world canvas { position: absolute; inset: 0; display: block; }

/* Text levels: the real robot (or linked pair) beside a checkpoint board, over the terminals. */

.stage.is-text .world {
  flex: none; display: flex; aspect-ratio: auto; height: auto; min-height: 108px; max-height: none; background: none;
}
.board {
  position: relative; flex: 1; min-width: 0; align-self: center;
  display: flex; flex-direction: column; gap: 6px;
  margin: 8px 8px 10px var(--actors, 6rem); padding: 8px 12px 9px;
  border: 2px solid var(--charcoal-700); border-radius: 12px; box-shadow: var(--edge);
  background: var(--color-screen-bg); color: var(--color-screen-text);
}
.pips { display: flex; align-items: center; gap: 10px; margin: 0; padding: 0; list-style: none; }
.pip {
  position: relative; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 5px;
  outline: 2px dashed var(--stone-500); outline-offset: -2px;
  color: var(--cream-200); font: 800 0.75rem/1 var(--font-ui); font-variant-numeric: tabular-nums;
}
.pip + .pip::before {
  content: ""; position: absolute; inset-inline-end: calc(100% + 3px); width: 4px; height: 2px; background: var(--stone-500);
}
.pip svg { width: 14px; height: 14px; stroke-width: 3.5; }
.pip[data-state="live"] {
  width: 28px; height: 28px; outline: none; background: var(--orange-500); color: var(--charcoal-900); font-size: 0.9375rem;
}
.pip[data-state="qualified"], .pip[data-state="reached"] { outline: none; background: var(--cyan-700); color: var(--cream-50); }
.goal { display: flex; flex-direction: column; gap: 3px; }
.goal-row { display: flex; align-items: flex-start; gap: 8px; margin: 0; }
.goal-text { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; min-width: 0; }
.goal-what { font-weight: 700; line-height: 1.3; }
.goal-what q { quotes: none; padding: 0 3px; border-radius: 4px; background: var(--charcoal-700); font: 600 0.95em/1.2 var(--font-key); white-space: pre; }
.goal-where { color: var(--cream-200); font: 600 var(--text-caption)/1.3 var(--font-key); font-variant-numeric: tabular-nums; }
.tag { flex: none; display: grid; place-items: center; min-width: 22px; height: 22px; border-radius: 5px; font: 800 0.8125rem/1 var(--font-ui); }
.tag svg { width: 14px; height: 14px; stroke-width: 3.5; }
.tag.is-target { outline: 2px solid var(--orange-500); outline-offset: -2px; color: var(--orange-500); }
.tag.is-you { min-width: 0; width: 11px; margin-inline: 5px 6px; border-radius: 2px; background: var(--cyan-300); }
.tag.is-done { background: var(--cyan-700); color: var(--cream-50); }
.tag.plate { min-width: 22px; height: 22px; padding: 0 4px; }
.goal-row:has(.is-you) .goal-what { font-weight: 600; color: var(--cream-200); }

.terminals { display: flex; flex-direction: column; gap: 10px; min-height: 0; margin-top: 8px; }
.term {
  /* --row is one text row in px terms anywhere inside the pane, whatever the local font size. */
  --lh: 1.9em; --cell-h: 1.35em; --row: calc(1.9 * clamp(0.875rem, 3.6vw, 1.125rem));
  display: flex; flex-direction: column; min-height: 0;
  border: 2px solid var(--charcoal-700); border-radius: var(--radius-panel);
  background: var(--color-screen-bg); overflow: hidden; box-shadow: var(--edge);
}
.term-head {
  display: flex; align-items: center; gap: 8px; padding: 4px 12px 4px 6px;
  background: var(--cream-100); color: var(--charcoal-900);
  border-bottom: 2px solid var(--charcoal-700); font-weight: 700;
}
.term-name { font: 600 var(--text-caption)/1 var(--font-key); }
.plate {
  display: grid; place-items: center; min-width: 24px; height: 24px; padding: 0 6px; border-radius: 7px;
  background: var(--cyan-300); color: var(--charcoal-900); font-weight: 800; font-variant-numeric: tabular-nums;
}
.plate.is-2, .robot-2 .plate { background: var(--brass-400); }
.term-grid { min-height: 0; overflow-y: auto; }
.term-body { position: relative; overflow-x: auto; overscroll-behavior-x: contain; }
.term-screen {
  display: flex; width: max-content; min-width: 100%; padding: 6px 16px 6px 0;
  font: 500 clamp(0.875rem, 3.6vw, 1.125rem)/1.9 var(--font-key);
  color: var(--color-screen-text);
}
.gutter {
  position: sticky; left: 0; z-index: 1; margin: 0; padding: 0 10px 0 12px; list-style: none;
  background: var(--color-screen-bg); color: var(--cream-200); opacity: 0.6;
  font-size: var(--text-caption); line-height: var(--row);
  text-align: end; font-variant-numeric: tabular-nums; user-select: none; -webkit-user-select: none;
}
.term-text { position: relative; }
.term pre { margin: 0; font: inherit; line-height: var(--lh); white-space: pre; tab-size: 1; }
.term pre::selection, .term pre ::selection { background: var(--cyan-700); color: var(--cream-50); }
.lead {
  background: radial-gradient(circle, var(--stone-500) 0.08em, transparent 0.1em) 0 50% / 1ch 1em repeat-x;
}
.layer { position: absolute; inset: 0; pointer-events: none; user-select: none; -webkit-user-select: none; }
.cell {
  position: absolute; width: 1ch; height: var(--cell-h);
  left: calc(var(--c) * 1ch); top: calc(var(--r) * var(--lh) + (var(--lh) - var(--cell-h)) / 2);
}
.tab {
  position: absolute; left: 50%; bottom: calc(100% + 1px); translate: -50% 0;
  display: grid; place-items: center; min-width: 0.95em; height: 0.95em; padding: 0 2px; border-radius: 3px;
  font: 800 0.58em/1 var(--font-ui);
}
.tab svg { width: 0.85em; height: 0.85em; stroke-width: 3.5; }
.mark { border-radius: 3px; }
.mark .tab { background: var(--charcoal-700); color: var(--cream-200); }
.mark[data-state="upcoming"] { outline: 2px dashed var(--stone-500); outline-offset: 1px; }
.mark[data-state="live"] {
  outline: 2px solid var(--orange-500); outline-offset: 1px; box-shadow: inset 0 0 0 1px var(--cream-100);
}
.mark[data-state="live"] .tab { background: var(--orange-500); color: var(--charcoal-900); }
.mark[data-state="qualified"] { border-bottom: 2px solid var(--cyan-700); }
.mark[data-state="reached"] { border-bottom: 2px dotted var(--cyan-700); }
.mark[data-state="qualified"] .tab, .mark[data-state="reached"] .tab { background: var(--cyan-700); color: var(--cream-50); }
.spark {
  display: grid; place-items: center; border-radius: 3px;
  background: rgb(142 58 30 / 0.7); color: var(--cream-50); line-height: 1;
}
.spark .tab { background: none; color: var(--brass-400); }
.spark .tab svg { width: 1em; height: 1em; stroke-width: 2.5; fill: currentColor; }
.cursor {
  display: grid; place-items: center; border-radius: 2px; z-index: 1;
  background: var(--cyan-300); color: var(--charcoal-900); line-height: 1;
}
.cursor .glyph { white-space: pre; }
.robot-2 .cursor { background: var(--brass-400); }
.robot-2 .cursor::before {
  content: ""; position: absolute; left: 0; top: 0; width: 0.32em; height: 0.32em;
  border-right: 2px solid var(--charcoal-900); border-bottom: 2px solid var(--charcoal-900);
}
.refused {
  border-radius: 4px; outline: 3px solid var(--orange-500); outline-offset: 2px; z-index: 2;
}
.ruler {
  display: flex; gap: 10px; justify-content: flex-end; padding: 2px 12px 4px;
  border-top: 1px solid var(--charcoal-700);
  color: var(--cream-200); font: 600 var(--text-caption)/1.5 var(--font-key); font-variant-numeric: tabular-nums;
}
.ruler .eol { color: var(--charcoal-900); background: var(--cyan-300); padding: 0 5px; border-radius: 4px; }
.ruler .pend { color: var(--brass-400); }
.ruler .pend:empty { display: none; }

@media (prefers-reduced-motion: no-preference) {
  .cursor.slide { transition: left 120ms ease-out; }
  .cursor.bump[data-bump="left"] { animation: bump-x 140ms ease-out; --bump: -0.14ch; }
  .cursor.bump[data-bump="right"] { animation: bump-x 140ms ease-out; --bump: 0.14ch; }
  .cursor.bump[data-bump="up"] { animation: bump-y 140ms ease-out; --bump: -0.14em; }
  .cursor.bump[data-bump="down"] { animation: bump-y 140ms ease-out; --bump: 0.14em; }
  .refused { animation: refuse 160ms ease-out 2; }
  .pip.is-new { animation: pip-in 700ms ease-out; }
}
@keyframes pip-in { from { box-shadow: 0 0 0 6px rgb(92 225 230 / 0.6); } to { box-shadow: 0 0 0 14px rgb(92 225 230 / 0); } }
@keyframes bump-x { 50% { translate: var(--bump) 0; } }
@keyframes bump-y { 50% { translate: 0 var(--bump); } }
@keyframes refuse { from { outline-offset: 6px; opacity: 0.4; } }

/* Editing levels: the board becomes the work order, and the terminal shows the mode. */

.board.is-order { container-type: inline-size; gap: 0; padding-block: 6px; }
.order { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.order-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 2px 10px;
  padding: 4px 0;
}
.order-row + .order-row { border-top: 1px solid var(--charcoal-700); }
.order-mark {
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 5px;
  outline: 2px solid var(--stone-500); outline-offset: -2px;
  color: var(--cream-200); font: 800 0.75rem/1 var(--font-ui); font-variant-numeric: tabular-nums;
}
.order-mark svg { width: 14px; height: 14px; stroke-width: 3.5; }
.order-row[data-state="done"] .order-mark { outline: none; background: var(--cyan-700); color: var(--cream-50); }
.order-row[data-state="miss"] .order-mark { outline-color: var(--orange-500); color: var(--orange-500); }
.order-line { font: 600 0.9375rem/1.35 var(--font-key); white-space: pre; overflow: hidden; text-overflow: ellipsis; }
.order-line mark {
  padding: 0 1px; border-radius: 3px; background: var(--orange-500); color: var(--charcoal-900);
}
.order-row[data-state="done"] .order-line { color: var(--cream-200); }
.order-machine { display: flex; align-items: center; gap: 6px; justify-self: end; }
.machine {
  display: grid; place-items: center; width: 28px; height: 28px; border-radius: 7px;
  background: var(--charcoal-700); color: var(--cream-200);
}
.machine svg { width: 18px; height: 18px; stroke-width: 2; }
.order-say { color: var(--cream-200); font-size: var(--text-caption); font-weight: 700; white-space: nowrap; }
.order-row[data-state="done"] .machine { background: var(--cyan-300); color: var(--charcoal-900); }
.order-row[data-state="done"] .order-say { color: var(--cyan-300); }
.order-row[data-state="miss"] .order-say { color: var(--orange-500); }
.order-row[data-state="done"][data-machine="lamp"] .machine svg path { fill: var(--brass-400); }
/* Arm bays: solid cream marks the cursor's row, dashed brass the next row once it is committed. */
.order-row[aria-current] .order-mark { outline-color: var(--cream-50); }
.order-row[data-next] .order-mark { outline-style: dashed; outline-color: var(--brass-400); }
.order-machine .part-next { font: 800 var(--text-caption)/1.4 var(--font-ui); }
/* Narrow boards: the line takes the full width so it never clips; its mark sits beside the machine. */
@container (max-width: 22rem) {
  .order-row { grid-template-columns: auto minmax(0, 1fr); gap: 3px 8px; }
  .order-line { grid-column: 1 / -1; grid-row: 1; font-size: 0.875rem; }
  .order-mark { grid-row: 2; }
  .order-machine { grid-column: 2; grid-row: 2; justify-self: start; }
  .machine { width: 22px; height: 22px; border-radius: 5px; }
  .machine svg { width: 15px; height: 15px; }
}
/* Box sealer: its full-width setting lines never clip, so the machine and status sit under each line. */
.stage.is-sealer .order-row { grid-template-columns: auto minmax(0, 1fr); gap: 3px 10px; }
.stage.is-sealer .order-mark, .stage.is-sealer .order-line { grid-row: 1; }
.stage.is-sealer .order-line { grid-column: 2; }
.stage.is-sealer .order-machine { grid-column: 2; grid-row: 2; justify-self: start; }
/* Arm bays: every row drives the same arm, so the icon goes and short rows stay on one line. */
.stage.is-bays .order-machine .machine { display: none; }
@container (min-width: 19.5rem) and (max-width: 22rem) {
  .stage.is-bays .order-row { grid-template-columns: auto minmax(0, 1fr) auto; gap: 2px 10px; }
  .stage.is-bays .order-row > * { grid-row: 1; }
  .stage.is-bays .order-line { grid-column: 2; }
  .stage.is-bays .order-machine { grid-column: 3; justify-self: end; }
}

.term .mode {
  margin-inline-start: auto; padding: 1px 8px; border-radius: 6px;
  background: var(--cream-200); color: var(--charcoal-900);
  font: 800 var(--text-caption)/1.4 var(--font-ui); letter-spacing: 0.04em; text-transform: uppercase;
}
.term.is-insert { border-color: var(--orange-500); box-shadow: 0 4px 0 var(--orange-700); }
.term.is-insert .term-head { border-bottom-color: var(--orange-500); }
.term.is-insert .mode { background: var(--orange-500); }
.term .fix { text-decoration: underline wavy var(--orange-500); text-decoration-thickness: 2px; text-underline-offset: 0.25em; }
.gutter li[data-state="done"] { color: var(--cyan-300); opacity: 1; }
.cursor.is-bar { width: 3px; margin-left: -1px; border-radius: 1px; }
.ruler .status { margin-inline-end: auto; color: var(--orange-500); font-weight: 800; }
.ruler .status:empty { display: none; }

/* Commands and Esc share one grid; Esc always takes the last column so it never moves. */
.textkeys.edit-keys { flex: none; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.edit-keys .is-esc { grid-column: -2; }
/* With dot, nine keys: two rows of five (i a A x d / c u . Esc) until all nine fit one row. */
.textkeys.edit-keys:has(.keycap[data-key="."]:not([hidden])) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.keycap.is-esc kbd { font: 800 1.125rem/1 var(--font-ui); }
.keycap.is-armed { background: var(--brass-400); box-shadow: 0 4px 0 var(--charcoal-700), 0 5px 0 var(--orange-700); }
.controls { container-type: inline-size; }
/* Room for eight 44px keys: counts and commands each fit one row. */
@container (min-width: 24.75rem) {
  .play:has(.stage.is-edit) .counts { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  .textkeys.edit-keys { grid-template-columns: repeat(var(--edit-n, 8), minmax(0, 1fr)); }
  .edit-keys .keycap.is-esc kbd { font-size: 1rem; }
}
@container (min-width: 28.75rem) {
  .textkeys.edit-keys:has(.keycap[data-key="."]:not([hidden])) { grid-template-columns: repeat(9, minmax(0, 1fr)); }
  /* With r as well, ten keys: two rows of five (i a A x d / c r u . Esc) until all ten fit one row. */
  .textkeys.edit-keys:has(.keycap[data-key="r"]:not([hidden])) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
@container (min-width: 32rem) {
  .textkeys.edit-keys:has(.keycap[data-key="r"]:not([hidden])) { grid-template-columns: repeat(10, minmax(0, 1fr)); }
}
/* Smallest phones: tighter gaps keep six 44px line and word keys inside the bench. */
@container (max-width: 18.5rem) {
  .controls .anchors, .controls .textkeys { gap: 4px; }
}

/* The touch field is focusable but never seen; 16px keeps iOS from zooming. */
.type-in {
  position: fixed; left: 0; bottom: 0; width: 1px; height: 1px; padding: 0; border: 0;
  opacity: 0; font-size: 16px; pointer-events: none;
}
.esc-float {
  position: fixed; inset-inline-end: max(16px, env(safe-area-inset-right)); z-index: 3;
  min-width: 64px; min-height: 48px; padding: 0 16px;
  border: 2px solid var(--charcoal-900); border-radius: 12px; box-shadow: var(--edge);
  background: var(--cream-100); font: 800 1.125rem/1 var(--font-ui);
}
.esc-float:active { translate: 0 3px; box-shadow: var(--edge-pressed); }

@media (prefers-reduced-motion: no-preference) {
  .order-row.is-new .machine { animation: machine-in 700ms cubic-bezier(0.2, 0, 0, 1); }
  .order-row.is-new[data-machine="wrench"] .machine svg { animation: wrench-turn 500ms cubic-bezier(0.2, 0, 0, 1); }
  .order-row.is-new[data-machine="lift"] .machine svg { animation: lift-up 600ms cubic-bezier(0.2, 0, 0, 1); }
  .order-row[data-state="done"][data-machine="fan"] .machine svg { animation: spin 1.1s linear infinite; }
}
@keyframes machine-in { from { box-shadow: 0 0 0 6px rgb(92 225 230 / 0.6); } to { box-shadow: 0 0 0 14px rgb(92 225 230 / 0); } }
@keyframes wrench-turn { from { rotate: -50deg; } }
@keyframes lift-up { from { translate: 0 6px; } }
@keyframes spin { to { rotate: 1turn; } }

/* Linked plate: replaces robot selectors on linked levels. */

.linked {
  display: flex; align-items: center; justify-content: center; gap: 6px; min-height: 52px;
  border: 2px dashed var(--cream-200); border-radius: 12px; font-weight: 800;
}
.linked svg { width: 34px; height: 20px; color: var(--cyan-700); stroke-width: 3; }
.linked-label { margin-inline-start: 8px; color: var(--color-text-secondary); }

.bench {
  display: flex; flex-direction: column; gap: 14px;
  width: 100%; max-width: 40rem; margin-inline: auto;
}
.cue { min-height: 2.8em; font-size: 1.0625rem; font-weight: 600; text-wrap: pretty; }
.cue.is-blocked { color: var(--orange-700); }
.cue kbd {
  display: inline-block; min-width: 1.5em; padding: 0 0.3em; border-radius: 6px;
  border: 2px solid var(--color-border); background: var(--color-bg-panel);
  font: 700 0.95em/1.25 var(--font-key); text-align: center;
}
.controls { display: flex; flex-direction: column; gap: 14px; }

/* Completion */

.done {
  display: flex; flex-direction: column; gap: 14px; padding: 16px;
  border-radius: var(--radius-panel); background: var(--color-screen-bg); color: var(--color-screen-text);
}
.done[hidden] { display: none; }
.done-title { font-size: 1.25rem; font-weight: 800; text-wrap: balance; }
.done-result { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-weight: 600; }
.done-result:empty { display: none; }
.result-item { display: inline-flex; align-items: center; gap: 6px; }
.result-item > svg { width: 20px; height: 20px; color: var(--brass-400); }
.pips { display: inline-flex; gap: 3px; }
.pip svg { display: block; width: 20px; height: 20px; color: var(--brass-400); }
.pip:not(.is-on) svg { color: var(--stone-500); }
.pip.is-on svg path { fill: var(--brass-400); stroke: var(--brass-400); }
.done-actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* New upgrade: a lit workshop window onto the robot, set apart from grades by its brass frame. */

.reward {
  display: grid; grid-template-columns: 8.5rem minmax(0, 1fr); align-items: center; gap: 14px;
  border: 2px solid var(--brass-400); border-radius: 14px; overflow: hidden; background: var(--charcoal-800);
}
.reward-view { block-size: 11rem; }
.reward-view canvas, .garage-view canvas { display: block; }
.reward-text { display: flex; flex-direction: column; gap: 2px; padding-inline-end: 12px; }
.reward-kicker { color: var(--brass-400); font-size: var(--text-caption); font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; }
.reward-name { color: var(--cream-50); font-size: var(--text-title); font-weight: 800; line-height: 1.15; text-wrap: balance; }
.reward-where { color: var(--cream-200); font-size: 0.9375rem; }
@media (prefers-reduced-motion: no-preference) {
  .reward-text > * { animation: reward-in 400ms cubic-bezier(0.2, 0, 0, 1) both; }
  .reward-text > :nth-child(2) { animation-delay: 100ms; }
  .reward-text > :nth-child(3) { animation-delay: 200ms; }
}
@keyframes reward-in { from { opacity: 0; translate: 0 6px; } }
.done .tool { background: var(--cream-100); color: var(--charcoal-900); border-color: var(--cream-100); }

/* Buttons */

.primary, .tool {
  min-height: 44px; padding: 0 18px; border-radius: 12px; font-weight: 700;
}
.primary {
  background: var(--color-accent-solid); color: var(--color-accent-on);
  border: 2px solid var(--charcoal-900); box-shadow: 0 4px 0 var(--charcoal-900);
}
.primary:active { background: var(--color-accent-pressed); translate: 0 3px; box-shadow: 0 1px 0 var(--charcoal-900); }
.tool { background: transparent; border: 2px solid var(--color-border); }
.tool:active:not(:disabled) { background: var(--color-bg-panel); }
.tools { display: flex; gap: 10px; }
.tools .tool { flex: 1; }

/* Robot selectors */

.robots { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.robot {
  display: grid; grid-template-columns: auto auto; justify-content: center; align-items: center; gap: 2px 6px;
  min-height: 56px; padding: 4px 2px;
  background: var(--color-bg-panel); border: 2px solid var(--color-border);
  border-radius: 12px; box-shadow: var(--edge);
}
.robot-sym { font-size: 1.5rem; font-weight: 800; line-height: 1; }
.robot-name { grid-column: 1 / -1; grid-row: 2; font-size: 0.75rem; font-weight: 700; line-height: 1.1; }
.robot-lamp {
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 6px;
  border: 2px solid var(--color-border); color: var(--color-diagnostic);
}
.robot.is-docked .robot-lamp { background: var(--color-screen-bg); border-color: var(--color-screen-bg); }
.robot-lamp svg { grid-area: 1 / 1; width: 16px; height: 16px; stroke-width: 3; visibility: hidden; }
.robot.is-docked:not(.is-loose) .robot-lamp svg:first-child,
.robot.is-loose .robot-lamp svg:last-child { visibility: visible; }
.robot[aria-pressed="true"] {
  background: var(--color-accent-solid); border-color: var(--charcoal-900);
  translate: 0 2px; box-shadow: 0 2px 0 var(--charcoal-900);
}

/* Movement keycaps */

.keys { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
.keycap {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: 88px; background: var(--color-bg-panel);
  border: 2px solid var(--color-border); border-radius: var(--radius-key); box-shadow: var(--edge);
}
.keycap kbd { font: 700 1.75rem/1 var(--font-key); white-space: nowrap; }
.keycap .pending { color: var(--orange-700); }
.keycap.is-pending { box-shadow: 0 4px 0 var(--charcoal-700), 0 5px 0 var(--brass-400); }

.anchors { display: flex; gap: 10px; }
.textkeys { flex: 3; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
#line-keys { flex: var(--line-n, 3); grid-template-columns: repeat(var(--line-n, 3), minmax(0, 1fr)); }
#find-keys { flex: 2; grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* With Find, eight motion keys: Line above Word, and Find as a column on the right (f over ;),
   until all eight fit one row. The right column is exactly one key wide. */
@container (max-width: 35.99rem) {
  .anchors:not(.is-families):has(#find-keys:not([hidden])) { display: grid; grid-template-columns: minmax(0, 1fr) calc((100% - 24px) / 4); gap: 8px; }
  .anchors:not(.is-families):has(#find-keys:not([hidden])) #word-keys { grid-row: 2; }
  .anchors:not(.is-families):has(#find-keys:not([hidden])) #find-keys { grid-column: 2; grid-row: 1 / span 2; grid-template-columns: minmax(0, 1fr); gap: 8px; }
}

.keycap.is-text { min-height: 56px; min-width: 44px; }
.keycap.is-text kbd { font-size: 1.5rem; }
.counts[hidden] { display: none; }
.counts { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.countkey {
  min-height: 44px; padding: 0; background: var(--color-bg-panel);
  border: 2px solid var(--color-border); border-radius: 8px; box-shadow: 0 3px 0 var(--charcoal-700);
  font: 700 1.25rem/1 var(--font-key);
}
.countkey:active:not(:disabled), .countkey.is-pressed { translate: 0 2px; box-shadow: var(--edge-pressed); }
.keycap svg { width: 28px; height: 28px; }
.keycap:active, .keycap.is-pressed, .robot:active { translate: 0 3px; box-shadow: var(--edge-pressed); }

@media (hover: hover) {
  .level:not(.is-locked):not([aria-current]):hover, .quiet:hover { background: var(--color-bg-panel); }
  .keycap:hover, .countkey:not(:disabled):hover, .robot:not([aria-pressed="true"]):hover { background: #F8EEDC; }
}

@media (prefers-reduced-motion: no-preference) {
  .keycap, .countkey, .robot, .primary { transition-property: translate, box-shadow; transition-duration: 80ms; }
}

/* Owned upgrades */

.upgrades { display: inline-flex; flex: none; align-items: center; gap: 6px; padding-inline: 10px; }
.upgrades svg { width: 22px; height: 22px; }
.upgrades:not([hidden]) + .quiet { margin-inline-start: 0; }
.upgrades-count {
  min-width: 1.6em; padding: 0 6px; border-radius: 8px; line-height: 1.5;
  background: var(--color-screen-bg); color: var(--color-diagnostic); font-weight: 700; font-variant-numeric: tabular-nums;
}
/* The robot stays in view while only the upgrade list scrolls. */
.sheet.garage { width: min(30rem, calc(100vw - 32px)); max-height: calc(100svh - 32px); padding: 0; }
.garage[open] { display: flex; flex-direction: column; }
.garage h2 { padding: 20px 20px 12px; }
.garage-body { display: flex; flex-direction: column; gap: 14px; min-height: 0; padding-inline: 20px; }
.garage-view { block-size: clamp(9rem, 28svh, 14rem); flex: none; border-radius: 14px; overflow: hidden; }
.garage-lists { display: flex; flex-direction: column; gap: 14px; min-height: 0; overflow-y: auto; margin-inline: -4px; padding: 2px 4px 4px; }
.garage .sheet-actions { margin: 0; padding: 14px 20px 20px; }
@media (min-width: 48rem) {
  .sheet.garage { width: min(46rem, calc(100vw - 32px)); }
  .garage-body { display: grid; grid-template-columns: 17rem minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); align-items: start; }
  .garage-view { block-size: 20rem; }
  .garage-lists { max-block-size: 100%; }
}
.garage h3 { margin: 0 0 8px; color: var(--color-text-secondary); font-size: var(--text-caption); font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; }
.chip-list { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-button {
  min-height: 44px; padding: 0 14px; border: 2px solid var(--color-border); border-radius: 12px;
  background: var(--color-bg-panel); font-weight: 700;
}
.chip-button[aria-pressed="true"] { background: var(--charcoal-900); border-color: var(--charcoal-900); color: var(--cream-50); }

/* Dialog */

.sheet {
  width: min(22rem, calc(100vw - 32px)); padding: 20px;
  border: 2px solid var(--color-border); border-radius: var(--radius-panel);
  background: var(--color-bg-page); color: var(--color-text); box-shadow: 0 6px 0 var(--charcoal-700);
  overscroll-behavior: contain;
}
.sheet::backdrop { background: rgb(36 31 29 / 0.5); }
.sheet h2 { font-size: var(--text-title); font-weight: 800; }
.sheet p { margin-top: 6px; color: var(--color-text-secondary); }
.sheet-actions { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 10px; margin-top: 20px; }

/* Level lesson and document practice: a scrolling body over a fixed action row. */

.lesson, .practice { width: min(34rem, calc(100vw - 32px)); max-height: calc(100svh - 32px); padding: 0; }
.lesson[open], .practice[open] { display: flex; flex-direction: column; }
.lesson-form { display: flex; flex-direction: column; min-height: 0; }
.lesson-body { display: flex; flex-direction: column; gap: 12px; min-height: 0; overflow-y: auto; padding: 20px 20px 4px; }
.lesson .sheet-actions, .practice .sheet-actions { margin: 0; padding: 14px 20px 20px; }
.sheet .lesson-body p { margin: 0; }
.lesson h2 { display: flex; align-items: center; gap: 10px; text-wrap: balance; }
.lesson-num {
  display: grid; place-items: center; flex: none; width: 32px; height: 32px; border-radius: 8px;
  background: var(--charcoal-800); color: var(--cream-100);
  font-size: 1rem; font-variant-numeric: tabular-nums;
}
.sheet .lesson-scene, .sheet .lesson-how, .sheet .practice-goal, .sheet #lesson-goal-text { color: var(--color-text); }
.lesson-scene { font-size: 1.0625rem; text-wrap: pretty; }
.lesson-how { text-wrap: pretty; }
.lesson kbd:not(.bigkey), .practice-goal kbd {
  display: inline-block; min-width: 1.5em; padding: 0 0.3em; border-radius: 6px;
  border: 2px solid var(--color-border); background: var(--color-bg-panel);
  font: 700 0.95em/1.25 var(--font-key); text-align: center; color: var(--color-text);
}

.lesson-example { display: grid; gap: 12px; padding: 14px 16px; border-radius: 14px; background: var(--color-bg-panel); }
.lesson-example:empty { display: none; }
.sheet .example { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px 12px; color: var(--color-text); }
.example-cap { display: inline-flex; flex-direction: column; align-items: center; gap: 4px; }
/* Alternatives, such as n or N, sit on one line. */
.example-cap.is-alt { flex-direction: row; gap: 12px; }
.bigkey {
  display: grid; place-items: center; min-width: 60px; height: 60px; padding: 0 10px;
  border: 2px solid var(--color-border); border-radius: var(--radius-key);
  background: var(--color-bg-page); box-shadow: var(--edge);
  font: 700 2rem/1 var(--font-key);
}
.key-name { color: var(--color-text-secondary); font-size: var(--text-caption); font-weight: 600; white-space: nowrap; }
.then, .says { display: flex; align-items: center; min-height: 64px; font-weight: 700; }
.then { color: var(--color-text-secondary); }
.says::before { content: "→"; margin-inline-end: 10px; color: var(--orange-700); }
/* A typed character is text on the screen, not a key: no keycap edge. */
.typed {
  display: grid; place-items: center; min-width: 60px; height: 60px; padding: 0 10px;
  border-radius: var(--radius-key); background: var(--color-screen-bg); color: var(--color-screen-text);
  font: 700 2rem/1 var(--font-key);
}
.sheet .example-rule { padding: 10px 0 2px; border-top: 2px dashed var(--cream-200); color: var(--color-text); font-weight: 700; }
/* Long step lists: smaller keys so every step stays in view. */
.lesson-example.is-long { gap: 8px; }
.lesson-example.is-long :is(.bigkey, .typed) { min-width: 48px; height: 48px; font-size: 1.625rem; }
.lesson-example.is-long :is(.then, .says) { min-height: 52px; }
.lesson-example.is-long .doc { padding: 10px 12px; }
.lesson .lesson-example.is-long .doc-page pre { font-size: clamp(0.75rem, 3.1vw, 1.125rem); }

.lesson-goal { display: grid; gap: 4px; padding-top: 12px; border-top: 2px dashed var(--cream-200); }
#lesson-goal-text { font-weight: 700; }
.sheet .lesson-unlock { color: var(--color-text); }

.sheet .practice-goal { font-size: 1.0625rem; font-weight: 700; }
.doc {
  position: relative; padding: 14px 16px; overflow-x: auto;
  border: 2px solid var(--charcoal-700); border-radius: 14px;
  background: var(--color-screen-bg); box-shadow: var(--edge);
}
.doc-page { width: max-content; min-width: 100%; color: var(--color-screen-text); border-radius: 6px; }
.doc-page:focus { outline: none; }
.doc-page:focus-visible { outline: 3px solid var(--color-diagnostic); outline-offset: 6px; }
.doc-page pre { margin: 0; font: 500 clamp(1.125rem, 4.6vw, 1.5rem)/1.8 var(--font-key); white-space: pre; }
/* Lesson previews show whole work-order lines, up to 32 characters, without clipping on phones. */
.lesson .doc-page pre { font-size: clamp(0.9375rem, 3.8vw, 1.25rem); }
.doc-page span { border-radius: 3px; }
.doc-page .is-target { outline: 2px solid var(--orange-500); outline-offset: 1px; }
.doc-page .is-cursor { background: var(--cyan-300); color: var(--charcoal-900); }
.practice.is-done .is-cursor { outline-color: var(--cyan-300); outline-width: 3px; }
.doc-pending {
  position: absolute; inset-inline-end: 10px; top: 6px;
  color: var(--brass-400); font: 700 var(--text-caption)/1.5 var(--font-key);
}
.sheet .practice-status { min-height: 1.4em; }
.practice.is-done .practice-status { color: var(--cyan-700); font-weight: 700; }
.practice-keys { display: flex; flex-direction: column; gap: 8px; }
.practice-keys .textkeys { flex: none; grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.practice-keys .keycap { min-height: 56px; }
.practice-keys .keycap kbd { font-size: 1.5rem; }
.practice-keys .keycap svg { width: 22px; height: 22px; }

/* Narrow: compact header, current level keeps its name. */

.level:not([aria-current]) .level-name {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* State icons sit on the badge corner so the stops stay compact beside the group buttons. */

.bar { gap: 8px 16px; }
@media (max-width: 63.99rem) {
  .levels { order: 3; width: 100%; }
}
.level { position: relative; justify-content: center; min-width: 44px; padding: 0 4px; }
.level[aria-current] { padding-inline: 6px 12px; }
.level-state {
  position: absolute; inset-inline-start: 26px; top: 2px; padding: 1px; border-radius: 50%;
  background: var(--color-bg-page);
}
.level[aria-current] .level-state { background: var(--color-bg-panel); }
.level svg { width: 13px; height: 13px; }

/* Portrait tablet: fixed column, the world takes what the bench leaves. */

@media (min-width: 40rem) and (orientation: portrait) {
  body { height: 100svh; min-height: 0; }
  .play { min-height: 0; }
  .stage { flex: 1; min-height: 0; }
  .world { flex: 1; min-height: 180px; aspect-ratio: auto; max-height: none; }
  .stage.is-text .world { flex: none; min-height: 104px; }
  .terminals { flex: 1; overflow-y: auto; }
  /* The reward sits beside the result so the text panel keeps its height. */
  .done { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); grid-template-rows: auto auto 1fr; }
  .done > :not(.reward) { grid-column: 1; align-self: start; }
  .done > .done-actions { align-self: end; }
  .reward { grid-column: 2; grid-row: 1 / span 3; align-self: start; }
}

@media (max-width: 39.99rem) {
  .brand img { height: 34px; }
  .levels { order: 3; width: 100%; }
  .levels ol { gap: 4px; justify-content: space-between; }
  .level .level-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .score { gap: 8px; }
  .strokes { min-width: 3.5rem; padding-inline: 6px; }
  .chip { padding: 0 6px; }
  .play { gap: 12px; }
  .stage h2 { font-size: 1.25rem; }
  .stage-head { gap: 6px; }
  .upgrades-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .keycap { min-height: 72px; }
  .keycap.is-text { min-height: 48px; }
  .anchors { gap: 6px; }
  .textkeys { gap: 6px; }
  .groups { width: 100%; }
  .group { flex: 1; flex-direction: column; justify-content: center; gap: 0; min-width: 0; padding: 2px 4px; line-height: 1.15; }
  .group-count { padding: 0 5px; font-size: 0.6875rem; }
  .group { position: relative; }
  .group-lock { position: absolute; top: 3px; inset-inline-end: 4px; }
  .robot { min-height: 52px; gap: 2px 4px; }
  .robot-lamp { width: 18px; height: 18px; }
  .robot-lamp svg { width: 13px; height: 13px; }
}

/* Landscape tablet and desktop: world beside the bench. */

@media (min-width: 60rem) and (orientation: landscape) {
  body { height: 100svh; min-height: 0; }
  .play {
    display: grid; grid-template-columns: minmax(0, 1fr) 21rem; gap: 28px; min-height: 0;
  }
  .stage { min-height: 0; }
  .world { flex: 1; min-height: 0; aspect-ratio: auto; max-height: none; }
  .stage.is-text .world { flex: none; min-height: 108px; }
  .terminals { flex: 1; overflow-y: auto; padding-bottom: 6px; }
  .bench { max-width: none; padding: 8px; min-height: 0; overflow-y: auto; }
  .controls { margin-top: auto; }
  /* Edit levels: a wider bench on large screens gives the keypad fewer, shorter rows. */
  .play:has(.stage.is-edit) { grid-template-columns: minmax(0, 1fr) clamp(21rem, 30vw, 26rem); }
  .play:has(.stage.is-edit) .controls { gap: 10px; }
  .play:has(.stage.is-edit) .keys .keycap { min-height: 64px; }
}

@media (forced-colors: active) {
  :focus-visible { outline-color: Highlight; }
  .cursor, .robot-2 .cursor, .doc-page .is-cursor { background: Highlight; color: HighlightText; forced-color-adjust: none; }
  .order-mark, .machine { forced-color-adjust: none; outline: 2px solid CanvasText; background: Canvas; color: CanvasText; }
  .order-row[data-state="done"] .order-mark, .order-row[data-state="done"] .machine { background: CanvasText; color: Canvas; }
  .order-line mark { background: Highlight; color: HighlightText; }
  .spark { border: 2px dotted CanvasText; }
  .mark[data-state="live"] { outline-color: Highlight; }
  .pip, .tag { forced-color-adjust: none; outline: 2px solid CanvasText; background: Canvas; color: CanvasText; }
  .pip[data-state="qualified"], .pip[data-state="reached"], .tag.is-done { background: CanvasText; color: Canvas; }
  .pip[data-state="live"], .tag.is-target, .tag.is-you { background: Highlight; color: HighlightText; }
  .robot[aria-pressed="true"] { outline: 3px solid Highlight; }
  .reward { border-color: CanvasText; }
  .chip-button[aria-pressed="true"] { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
}

/* Arm controller capstone: workcell beside (or above) the part board, sectioned document. */

.stage:is(.is-arm, .is-bays) .world { min-height: 184px; }
.arm { display: flex; flex-direction: column; gap: 4px; }
.systems {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px;
  margin: 0; padding: 0; list-style: none;
}
.system {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 1px 7px;
  min-width: 0; padding: 3px 0 5px; border-bottom: 2px solid transparent;
}
.system[aria-current] { border-bottom-color: var(--cream-200); }
/* The next part to repair: dashed brass, where solid cream marks the cursor's part. */
.system[data-next] { border-bottom: 2px dashed var(--brass-400); }
.part-next {
  padding: 0 6px; border: 1px dashed var(--brass-400); border-radius: 6px;
  color: var(--brass-400); font-weight: 800;
}
.system-icon {
  grid-row: 1 / span 2; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 6px;
  outline: 2px solid var(--stone-500); outline-offset: -2px; background: var(--charcoal-700); color: var(--cream-200);
}
.system-icon svg { width: 16px; height: 16px; stroke-width: 2; }
.system-name { min-width: 0; overflow: hidden; font: 700 var(--text-caption)/1.15 var(--font-ui); white-space: nowrap; text-overflow: ellipsis; }
.system-state { color: var(--cream-200); font: 700 0.6875rem/1.2 var(--font-ui); font-variant-numeric: tabular-nums; white-space: nowrap; }
.system[data-state="waiting"] .system-icon { outline-color: var(--orange-500); color: var(--orange-500); }
.system[data-state="waiting"] .system-state { color: var(--orange-500); }
.system[data-state="running"] .system-icon { outline: none; background: var(--cyan-300); color: var(--charcoal-900); }
.system[data-state="running"] .system-state { color: var(--cyan-300); }
.part-head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 5px; padding-top: 4px;
  border-top: 1px solid var(--charcoal-700); color: var(--cream-200); font: 600 var(--text-caption)/1.35 var(--font-ui);
}
.part-name { color: var(--cream-50); font-weight: 800; }
.part-state { font-weight: 800; }
.part-head[data-state="waiting"] .part-state { color: var(--orange-500); }
.part-head[data-state="running"] .part-state { color: var(--cyan-300); }
.part-rows .order-row { grid-template-columns: auto minmax(0, 1fr); }
/* No machine cell here, so the mark stays beside its line at every width. */
.part-rows .order-mark, .part-rows .order-line { grid-row: 1; }
.part-rows .order-line { grid-column: 2; }
/* Line numbers grow with large text instead of spilling onto the line. */
.part-rows .order-mark { width: auto; min-width: 22px; height: auto; min-height: 22px; padding-inline: 3px; }
/* Stacked chips once five side-by-side labels stop fitting; the name drops last. */
@container (max-width: 28rem) {
  .systems { gap: 4px; }
  .system { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 2px; text-align: center; }
  .system-icon { grid-row: auto; }
  .system-name { max-width: 100%; font-size: 0.6875rem; }
}
/* Phones: room for a wrapped dependency list, so moving between parts never shifts the page. */
@container (max-width: 21rem) {
  .part-head { min-height: calc(2 * 1.35em + 4px); align-content: flex-start; }
}

/* Section rules every three rows and a tint behind the cursor's part, both on the real row height. */
.stage.is-arm .term-text, .stage.is-arm .gutter {
  background-image: repeating-linear-gradient(to bottom, transparent 0 calc(3 * var(--row) - 1px),
    rgb(230 211 179 / 0.16) calc(3 * var(--row) - 1px) calc(3 * var(--row)));
  background-size: 100% calc(12 * var(--row)); background-repeat: no-repeat;
}
.stage.is-arm .term-text { flex: 1; isolation: isolate; }
.term-part {
  position: absolute; z-index: -1; inset-inline: 0 -16px; top: calc(var(--r) * var(--row)); height: calc(3 * var(--row));
  background: rgb(251 244 232 / 0.06); pointer-events: none;
}

/* The cursor's whole part always shows; a short window lets the page scroll rather than hide it. */
.stage.is-arm .term-grid { min-height: calc(3 * var(--row) + 12px); }
/* Portrait tablet: a shorter workcell and bench leave the document more rows. */
@media (min-width: 40rem) and (orientation: portrait) {
  .stage.is-arm .world { min-height: 176px; }
  .play:has(.stage.is-arm) .keycap { min-height: 64px; }
  .play:has(.stage.is-arm) .keycap.is-text { min-height: 48px; }
  .play:has(.stage.is-arm) .controls, .play:has(.stage.is-arm) .bench { gap: 10px; }
}
@media (min-width: 60rem) and (orientation: landscape) {
  .stage:is(.is-arm, .is-bays) .world { min-height: clamp(184px, 24svh, 260px); }
  /* Large text: the pane keeps its head and three rows, so the page scrolls instead of clipping the cursor. */
  .stage.is-arm {
    --term-min: calc(3 * 1.9 * clamp(0.875rem, 3.6vw, 1.125rem) + 12px + 14px + max(24px, 1.1375rem + 2px));
  }
  .stage.is-arm .terminals { flex-shrink: 0; min-height: calc(var(--term-min) + 6px); }
  .stage.is-arm .term { min-height: var(--term-min); }
}
/* Short landscape: the keypad stays beside the document, as on wider landscape screens. */
@media (min-width: 40rem) and (max-width: 59.99rem) and (orientation: landscape) {
  .play:has(.stage.is-arm) { display: grid; grid-template-columns: minmax(0, 1fr) 21rem; align-items: start; gap: 20px; }
  .stage.is-arm .world { --arm-cell: 132px; flex-direction: column; padding-top: var(--arm-cell); }
  .stage.is-arm .board { align-self: stretch; margin: 8px 0 0; }
  .stage.is-arm .term-grid { max-height: calc(6 * var(--row) + 12px); }
  .play:has(.stage.is-arm) .bench {
    position: sticky; top: 0; max-height: 100svh; overflow-y: auto; gap: 8px; padding: 8px;
  }
  .play:has(.stage.is-arm) .controls { gap: 8px; }
  .play:has(.stage.is-arm) .keycap { min-height: 56px; }
  .play:has(.stage.is-arm) .keycap.is-text { min-height: 44px; }
}
/* Narrow: the workcell takes a fixed band and the board runs full width beneath it. */
@media (max-width: 39.99rem) {
  .stage.is-arm .world { --arm-cell: 132px; flex-direction: column; padding-top: var(--arm-cell); }
  .stage.is-arm .board { align-self: stretch; margin: 8px 0 0; }
  /* The wider bay row is width-bound, so a shorter band holds the same drawing. */
  .stage.is-bays .world { --arm-cell: 104px; min-height: 0; flex-direction: column; padding-top: var(--arm-cell); }
  .stage.is-bays .board { align-self: stretch; margin: 8px 0 0; }
  .stage.is-arm .term-grid { max-height: calc(6 * var(--row) + 12px); }
}
@media (forced-colors: active) {
  .system-icon { forced-color-adjust: none; outline: 2px solid CanvasText; background: Canvas; color: CanvasText; }
  .system[data-state="running"] .system-icon { background: CanvasText; color: Canvas; }
  .system { border-bottom-color: Canvas; }
  .system[aria-current] { border-bottom-color: Highlight; }
  .system[data-next], .part-next { border-color: CanvasText; }
  .order-row[aria-current] .order-mark { outline-color: Highlight; }
  .order-row[data-next] .order-mark { outline-color: CanvasText; }
}

/* Sorter gate and box sealer: the machine's workcell beside (or above) the work order. */

.stage:is(.is-sorter, .is-sealer) .world { min-height: 200px; }
@media (min-width: 60rem) and (orientation: landscape) {
  .stage:is(.is-sorter, .is-sealer) .world { flex: none; min-height: clamp(220px, 28svh, 280px); }
}
@media (min-width: 40rem) and (max-width: 59.99rem) and (orientation: landscape), (max-width: 39.99rem) {
  .stage:is(.is-sorter, .is-sealer) .world { --arm-cell: 132px; flex-direction: column; padding-top: var(--arm-cell); }
  .stage:is(.is-sorter, .is-sealer) .board { align-self: stretch; margin: 8px 0 0; }
}

/* First job (26–29): the job strip beside (or above) a board of only the rows that change. */

.stage.is-job .world { min-height: 200px; }
.job-steps {
  display: flex; justify-content: space-between; gap: 4px 10px;
  margin: 0 0 4px; padding: 2px 0 7px; list-style: none; border-bottom: 1px solid var(--charcoal-700);
}
.job-step { display: flex; align-items: center; gap: 6px; min-width: 0; color: var(--cream-200); font: 700 var(--text-caption)/1.2 var(--font-ui); }
.job-step-mark {
  flex: none; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%;
  outline: 2px solid var(--stone-500); outline-offset: -2px; color: var(--cream-50);
}
.job-step-mark svg { width: 12px; height: 12px; stroke-width: 3.5; }
.job-step-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.job-step[data-state="done"] .job-step-mark { outline: none; background: var(--cyan-700); }
.job-step[aria-current] { color: var(--cream-50); }
.job-step[aria-current] .job-step-mark { outline-color: var(--orange-500); background: radial-gradient(circle, var(--orange-500) 0 3.5px, transparent 4px); }
.job-step[aria-current][data-state="done"] .job-step-mark { background: var(--cyan-700); box-shadow: 0 0 0 2px var(--orange-500); }
.job-status {
  order: 1; margin: 4px 0 0; padding-top: 6px; border-top: 1px solid var(--charcoal-700);
  color: var(--cream-200); font: 600 var(--text-caption)/1.35 var(--font-ui);
}
/* Line numbers are the marks here, so they grow with large text instead of spilling. */
.stage.is-job .order-mark { width: auto; min-width: 22px; height: auto; min-height: 22px; padding-inline: 3px; }
.stage.is-job .order-row[data-state="done"] .order-mark { color: var(--cream-50); }
/* The exact target never clips: when the machine and status don't fit beside it, they wrap under it. */
.stage.is-job .order-row { display: flex; flex-wrap: wrap; gap: 3px 10px; }
.stage.is-job .order-line { flex: 1 0 auto; }
.stage.is-job .order-machine { margin-inline-start: auto; }
@media (min-width: 60rem) and (orientation: landscape) {
  .stage.is-job .world { flex: none; min-height: clamp(220px, 28svh, 280px); }
}
@media (min-width: 40rem) and (max-width: 59.99rem) and (orientation: landscape), (max-width: 39.99rem) {
  .stage.is-job .world { --arm-cell: 128px; flex-direction: column; padding-top: var(--arm-cell); }
  .stage.is-job .board { align-self: stretch; margin: 8px 0 0; }
  /* Fifteen lines: the grid shows six around the cursor and the page stays short. */
  .stage.is-job .term-grid { max-height: calc(6 * var(--row) + 12px); }
}
/* Short landscape: the keypad stays beside the document, as in the capstone. */
@media (min-width: 40rem) and (max-width: 59.99rem) and (orientation: landscape) {
  .play:has(.stage.is-job) { display: grid; grid-template-columns: minmax(0, 1fr) 21rem; align-items: start; gap: 20px; }
  .play:has(.stage.is-job) .bench { position: sticky; top: 0; max-height: 100svh; overflow-y: auto; gap: 8px; padding: 8px; }
  /* The bench scrolls instead of squeezing a two-line cue under the keys. */
  .play:has(.stage.is-job) .bench > * { flex-shrink: 0; }
  .play:has(.stage.is-job) .controls { gap: 8px; }
  .play:has(.stage.is-job) .keycap { min-height: 56px; }
  .play:has(.stage.is-job) .keycap.is-text { min-height: 44px; }
  /* At 200% zoom the column is too narrow for title and tools; How to play wraps under them. */
  .stage:is(.is-job, .is-arm) .stage-head { flex-wrap: wrap; }
}

/* Key families: one toggle row, then the open family's keys in one row. */
.anchors.is-families { flex-direction: column; gap: 8px; }
.families { display: flex; gap: 6px; }
.family {
  flex: 1 1 0; min-width: 0; min-height: 44px; padding: 0 4px;
  border: 2px solid var(--color-border); border-radius: var(--radius-key); background: var(--color-bg-page);
  color: var(--color-text-secondary); font: 700 var(--text-caption)/1 var(--font-ui);
}
.family[aria-pressed="true"] { background: var(--charcoal-800); border-color: var(--charcoal-900); color: var(--cream-50); }
.anchors.is-families .textkeys { flex: none; grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.keycap.is-enter kbd { font: 800 1rem/1 var(--font-ui); }
@media (hover: hover) {
  .family:not([aria-pressed="true"]):hover { background: var(--color-bg-panel); }
}

/* Vim's bottom line: a search being typed, or the echo of the last one. Long text keeps its end. */
.ruler .status.is-cmd {
  display: flex; justify-content: flex-end; flex: 0 1 auto; min-width: 0; overflow: hidden;
  white-space: pre; color: var(--cream-50); font-weight: 700;
}
.ruler .status.is-warn { color: var(--brass-400); }
.ruler .status.is-error { color: var(--orange-500); }
.ruler .caret { flex: none; width: 1ch; margin-inline-start: 1px; background: var(--cyan-300); }

@media (forced-colors: active) {
  .keycap.is-armed { forced-color-adjust: none; background: Highlight; color: HighlightText; }
  .ruler .caret { forced-color-adjust: none; background: Highlight; }
  .job-step-mark { forced-color-adjust: none; outline: 2px solid CanvasText; background: Canvas; color: CanvasText; }
  .job-step[data-state="done"] .job-step-mark { background: CanvasText; color: Canvas; }
  .job-step[aria-current] .job-step-mark { outline-color: Highlight; }
  .family[aria-pressed="true"] { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
}

/* Second job (30–32): the card chip, the put seam, ~ rows past the end and the aligned board. */

.term-text { min-height: calc(var(--rows, 0) * var(--lh)); }
.gutter li[data-state="tilde"] { color: var(--stone-500); }
.gutter li[data-state="tick"] { color: var(--orange-500); opacity: 1; box-shadow: inset -2px 0 0 var(--orange-500); }
.stage.is-job2 .term-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.term-card {
  display: inline-flex; align-items: center; flex: 0 1 auto; min-width: min(13ch, 40%); max-width: 26ch;
  margin-inline-start: auto; padding: 1px 7px; border: 1.5px solid var(--charcoal-700); border-radius: 5px;
  background: var(--cream-50); color: var(--charcoal-900); font: 600 var(--text-caption)/1.4 var(--font-key);
  white-space: pre; overflow: hidden;
}
.term-card[hidden] { display: none; }
.term-card:not([hidden]) + .mode { margin-inline-start: 0; }
.term-card .card-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.term-card .card-eol, .term-card .card-sp, .term-card .card-q { flex: none; color: var(--stone-500); }
.term-card .card-eol { margin-inline-start: 4px; color: var(--cyan-700); font-weight: 800; }
.term-card[data-kind="empty"] { border-style: dashed; border-color: var(--stone-500); background: transparent; color: var(--stone-500); font-family: var(--font-ui); }
.seam { position: absolute; pointer-events: none; }
.seam.is-line {
  left: 0; right: 0; top: calc((var(--r) + 1) * var(--lh) - 1px); border-top: 2px dashed var(--cyan-300);
}
.seam.is-char {
  left: calc((var(--c) + 1) * 1ch - 1px); top: calc(var(--r) * var(--lh) + (var(--lh) - var(--cell-h)) / 2);
  height: var(--cell-h); border-left: 2px dashed var(--cyan-300);
}
.wash {
  position: absolute; left: 0; right: 0; top: calc(var(--r) * var(--lh)); height: var(--lh);
  background: rgb(92 225 230 / 0.28); pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .term-card.is-new { animation: card-in 160ms ease-out; }
  .wash { animation: wash-out 300ms ease-out forwards; }
}
@keyframes card-in { from { background: var(--cyan-300); } }
@keyframes wash-out { to { opacity: 0; } }

/* Twelve edit keys with y and p: two rows of six (i a A x d c / r y p u . Esc) until twelve 44px keys fit. */
.textkeys.edit-keys:has(.keycap[data-key="p"]:not([hidden])) { grid-template-columns: repeat(6, minmax(0, 1fr)); }
@container (min-width: 38.5rem) {
  .textkeys.edit-keys:has(.keycap[data-key="p"]:not([hidden])) { grid-template-columns: repeat(12, minmax(0, 1fr)); }
}

.order-row[data-state="held"] .order-mark { outline-style: dashed; outline-color: var(--cyan-300); color: var(--cyan-300); }
.order-row[data-state="held"] .order-say { color: var(--cyan-300); }

@media (forced-colors: active) {
  .term-card { forced-color-adjust: none; border-color: CanvasText; background: Canvas; color: CanvasText; }
  .term-card[data-kind="empty"] { border-style: dashed; color: GrayText; }
  .term-card .card-eol, .term-card .card-sp, .term-card .card-q { color: CanvasText; }
  .seam.is-line { border-top-color: Highlight; }
  .seam.is-char { border-left-color: Highlight; }
  .gutter li[data-state="tick"] { box-shadow: none; text-decoration: underline; }
}

/* Six groups: between phone and desktop widths the group row tightens, then wraps rather than scroll. */
@media (min-width: 40rem) and (max-width: 63.99rem) {
  .groups { flex-wrap: wrap; }
  .group { padding-inline: 6px; }
}

/* End of shift (33–34): the [+] mark, the closed file, Reopen and the colon key. */

.stage.is-shift .term-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.term-dirty { flex: none; color: var(--rust-700); font: 800 var(--text-caption)/1 var(--font-key); }
.term-dirty[hidden] { display: none; }
.term.is-closed .term-head { background: var(--cream-200); }
.term.is-closed .mode { background: var(--charcoal-700); color: var(--cream-100); }
.term.is-closed .term-screen { color: rgb(230 211 179 / 0.7); }
.term.is-closed .gutter li { color: var(--stone-500); opacity: 1; }
.term.is-closed .cursor, .term.is-closed .seam { display: none; }
.ruler[hidden], .term-reopen[hidden] { display: none; }
.term-reopen {
  align-self: stretch; min-height: 44px; margin: 4px 8px 8px;
  background: var(--cream-100); border-color: var(--cream-100); color: var(--charcoal-900);
}
.term-reopen:focus-visible { outline-color: var(--color-diagnostic); }
/* The colon key sits directly under Esc: Esc, then : reads top to bottom, and no other key moves. */
.edit-keys .keycap[data-key=":"] { grid-column: -2; }

@media (forced-colors: active) {
  .term-dirty { color: Highlight; }
  .term.is-closed .term-screen, .term.is-closed .gutter li { color: GrayText; }
  .term-reopen { forced-color-adjust: none; border: 2px solid ButtonText; color: ButtonText; background: ButtonFace; }
}
/* Seven groups: phones give them a four-column grid, two rows, so every name fits on one line. */
@media (max-width: 39.99rem) {
  .groups { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* Seven groups on desktop: the level nav takes the row beside the logo and wraps its stops under the
   groups, so the header stays two rows instead of dropping the whole nav to a row of its own. */
@media (min-width: 64rem) {
  .levels { flex: 1 1 0; min-width: 0; }
  .groups { flex-wrap: wrap; }
}

/* Game footer: an optional support link after the play area, in flow so it never covers the game. */
.play-foot {
  flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 4px 12px;
  padding: 0 var(--gutter-end) max(8px, env(safe-area-inset-bottom)) var(--gutter);
  color: var(--color-text-secondary); font-size: var(--text-caption);
}
.play-foot a { display: grid; place-items: center; min-height: 44px; border-radius: 8px; }
.play-foot img { display: block; height: 32px; width: auto; }
