/* The simulator's page (docs/ui-design.md). A dark Material 3 scheme for a classroom (U5): blue
   for the instrument, amber for "your turn", green for done, red for errors; the brass is the
   machine's own. The layout is a fixed frame (U1): top bar, stage (with the machine's toolbar
   floating at its bottom, U18) and dock, status bar. */

:root {
  color-scheme: dark;
  /* blue: the instrument itself: navigation, selection, where you are, links, focus */
  --md-primary: #9ecaff;
  --md-on-primary: #00325a;
  --md-primary-container: #12497c;
  --md-on-primary-container: #d3e4ff;
  /* blue-grey: the machine's controls (tonal buttons) */
  --md-secondary-container: #364657;
  --md-on-secondary-container: #d5e4f7;
  /* cool neutrals, a touch of blue */
  --md-surface: #0f1317;
  --md-surface-low: #171b20;
  --md-surface-mid: #1b2026;
  --md-surface-high: #252a31;
  --md-surface-highest: #30353d;
  --md-on-surface: #e0e3e9;
  --md-on-surface-variant: #c1c7d0;
  --md-outline: #8b919a;
  --md-outline-variant: #3f464f;
  /* a card's fine edge, between its surface and the outline */
  --card-edge: #343a43;
  --md-scrim: rgba(0, 0, 0, 0.55);
  /* amber, one meaning only: your turn. The control a step asks for (its glow), the task line,
     and (the same hue, in 3D) the parts a step points at. */
  --attention: #ffb74d;
  --attention-container: #573c00;
  --on-attention-container: #ffdfb0;
  /* green: done (a task, a lesson) */
  --success: #9bd88e;
  --success-container: #1f4a24;
  --on-success-container: #c3f2b8;
  /* red: something went wrong (a refused control, a blocked step) */
  --md-error: #ffb4ab;
  /* the machine's own red: its numbers counted backward (the Magna Rota's red digits) */
  --red: #ff8a80;
  /* state layers: how much a control lightens (or darkens) under the pointer and when pressed */
  --state-hover: 0.14;
  --state-press: 0.22;
  --font: "Roboto Flex", system-ui, -apple-system, "Segoe UI", "Noto Sans", "PingFang SC", "Hiragino Sans", "Microsoft YaHei", "Malgun Gothic", sans-serif;
  --radius-s: 8px;
  --radius-m: 12px;
  --radius-l: 16px;
  --radius-full: 999px;
  --dock-w: clamp(340px, 30vw, 440px);
  --bar-h: 56px;
  --status-h: 30px;
  --ease: cubic-bezier(0.2, 0, 0, 1);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.45;
  color: var(--md-on-surface);
  background: var(--md-surface);
  font-variant-numeric: tabular-nums;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; }
body {
  display: grid;
  grid-template-rows: var(--bar-h) minmax(0, 1fr) var(--status-h);
  height: 100dvh;
}
[hidden] { display: none !important; }
/* Selecting and dragging (U28). The page is an instrument: its chrome (bars, buttons, chips,
   tabs, menus, labels, the 3D view, the toolbar) is not selectable, its images and links are not
   dragged, a long press shows no callout and a tap no grey flash. What is read stays selectable,
   so a teacher can copy it: the dock's text, About, the status line, the readouts' values, and
   whatever is typed. Controls inside the reading areas stay chrome. */
body { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }
img, svg { -webkit-user-drag: none; }
.panel, .dialog-body, #status, .readout output, input, textarea {
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
}
.panel button, .panel a, .panel .taskline, .panel .progress, .panel .step-meta, .panel .kicker, .dialog-head, .dialog-body a {
  user-select: none;
  -webkit-user-select: none;
}
.figure img { -webkit-user-drag: auto; }
button, input, select { font: inherit; color: inherit; }
a { color: var(--md-primary); }
:focus-visible { outline: 2px solid var(--md-primary); outline-offset: 2px; }
.icon { width: 20px; height: 20px; fill: currentColor; flex: none; display: block; }

/* ---- buttons (Material 3: filled, tonal, text, icon; state layers) --------------------------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--md-primary);
  font-weight: 560;
  letter-spacing: 0.01em;
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  -webkit-user-select: none;
  isolation: isolate;
}
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: currentColor;
  opacity: 0;
  transition: opacity 120ms var(--ease);
  z-index: -1;
}
.btn:hover::before { opacity: var(--state-hover); }
.btn:active::before { opacity: var(--state-press); }
.btn.filled { background: var(--md-primary); color: var(--md-on-primary); }
.btn.tonal { background: var(--md-secondary-container); color: var(--md-on-secondary-container); }
.btn.has-icon { padding-left: 12px; }
.btn[disabled], .btn[aria-disabled="true"] {
  cursor: default;
  color: color-mix(in srgb, var(--md-on-surface) 38%, transparent);
  background: transparent;
}
.btn.filled[disabled], .btn.tonal[disabled], .btn.filled[aria-disabled="true"], .btn.tonal[aria-disabled="true"] {
  background: color-mix(in srgb, var(--md-on-surface) 12%, transparent);
}
.btn[disabled]::before, .btn[aria-disabled="true"]::before { display: none; }
.btn.icon-only { width: 40px; padding: 0; color: var(--md-on-surface-variant); }
/* a task's control: the one the step asks for */
.btn.wanted:not([disabled]):not([aria-disabled="true"]) { box-shadow: 0 0 0 2px var(--attention), 0 0 14px color-mix(in srgb, var(--attention) 45%, transparent); }

/* chips (filter chips for the stage tools) */
.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px 0 8px;
  border: 1px solid var(--md-outline-variant);
  border-radius: var(--radius-s);
  background: color-mix(in srgb, var(--md-surface) 72%, transparent);
  backdrop-filter: blur(6px);
  color: var(--md-on-surface-variant);
  font-size: 13px;
  font-weight: 520;
  cursor: pointer;
  isolation: isolate;
}
.chip::before { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; z-index: -1; }
.chip:hover::before { opacity: var(--state-hover); }
.chip:active::before { opacity: var(--state-press); }
.chip[aria-disabled="true"] { opacity: 0.4; cursor: default; }
.chip[aria-disabled="true"]::before { display: none; }
.chip .icon { width: 18px; height: 18px; }

/* ---- top bar ------------------------------------------------------------------------------------ */
.topbar {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 8px 0 12px;
  background: var(--md-surface-low);
  border-bottom: 1px solid var(--md-outline-variant);
  min-width: 0;
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  color: var(--md-on-surface);
  text-decoration: none;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.005em;
}
.brand img { width: 64px; height: 34px; flex: none; }
.brand span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar .spacer { flex: 1; }
.lang-btn { gap: 6px; padding: 0 8px 0 10px; color: var(--md-on-surface-variant); font-weight: 600; }
/* the dock button's dot: a lesson is under way in the closed dock (U27) */
#dockBtn .dot { position: absolute; top: 7px; right: 7px; width: 8px; height: 8px; border-radius: 50%; background: var(--md-primary); box-shadow: 0 0 0 2px var(--md-surface-low); }
/* The mode, always in view (U27): free play (a menu to start or resume learning), or the lesson
   under way (its name and step, and a button back to free play). It is the one part of the bar
   that gives way: its text shortens before anything else. */
.mode { display: flex; min-width: 0; margin-left: 12px; }
.mode .chip { min-width: 0; height: 34px; }
.mode .mode-label, .mode .mode-long { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mode .mode-long { max-width: 34ch; }
.mode .mode-short { display: none; white-space: nowrap; }
.mode-free { color: var(--md-on-surface); }
.mode .chip.course { flex: 0 1 auto; background: var(--md-primary-container); color: var(--md-on-primary-container); border-color: transparent; }
.mode #modeLeave { flex: none; color: var(--md-on-surface); }

/* ---- workspace: the machine area and the dock ------------------------------------------------------ */
.workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--dock-w);
  min-height: 0;
}
.workspace.dock-closed { grid-template-columns: minmax(0, 1fr) 0; }
.workspace.dock-closed .dock { display: none; }
.machine-area { display: grid; grid-template-rows: minmax(0, 1fr); min-width: 0; min-height: 0; }

/* the 3D stage */
.stage {
  position: relative;
  container: stage / inline-size;
  min-height: 0;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 50% 38%, #2a3747 0%, #18212c 55%, #0d1116 100%);
}
.stage canvas { display: block; width: 100%; height: 100%; touch-action: none; }
/* While a lesson is under way, a slim frame in the lesson chip's blue runs round the inside of
   the 3D view (U27): a shape, not a change of colour, so the scene and its lighting stay as they
   are, and colour-blind readers see it too. */
.stage::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid color-mix(in srgb, var(--md-primary) 70%, transparent);
  box-shadow: inset 0 0 18px color-mix(in srgb, var(--md-primary-container) 85%, transparent);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}
.stage.in-lesson::after { opacity: 1; }
/* the 3D view takes the keyboard's focus (U24): its ring sits just inside the stage */
.stage canvas:focus-visible { outline: 2px solid var(--md-primary); outline-offset: -3px; }
/* zoom out and in, one joined pair of chips (U24) */
.chip-pair { display: inline-flex; }
.chip-pair .chip { padding: 0 7px; }
.chip-pair .chip:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.chip-pair .chip:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: -1px; }
.stage-top {
  position: absolute;
  left: 12px;
  right: 12px;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  pointer-events: none;
}
.stage-top { top: 12px; }
.stage-top > * { pointer-events: auto; }
/* the machine's toolbar floats at the stage's bottom, centred under the machine (U18) */
.stage-bottom {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 12px;
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.stage-bottom > * { pointer-events: auto; }
.stage .grow { flex: 1; pointer-events: none; }
.tools { display: flex; flex-wrap: wrap; gap: 6px; }
/* the view menu's button names the view on show (U15) */
.stage-top .tools { flex: none; flex-wrap: nowrap; }
.view-btn { padding-right: 6px; }
.view-btn .txt { max-width: 18ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip:not(.view-btn):not(:has(.txt)) { padding: 0 7px; }

/* readouts (the machine's state, as on the machine) */
.readouts { display: flex; flex-wrap: wrap; gap: 8px; }
.readout {
  display: flex;
  flex-direction: column;
  padding: 6px 12px 7px;
  border-radius: var(--radius-m);
  background: color-mix(in srgb, var(--md-surface) 74%, transparent);
  backdrop-filter: blur(6px);
  border: 1px solid var(--md-outline-variant);
  min-width: 64px;
}
.readout label { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--md-on-surface-variant); }
.readout output { font-size: 22px; font-weight: 560; line-height: 1.15; color: var(--md-on-surface); white-space: nowrap; }
.readout.result output { color: var(--md-primary); font-size: 24px; letter-spacing: 0.02em; }
.readout output.red { color: var(--red); }

/* loading */
.loader {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 14px;
  color: var(--md-on-surface-variant);
  pointer-events: none;
}
.loader .bar { width: 220px; height: 4px; border-radius: 2px; background: var(--md-surface-highest); overflow: hidden; }
.loader .bar > i { display: block; height: 100%; width: 0; background: var(--md-primary); transition: width 200ms linear; }

/* hover label and callouts */
.hover-label, .callout {
  position: absolute;
  padding: 6px 10px;
  border-radius: var(--radius-s);
  background: rgba(10, 14, 20, 0.92);
  color: #fff;
  font-size: 12.5px;
  pointer-events: none;
  white-space: nowrap;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}
.hover-label { transform: translate(14px, 14px); z-index: 3; }
.hover-label .hint { margin-top: 2px; color: var(--md-primary); font-size: 12px; }
.callout { transform: translate(-50%, calc(-100% - 12px)); border: 1px solid color-mix(in srgb, var(--md-primary) 55%, transparent); z-index: 2; }
.callout::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -6px;
  width: 10px;
  height: 10px;
  transform: translateX(-50%) rotate(45deg);
  background: rgba(10, 14, 20, 0.92);
  border-right: 1px solid color-mix(in srgb, var(--md-primary) 55%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--md-primary) 55%, transparent);
}
.callout .val, .hover-label .val {
  display: inline-block;
  margin-left: 8px;
  padding: 0 7px;
  border-radius: 6px;
  background: var(--md-primary);
  color: var(--md-on-primary);
  font-weight: 650;
}
.callout .val.red, .hover-label .val.red { background: var(--red); color: #3a0a04; }

/* ---- the machine's toolbar (U18) ------------------------------------------------------------------ */
.strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 8px 6px;
  max-width: 100%;
  padding: 12px 10px 8px;
  border: 1px solid var(--md-outline-variant);
  border-radius: var(--radius-l);
  background: var(--md-surface-low);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.4);
}
/* One control's two ways, joined and alike (U20): the crank forward and back (the carriage's
   left and right are joined to its place's box, below). Every machine operation is a tonal button: none looks like the default or the
   active one; a lesson marks the one it asks for (the glow, and its task line, U18). Reset, which
   clears the machine, is the one quiet text button, at the end (only the sound switch follows it, U29). */
.pair { display: inline-flex; align-items: stretch; gap: 2px; }
.pair > * { border-radius: 6px; }
.pair > :first-child { border-radius: var(--radius-full) 6px 6px var(--radius-full); }
.pair > :last-child { border-radius: 6px var(--radius-full) var(--radius-full) 6px; }
/* the crank's buttons: its turning icon and the sign of what the turn does, the same in every
   language (the words are in the tooltip and the accessible name) */
.btn .sym { font-size: 22px; font-weight: 600; line-height: 1; min-width: 0.6em; text-align: center; }
.strip .sep { width: 1px; height: 28px; background: var(--md-outline-variant); margin: 0 4px; }
/* the toolbar fits the stage's own width (U18): labels go as room runs out, short ones last */
@container stage (max-width: 700px) {
  .strip #resetBtn .txt { display: none; }
  .strip #resetBtn { padding: 0 10px; }
}
@container stage (max-width: 760px) {
  .strip { gap: 8px 4px; }
  .strip .sep { display: none; }
}
@container stage (max-width: 640px) {
  /* two rows on a phone: the number, the crank and the sound; then the carriage, the pin, reset */
  .strip #carriageGroup, .strip .split, .strip #resetBtn { order: 1; }
  .strip .btn .txt { display: none; }
  .strip .btn.has-icon { padding: 0 10px; }
  .strip .sep { display: none; }
}
.number-field, .field-group {
  position: relative;
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 12px;
  border: 1px solid var(--md-outline);
  border-radius: var(--radius-s);
  background: var(--md-surface);
}
.number-field:focus-within { border-color: var(--md-primary); box-shadow: inset 0 0 0 1px var(--md-primary); }
.number-field label, .field-group .field-label {
  /* Material's outlined field: the label sits on the border */
  position: absolute;
  left: 8px;
  top: -7px;
  padding: 0 4px;
  font-size: 11px;
  line-height: 12px;
  color: var(--md-on-surface-variant);
  background: var(--md-surface-low);
  white-space: nowrap;
  pointer-events: none;
}
.number-field:focus-within label { color: var(--md-primary); }
.number-field input {
  width: 9.5ch;
  border: 0;
  background: transparent;
  font-size: 18px;
  font-weight: 560;
  text-align: right;
  letter-spacing: 0.04em;
  outline: none;
}
.number-field.wanted { border-color: var(--attention); box-shadow: 0 0 0 2px var(--attention), 0 0 14px color-mix(in srgb, var(--attention) 45%, transparent); }
.number-field input[aria-disabled="true"] { color: color-mix(in srgb, var(--md-on-surface) 38%, transparent); }
/* the carriage's place: a value in its box, like the pin's hole (U21) */
.value-field { justify-content: center; min-width: 76px; padding: 0 12px; }
.carriage-place { min-width: 2ch; text-align: center; font-size: 18px; font-weight: 560; }
/* The pin's hole: a dropdown, boxed and named like the other settings (U22). What is set is a
   box with its name on the border; what is done is a button. */
.select-field { align-items: center; justify-content: space-between; gap: 6px; min-width: 78px; padding: 0 6px 0 14px; color: var(--md-on-surface); font: inherit; cursor: pointer; }
.select-field .select-value { font-size: 18px; font-weight: 560; min-width: 1ch; text-align: center; }
.select-field .icon { color: var(--md-on-surface-variant); }
.select-field:hover { border-color: var(--md-on-surface); background: color-mix(in srgb, var(--md-on-surface) 6%, var(--md-surface)); }
.select-field[aria-expanded="true"] { border-color: var(--md-primary); box-shadow: inset 0 0 0 1px var(--md-primary); }
.select-field[aria-expanded="true"] .field-label { color: var(--md-primary); }
.select-field[aria-disabled="true"] { opacity: 0.45; cursor: default; }
/* A value's box with the buttons that act on it joined to its edges, full height, one outer
   corner shape (U21, U23): the pin's box and Run to stop (→|), the carriage's place between
   its arrows. Icon-only buttons; their names are in their tooltips. */
.split { display: inline-flex; align-items: stretch; }
.split > * { border-radius: 0; }
.split > :first-child { border-radius: var(--radius-s) 0 0 var(--radius-s); }
.split > :last-child { border-radius: 0 var(--radius-s) var(--radius-s) 0; }
.split .btn { width: 38px; height: 40px; color: var(--md-on-secondary-container); }
.field-group.wanted:not([aria-disabled="true"]) { border-color: var(--attention); box-shadow: 0 0 0 2px var(--attention), 0 0 14px color-mix(in srgb, var(--attention) 45%, transparent); }

/* ---- dock ---------------------------------------------------------------------------------------- */
.dock {
  position: relative;
  container: dock / inline-size;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  min-width: 0;
  min-height: 0;
  /* Three levels (U5): the tab bar a band of its own, the body the darkest well the content
     sits in, the cards raised above it with a fine outline. */
  background: var(--md-surface);
  border-left: 1px solid var(--md-outline-variant);
}
/* the dock's resize handle (U17): its own edge; a grab pill shows on hover and focus beside the
   machine, and always below it (like a bottom sheet's) */
.dock-handle {
  position: absolute;
  z-index: 5;
  top: 0;
  bottom: 0;
  left: -7px;
  width: 14px;
  display: grid;
  place-items: center;
  cursor: col-resize;
  touch-action: none;
}
.dock-handle::before {
  content: "";
  width: 4px;
  height: 40px;
  border-radius: var(--radius-full);
  background: var(--md-outline);
  opacity: 0;
  transition: opacity 0.15s var(--ease), background-color 0.15s var(--ease);
}
.dock-handle:hover::before, body.resizing .dock-handle::before { opacity: 1; }
.dock-handle:focus-visible { outline: none; }
.dock-handle:focus-visible::before { opacity: 1; background: var(--md-primary); }
body.resizing { user-select: none; }
body.resizing-cols, body.resizing-cols * { cursor: col-resize !important; }
body.resizing-rows, body.resizing-rows * { cursor: row-resize !important; }
.tabs { display: flex; border-bottom: 1px solid var(--md-outline-variant); padding: 0 4px; background: var(--md-surface-high); }
.tab {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 6px 8px;
  border: 0;
  background: transparent;
  color: var(--md-on-surface-variant);
  font-size: 13px;
  font-weight: 560;
  cursor: pointer;
}
.tab:hover { color: var(--md-on-surface); }
.tab[aria-selected="true"] { color: var(--md-primary); }
.tab[aria-selected="true"]::after { content: ""; position: absolute; left: 22%; right: 22%; bottom: -1px; height: 3px; border-radius: 3px 3px 0 0; background: var(--md-primary); }
.tab .dot { position: absolute; top: 8px; right: calc(50% - 20px); width: 8px; height: 8px; border-radius: 50%; background: var(--md-primary); }
/* A wide dock lays each tab's icon beside its label, in a thinner bar, leaving more room for
   the panel (U25). It goes by the dock's own width, beside the machine or below it. */
@container dock (min-width: 470px) {
  .tab { flex-direction: row; justify-content: center; gap: 8px; padding: 11px 8px 10px; white-space: nowrap; }
  .tab .dot { position: static; flex: none; }
}
.panel { overflow-y: auto; min-height: 0; padding: 16px; scrollbar-gutter: stable; }
/* a wide dock centres its content at a reading width (U26) */
.panel > * { max-width: 960px; margin-inline: auto; }
.panel h2 { font-size: 20px; font-weight: 600; margin: 0 0 6px; line-height: 1.25; }
.panel h3 { font-size: 13px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--md-on-surface-variant); margin: 20px 0 8px; }
.panel p { margin: 0 0 12px; }
.lead { color: var(--md-on-surface-variant); }

/* cards and lists */
.card {
  padding: 16px;
  border: 1px solid var(--card-edge);
  border-radius: var(--radius-l);
  background: var(--md-surface-high);
  margin-bottom: 12px;
}
.card.hero { background: linear-gradient(135deg, #1b3655, #18222f); border: 1px solid color-mix(in srgb, var(--md-primary) 25%, transparent); }
.hero .btn.filled { margin-top: 4px; }
.chapters { margin: 6px 0 14px; padding: 0; list-style: none; counter-reset: ch; }
.chapters li { counter-increment: ch; display: flex; gap: 10px; align-items: center; padding: 4px 0; color: var(--md-on-surface-variant); }
.chapters li::before { content: counter(ch); display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--md-secondary-container); color: var(--md-on-secondary-container); font-size: 12px; font-weight: 700; flex: none; }
.howto { margin: 0; padding: 0; list-style: none; }
.howto li { display: flex; gap: 10px; padding: 5px 0; color: var(--md-on-surface-variant); }
.howto .icon { width: 18px; height: 18px; margin-top: 1px; color: var(--md-primary); }

.lesson-list { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; }
.lesson-item {
  position: relative;
  display: grid;
  grid-template-columns: 32px 1fr auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 12px 12px 14px;
  border: 1px solid var(--card-edge);
  border-radius: var(--radius-m);
  background: var(--md-surface-high);
  text-align: left;
  cursor: pointer;
  isolation: isolate;
}
.lesson-item::before { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--md-on-surface); opacity: 0; z-index: -1; }
.lesson-item:hover::before { opacity: var(--state-hover); }
.lesson-item:active::before { opacity: var(--state-press); }
.lesson-item .num { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; background: var(--md-secondary-container); color: var(--md-on-secondary-container); font-weight: 700; }
.lesson-item.done .num { background: var(--success-container); color: var(--on-success-container); }
.lesson-item b { display: block; font-weight: 620; margin-bottom: 2px; }
.lesson-item span { display: block; color: var(--md-on-surface-variant); font-size: 13px; }
.lesson-item small { color: var(--md-on-surface-variant); font-size: 12px; white-space: nowrap; }

.ref-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 2px; }
.ref-list a {
  display: grid;
  grid-template-columns: 1fr 18px;
  gap: 2px 10px;
  padding: 10px 12px;
  border-radius: var(--radius-m);
  color: var(--md-on-surface);
  text-decoration: none;
}
.ref-list a:hover { background: var(--md-surface-high); }
.ref-list b { font-weight: 600; color: var(--md-primary); }
.ref-list span { grid-column: 1; color: var(--md-on-surface-variant); font-size: 13px; }
.ref-list .icon { grid-row: 1 / span 2; grid-column: 2; width: 18px; height: 18px; color: var(--md-on-surface-variant); align-self: center; }
.ref-list em { font-style: normal; font-size: 12px; color: var(--md-outline); }

/* the step player */
.player { display: flex; flex-direction: column; gap: 12px; }
.player-head { display: flex; align-items: flex-start; gap: 8px; }
.player-head .titles { flex: 1; min-width: 0; }
.player-head .kicker { font-size: 12px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--md-primary); }
.player-head h2 { margin: 2px 0 0; }
.progress { display: flex; gap: 4px; }
.progress i { flex: 1; height: 4px; border-radius: 2px; background: var(--md-surface-highest); }
.progress i.done { background: color-mix(in srgb, var(--md-primary) 45%, var(--md-surface-highest)); }
.progress i.now { background: var(--md-primary); }
.step-meta { display: flex; justify-content: space-between; font-size: 12px; color: var(--md-on-surface-variant); }
/* A step is one card (U26): its picture, then its text and task line. The picture keeps its own
   shape, never letterboxed, with its credit under it. A wide dock sets the picture beside the
   text; a narrow one above it. */
.step-card { display: grid; gap: 14px; margin: 0; }
.step-body { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.figure { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.figure img { display: block; max-width: 100%; max-height: 240px; width: auto; height: auto; border-radius: var(--radius-m); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35); }
.figure figcaption { font-size: 12px; line-height: 1.4; color: var(--md-on-surface-variant); text-align: center; }
.step-text { font-size: 15.5px; line-height: 1.55; margin: 0; max-width: 68ch; }
@container dock (min-width: 640px) {
  .step-card.has-figure { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); align-items: start; gap: 20px; }
  .step-card.has-figure .figure img { max-height: 320px; }
}
.taskline {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--radius-m);
  background: var(--attention-container);
  color: var(--on-attention-container);
  font-weight: 560;
}
/* the controls the step asks for, right in the task line (U18) */
.taskline { flex-wrap: wrap; }
.taskline .task-controls { display: flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }
.taskline .btn { height: 32px; padding: 0 12px; }
.taskline .btn.has-icon { padding-left: 10px; }
.taskline .btn.icon-only { width: 32px; padding: 0; }
.taskline .btn[aria-disabled="true"] { opacity: 0.45; }
.taskline.ok { background: var(--success-container); color: var(--on-success-container); }
.taskline.watch { background: var(--md-surface-high); color: var(--md-on-surface-variant); }
.navrow { display: flex; gap: 8px; justify-content: space-between; align-items: center; margin-top: 4px; }
.finish-card { text-align: center; padding: 24px 16px; }
/* the card's own celebration icon, not the icons in its buttons */
.finish-card > .icon { width: 40px; height: 40px; margin: 0 auto 8px; color: var(--success); }

/* ---- status bar ------------------------------------------------------------------------------------- */
.statusbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  background: var(--md-surface-low);
  border-top: 1px solid var(--md-outline-variant);
  font-size: 12.5px;
  color: var(--md-on-surface-variant);
  min-width: 0;
}
.statusbar #status { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.statusbar #status.warn { color: var(--md-error); }

/* ---- menus, tooltips and dialogs -------------------------------------------------------------------- */
.menu {
  position: fixed;
  z-index: 20;
  min-width: 180px;
  max-height: 70vh;
  overflow-y: auto;
  padding: 6px 0;
  border-radius: var(--radius-s);
  background: var(--md-surface-highest);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}
.menu [role^="menuitem"] {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  height: 40px;
  padding: 0 14px;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.menu [role^="menuitem"]:hover, .menu [role^="menuitem"]:focus-visible { background: color-mix(in srgb, var(--md-on-surface) 14%, transparent); outline: none; }
.menu [aria-checked="true"] { color: var(--md-primary); font-weight: 620; }
.menu .check { width: 20px; }
.menu [role="menuitemcheckbox"][aria-checked="true"] { color: inherit; font-weight: inherit; }
.menu [role="menuitemcheckbox"] .icon { color: var(--md-primary); }
.menu-divider { margin: 6px 0; border-top: 1px solid var(--md-outline-variant); }
.menu-divider span { display: block; padding: 8px 14px 2px; color: var(--md-on-surface-variant); font-size: 11px; font-weight: 620; letter-spacing: 0.06em; text-transform: uppercase; }

.tooltip {
  position: fixed;
  z-index: 30;
  max-width: 280px;
  padding: 5px 9px;
  border-radius: 6px;
  background: var(--md-on-surface);
  color: var(--md-surface-low);
  font-size: 12px;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}

/* A dialog (About): a title band with its close button, as a dialog's title bar is, then the
   body, which scrolls while the band stays in reach. */
dialog {
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100dvh - 48px);
  padding: 0;
  border: 1px solid var(--card-edge);
  border-radius: var(--radius-l);
  overflow: hidden;
  background: var(--md-surface-mid);
  color: var(--md-on-surface);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.6);
}
dialog[open] { display: flex; flex-direction: column; }
dialog::backdrop { background: var(--md-scrim); }
.dialog-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 8px 6px 20px; background: var(--md-surface-high); border-bottom: 1px solid var(--md-outline-variant); }
.dialog-title { margin: 0; font-size: 16px; font-weight: 600; }
.dialog-close { color: var(--md-on-surface-variant); }
.dialog-body { min-height: 0; padding: 20px 24px 22px; overflow-y: auto; }
.dialog-name { margin: 0 0 4px !important; font-size: 22px; font-weight: 600; color: var(--md-on-surface) !important; }
.dialog-body h3 { margin: 18px 0 6px; font-size: 13px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--md-on-surface-variant); }
.dialog-body ul { margin: 0; padding-left: 18px; color: var(--md-on-surface-variant); }
.dialog-body p { color: var(--md-on-surface-variant); margin: 0 0 10px; }
.dialog-logo { width: 200px; height: auto; display: block; margin: 0 0 12px; }

/* ---- self-test panel (?selftest) --------------------------------------------------------------------- */
.selftest { margin: 12px 0; padding: 12px; border-radius: var(--radius-m); background: var(--md-surface-high); font-size: 12px; }
.selftest h2 { font-size: 14px; margin: 0 0 6px; }
.selftest .ok { color: var(--success); }
.selftest .bad { color: var(--md-error); }

/* ---- narrow or portrait: the regions stack (U1, P9) ------------------------------------------------------ */
@media (max-width: 899px), (orientation: portrait) {
  .workspace { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) var(--dock-h, 45%); }
  .workspace.dock-closed { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) 0; }
  .dock { border-left: 0; border-top: 1px solid var(--md-outline-variant); }
  .dock-handle { top: -9px; bottom: auto; left: 0; right: 0; width: auto; height: 18px; cursor: row-resize; }
  .dock-handle::before { width: 40px; height: 4px; opacity: 1; }
  .brand img { width: 48px; height: 25px; }
  .brand { font-size: 15px; }
}
@media (max-width: 599px) {
  .chip .txt { display: none; }
  .chip { padding: 0 8px; }
  /* the top bar on a phone (U27): the logo without the title, the language by its 文A alone,
     the lesson by its step alone (its name is in the dock's header) */
  .brand span { display: none; }
  .lang-btn > .icon:last-child, .lang-btn #langShort { display: none; }
  .lang-btn { width: 40px; padding: 0; }
  .mode { margin-left: 8px; }
  .mode .mode-long { display: none; }
  .mode .mode-short { display: inline; }
  .readout { padding: 4px 8px 5px; min-width: 0; }
  .readout output { font-size: 17px; }
  .readout.result output { font-size: 18px; }
  .brand span { font-size: 14px; }
  .panel { padding: 12px; }
}
/* the narrowest phones: the free-play chip keeps its words and its ▾, not its icon (U27) */
@media (max-width: 359px) {
  .mode-free > .icon:first-child { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* the machine's sound, on or off (U29): quiet, at the toolbar's end */
.strip .sound-btn { width: 36px; color: var(--md-on-surface-variant); }
.strip .sound-btn[aria-pressed="true"] { color: var(--md-outline); }
