/* QUIZ app 2.0: the player and the creator. Colors come from @basee/head's tokens, or from the
   theme picked in ⚙ (themes.js puts its tokens on <html>). */

:root {
  --surface-2: light-dark(#efeee9, #26262c);
  --hit: light-dark(#e3f4e9, #1b2e23);
  --miss: light-dark(#fbe9e1, #33221c);
  /* a thing about to be removed (dragged out of its card): red whatever the theme's warning color */
  --remove: light-dark(#c62828, #f05252);
  --remove-bg: color-mix(in srgb, var(--remove) 18%, var(--surface));
  --accent-fg: var(--bg);
  /* each mode's own color (play.tileModesColor "mode"): practice the theme's good-news green, a test
     its accent */
  --mode-practice: var(--ok);
  --mode-test: var(--accent);
  /* the main buttons (Test, Save…) and switches: the accent as it is, toned or soft (⚙ → Main buttons) */
  --primary-bg: var(--accent);
  --primary-line: var(--accent);
  --primary-fg: var(--accent-fg);
}
:root[data-buttons="toned"] {
  --primary-bg: oklch(from var(--accent) l calc(c * 0.55) h);
  --primary-line: var(--primary-bg);
}
:root[data-buttons="soft"] {
  --primary-bg: color-mix(in oklab, var(--accent) 16%, var(--surface));
  --primary-line: color-mix(in oklab, var(--accent) 45%, var(--surface));
  --primary-fg: var(--accent);
}
/* a theme gives the main colors; the right and wrong answers' backgrounds come from them */
:root[data-theme] {
  --hit: color-mix(in srgb, var(--ok) 16%, var(--surface));
  --miss: color-mix(in srgb, var(--warn) 16%, var(--surface));
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  line-height: 1.5;
}

.page {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 16px 64px;
}
.page-wide { max-width: 1100px; }

.head { margin-bottom: 24px; }
.head h1 { font-size: 1.8rem; }
.muted { color: var(--muted); }
.small { font-size: 0.85rem; }
.foot { margin-top: 24px; }
a { color: var(--accent); }

button {
  cursor: pointer;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 6px;
  padding: 8px 14px;
  transition: background-color 0.12s, border-color 0.12s, color 0.12s;
  &:disabled { cursor: default; opacity: 0.5; }
}
/* hover (⚙ → Look → Hover, themes.js puts it on <html data-hover>): a button goes a step toward the
   text's color, lighter on dark themes and darker on light ones. :where keeps these rules as weak
   as `button`, so a button with a look of its own (.icon, .answer…) keeps its own. */
:where(:root[data-hover="shade"]) button:where(:hover:not(:disabled)) {
  background: color-mix(in oklab, var(--surface) 88%, var(--text));
  border-color: color-mix(in oklab, var(--line) 70%, var(--text));
}
:where(:root[data-hover="shade"]) :is(.primary, .danger):where(:hover:not(:disabled)) {
  filter: brightness(1.12) saturate(1.05);
}
:where(:root[data-hover="shade"]) .link:where(:hover:not(:disabled)) { text-decoration: underline; }
.primary {
  background: var(--primary-bg);
  border-color: var(--primary-line);
  color: var(--primary-fg);
  font-weight: 600;
}
.link {
  border: 0;
  background: none;
  padding: 0;
  color: var(--accent);
}
.icon {
  border: 0;
  background: none;
  padding: 4px 8px;
  color: var(--muted);
  &:hover:not(:disabled) { color: var(--warn); }
}
.wide { width: 100%; }
.actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
.error {
  margin-top: 16px;
  padding: 10px 12px;
  border-radius: 6px;
  background: var(--miss);
  color: var(--warn);
}

/* ————————————————————————— the player */

.quiz-list { display: grid; gap: 8px; }
/* the quizzes as tiles (2026-10-31): a grid of pictures, each its icon on its category's hue where it has
   no image; the groups by category under their names */
.quiz-group { margin: 0 0 18px; }
.group-name { margin: 6px 0 8px; font-size: 1.05rem; }
.quiz-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.quiz-tile {
  position: relative;
  /* its width, for the row over its picture's lower edge (100cqw) */
  container-type: inline-size;
  display: grid;
  grid-template-rows: 1fr auto;
  border-radius: 6px;
  background: var(--surface);
  &:hover, &:focus-within { background: var(--surface-2); }
}
.tile-open {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 6px;
  padding: 8px 8px 10px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--text);
  text-align: left;
  font: inherit;
}
/* a tile's mode buttons (play.tileModes): on its picture's two top corners (the first left, the last
   right), together in its top right corner, or a row under its title; the last (the test) in the
   main color */
.tile-modes {
  display: flex;
  gap: 4px;
  &.at-art { position: absolute; top: 14px; right: 14px; }
  /* one row along the picture's lower edge (the picture: 8px in, 4:3 of the tile's width less 16px) */
  &.at-row { position: absolute; left: 14px; right: 14px; top: calc(8px + (100cqw - 16px) * 0.75 - 36px); align-items: center; pointer-events: none; > * { pointer-events: auto; } }
  &.at-corners { position: absolute; top: 14px; left: 14px; right: 14px; justify-content: space-between; pointer-events: none; > * { pointer-events: auto; } }
  &.at-below { padding: 0 8px 10px; }
  &.at-below.labeled .tile-mode { flex: 1; }
}
.tile-mode {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 30px;
  height: 30px;
  padding: 0 6px;
  border-radius: 6px;
  font-size: 0.8rem;
  :is(.at-art, .at-corners, .at-row) & { background: color-mix(in oklab, var(--surface) 82%, transparent); box-shadow: 0 1px 4px rgb(0 0 0 / 0.25); }
  :is(.at-art, .at-corners, .at-row) &.primary, &.primary { background: var(--primary-bg); color: var(--primary-fg); }
  :is(.at-art, .at-corners, .at-row) &:hover { background: var(--surface); }
  :is(.at-art, .at-corners, .at-row) &.primary:hover { background: var(--primary-bg); filter: brightness(1.1); }
}
/* the mode buttons' colors (play.tileModesColor): "main" as above; "neutral" the test plain too;
   "tile" in the tile's hue (its tone, on the tile), the last stronger; "mode" each mode its own */
.tile-modes.colors-neutral .tile-mode.primary { background: color-mix(in oklab, var(--surface) 82%, transparent); color: var(--text); }
.tile-modes.at-below.colors-neutral .tile-mode.primary { background: var(--surface-2); }
.tile-modes.colors-tile .tile-mode { background: light-dark(oklch(0.97 0.025 var(--hue)), oklch(0.24 0.04 var(--hue))); color: light-dark(oklch(0.42 0.1 var(--hue)), oklch(0.86 0.07 var(--hue))); }
.tile-modes.colors-tile .tile-mode.primary { background: light-dark(oklch(0.5 0.12 var(--hue)), oklch(0.78 0.1 var(--hue))); color: var(--bg); }
.tile-modes.colors-mode .tile-mode { background: var(--surface-2); color: var(--text); }
.tile-modes.colors-mode .tile-mode.mode-practice { background: var(--mode-practice); color: var(--bg); }
.tile-modes.colors-mode .tile-mode.mode-test { background: var(--mode-test); color: var(--bg); }
.tile-modes:is(.colors-tile, .colors-mode) .tile-mode:hover { filter: brightness(1.12); }

/* a mode's name beside its icon: with play.tileModes "labels", on a touch screen with
   play.tileModesTouch "labels", and on a button tapped once (armed: its name, waiting for the second tap) */
.tile-mode .mode-name { display: none; }
.tile-modes.labeled .mode-name, .tile-mode.armed .mode-name { display: inline; }
@media (pointer: coarse) { .tile-modes.touch-labels .mode-name { display: inline; } }
.tile-mode.armed { position: relative; z-index: 1; padding: 0 10px 0 8px; outline: 2px solid var(--accent); outline-offset: 1px; font-weight: 600; animation: arm-in 140ms ease-out; }
@keyframes arm-in { from { transform: scale(0.9); } }
@media (prefers-reduced-motion: reduce) { .tile-mode.armed { animation: none; } }
.mode-icon { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; font-weight: 700; line-height: 18px; text-align: center; }
.tile-art {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 4px;
  background: light-dark(oklch(0.91 0.04 var(--hue)), oklch(0.33 0.05 var(--hue)));
  img { width: 100%; height: 100%; object-fit: cover; }
}
/* the tiles' tones: hues that sit together in both themes (blue, violet, teal, coral, green, rose,
   sky, indigo), at one lightness and a calm chroma; no yellows, which go muddy when dark */
.tone-0 { --hue: 255; }
.tone-1 { --hue: 300; }
.tone-2 { --hue: 190; }
.tone-3 { --hue: 30; }
.tone-4 { --hue: 155; }
.tone-5 { --hue: 345; }
.tone-6 { --hue: 225; }
.tone-7 { --hue: 275; }
.tile-icon { font-size: 2.6rem; line-height: 1; color: light-dark(oklch(0.42 0.08 var(--hue)), oklch(0.86 0.05 var(--hue))); }
.tile-title { font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
.tile-meta { line-height: 1.2; }
/* a narrow tile (a phone's two columns): the row's pieces smaller, so the modes, the 🔥 and the level
   fit side by side */
@container (max-width: 190px) {
  .tile-modes.at-row { left: 12px; right: 12px; top: calc(8px + (100cqw - 16px) * 0.75 - 32px); gap: 3px; }
  .tile-modes.at-row .tile-mode { min-width: 26px; height: 26px; padding: 0 4px; }
  .tile-modes.at-row .mode-icon { width: 16px; height: 16px; }
  .tile-badges { gap: 3px; > * { height: 26px; } > .tile-hard { padding: 0 4px; font-size: 0.8rem; } > .level { padding: 0 5px; } > .level-bars > i { width: 3px; margin-bottom: 7px; } }
}
/* with the row over the picture's lower edge, an icon (not an image) stands in the space above it */
.quiz-tile:has(.tile-modes.at-row) .tile-art:not(.picture) { padding-bottom: 34px; box-sizing: border-box; }
/* the 🔥 and the level at the row's other end (play.tileModesAt "row"), as high as the buttons */
.tile-badges {
  display: inline-flex;
  gap: 4px;
  margin-left: auto;
  > * { box-sizing: border-box; height: 30px; display: inline-flex; align-items: center; border-radius: 6px; background: color-mix(in oklab, var(--surface) 82%, transparent); box-shadow: 0 1px 4px rgb(0 0 0 / 0.25); }
  > .tile-hard { position: static; padding: 0 6px; background: color-mix(in srgb, var(--warn) 30%, var(--surface)); }
  > .level { padding: 0 7px; align-items: center; > i { align-self: center; } }
  > .level-bars > i { align-self: flex-end; margin-bottom: 8px; }
}
/* a quiz's level (play.levelLook): five marks, the first `level` lit in its color (green → red through
   the levels, in OKLCH), on the picture's lower right corner; in the details by the text */
.level {
  --level-color: color-mix(in oklch, var(--warn) calc(var(--level) * 100%), var(--ok));
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
  padding: 4px 5px;
  border-radius: 4px;
  > i { display: block; background: color-mix(in oklab, var(--text) 22%, transparent); }
  > i.on { background: var(--level-color); }
  .tile-art & { position: absolute; right: 6px; bottom: 6px; background: color-mix(in oklab, var(--surface) 82%, transparent); }
  .level-name { margin-left: 6px; align-self: center; font-size: 0.85rem; color: var(--level-color); font-weight: 600; }
}
.level-bars > i { width: 4px; height: calc(5px + var(--i) * 2.5px); border-radius: 1px; }
.level-dots { align-items: center; gap: 3px; > i { width: 6px; height: 6px; border-radius: 50%; } }
.quiz-details .level { justify-self: start; padding: 0; }
/* hard mode on for a tile (its 🔥 in the details): a warm edge, a 🔥 on the picture, the 🔥 lit */
.quiz-tile.hard-on { box-shadow: inset 0 0 0 2px var(--warn); }
.tile-hard { position: absolute; bottom: 6px; left: 6px; padding: 2px 6px; border-radius: 6px; background: color-mix(in srgb, var(--warn) 30%, var(--surface)); font-size: 0.9rem; line-height: 1.4; }
.tile-flame { filter: grayscale(1); opacity: 0.6; &.on { filter: none; opacity: 1; } }
.library.quiz-details {
  /* centered without a transform: the motion moves it with one */
  left: 0;
  right: 0;
  margin: 0 auto;
  transform: none;
  transform-origin: top left;
  width: min(520px, 100vw - 32px);
  &:focus { outline: none; }
  /* the mode Space starts: marked whether the focus came by a key or by a click */
  .modes button:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
  display: grid;
  gap: 10px;
  .tile-art { max-height: 200px; }
  .quiz-description { white-space: pre-line; margin: 0; }
  p { margin: 0; }
  .modes { flex-wrap: wrap; justify-content: flex-end; }
}
/* the free piano (15y): its tools over a keyboard of five octaves; the keys the computer's play
   underlined */
.free-piano {
  display: grid;
  gap: 8px;
  margin: 0 0 14px;
  padding: 10px;
  border-radius: 6px;
  background: var(--surface);
  .piano.free { height: 120px; }
  .key.reach.white { box-shadow: inset 0 -4px 0 color-mix(in oklab, var(--accent) 55%, transparent); }
  .key.reach.black { box-shadow: inset 0 -3px 0 color-mix(in oklab, var(--accent) 70%, transparent); }
  .hint { margin: 0; }
}
.free-piano-top { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; > .icon:last-child { margin-left: auto; } }
.free-piano-octave { display: inline-flex; align-items: center; gap: 4px; }
.free-piano-pedal.on { background: color-mix(in oklab, var(--accent) 22%, var(--surface-2)); color: var(--accent); }
.free-piano-midi { display: inline-flex; align-items: center; gap: 6px; > input { width: 4em; } }
/* the list's order (play.listSort): the orders side by side, the one on in the accent */
.list-sort {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin: 0 0 8px;
  > span { margin-right: 4px; }
  .sort-by { padding: 3px 10px; font-size: 0.85rem; }
  /* the admin's "as a player" switch at the bar's far end, apart from the orders */
  .as-player { margin-left: auto; }
  .sort-by.on { background: color-mix(in oklab, var(--accent) 22%, var(--surface-2)); color: var(--accent); }
}
.quiz-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
}
.quiz-cover { flex: none; width: 96px; height: 72px; object-fit: cover; border-radius: 6px; }
.quiz-card-text { flex: 1 1 160px; min-width: 0; }
.q-image.cover img { max-height: 140px; }
.list-fields { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 8px; .category-field { flex: 1 1 200px; } .icon-field { flex: 0 0 6em; text-align: center; } }
.level-pick { display: inline-flex; align-items: center; gap: 2px; > .muted { margin-right: 4px; } button { min-width: 28px; padding: 3px 6px; } button.on { background: color-mix(in oklab, var(--accent) 22%, var(--surface-2)); color: var(--accent); } }
.q-image img[data-act], .q-image img[data-dblact] { cursor: pointer; }
.q-image .icon.replace { right: 36px; }
.quiz-title { font-weight: 600; }
.quiz-description { white-space: pre-line; margin: 2px 0 4px; }
.modes { display: flex; gap: 8px; }

.chip {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: 4px;
  font-size: 0.8rem;
  font-weight: 600;
  background: var(--surface-2);
  color: var(--text);
  &.chip-test { background: var(--primary-bg); color: var(--primary-fg); }
}

.progress {
  height: 6px;
  margin: 8px 0;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}
.progress-fill { height: 100%; background: var(--accent); transition: width 0.3s; }

.question { font-size: 1.4rem; margin-bottom: 20px; }
.q-image-play { display: block; max-width: 100%; max-height: 50vh; margin: 8px 0 16px; border-radius: 8px; }
/* the question on one screen (tweak play.fit; play.js sizes the image): tighter around it, the button
   kept at the window's bottom when the page still has to scroll */
.page:has(.q-layout:not([data-fit="scroll"])) {
  padding-top: 16px;
  padding-bottom: 16px;
  .head { margin-bottom: 12px; }
  .question { margin-bottom: 12px; }
  .q-image-play { margin: 0 0 12px; }
  .answers { gap: 6px; }
  .answer { padding: 8px 12px; }
  .actions { position: sticky; bottom: 0; z-index: 2; margin-top: 14px; padding: 8px 0; background: var(--bg); }
  .hint { margin-top: 4px; }
}
/* beside: the image on the left, the question and its answers on the right, where the window is wide
   (the same width as SIDE in play.js) */
@media (min-width: 900px) and (orientation: landscape) {
  .page:has(.q-layout.has-image[data-fit="side"]) { max-width: 1240px; }
  .q-layout.has-image[data-fit="side"] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 24px;
    align-items: start;
    .q-media { position: sticky; top: 16px; }
    .q-image-play { width: 100%; height: auto; object-fit: contain; margin: 0; }
  }
}
.review-image { display: block; max-width: 100%; max-height: 160px; margin: 6px 0; border-radius: 6px; }
.answers { display: grid; gap: 8px; }
/* an answer with its own clip (step 13): ▶ beside it */
.answer-line { display: flex; gap: 6px; > .answer { flex: 1; min-width: 0; } }
.answer-play {
  flex: none;
  min-width: 44px;
  padding: 0 12px;
  &.on { border-color: var(--accent); color: var(--accent); }
  &.small { min-width: 0; padding: 0 8px; font-size: 0.8rem; }
}
.answer {
  display: flex;
  align-items: center;
  gap: 12px;
  text-align: left;
  padding: 12px 14px;
  &:hover { border-color: var(--accent); }
  &.picked { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, var(--surface)); }
  &.right { border-color: var(--ok); background: var(--hit); opacity: 1; }
  &.wrong { border-color: var(--warn); background: var(--miss); opacity: 1; }
  &:disabled:not(.right, .wrong) { opacity: 0.5; }
}
/* an answer in parts (15t): each part its name over its answers */
.parts { display: grid; gap: 12px; }
.part { display: grid; gap: 4px; }
.part-name { text-transform: lowercase; }
/* answered, with tones of their own (15m): each answer plays on a click, to compare; the rest stay
   a little quieter than the right and the wrong one */
.answers.compare .answer {
  cursor: pointer;
  &:not(.right, .wrong) { opacity: 0.75; }
  &:hover { opacity: 1; border-color: var(--accent); }
}
/* answers at their places in a grid (15l, a question's `grid`): short cells, the text centered, the
   dark ones (a keyboard's black keys) a shade deeper; an empty place stays empty */
.answers.grid {
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  gap: 6px;
  .answer {
    justify-content: center;
    text-align: center;
    padding: 10px 4px;
    min-height: 3.2em;
    line-height: 1.2;
    overflow-wrap: anywhere;
  }
  .answer.dark:not(.picked, .right, .wrong) { background: color-mix(in oklab, var(--text) 14%, var(--surface)); }
  /* a place only shown (15z): what the pool leaves out, dimmed and quiet */
  .answer.ghost { opacity: 0.32; cursor: default; pointer-events: none; }
}
/* the player's history with the quiz (15p): a badge for the first time or a new best */
.history { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: center; margin: 6px 0 0; }
.history-badge { padding: 2px 8px; border-radius: 4px; background: var(--surface-2); font-weight: 600; font-size: 0.85rem; &.best { background: var(--hit); color: var(--ok); } }
/* what the attempt says (15o): to practice, the mix-ups, and the run, a row per topic and a cell per
   question, right in ok, partly in the accent, wrong in warn */
.summary {
  display: grid;
  gap: 14px;
  margin: 16px 0;
  h3 { margin: 0 0 6px; font-size: 0.95rem; }
  ul { margin: 0; padding-left: 18px; }
}
.summary-run {
  display: grid;
  grid-template-columns: minmax(6em, max-content) repeat(var(--run), minmax(8px, 1fr));
  gap: 2px;
  align-items: center;
  font-size: 0.8rem;
  .run-name { padding-right: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 14em; }
  .run-cell { height: 12px; border-radius: 3px; background: var(--surface-2); }
  .run-cell.ok { background: var(--ok); }
  .run-cell.partly { background: var(--accent); }
  .run-cell.miss { background: var(--warn); }
  /* each question's time (a bar against the slowest) and its sound's plays (15w) */
  .run-time { height: 22px; display: flex; align-items: flex-end; > i { display: block; width: 100%; min-height: 2px; border-radius: 2px; background: var(--muted); } }
  .run-heard { text-align: center; color: var(--muted); }
}
/* a near miss, said under the feedback (15n): "Hit 1 of 2", "Right name, wrong octave" */
.feedback-detail { margin: 6px 0 0; color: var(--warn); font-weight: 600; }
.feedback {
  margin-top: 14px;
  padding: 10px 12px;
  border-radius: 6px;
  font-weight: 600;
  &.feedback-right { background: var(--hit); color: var(--ok); }
  &.feedback-wrong { background: var(--miss); color: var(--warn); }
}
.letter {
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--surface-2);
  font-weight: 700;
  .picked & { background: var(--accent); color: var(--accent-fg); }
}
.hint { margin-top: 12px; font-size: 0.85rem; }
/* a slider's question on the middle line (tweak play.numberCenter) */
.q-body.centered {
  > .actions { justify-content: center; }
  > .hint { text-align: center; }
  .number-key { justify-self: center; text-align: center; }
}
.multi-hint { margin: -12px 0 12px; }
/* several right (tweak play.multipleLook): a banner above the answers, a box to tick on each, in a
   color of their own (play.js sets --multi and --multi-fg: tweaks play.multipleColor and
   play.multipleStrength) */
.multi-banner, .answers.loud { --multi: var(--accent); --multi-fg: var(--accent-fg); }
.multi-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: -6px 0 14px;
  padding: 8px 12px;
  border: 1px solid var(--multi);
  border-left-width: 4px;
  border-radius: 6px;
  background: color-mix(in oklab, var(--multi) 10%, var(--surface));
  font-weight: 600;
  .multi-icon { flex: none; display: inline-flex; gap: 2px; color: var(--multi); }
  .multi-icon svg { width: 1.15em; height: 1.15em; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
}
/* how it comes in (tweak play.multipleIntro): a flash of light around it, or sliding in */
.multi-banner.intro-flash { animation: multi-flash 1s ease-out; }
.multi-banner.intro-slide { animation: multi-slide 0.35s ease-out; }
@keyframes multi-flash {
  /* never through its opacity: a banner caught mid-way (a paused page) is still there to read */
  0% { transform: translateY(-4px) scale(0.985); box-shadow: 0 0 0 0 color-mix(in oklab, var(--multi) 70%, transparent); }
  25% { transform: none; box-shadow: 0 0 0 5px color-mix(in oklab, var(--multi) 40%, transparent), 0 0 26px color-mix(in oklab, var(--multi) 65%, transparent); background: color-mix(in oklab, var(--multi) 34%, var(--surface)); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@keyframes multi-slide { from { transform: translateY(-8px); } }
/* the banner's two boxes pop in one after the other and their ticks are drawn (tweak play.multipleIcon) */
.multi-icon.icon-stagger svg { animation: box-pop 0.4s cubic-bezier(0.34, 1.7, 0.64, 1) both; animation-delay: calc(var(--i, 0) * 130ms + 120ms); }
.multi-icon.icon-stagger path { stroke-dasharray: 16; animation: check-draw 0.3s ease-out both; animation-delay: calc(var(--i, 0) * 130ms + 320ms); }
@keyframes box-pop { from { transform: scale(0.3) rotate(-20deg); } }
@keyframes check-draw { from { stroke-dashoffset: 16; } to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) { .multi-banner, .multi-icon svg, .multi-icon path { animation: none !important; } }
.answers.loud .answer {
  &:hover { border-color: var(--multi); }
  &.picked { border-color: var(--multi); background: color-mix(in oklab, var(--multi) 11%, var(--surface)); }
  &.picked .letter { background: var(--multi); color: var(--multi-fg); }
}
.answers.loud .answer .tick {
  flex: none;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin-left: auto;
  border: 2px solid var(--line);
  border-radius: 5px;
  font-weight: 800;
  line-height: 1;
}
.answers.loud .answer.picked .tick { border-color: var(--multi); background: var(--multi); color: var(--multi-fg); }
/* the boxes pop in one after another, top to bottom (tweak play.multipleTicks), once per question;
   from small, never from nothing, so a page caught mid-way still shows them */
.answers.loud.ticks-stagger .tick { animation: tick-in 0.42s cubic-bezier(0.34, 1.7, 0.64, 1) both; animation-delay: calc(var(--i, 0) * 75ms + 180ms); }
@keyframes tick-in {
  0% { transform: scale(0.25) rotate(-25deg); border-color: var(--multi); box-shadow: 0 0 0 0 color-mix(in oklab, var(--multi) 60%, transparent); }
  60% { box-shadow: 0 0 0 5px color-mix(in oklab, var(--multi) 0%, transparent); }
  100% { transform: none; }
}
@media (prefers-reduced-motion: reduce) { .answers.loud .tick { animation: none !important; } }
.ticked { font-weight: 400; opacity: 0.85; }
.answered-note { margin: 10px 0 0; }
.answers.multi .letter { border-radius: 6px; }

.score { font-size: 3.5rem; font-weight: 800; line-height: 1.1; }
.review { display: grid; gap: 10px; }
.review-card {
  padding: 12px 14px;
  border-radius: 8px;
  background: var(--surface);
  border-left: 4px solid var(--line);
  &.hit { border-left-color: var(--ok); }
  &.part { border-left-color: var(--accent); }
  &.miss { border-left-color: var(--warn); }
}
.review-head { font-size: 0.9rem; }
/* the compact review of an ear quiz (tweak play.generatedReview): a line a question, in two columns
   where there is room; its mark on the left edge as a card's */
.review-rows {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2 300px;
  column-gap: 10px;
}
.review-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 6px;
  break-inside: avoid;
  margin: 0 0 4px;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--surface);
  border-left: 3px solid var(--line);
  &.hit { border-left-color: var(--ok); }
  &.part { border-left-color: var(--accent); }
  &.miss { border-left-color: var(--warn); }
  .row-n { min-width: 2.2em; text-align: right; font-variant-numeric: tabular-nums; }
  .row-right { font-weight: 600; }
  .row-mine { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }
}
.row-play, .row-play-gap { width: 26px; height: 24px; flex: none; }
.row-play { padding: 0; font-size: 0.75rem; border-radius: 4px; &.on { color: var(--accent); } }
.review-fold { margin: 4px 0 0; }
.review-question { font-weight: 600; margin: 4px 0 8px; }
.review-mine { margin: 0 0 8px; }
/* the AI's grade and reason (step 7) */
.ai-why { margin: 8px 0 0; padding: 8px 12px; border-radius: 6px; background: var(--surface-2); }
/* the AI is checking a typed answer (practice) or the test's answers before the result: a line in
   the accent, its icon breathing and three dots going round */
.ai-checking {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 0 0;
  padding: 10px 12px;
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 12%, var(--surface));
  font-weight: 600;
}
.ai-checking-icon { display: inline-block; animation: ai-breathe 1.2s ease-in-out infinite; }
.ai-dots { display: inline-flex; gap: 3px; margin-left: 2px; > i { width: 5px; height: 5px; border-radius: 50%; background: currentColor; animation: ai-dot 1s ease-in-out infinite; } > i:nth-child(2) { animation-delay: 0.15s; } > i:nth-child(3) { animation-delay: 0.3s; } }
@keyframes ai-breathe { 50% { transform: scale(1.15); } }
@keyframes ai-dot { 0%, 100% { opacity: 0.25; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .ai-checking-icon, .ai-dots > i { animation: none; opacity: 1; } }
.review-ai, .grades-ai { margin: 4px 0 0; }
.grades-ai-ask { margin: 8px 0 0; padding: 8px 12px; border-radius: 6px; background: var(--surface-2); > p { margin: 0 0 6px; } }
.ai-tag { margin-left: 6px; padding: 0 7px; border-radius: 999px; border: 1px solid var(--line); font-size: 0.75rem; color: var(--muted); }
/* a typed answer (step 6): the field, marked once checked, and the right answer under it */
.typed-answer {
  width: 100%;
  padding: 12px 14px;
  font-size: 1.1rem;
  &.right { border-color: var(--ok); background: var(--hit); }
  &.wrong { border-color: var(--warn); background: var(--miss); }
}
.review-typed { margin: 0; .mark { margin-right: 6px; } }
/* a number (step 17): on a slider, the number it stands at large over it (or riding over its knob),
   a dash until moved; its ends under it; or in a field with its unit */
.number-answer { display: grid; gap: 6px; margin: 4px 0 0; }
.number-answer.slider {
  --thumb: 30px;
  --rail: 10px;
  --fill: var(--accent);
  /* the knob's middle, from its left end (the knob stays inside the track) */
  --knob: calc(var(--thumb) / 2 + var(--at) * (100% - var(--thumb)));
  gap: 4px;
  padding: 4px 8px 0;
  &.right { --fill: var(--ok); }
  &.wrong { --fill: var(--warn); }
  /* a tall input: the whole band around the rail takes the pointer, not just the thin line */
  input[type="range"] {
    appearance: none;
    display: block;
    width: 100%;
    height: 44px;
    margin: 0;
    background: transparent;
    cursor: pointer;
    touch-action: none;
    &:disabled { cursor: default; }
    &:focus-visible { outline: none; }
  }
  input[type="range"]::-webkit-slider-runnable-track {
    height: var(--rail);
    border-radius: calc(var(--rail) / 2);
    background: linear-gradient(to right, var(--fill) 0 var(--knob), var(--surface-2) var(--knob));
  }
  input[type="range"]::-moz-range-track { height: var(--rail); border-radius: calc(var(--rail) / 2); background: var(--surface-2); }
  input[type="range"]::-moz-range-progress { height: var(--rail); border-radius: calc(var(--rail) / 2); background: var(--fill); }
  input[type="range"]::-webkit-slider-thumb {
    appearance: none;
    width: var(--thumb);
    height: var(--thumb);
    margin-top: calc((var(--rail) - var(--thumb)) / 2);
    border: none;
    border-radius: 50%;
    background: var(--fill);
    box-shadow: 0 2px 8px rgb(0 0 0 / 0.45);
    transition: transform 100ms, box-shadow 100ms;
  }
  input[type="range"]::-moz-range-thumb {
    width: var(--thumb);
    height: var(--thumb);
    border: none;
    border-radius: 50%;
    background: var(--fill);
    box-shadow: 0 2px 8px rgb(0 0 0 / 0.45);
    transition: transform 100ms, box-shadow 100ms;
  }
  input[type="range"]:not(:disabled):hover::-webkit-slider-thumb { transform: scale(1.08); }
  input[type="range"]:not(:disabled):hover::-moz-range-thumb { transform: scale(1.08); }
  input[type="range"]:not(:disabled):active::-webkit-slider-thumb { transform: scale(1.18); }
  input[type="range"]:not(:disabled):active::-moz-range-thumb { transform: scale(1.18); }
  input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: 0 2px 8px rgb(0 0 0 / 0.45), 0 0 0 5px color-mix(in oklab, var(--fill) 35%, transparent); }
  input[type="range"]:focus-visible::-moz-range-thumb { box-shadow: 0 2px 8px rgb(0 0 0 / 0.45), 0 0 0 5px color-mix(in oklab, var(--fill) 35%, transparent); }
  /* not moved yet: the rail without its fill */
  &.untouched input[type="range"]::-webkit-slider-runnable-track { background: var(--surface-2); }
  &.untouched input[type="range"]::-moz-range-progress { background: transparent; }
}
/* the number large over the slider, as in 1.0; its unit smaller beside it */
.number-readout {
  justify-self: center;
  margin-bottom: 4px;
  font-size: 2.75rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  .right & { color: var(--ok); }
  .wrong & { color: var(--warn); }
  .untouched & { color: var(--muted); font-weight: 400; }
}
.number-unit {
  margin-left: 0.3em;
  font-size: 0.5em;
  font-weight: 500;
  color: var(--muted);
  &.tight { margin-left: 0; }
}
.number-hint { color: var(--muted); }
.number-answer.knob .number-track { padding-top: 46px; }
.number-track { position: relative; }
.number-value {
  position: absolute;
  top: 0;
  left: var(--knob);
  /* over the knob, sliding to stay inside at the ends */
  translate: calc(-1 * var(--at) * 100%) 0;
  padding: 3px 12px;
  border-radius: 6px;
  background: var(--fill);
  color: var(--accent-fg);
  font-size: 1.3rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  .untouched & { background: var(--surface-2); color: var(--muted); font-weight: 600; }
  > .number-unit { color: inherit; opacity: 0.8; }
}
.number-ends { display: flex; justify-content: space-between; }
.number-field { display: flex; align-items: center; gap: 8px; > input { max-width: 16em; } }
.number-key { margin: 4px 0 0; font-weight: 600; }
/* a piano keyboard (step 15c): white keys side by side, black ones over their gaps; the pressed key
   in the accent, after the answer the right ones in ok and a wrong one pressed in warn. The keys keep
   a piano's colors in every theme (the app's own roles) */
.piano {
  --key-white: oklch(96% 0.005 260);
  --key-black: oklch(24% 0.01 260);
  --key-given: oklch(70% 0.14 300);
  position: relative;
  height: 150px;
  margin: 4px 0 0;
  user-select: none;
  touch-action: manipulation;
}
.key {
  position: absolute;
  top: 0;
  padding: 0;
  border: 1px solid oklch(55% 0.01 260);
  cursor: pointer;
  transition: background-color 80ms, transform 80ms;
  &.white {
    width: var(--white);
    height: 100%;
    border-radius: 0 0 5px 5px;
    background: var(--key-white);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    &:hover:not(:disabled) { background: color-mix(in oklab, var(--accent) 18%, var(--key-white)); }
  }
  &.black {
    z-index: 1;
    width: calc(var(--white) * 0.6);
    height: 62%;
    border-color: var(--key-black);
    border-radius: 0 0 4px 4px;
    background: var(--key-black);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    &:hover:not(:disabled) { background: color-mix(in oklab, var(--accent) 35%, var(--key-black)); }
  }
  /* a lit key: the note given (an interval's first, never mistaken for the pick), the pick, the right
     ones and a wrong one. Lit keys side by side stay apart: each keeps a dark line between it and the
     next and a light edge on its top left, and a black one is a darker shade of its color, so it stands
     out over lit white ones */
  &.given { --lit: var(--key-given); }
  &.picked { --lit: var(--accent); }
  &.right { --lit: var(--ok); }
  &.wrong { --lit: var(--warn); }
  &:is(.given, .picked, .right, .wrong) {
    background: var(--lit);
    border-color: color-mix(in oklab, var(--lit) 45%, var(--key-black));
    box-shadow: inset 2px 2px 0 color-mix(in oklab, white 45%, transparent);
    &:hover:not(:disabled) { background: color-mix(in oklab, var(--lit) 85%, white); }
    &.black {
      background: color-mix(in oklab, var(--lit) 62%, var(--key-black));
      border-color: var(--key-black);
      box-shadow: inset 1px 1px 0 color-mix(in oklab, white 30%, transparent);
      &:hover:not(:disabled) { background: color-mix(in oklab, var(--lit) 75%, var(--key-black)); }
    }
  }
  &:active:not(:disabled) { transform: translateY(1px); }
  /* a note the question never asks (15u): dimmed, not pressed */
  &.out { opacity: 0.35; cursor: default; }
  /* answered: the keys stay as bright as they were, so the lit ones read */
  &:disabled { cursor: default; opacity: 1; }
  &:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
}
.key-name { margin-bottom: 6px; font-size: 0.75rem; color: oklch(45% 0.01 260); pointer-events: none; .picked > &, .right > &, .wrong > & { color: var(--accent-fg); } }
/* an order (step 17): its items, dragged or moved with the keys; the picked one in the accent, and
   after the answer each marked in its place or not */
.order-answer { display: grid; gap: 4px; }
.order-end { margin: 0; }
.order-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.order-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  cursor: grab;
  user-select: none;
  touch-action: none;
  transition: background 120ms, border-color 120ms;
  &:hover:not(.off) { border-color: var(--accent); }
  &.picked { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, var(--surface)); }
  /* the dragged one rides over the others, which slide aside to make its place */
  .moving > & { transition: background 120ms, border-color 120ms, transform var(--order-ms) var(--order-easing); }
  &.dragging { position: relative; z-index: 2; scale: 1.02; cursor: grabbing; transition: none; box-shadow: 0 6px 18px rgb(0 0 0 / 0.3); border-color: var(--accent); }
  &.placed { border-color: var(--ok); background: var(--hit); }
  &.misplaced { border-color: var(--warn); background: var(--miss); }
  &.off { cursor: default; }
  > .order-text { flex: 1; }
  > .drag-handle { color: var(--muted); }
}
.order-n {
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--surface-2);
  font-weight: 700;
  .picked > & { background: var(--accent); color: var(--accent-fg); }
}
.order-key { margin: 6px 0 0; font-weight: 600; }
.review-order {
  margin: 0;
  padding: 0 0 0 1.6em;
  display: grid;
  gap: 4px;
  li { padding: 2px 8px; border-radius: 4px; }
  .correct { background: var(--hit); }
  .wrong { background: var(--miss); }
}
.review-accepted { margin: 4px 0 0; }
/* the question's explanation, after the answer and in the review (D) */
.explanation {
  margin: 10px 0 0;
  padding: 10px 12px;
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  background: var(--surface-2);
  white-space: pre-line;
  &::before { content: '💡 '; }
}
.explanation-edit textarea { width: 100%; }
.shared-wrong { display: grid; gap: 6px; padding-top: 8px; border-top: 1px dashed var(--line); > p { margin: 0; } }
.shared-mark { display: grid; place-items: center; color: var(--muted); }
.shared-add { justify-self: start; }
.explanation-add { justify-self: start; }
.review-answers {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 4px;
  li { display: flex; gap: 8px; padding: 4px 8px; border-radius: 4px; }
  .correct { background: var(--hit); }
  .wrong { background: var(--miss); }
}
.mark { width: 1.4em; flex: none; }
.review-numbers { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.review-number {
  padding: 6px 12px;
  border-radius: 6px;
  background: var(--surface);
  font-weight: 600;
  &.hit { background: var(--hit); }
  &.part { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); }
  &.miss { background: var(--miss); }
}

/* ————————————————————————— weights in the draw (creator.js, draw.js) and rare draws in the game */

/* a thing's badge: under the cursor, and always once its weight is not 1 */
.weight {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: ns-resize;
  user-select: none;
  /* hidden but still reachable with Tab (opacity, not visibility), and not in the way of clicks */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s;
  .weight-x { color: var(--muted); }
  &.set { border-color: var(--accent); }
  &.rare { border-color: var(--warn); color: var(--warn); }
  &.set, &.open, &:focus-within { opacity: 1; pointer-events: auto; }
  /* the label opens the stepper; − and + around it while it is open */
  button { border: 0; background: none; padding: 0; color: inherit; font: inherit; cursor: inherit; }
  .weight-label { display: inline-flex; align-items: center; gap: 4px; }
  .weight-step { width: 1.6em; border-radius: 999px; font-weight: 700; cursor: pointer; }
  .weight-step:hover { background: var(--surface); }
  /* one ring, the capsule's own: its label in focus rings the capsule, − / + in focus light up */
  button:focus-visible { outline: none; }
  &:has(.weight-label:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
  .weight-step:focus-visible { background: var(--surface); color: var(--accent); }
}
[data-w-key]:hover > .weight,
[data-w-key]:hover > .q-top > .weight,
[data-w-key]:hover > .wording-text > .weight,
[data-w-key]:hover > .wording-row > .wording-text > .weight,
.weight:hover { opacity: 1; pointer-events: auto; }
/* no cursor to point with (a touch screen): every badge stays in sight, faint until it matters */
@media (hover: none) {
  .weight { opacity: 0.7; pointer-events: auto; }
}
/* on an image and on the question's own wording the badge sits in the corner */
.q-image > .weight, .wording-text > .weight { position: absolute; z-index: 1; }
.q-image > .weight { left: 4px; bottom: 4px; }
.wording-text { position: relative; flex: 1; min-width: 0; textarea { width: 100%; } }
.wording-text > .weight { right: 6px; bottom: 8px; }
.answer-row > .weight, .q-top > .weight { margin-left: auto; }
/* 📌 at an answer: faint until it is pinned */
.pin { filter: grayscale(1); opacity: 0.35; }
.pin:hover, .pin:focus-visible { opacity: 0.8; }
.pin.on { filter: none; opacity: 1; background: var(--surface-2); }

/* a text with choices ({dwa|2}): its number of versions and an example, under it or next to it */
.words-preview { margin: 2px 0 6px; overflow-wrap: anywhere; }
.words-chip { padding: 1px 6px; border-radius: 999px; background: var(--surface-2); white-space: nowrap; cursor: help; }
/* an answer's field with its chip in the corner, so every field in the list is as wide */
.answer-text {
  position: relative;
  flex: 1;
  min-width: 0;
  input { width: 100%; }
  &:has(.words-chip) input { padding-right: 3.5em; }
  .words-chip { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); }
}
.words-warning { margin: 0; color: var(--warn); }

.rare-mark {
  display: inline-block;
  margin: 0 0 10px;
  padding: 3px 10px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--warn) 16%, var(--surface));
  color: var(--warn);
  font-size: 0.85rem;
  font-weight: 600;
}

/* ————————————————————————— the app's own questions (ask.js) */

.ask {
  max-width: min(440px, 100vw - 32px);
  padding: 20px 22px 18px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 16px 48px rgb(0 0 0 / 0.35);
  transition: opacity 0.15s, transform 0.15s;
  @starting-style { opacity: 0; transform: translateY(8px) scale(0.98); }
  &::backdrop { background: rgb(0 0 0 / 0.45); }
  p { margin: 0 0 18px; line-height: 1.5; }
}
.ask-buttons { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } }
.danger {
  background: var(--warn);
  border-color: var(--warn);
  color: var(--accent-fg);
  font-weight: 600;
}

/* ————————————————————————— settings rows (settings.js): the ⚙ panel, later module cards */

.head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.head-tools { display: flex; align-items: center; gap: 10px; flex: none; }
/* the volume beside a question's sound */
.volume { display: flex; align-items: center; gap: 4px; > input { width: 80px; accent-color: var(--accent); cursor: pointer; } }
.link.quit { color: var(--muted); &:hover { color: var(--warn); } }
.settings-open {
  flex: none;
  &.on { border-color: var(--accent); color: var(--accent); }
}
.settings-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  width: min(400px, 100vw - 32px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px 18px 0;
  overflow-y: auto;
  background: var(--surface);
  border-left: 1px solid var(--line);
  box-shadow: -12px 0 32px rgb(0 0 0 / 0.25);
}
/* the ⚙ panel with categories (edit.settingsLayout): a dialog over the dimmed page */
.settings-back { position: fixed; inset: 0; z-index: 9; background: rgb(0 0 0 / 0.4); }
.settings-dialog {
  position: fixed;
  top: 4vh;
  left: 50%;
  z-index: 10;
  width: min(980px, 100vw - 32px);
  height: 88vh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  transform: translateX(-50%);
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: 0 16px 48px rgb(0 0 0 / 0.45);
  overflow: hidden;
  > .settings-top { padding: 14px 18px; border-bottom: 1px solid var(--line); }
  > .settings-help { margin: 0; padding: 10px 18px; min-height: 3.2em; border-top: 1px solid var(--line); }
}
.settings-body { display: grid; grid-template-columns: 230px minmax(0, 1fr); min-height: 0; }
.settings-side {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 10px;
  overflow-y: auto;
  border-right: 1px solid var(--line);
  .settings-search { margin-bottom: 8px; }
}
.settings-cat {
  display: grid;
  grid-template-columns: 1.6em minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border: 0;
  border-radius: 6px;
  background: none;
  text-align: left;
  &.on { background: var(--surface-2); color: var(--text); font-weight: 600; }
  &:hover:not(.on) { background: var(--surface-2); }
}
.settings-cat-n { font-size: 0.8rem; color: var(--muted); &.changed { color: var(--accent); } }
.settings-side-foot {
  display: grid;
  justify-items: start;
  gap: 6px;
  margin-top: 14px;
  padding: 0 10px;
  .link.on { color: var(--accent); font-weight: 600; }
}
.settings-main { display: grid; align-content: start; gap: 12px; padding: 14px 18px; overflow-y: auto; > p { margin: 0; } }
@media (max-width: 700px) {
  .settings-body { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); }
  .settings-side { flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--line); max-height: 40vh; }
  .settings-side .settings-search { flex-basis: 100%; }
}
.settings-top { display: flex; align-items: center; justify-content: space-between; h2 { font-size: 1.15rem; } }
.settings-group {
  display: grid;
  gap: 2px;
  h3 { font-size: 0.8rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); margin: 6px 0 4px; }
}
.setting {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 24px;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-left: 3px solid transparent;
  border-radius: 4px;
  &:hover, &:focus-within { background: var(--surface-2); }
  &.changed { border-left-color: var(--accent); }
}
.setting-name { font-size: 0.92rem; cursor: default; }
/* a row in focus (the keys: ↑ ↓ rows, ← → value) */
.setting[tabindex]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* the controls right by the names (tweak edit.controlsPlace "edge": at the row's right edge) */
:root:not([data-controls="edge"]) .setting {
  grid-template-columns: minmax(0, 15em) minmax(0, auto) 24px;
  justify-content: start;
}
.segmented.multi button.on { background: var(--surface); color: var(--text); font-weight: 600; }
.quiz-panel .settings-group h3 { margin-top: 2px; }
/* the compact look (tweak edit.quizPanelLook): groups side by side, tight rows with icons */
/* the card's "+ …" links in one line (tweak edit.addLinks) */
.add-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 18px;
  padding-top: 6px;
  border-top: 1px dashed var(--line);
  > div { display: contents; }
}
/* the question's panel, compact like the quiz's: an inherited value dimmed */
.q-settings.compact .setting.inherited .setting-control { opacity: 0.55; }
.q-settings.compact .setting.inherited:hover .setting-control,
.q-settings.compact .setting.inherited:focus-within .setting-control { opacity: 1; }
.q-settings.compact .q-settings-note { column-span: all; margin: 2px 6px 0; font-size: 0.72rem; }
:is(.quiz-panel, .q-settings).compact {
  /* columns, so a short group (the modes) leaves no hole: the next one flows in under it */
  display: block;
  columns: 250px;
  column-gap: 18px;
  padding: 8px 10px;
  .settings-group { gap: 0; margin-bottom: 6px; break-inside: avoid; h3 { margin: 0 0 2px; font-size: 0.7rem; } }
  /* the name keeps room for itself; a choice too long for the row wraps onto a second line */
  .setting {
    grid-template-columns: minmax(7em, 1fr) minmax(0, auto) 16px;
    gap: 6px;
    padding: 2px 6px;
    font-size: 0.86rem;
  }
  .setting-control { min-width: 0; }
  .segmented { flex-wrap: wrap; justify-content: flex-end; }
  .setting-name { display: flex; align-items: center; gap: 6px; font-size: inherit; }
  .setting-icon { flex: none; width: 1.15em; height: 1.15em; text-align: center; }
  .setting-icon.emoji { width: 1.3em; height: auto; font-size: 0.95em; }
  .setting[tabindex] { cursor: pointer; }
  .setting-reset { font-size: 0.85rem; }
  .switch { width: 30px; height: 17px; span { top: 2px; left: 2px; width: 13px; height: 13px; } &[aria-pressed="true"] span { transform: translateX(13px); } }
  .segmented button { padding: 1px 7px; font-size: 0.78rem; }
  .limit-field { width: 4.2em; padding: 1px 6px; margin-left: 0; font-size: 0.85rem; }
  .setting-control .small { font-size: 0.72rem; }
}
.quiz-panel-foot {
  grid-column: 1 / -1;
  column-span: all;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 18px;
  padding-top: 6px;
  border-top: 1px solid var(--line);
  .quiz-images { flex: 1 1 100%; }
  .quiz-images:not(:has(.q-image)) { flex: 0 1 auto; }
}
.quiz-notes {
  summary { cursor: pointer; list-style: none; }
  &[open] { flex-basis: 100%; }
  p { margin: 4px 0 0; }
}
.setting-control {
  display: flex;
  align-items: center;
  gap: 8px;
  /* a narrow row narrows the slider, never pushes its value out over ↺ */
  min-width: 0;
  input[type="range"] { flex: 0 1 120px; width: 120px; min-width: 48px; accent-color: var(--accent); }
  output { flex: none; min-width: 3.6em; font-size: 0.8rem; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
}
.setting-reset { border: 0; background: none; padding: 0; color: var(--accent); font-size: 1rem; }
.switch {
  position: relative;
  width: 38px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: 11px;
  background: var(--line);
  transition: background 0.15s;
  span {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--bg);
    transition: transform 0.15s;
  }
  &[aria-pressed="true"] { background: var(--primary-line); span { transform: translateX(16px); } }
}
.segmented {
  display: flex;
  padding: 2px;
  border-radius: 6px;
  background: var(--surface-2);
  button { border: 0; background: none; padding: 3px 10px; font-size: 0.85rem; color: var(--muted); }
  button.on { background: var(--surface); color: var(--text); font-weight: 600; }
  :where(:root[data-hover="shade"]) & button:not(.on):hover { color: var(--text); }
}
/* the color theme: the chosen one in the row, all of them folded out under it in two columns */
.swatch-fold {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 8px;
  border: 0;
  background: var(--surface-2);
  font-size: 0.85rem;
  .fold-mark { color: var(--muted); transition: transform 0.15s; }
  &[aria-expanded="false"] .fold-mark { transform: rotate(-90deg); }
}
.setting:not(.open) .swatches { display: none; }
.swatches {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px;
  width: 100%;
}
.swatch {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border: 1px solid transparent;
  background: none;
  font-size: 0.85rem;
  text-align: left;
  &:hover, &:focus-visible { background: var(--surface); }
  &.on { border-color: var(--accent); font-weight: 600; }
}
.swatch-colors {
  display: flex;
  flex: none;
  gap: 2px;
  b { width: 10px; height: 14px; border-radius: 2px; outline: 1px solid rgb(127 127 127 / 0.25); outline-offset: -1px; }
}
.settings-help {
  position: sticky;
  bottom: 0;
  margin: auto -18px 0;
  padding: 12px 18px 16px;
  min-height: 4.5em;
  background: var(--surface);
  border-top: 1px solid var(--line);
}

/* ————————————————————————— the creator */

.creator {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 24px;
  align-items: start;
}
@media (max-width: 760px) {
  .creator { grid-template-columns: 1fr; }
}
.side { display: grid; gap: 12px; }
.side-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 4px; }
.side-item {
  width: 100%;
  display: grid;
  text-align: left;
  border-color: transparent;
  background: none;
  &:hover { background: var(--surface); }
  &.active { background: var(--surface); border-color: var(--accent); }
  &.with-cover { grid-template-columns: 44px 1fr; column-gap: 10px; align-items: center; }
  .side-cover { grid-row: span 2; width: 44px; height: 33px; object-fit: cover; border-radius: 4px; }
  .side-cover.empty { border: 1px dashed var(--line); }
}

.editor { display: grid; gap: 14px; min-width: 0; }
/* the editor with the bar over it while a past version is looked at (7b) */
.editor-col { display: grid; min-width: 0; }
.field {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  &:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
}
textarea.field { resize: vertical; }
/* the texts' fields grow from one line (tweak edit.textGrow) */
:root[data-text-grow="grow"] textarea.field { field-sizing: content; min-height: calc(1lh + 18px); resize: none; }
/* slim answer rows (tweak edit.answerRows) */
:root[data-answer-rows="slim"] {
  .answer-rows { gap: 3px; }
  .answer-row { gap: 6px; .field { padding: 4px 8px; } }
  .answer-row .correct-pick { width: 26px; height: 26px; font-size: 0.85rem; }
  .accepted .correct-pick { width: 26px; height: 26px; }
}
.title-row { display: flex; align-items: center; gap: 8px; }
.title-field { font-size: 1.3rem; font-weight: 600; }
.modes-pick {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  border: 0;
  padding: 0;
  margin: 0;
  legend { width: 100%; padding: 0; margin-bottom: 2px; }
  label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
  label:has(input:disabled) { cursor: default; }
}

.limit-field { width: 6.5em; padding: 4px 8px; margin-left: 4px; }
/* number fields are dragged sideways to change (number-fields.js, tweak edit.fieldDrag) */
:root.field-drag input[type="number"]:not(:focus, :disabled) { cursor: ew-resize; }
:root.field-dragging, :root.field-dragging * { cursor: ew-resize !important; user-select: none; }
/* a number's arrows (number-fields.js, tweaks edit.fieldSpin and play.fieldSpin): our own over the
   field's right end while it is pointed at or in focus, none, or the browser's (the old way) */
:root:not(.spin-browser) input[type="number"] { appearance: textfield; -moz-appearance: textfield; }
:root:not(.spin-browser) input[type="number"]::-webkit-inner-spin-button,
:root:not(.spin-browser) input[type="number"]::-webkit-outer-spin-button { appearance: none; margin: 0; }
:root.spin-own input[type="number"] { padding-right: 24px; }
.field-arrows {
  position: fixed;
  z-index: 1000;
  width: 18px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  &[hidden] { display: none; }
  > button {
    flex: 1;
    min-height: 0;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 3px;
    background: var(--surface-2);
    color: var(--muted);
    cursor: pointer;
    transition: background-color 80ms, color 80ms;
    &:hover { background: color-mix(in oklab, var(--accent) 24%, var(--surface-2)); color: var(--text); }
    &:active { background: var(--accent); color: var(--accent-fg); }
  }
  svg { width: 8px; height: 5px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
}
.answer-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.shown-answers { margin-left: auto; display: flex; align-items: center; gap: 4px; }

.q-card {
  display: grid;
  gap: 10px;
  padding: 14px;
  border-radius: 8px;
  background: var(--surface-2);
}
.q-top { display: flex; justify-content: space-between; align-items: center; }
.q-label { display: flex; align-items: center; gap: 6px; }
.drag-handle { cursor: grab; color: var(--muted, #888); user-select: none; padding: 0 2px; }
.drag-handle.off { visibility: hidden; }
.q-locked { border: 1px dashed var(--line); }
/* the question's wordings in one stack: its own text (1) and its variants (2, 3…), each a row with
   its number, its text, its chance and ✕; what belongs to a variant sits under its text */
.wordings { display: grid; gap: 6px; }
.wording-row {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  > .drag-handle { margin-top: 10px; }
  > .icon { align-self: center; }
  > .icon-space { visibility: hidden; }
}
.wording-n {
  flex: none;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin-top: 8px;
  border-radius: 50%;
  background: var(--surface);
  color: var(--muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}
.variant { display: grid; gap: 2px; }
/* under a variant's text, lined up with it: past the handle and the number (--wording-indent) */
.wordings { --wording-indent: 50px; }
.variant-more { display: grid; gap: 4px; padding-left: var(--wording-indent); font-size: 0.9rem; }
.wordings:has(.variant) > :is(.words-preview, .variant-add) { margin-left: var(--wording-indent); }
.variant-add, .variant-answers, .answer-add { justify-self: start; }
/* a thing dragged out of where it sits (tweak edit.dragOut; the old look of edit.dragOutLook): that place outlined, it would be removed */
.drag-home-out { outline: 2px dashed var(--warn); outline-offset: 3px; }
/* the empty row a new answer is written into (tweak edit.addAnswer) */
.answer-row.ghost {
  opacity: 0.55;
  .ghost-pick { border-style: dashed; cursor: default; }
  .field { border-style: dashed; background: none; }
  &:focus-within, &:hover { opacity: 1; }
}
/* a variant's links in one line (tweak edit.variantLinks); the picker's own wrapper steps aside */
.answer-foot > div:has(> [data-act="add-image"]) { display: contents; }
/* a question's own settings (question-settings.js): chips next to its ⚙, and the ⚙ panel */
/* the quiz's ⚙ and the chips of what differs from the defaults; its panel unfolds like a question's */
.quiz-panel-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.quiz-panel-open { margin-right: 6px; &.on { color: var(--accent); } }
/* the lit row's help in the free room beside the quiz's ⚙ (tweak edit.panelHelp "beside"): always
   three lines high, a longer help cut, so nothing moves under the cursor as it goes over the rows */
.quiz-panel-help { flex: 1 1 260px; margin: 0 0 0 auto; max-width: 62ch; height: 3.9em; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; text-align: right; line-height: 1.3; text-wrap: pretty; }
/* a question's note holds the lit row's help in the same three lines, so its panel keeps its height */
.q-settings.help-beside .q-settings-note { height: 3.9em; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-height: 1.3; }
.q-settings-note.lit { color: var(--text); }
.quiz-panel { display: grid; gap: 12px; padding: 12px; border-radius: 8px; background: var(--surface); > p { margin: 0; } }
.q-chips { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 4px; margin-left: auto; margin-right: 4px; }
.q-chip {
  padding: 1px 8px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: none;
  color: var(--accent);
  font-size: 0.75rem;
}
.q-settings-open.on { color: var(--accent); }
.q-settings {
  display: grid;
  gap: 2px;
  padding: 8px;
  border-radius: 6px;
  background: var(--surface);
  .setting:hover, .setting:focus-within { background: var(--surface-2); }
  .setting-name { display: grid; }
  .q-setting-from { font-size: 0.75rem; }
  > p { margin: 4px 8px 0; }
}
/* the ⚙ panel unfolds from nothing to its height (its rows 0fr → 1fr) and folds back when it
   closes; "fade" only fades in, "none" is there at once (tweak edit.panelMotion) */
.q-settings-fold { display: grid; grid-template-rows: 1fr; }
.q-settings-clip { min-height: 0; overflow: hidden; }
.q-settings-fold.motion-unfold { animation: panel-unfold var(--motion-time, 200ms) ease-out; }
.q-settings-fold.motion-unfold.closing { animation: panel-fold var(--motion-time, 200ms) ease-in forwards; }
.q-settings-fold.motion-fade { animation: panel-fade var(--motion-time, 200ms) ease-out; }
.q-settings-fold.motion-fade.closing { animation: panel-fade-out var(--motion-time, 200ms) ease-in forwards; }
@keyframes panel-unfold { from { grid-template-rows: 0fr; opacity: 0; } to { grid-template-rows: 1fr; opacity: 1; } }
@keyframes panel-fold { from { grid-template-rows: 1fr; opacity: 1; } to { grid-template-rows: 0fr; opacity: 0; } }
@keyframes panel-fade { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes panel-fade-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) { .q-settings-fold { animation: none !important; } }
.setting-choice { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; }
.multi-pick { display: flex; align-items: center; gap: 6px; margin-left: auto; margin-right: 8px; cursor: pointer; }
.points-pick { display: flex; align-items: center; gap: 6px; margin-right: 8px; cursor: pointer; }
.points-field { flex: none; width: 5.5em; text-align: right; }
.correct-pick.multi { border-radius: 6px; }
.q-image {
  position: relative;
  margin: 0;
  justify-self: start;
  img { display: block; max-width: 100%; max-height: 220px; border-radius: 6px; }
  .icon { position: absolute; top: 4px; right: 4px; background: var(--surface); border-radius: 50%; }
  .pin { position: absolute; top: 6px; left: 6px; }
}
/* the 🖼 library: a panel of the images uploaded so far, over a dimmed page */
.library-back { position: fixed; inset: 0; z-index: 11; background: rgb(0 0 0 / 0.4); }
/* versions (7b): the list, and the bar over the editor while a past one is looked at */
.versions { width: min(640px, 100vw - 32px); }
.versions-game { margin: 0; display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; }
.version-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.version-row {
  display: grid;
  grid-template-columns: 3.2em 1fr auto;
  gap: 4px 10px;
  align-items: baseline;
  padding: 6px 8px;
  border-radius: 6px;
  &:hover { background: var(--surface-2); }
  &.looked { outline: 2px solid var(--accent); outline-offset: -2px; }
  .version-n { font-weight: 600; font-variant-numeric: tabular-nums; }
  .version-what { display: grid; gap: 2px; min-width: 0; }
  .version-note { overflow-wrap: anywhere; }
  .version-acts { display: flex; gap: 12px; flex-wrap: wrap; justify-content: end; }
}
.version-tag {
  margin-left: 6px;
  padding: 0 7px;
  border-radius: 999px;
  border: 1px solid var(--line);
  font-size: 0.75rem;
  color: var(--muted);
  &.played { border-color: var(--ok); color: var(--ok); }
}
.past-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-bottom: 8px;
  padding: 10px 14px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 18%, var(--surface));
  border: 1px solid var(--accent);
  > span { flex: 1 1 16em; }
}
.editor.past { opacity: 0.75; filter: saturate(0.6); }
.library {
  position: fixed;
  top: 5vh;
  left: 50%;
  z-index: 12;
  width: min(760px, 100vw - 32px);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px;
  overflow-y: auto;
  transform: translateX(-50%);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: 0 12px 40px rgb(0 0 0 / 0.4);
  .settings-top { gap: 12px; }
  .library-filter { margin-left: auto; }
}
.library-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; }
.library-item {
  display: grid;
  gap: 4px;
  padding: 6px;
  border: 2px solid transparent;
  border-radius: 8px;
  background: var(--surface-2);
  img { width: 100%; height: 100px; object-fit: contain; }
  &.mine { border-color: var(--line); }
  &:hover, &:focus-visible { border-color: var(--accent); }
}
.library-open { margin-left: 12px; }
.quiz-images { display: grid; gap: 6px; > p { margin: 0; } }
.q-images {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  .q-image[draggable="true"] { cursor: grab; }
  /* how tall: the tweak image.thumbSize (creator.js sets --thumb) */
  .q-image img { max-height: var(--thumb, 160px); }
}
.answer-rows { display: grid; gap: 6px; }
.answer-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* B3: right only for some options of a named choice */
.correct-pick.some { border-color: var(--ok); background: linear-gradient(90deg, var(--hit) 50%, transparent 50%); color: var(--ok); }
.answer-clip.quiet { opacity: 0; }
.answer-row:hover .answer-clip.quiet, .answer-clip.quiet:focus-visible { opacity: 0.6; }
.answer-clip.on { color: var(--accent); }
.right-when-open { opacity: 0.45; &:hover, &:focus-visible { opacity: 1; } }
.right-when {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding-left: 64px;
  select { width: auto; padding: 2px 6px; }
}
.right-option {
  padding: 2px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  &.on { border-color: var(--ok); background: var(--hit); color: var(--ok); }
}
.words-flip { margin: 0; }
.correct-pick {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid var(--line);
  font-weight: 700;
  cursor: pointer;
  input { position: absolute; opacity: 0; pointer-events: none; }
  &.on { border-color: var(--ok); background: var(--hit); color: var(--ok); }
  &:has(input:focus-visible) { outline: 2px solid var(--accent); }
}
.add-question { border-style: dashed; padding: 12px; }
/* "+ New quiz" with its ▾ of templates */
.new-row { display: flex; gap: 4px; > .wide { flex: 1; } }
.new-menu-open { padding: 0 10px; }
.new-menu {
  display: grid;
  margin: 4px 0 8px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  button { border: 0; background: none; padding: 6px 10px; text-align: left; border-radius: 4px; &:hover { background: var(--surface-2); } }
}
.template-row { display: grid; grid-template-columns: 24px auto minmax(0, 1fr) 24px; align-items: center; gap: 8px; padding: 4px 8px; }
.template-star { color: var(--muted); &.on { color: var(--accent); } }
.template-sum { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.save-template { justify-self: start; }
.ask input.field { width: 100%; margin: 4px 0 12px; }
/* "+ Add…" and the kind added last; the menu under them: a filter, the kinds in groups, the lit
   one's help in the footer (15h) */
.add-questions { display: flex; gap: 8px; > button { flex: 1; } }
.add-question.on { border-color: var(--accent); color: var(--accent); }
.add-menu {
  display: grid;
  gap: 4px;
  margin-top: 6px;
  padding: 6px;
  border-radius: 6px;
  background: var(--surface);
  .add-filter { width: 100%; }
  .add-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 2px 8px; }
  .add-group { grid-column: 1 / -1; margin: 6px 4px 0; }
  .add-kind { border: 0; background: none; padding: 6px 10px; text-align: left; border-radius: 4px; }
  .add-kind.lit { background: var(--surface-2); color: var(--accent); }
  .add-help { margin: 4px; min-height: 2.6em; }
}
/* a Słuch generator's submodules on its card */
.ear-kinds { margin: 0 6px; > button { padding: 2px 8px; } }
/* a kind's icon before its name, in the menu and on the switch */
.kind-icon { display: inline-block; width: 1.5em; }
.accepted { display: grid; gap: 6px; > p { margin: 0; } }
.typed-mark { cursor: default; }
/* a number question in the creator (step 17): its fields in one row that wraps */
.number-edit { display: grid; gap: 6px; > p { margin: 0; } }
.number-props { display: flex; flex-wrap: wrap; gap: 8px; }
.number-prop { display: grid; gap: 2px; > input { width: 7.5em; } > .number-unit { width: 6em; } }
/* a generator's field linked to a quiz variable (15g): its ⛓ list beside it, the link in the accent */
.linkable { display: inline-flex; align-items: center; gap: 4px; > input { width: 7.5em; } }
/* a range in one cell (15j): "from – up to", two narrow fields */
.range-pair { display: inline-flex; align-items: center; gap: 4px; .linkable > input { width: 4.8em; } }
.var-pick { width: auto; max-width: 9em; padding-inline: 4px; font-size: 0.85rem; &.on { border-color: var(--accent); color: var(--accent); } }
.linked :is(input, select):disabled { color: var(--accent); opacity: 1; }
/* an order question in the creator: its items numbered in the right order, what the ends mean */
.order-edit { display: grid; gap: 6px; > p { margin: 0; } }
/* a notes generator's card (step 15): its settings, and one example question made like the game's */
.notes-card {
  display: grid;
  gap: 8px;
  .note-name { color: var(--text); font-weight: 600; }
  .live-problem { margin: 0; }
}
.notes-switches { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; }
.notes-choice { display: inline-flex; align-items: center; gap: 6px; }
/* an intervals generator's sizes (15b): their short signs, the ticked ones in the accent */
.interval-sizes { display: inline-flex; flex-wrap: wrap; gap: 4px; }
/* a pool's item that weighs (15j): its chance under it, the accent when its weight is set */
.weighed { display: inline-grid; justify-items: center; }
.pool-chance { font-size: 11px; color: var(--muted); }
.weighed.set .pool-chance { color: var(--accent); }
.interval-size {
  min-width: 2.6em;
  padding: 2px 6px;
  border: 0;
  border-radius: 4px;
  background: var(--surface-2);
  color: var(--muted);
  font-family: inherit;
  cursor: pointer;
  &.on { background: var(--accent); color: var(--accent-fg); }
  &:hover:not(.on) { color: var(--text); }
}
.notes-switch { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.notes-example { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; min-height: 30px; }
.notes-answers { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.notes-answer {
  padding: 1px 8px;
  border-radius: 4px;
  background: var(--surface-2);
  &.right { background: var(--hit); color: var(--ok); font-weight: 600; }
}
.order-pick { cursor: default; font-variant-numeric: tabular-nums; }
.order-end-field { max-width: 22em; font-size: 0.9rem; }
.save-bar {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 12px 0;
  background: var(--bg);
  border-top: 1px solid var(--line);
}
.play-link { margin-left: auto; }
.live-problem { color: var(--warn); font-size: 0.875rem; }
.preview-open.on { color: var(--accent); }
.file-preview {
  border-radius: 8px;
  background: var(--surface);
  pre { margin: 0; padding: 12px; max-height: 60vh; overflow: auto; font-size: 0.8rem; white-space: pre-wrap; overflow-wrap: anywhere; }
  > p { margin: 0; padding: 12px; }
}
.save-bar .history { font-size: 1.2rem; &:hover:not(:disabled) { color: var(--accent); } }

/* the grades' log (step 8, grades.html) */
.grades-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px; select.field { width: auto; } }
.grades-only { display: inline-flex; gap: 2px; button.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, var(--surface)); } }
.grades-tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 10px; border-radius: 999px; background: var(--surface-2); font-size: 0.85rem; }
.grades-question-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 0 0 12px;
  padding: 8px 12px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 14%, var(--surface));
  > span { flex: 1 1 14em; font-weight: 600; }
}
.grades-status { margin: 0 0 12px; padding: 8px 12px; border-radius: 6px; background: var(--hit); }
.grades-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: 0; font-size: 0.9rem; .chip { margin-left: 0; } }
.grades-points { margin-left: auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
.grades-grader { margin: 8px 0 0; q { font-style: italic; } }
.grades-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.grades-fix-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  margin-top: 8px;
  padding: 8px;
  border-radius: 6px;
  background: var(--surface-2);
  .grades-note { flex: 1 1 14em; }
}
.grades-regrade { width: min(560px, 100vw - 32px); }
.grades-changes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
  max-height: 40vh;
  overflow-y: auto;
  li { display: flex; gap: 8px; align-items: baseline; padding: 4px 8px; border-radius: 4px; &:nth-child(odd) { background: var(--surface-2); } }
  .grades-change-answer { flex: 1; overflow-wrap: anywhere; }
}
/* an answer the organizer corrected, on the player's result screen (step 8) */
.fixed-tag { margin-left: 6px; padding: 0 7px; border-radius: 999px; border: 1px solid var(--accent); font-size: 0.75rem; color: var(--accent); }
.fixed-note { margin: 0 0 6px; color: var(--muted); font-style: italic; }

/* time (step 9): the question's clock (a bar that empties and the seconds left), the quiz's 🕒, and
   what the result says of the time */
.clock {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: -8px 0 14px;
  --clock-color: var(--accent);
  &.low { --clock-color: var(--warn); }
  .clock-bar { flex: 1; height: 8px; border-radius: 4px; background: var(--surface-2); overflow: hidden; }
  .clock-fill { height: 100%; width: calc(var(--left, 1) * 100%); background: var(--clock-color); transition: width 0.2s linear, background 0.3s; }
  .clock-s { min-width: 2.5em; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--clock-color); }
  &.clock-number .clock-s { font-size: 1.3rem; text-align: left; }
}
.quiz-clock { margin-left: 6px; font-variant-numeric: tabular-nums; font-weight: 600; &.low { color: var(--warn); } }
.time-note { margin: 8px 0 0; color: var(--warn); }
.time-tag { margin-left: 6px; padding: 0 7px; border-radius: 999px; border: 1px solid var(--warn); font-size: 0.75rem; color: var(--warn); }
.rules { display: inline-block; margin: 6px 0 0; padding: 4px 12px; border-radius: 6px; background: var(--hit); color: var(--ok); font-weight: 600; &.broken { background: var(--miss); color: var(--warn); } }
.grades-time { margin: 6px 0 0; color: var(--muted); &.late { color: var(--warn); } }
.q-settings-warn { margin: 4px 6px 0; color: var(--warn); column-span: all; }
/* a typed answer a typo away from an accepted one (typedTypos "almost") */
.multi-tag { margin-left: 6px; padding: 0 7px; border-radius: 999px; border: 1px solid var(--multi); font-size: 0.75rem; color: var(--multi); background: color-mix(in oklab, var(--multi) 12%, transparent); }
.near-tag { margin-left: 6px; padding: 0 7px; border-radius: 999px; border: 1px solid var(--accent); font-size: 0.75rem; color: var(--accent); }
.near-note { margin: 4px 0 0; color: var(--accent); }
/* the quiz's equivalents: words that mean the same in typed answers */
.equivalents { column-span: all; display: grid; gap: 6px; > p { margin: 0; } }
.equivalents-field { width: 100%; font-family: ui-monospace, Consolas, monospace; font-size: 0.85rem; resize: vertical; }
.equivalents-tools { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
/* the quiz's variables (15g): a row each, its name, kind, value, uses and ✕ */
.variables { column-span: all; display: grid; gap: 6px; justify-items: start; > p { margin: 0; } }
.variable-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.variable-name { width: 11em; }
.variable-value { width: 8em; }
/* "my answer is right" (B): the player's report on the result screen, and in the grades' log */
.report-open { margin-top: 6px; }
.report-form { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; margin-top: 8px; .field { flex: 1 1 14em; } }
.report-done { margin: 6px 0 0; }
.grades-report {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  margin: 8px 0 0;
  padding: 6px 10px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 14%, var(--surface));
  font-size: 0.9rem;
  > span { flex: 1 1 14em; }
  q { font-style: italic; }
  &.accepted { background: var(--hit); }
  &.rejected { background: var(--surface-2); color: var(--muted); }
}
.grades-count { display: inline-block; min-width: 1.4em; padding: 0 5px; border-radius: 999px; background: var(--accent); color: var(--accent-fg); font-size: 0.75rem; }
/* hints (step 10): the ones shown, the button that asks for the next, the free ones left */
.hints { display: grid; gap: 6px; margin: 12px 0 0; justify-items: start; }
.hint-line { margin: 0; padding: 8px 12px; border-radius: 6px; background: color-mix(in srgb, var(--accent) 12%, var(--surface)); white-space: pre-line; }
.hint-level { font-weight: 700; color: var(--accent); margin-right: 4px; }
.hint-ask.armed { border-color: var(--warn); color: var(--warn); }
.hints-left { margin-left: 6px; font-weight: 600; }
.hint-tag { margin-left: 6px; padding: 0 7px; border-radius: 999px; border: 1px solid var(--line); font-size: 0.75rem; color: var(--muted); }
.grades-hints { margin: 6px 0 0; color: var(--muted); }
/* the question's hints in the creator */
.hint-rows { display: grid; gap: 6px; }
.hint-row { display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: start; .hint-n { padding-top: 6px; color: var(--muted); font-size: 0.85rem; white-space: nowrap; } textarea { width: 100%; } }
.hint-add { justify-self: start; }
/* hard mode (step 11): the 🔥 on a quiz's card, and its chip */
.hard-toggle { filter: grayscale(1); opacity: 0.6; &.on { filter: none; opacity: 1; border-color: var(--warn); background: color-mix(in srgb, var(--warn) 18%, var(--surface)); } }
.chip.chip-hard { background: color-mix(in srgb, var(--warn) 22%, var(--surface)); color: var(--warn); }
/* the ranking (step 12): on a quiz's card, the box on the result screen, the board */
.ranking-line { margin-top: 4px; }
.ranking-box {
  display: grid;
  gap: 6px;
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: 8px;
  background: var(--surface);
  border-left: 4px solid var(--accent);
  > p { margin: 0; }
  &.best { border-left-color: var(--ok); }
}
.ranking-best { font-weight: 700; color: var(--ok); }
.ranking-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.ranking-comment { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; .field { flex: 1 1 14em; } }
.reveal-line { margin: 0 0 12px; }
.board { width: min(560px, 100vw - 32px); }
.board-rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
  li { display: grid; grid-template-columns: 2.4em 1fr auto; gap: 8px; align-items: baseline; padding: 6px 8px; border-radius: 6px; &:nth-child(odd) { background: var(--surface-2); } &.mine { outline: 2px solid var(--accent); outline-offset: -2px; } }
  .board-place { font-weight: 700; font-variant-numeric: tabular-nums; }
  .board-who { display: grid; min-width: 0; overflow-wrap: anywhere; }
  .board-score { text-align: right; }
}
/* clips (step 13): in the creator's card, in the game, on the result and in the grades */
.clip-rows { display: grid; gap: 6px; }
.clip-row { display: flex; align-items: center; gap: 8px; audio { flex: 1; min-width: 0; height: 36px; } .clip-n { color: var(--muted); font-size: 0.85rem; white-space: nowrap; } }
.clip-play { display: grid; gap: 4px; margin: 4px 0 16px; audio { width: 100%; } }
/* a generated question's own player (15f): Play, the reference note, the plays left */
.tone-buttons { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.tone-button { padding: 6px 14px; }
.tone-button.on { color: var(--accent); }
.tone-bar { flex: 1 1 120px; min-width: 80px; max-width: 320px; height: 4px; border-radius: 2px; background: var(--surface-2); overflow: hidden; }
.tone-bar.seek { height: 8px; border-radius: 4px; cursor: pointer; }
.tone-bar-fill { display: block; height: 100%; width: 0; background: var(--accent); }
.review-tone { display: block; margin: 6px 0; }
.review-clip { display: block; width: 100%; max-width: 420px; height: 36px; margin: 6px 0; }
/* the creator's list: a quiz's eye (on the players' list or hidden from it), a hidden one dimmed */
.side-row { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 2px; }
.side-eye { color: var(--muted); opacity: 0.35; padding: 4px; &:hover, &:focus-visible { opacity: 1; } }
.side-row:hover .side-eye { opacity: 0.8; }
.side-row.hidden { .side-eye { opacity: 1; color: var(--text); } .side-item > span:not(.muted), .side-cover { opacity: 0.5; } }
.chip-hidden { font-size: 0.75rem; vertical-align: middle; }
/* a hidden quiz dimmed on the admin's list (tweak play.hiddenLook): its picture grayed and darker,
   its words muted; pointing at it brings it most of the way back */
.hidden-dim { .tile-art, .quiz-cover { filter: grayscale(0.7) brightness(0.65); transition: filter 120ms; } .tile-title, .quiz-title, .tile-meta { color: var(--muted); } }
.hidden-dim:hover { .tile-art, .quiz-cover { filter: grayscale(0.3) brightness(0.85); } }
@media (prefers-reduced-motion: reduce) { .hidden-dim .tile-art, .hidden-dim .quiz-cover { transition: none; } }
/* the setting a chip was clicked for, lit up for a moment (tweak edit.chipClick) */
.flash { animation: setting-flash 1.6s ease-out; }
@keyframes setting-flash {
  0%, 35% { background: color-mix(in oklab, var(--accent) 30%, transparent); box-shadow: inset 0 0 0 1px var(--accent); }
  100% { background: transparent; box-shadow: none; }
}
