/* One material, loaded last. A control is a solid tile with a lip one step
   darker; a field is a well sunk into the surface; a sheet is a tray that rises.
   The crossword stays flat printing: construction stops at the board's frame.
   Selectors lead with :root so a rule here beats the older layers without
   !important. A variant only sets --tile-* on the control itself; the tile rule
   reads them, so no variant has to win a specificity fight. */

@font-face { font-family: Figtree; src: url('assets/fonts/Figtree-500.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: Figtree; src: url('assets/fonts/Figtree-600.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: Figtree; src: url('assets/fonts/Figtree-700.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }

/* ------------------------------------------------------------------ tokens
   Worked out from the palette in styles.css, so both themes follow it. */
:root {
  --ui-display: Figtree, Arial, Helvetica, ui-sans-serif, system-ui, sans-serif;

  --tile: color-mix(in srgb, var(--ui-surface) 45%, #fff);
  --tile-2: var(--ui-raised);
  --tile-lip: color-mix(in srgb, var(--ui-field-line) 78%, var(--ui-raised));
  --accent-lip: color-mix(in srgb, var(--ui-accent) 68%, #1d1d1b);
  --ink-lip: #000;
  --learn-lip: color-mix(in srgb, var(--ui-learn) 68%, #1d1d1b);
  --hi: inset 0 0 0 0 transparent;
  --contact: rgba(29, 29, 27, .16);

  --floor: color-mix(in srgb, var(--ui-raised) 82%, var(--ui-line));
  --wall: color-mix(in srgb, var(--ui-field-line) 42%, var(--ui-raised));
  --well: color-mix(in srgb, var(--ui-raised) 72%, var(--ui-line));
  --well-shade: color-mix(in srgb, var(--ui-field-line) 72%, var(--ui-raised));
  --well-rim: color-mix(in srgb, var(--ui-bg) 40%, #fff);
  --well-ink: #5a5348;
  --scrim: rgba(29, 29, 27, .46);

  --press: 80ms;
  --settle: cubic-bezier(.2, .8, .3, 1);
  --radius: 14px;
  --gutter: 20px;
}
:root[data-theme="dark"] {
  --tile: var(--ui-raised);
  --tile-2: color-mix(in srgb, var(--ui-raised) 76%, var(--ui-line));
  --tile-lip: color-mix(in srgb, var(--ui-bg) 22%, #000);
  --accent-lip: color-mix(in srgb, var(--ui-accent) 58%, #20201f);
  --ink-lip: #b1a897;
  --learn-lip: color-mix(in srgb, var(--ui-learn) 58%, #20201f);
  --hi: inset 0 1px 0 rgba(255, 245, 227, .11);
  --contact: rgba(0, 0, 0, .34);

  --floor: color-mix(in srgb, var(--ui-bg) 72%, #000);
  --wall: color-mix(in srgb, var(--ui-bg) 40%, #000);
  --well: color-mix(in srgb, var(--ui-bg) 62%, #000);
  --well-shade: color-mix(in srgb, var(--ui-bg) 24%, #000);
  --well-rim: color-mix(in srgb, var(--ui-bg) 78%, var(--ui-line));
  --well-ink: var(--ui-soft);
  --scrim: rgba(0, 0, 0, .58);
}

/* Grid vocabulary. Rules: flat cells and 1px lines, letters and numbers at least
   4.5:1 on every fill, marker at least 3:1, key tint within 1.2:1 of a plain cell.
   The dark grid really is dark, so the squares go down with the rest of the UI.
   Its highlights stay dim enough for the bright right, wrong and revealed inks,
   and its cells are only 1.47:1 from a block, so the 1px line does that work. */
:root, :root[data-grid="light"] {
  --cell: #fffaf0;
  --cell-line: #d9cfbc;
  --cell-block: #1d1d1b;
  --cell-theme: #efe3f7;
  --cell-ink: #15161a;
  --cell-num: #4a473f;
  --cell-word: #cfe1ec;
  --word-line: #4a7a9c;
  --theme-word: #c9cff3;
  --cell-sel: #f9ce49;
  --theme-sel: #f7cf63;
  --cell-flash: #d5c0ec;
  --cell-wave: #cfe6d3;
  --cell-good: #0f5a3c;
  --cell-bad: #9c2119;
  --cell-shown: #4b4d52;
  --key-mark: #5b2f8f;
  --frame: #2b2a27;
}
:root[data-grid="dark"] {
  --cell: #34342f;
  --cell-line: #5e5b52;
  --cell-block: #141413;
  --cell-theme: #453b53;
  --cell-ink: #fff5e3;
  --cell-num: #e0d9cc;
  --cell-word: #2e5a78;
  --word-line: #8cc3e4;
  --theme-word: #44558f;
  --cell-sel: #705812;
  --theme-sel: #725a1c;
  --cell-flash: #6a4f94;
  --cell-wave: #2d6048;
  --cell-good: #a8f7ca;
  --cell-bad: #ffcdbd;
  --cell-shown: #ece5da;
  --key-mark: #d2b6f0;
  --frame: #0f0f0e;
}

/* -------------------------------------------------------------------- type */
button, input, textarea, select { font-family: inherit; }
body { -webkit-font-smoothing: antialiased; }
:root .view .page-title, :root .sheet-title,
:root .generate.create-flow .flow-panel-heading h2,
:root .browse .empty-search h3 {
  font-family: var(--ui-headline); font-weight: 900; letter-spacing: -.045em;
}
:root .view .page-title { font-size: 30px; line-height: 1.1; }
:root .sheet-title, :root .choice-sheet .sheet-title { font-size: 22px; line-height: 1.2; }
:root .view .sec-title { font-weight: 700; letter-spacing: -.015em; }
:root .timer, :root .solved-splash span { font-family: var(--ui-display); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- touch basics */
:root :is(button, a, summary, .clue-card, .srow-tap, input, textarea, select) {
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}

/* ---------------------------------------------------------------- the tile
   Standard tile: 14px radius, solid fill, no outline, 3px lip. The press rule
   further down is written against this same list. */
:root :is(
  .view .btn, .sheet .btn, .solved-bar .btn, .home.home-focus .stage-play,
  .home.home-focus .home-shortcut, .home.home-focus .avatar,
  .generate.create-flow .sugg, .generate.create-flow .flow-link, .generate.create-flow .flow-back,
  .generate.create-flow .setting-row, .generate.create-flow .flow-guide-link,
  .choice-option, .choice-sheet .sheet-x, .sheet-x,
  .view .chip,
  .view .catcard, .view .pcard, .home .rail .pcard,
  .view .page-back, .pin-tool, .profile-entry, .profile.profile-focus .allowance-link, .profile .allowance-link,
  .recent-card, .recall-stop, .iconbtn, .learn-close, .icon, .key, .kbd-restore, .genbar-act.strong,
  .profile-focus .profile-keepsake .link
) {
  --l: var(--tile-l, 3px); --lc: var(--tile-lc, var(--tile-lip));
  background: var(--tile-bg, var(--tile)); color: var(--tile-ink, var(--ink));
  border: 0; border-radius: var(--tile-r, var(--radius));
  box-shadow: var(--hi), 0 var(--l) 0 var(--lc), 0 calc(var(--l) + 1px) 2px var(--tile-cs, var(--contact));
  transition: transform var(--press) ease-out, box-shadow var(--press) ease-out,
              background-color 150ms ease, color 150ms ease;
}
/* A tile that isn't a control: same object, no press. */
:root :is(
  .profile-focus .profile-keepsake, .plan, .plan-strip, .gencard, .learn .recall-card,
  .learn.learn-focus .recall-session .recall-card, .settings .card, .paywall .allowance-balance,
  .learn-panel, .generate .gen-result .card, .view .empty, .profile .mastery-intro,
  .profile-empty .mastery-intro, .view .card
) {
  background: var(--tile); border: 0; border-radius: var(--radius);
  box-shadow: var(--hi), 0 3px 0 var(--card-lc, var(--tile-lip)), 0 4px 2px var(--contact);
}

/* Accent tiles */
.btn.primary, .genbar-act.strong { --tile-bg: var(--accent); --tile-ink: var(--ui-on-accent); --tile-lc: var(--accent-lip); }
/* Selected: the one dark piece on the rack */
.chip.on, .pin-tool.on, .level-opt.on { --tile-bg: var(--ink); --tile-ink: var(--app-bg); --tile-lc: var(--ink-lip); }
/* Tonal tiles: they sit on another tile */
:is(.settings .card .btn, .view .card .btn, .gencard .btn):not(.primary) { --tile-bg: var(--tile-2); --tile-ink: var(--ink); }
.profile-keepsake .link { --tile-r: 12px; --tile-l: 2px; }
.profile-keepsake .link { --tile-bg: var(--tile-2); }
:root .profile-focus .profile-keepsake .link { padding: 8px 12px; gap: 4px; margin-top: 8px; font-size: 14px; font-weight: 600; }
.btn.utility, .browse .backlink { --tile-ink: var(--accent); }
.btn.danger, .btn.again, .view .card .btn.danger { --tile-ink: var(--bad-ink); }
/* Disabled: flat, out of the material */
.btn:disabled { --tile-bg: var(--well); --tile-ink: var(--well-ink); --tile-l: 0px; --tile-cs: transparent; opacity: 1; cursor: default; }
:root .view .btn:disabled { opacity: 1; border: 0; }

/* Radii and lips by size */
.btn.small, .solved-bar .btn { --tile-r: 12px; }
.chip, .sugg, .pin-tool { --tile-l: 2px; --tile-r: 11px; }
.icon { --tile-l: 2px; --tile-r: 12px; }
.genbar-act.strong { --tile-l: 2px; --tile-r: 10px; }
.key { --tile-l: 2px; --tile-r: 9px; }
.key.key-wide { --tile-bg: var(--tile-2); --tile-ink: var(--ink-soft); }
.learn-close { --tile-bg: var(--tile-2); }
.icon.on { --tile-lc: var(--accent); --tile-ink: var(--accent); }
.icon.menu-open { --tile-bg: var(--tile-2); }

/* ---------------------------------------------------------- press + reaction */
:root :is(
  .view .btn, .sheet .btn, .solved-bar .btn, .home.home-focus .stage-play,
  .home.home-focus .home-shortcut, .home.home-focus .avatar,
  .generate.create-flow .sugg, .generate.create-flow .flow-link, .generate.create-flow .flow-back,
  .generate.create-flow .setting-row, .generate.create-flow .flow-guide-link,
  .choice-option, .choice-sheet .sheet-x, .sheet-x,
  .view .chip, .view .catcard, .view .pcard, .home .rail .pcard,
  .view .page-back, .pin-tool, .profile-entry, .profile.profile-focus .allowance-link, .profile .allowance-link,
  a.recent-card, .recall-stop, .iconbtn, .learn-close, .icon, .key, .kbd-restore, .genbar-act.strong,
  .profile-focus .profile-keepsake .link
):is(:active, .down):not(:disabled) {
  transform: translateY(calc(var(--l) - 1px));
  box-shadow: var(--hi), 0 1px 0 var(--lc), 0 1px 1px var(--contact);
}
@media (hover: hover) {
  :root :is(.view .btn:not(.primary):not(:disabled), .sheet .btn:not(.primary), .home.home-focus .home-shortcut,
    .generate.create-flow .sugg, .generate.create-flow .flow-link, .generate.create-flow .setting-row, .choice-option,
    .view .pcard, .view .catcard, .profile-entry, a.recent-card, .icon, .iconbtn, .key):hover { background: var(--tile-2); }
  :root :is(.view .btn.primary, .sheet .btn.primary, .solved-bar .btn.primary):hover { filter: brightness(1.04); }
  .menu-pop button:hover { background: var(--tile-2); }
}

/* -------------------------------------------------------------------- wells */
:root :is(.view .topic-input, .view .words-input, .view .search, .generate.create-flow .topic-input,
  .generate.create-flow .teacher-body .words-input, .generate .teacher-body .words-input, .browse-tools .search) {
  background: var(--well); border: 0; border-radius: var(--radius); color: var(--ink);
  box-shadow: inset 0 1px 0 var(--well-shade), inset 0 3px 3px -1px color-mix(in srgb, var(--well-shade) 45%, transparent), 0 1px 0 var(--well-rim);
  outline: 0;
}
:root :is(.view .topic-input, .view .words-input, .view .search, .generate.create-flow .topic-input,
  .generate.create-flow .teacher-body .words-input, .browse-tools .search):focus {
  outline: 0;
  box-shadow: inset 0 1px 0 var(--well-shade), inset 0 0 0 2px var(--accent), 0 1px 0 var(--well-rim);
}
:root .view :is(.topic-input, .words-input, .search)::placeholder { color: var(--well-ink); opacity: 1; }
:root .browse .search-field > svg { color: var(--well-ink); }
:root .browse .search-clear { border-radius: 10px; color: var(--ink); }
:root .browse .search-clear:is(:active, .down) { background: var(--tile-2); }

/* Tracks are wells too */
:root :is(.gen-bar, .progress-bar, .profile .mastery-track, .paywall .allowance-meter,
  .view .catcard-bar, .home .stage-progress-track, .view .pcard-progress-track) {
  background: var(--well); border-radius: 3px; box-shadow: inset 0 1px 0 var(--well-shade); overflow: hidden;
}
:root .view .pcard-progress-track { height: 4px; }
:root .home .stage-progress-track { height: 6px; }
:root .profile .mastery-track { height: 6px; border-radius: 3px; }
:root .progress-bar span { background: var(--accent); }
:root .progress-bar.done span { background: var(--good); }

/* Progress runs up to its value on arrival, once, without a reflow */
@keyframes fill-in { from { transform: scaleX(0); } }
:root :is(.profile .mastery-track > span, .paywall .allowance-meter > span,
  .view .catcard-bar span, .home .stage-progress-track span, .view .pcard-progress-track > span) {
  transform-origin: 0 50%; animation: fill-in 360ms var(--settle) both;
}

/* ------------------------------------------------- segments, tabs, switches */
:root .seg, :root .settings .seg, :root .learn.learn-focus .tabs, :root .learn .tabs {
  background: var(--well); border: 0; border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--well-shade), 0 1px 0 var(--well-rim);
  padding: 3px 3px 6px; gap: 3px;
}
:root .learn.learn-focus .tabs { min-height: 0; }
:root :is(.seg-b, .settings .seg-b, .learn .tab, .learn.learn-focus .tab) {
  min-height: 44px; border: 0; border-radius: 11px; background: transparent; color: var(--well-ink);
  font-weight: 600; box-shadow: none;
  transition: transform var(--press) ease-out, box-shadow var(--press) ease-out, background-color 150ms ease, color 150ms ease;
}
:root :is(.seg-b.on, .settings .seg-b.on, .learn .tab.on, .learn.learn-focus .tab.on),
:root[data-theme="light"] .view .seg-b.on {
  --l: 3px; --lc: var(--tile-lip);
  background: var(--tile); color: var(--ink); font-weight: 700; border: 0;
  box-shadow: var(--hi), 0 var(--l) 0 var(--lc), 0 calc(var(--l) + 1px) 2px var(--contact);
}
:root :is(.seg-b, .learn .tab, .browse .tab):is(:active, .down) { transform: translateY(1px); }
:root .learn.learn-focus .tab.on { color: var(--themed); }

/* Browse's tabs: one tile that slides along the well between them */
:root .browse .browse-tabs {
  position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: 0; padding: 3px 3px 6px;
  background: var(--well); border: 0; border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--well-shade), 0 1px 0 var(--well-rim);
}
:root .browse .tab {
  position: relative; z-index: 1; min-height: 44px; padding: 8px 6px; border: 0; border-radius: 11px;
  background: none; box-shadow: none; color: var(--well-ink); font-weight: 600;
  transition: transform var(--press) ease-out, color 150ms ease;
}
:root .browse .tab.on { background: none; box-shadow: none; color: var(--ink); font-weight: 700; }
.tab-ind {
  position: absolute; top: 3px; left: 3px; width: calc(50% - 3px); height: 44px; border-radius: 11px;
  background: var(--tile); box-shadow: var(--hi), 0 3px 0 var(--tile-lip), 0 4px 2px var(--contact);
  transform: translateX(calc(var(--at, 0) * 100%));
  transition: transform 180ms var(--settle);
}

:root .switch {
  width: 48px; height: 28px; border: 0; border-radius: 10px; background: var(--well);
  box-shadow: inset 0 1px 0 var(--well-shade), 0 1px 0 var(--well-rim);
}
:root .switch .knob, :root .settings .switch.on .knob {
  top: 3px; left: 3px; width: 22px; height: 19px; border-radius: 7px;
  background: var(--tile); box-shadow: 0 2px 0 var(--tile-lip);
  transition: transform 120ms ease-out, background-color 120ms ease;
}
:root .switch.on, :root .settings .switch.on { background: var(--well); }
:root .switch.on .knob, :root .settings .switch.on .knob {
  transform: translateX(20px); background: var(--accent); box-shadow: 0 2px 0 var(--accent-lip);
}
:root[data-theme="light"] .switch .knob { background: #fff; }
:root[data-theme="light"] .switch.on .knob { background: var(--accent); }

/* -------------------------------------------------------------------- home */
:root .home.home-focus .avatar { width: 44px; height: 44px; color: var(--ink); }
:root .home.home-focus .home-top { grid-template-columns: minmax(0, 1fr) 44px; }
:root .home.home-focus .stage-play { min-height: 52px; border-radius: 15px; }
:root .home.home-focus .stage-art { border-radius: var(--radius); }
/* The art takes a fixed share of the height; the two tiles take all that's left,
   so nothing pools under the primary action on any phone. */
:root .home.home-focus .play-stage { flex: none; }
:root .home.home-focus .stage-art {
  flex: none; min-height: 132px; max-height: 460px;
  height: clamp(132px, calc((100dvh - 344px) * .58), 460px);
}
:root .home.home-focus .home-shortcuts {
  flex: 1 1 auto; min-height: 128px; grid-auto-rows: minmax(0, 1fr); gap: 10px; padding-bottom: 3px;
}
:root .home.home-focus .home-shortcut {
  flex-direction: column; align-items: stretch; justify-content: stretch;
  gap: 8px; min-height: 0; padding: 6px; text-align: left;
}
.home-tile-art {
  position: relative; display: block; flex: 1 1 0; min-height: 0; overflow: hidden;
  border-radius: 10px; background: #faf3e3; container-type: size;
}
:root .home-tile-art > .category-motif { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; }
/* Browse: three category posters laid over one another on a well */
:root .home-tile-stack { background: var(--well); box-shadow: inset 0 1px 0 var(--well-shade); }
:root .home-tile-stack > .category-motif {
  --s: min(80cqh, 46cqw);
  inset: auto; left: 50%; top: 50%; width: var(--s); height: var(--s);
  margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
  border-radius: 7px; box-shadow: 0 2px 0 var(--tile-lip);
}
:root .home-tile-stack > .category-motif:nth-child(1) { transform: translateX(-42%) rotate(-5deg); }
:root .home-tile-stack > .category-motif:nth-child(2) { transform: translateX(42%) rotate(5deg); }
:root .home-tile-stack > .category-motif:nth-child(3) { z-index: 1; }
.home-tile-copy { flex: none; display: flex; flex-direction: column; gap: 1px; min-width: 0; padding: 0 6px 3px; }
.home-tile-copy strong { font: 900 16px/1.15 var(--ui-headline); letter-spacing: -.035em; }
.home-tile-copy small { font-size: 12px; line-height: 16px; font-weight: 500; color: var(--ink-soft); }

/* ---------------------------------------------------------- create + browse */
:root .generate.create-flow .sugg { font-weight: 600; text-align: center; }
:root .generate.create-flow .suggestion-rail { gap: 10px; }
:root .generate.create-flow .flow-link { min-height: 54px; padding: 10px 14px; font-weight: 600; }
:root .generate.create-flow .flow-settings { gap: 10px; background: none; padding: 0; border-radius: 0; }
:root .generate.create-flow .flow-settings .setting-field + .setting-field { border-top: 0; }
:root .generate.create-flow .setting-row { padding: 10px 14px; min-height: 54px; }
:root .generate.create-flow .setting-label { font-weight: 600; }
:root .generate.create-flow .flow-back { width: 44px; height: 44px; margin-left: 0; }
:root .generate.create-flow .flow-guide-link { min-height: 44px; padding: 8px 14px; color: var(--ink); text-decoration: none; font-weight: 600; }
:root .generate.create-flow .flow-guide-link > svg { color: var(--accent); }
:root .generate.create-flow .flow-actions > .btn { border-radius: var(--radius); }
:root .generate.create-flow .flow-primary { padding-top: 12px; }
:root .generate.create-flow .teacher-body > .setting-field { background: none; padding-inline: 0; border-radius: 0; }

:root .view .catgrid { gap: 14px 12px; }
:root .view .catcard { overflow: hidden; }
:root .view .catcard-action { background: var(--tile); color: var(--ink); box-shadow: 0 2px 0 var(--tile-lip); border-radius: 10px; }
:root .view .pcard-emblem { border-radius: 9px; }
:root .browse .pgrid { gap: 12px; }
:root .view .page-back { width: 44px; height: 44px; color: var(--ink); }

:root .pill, :root .view .pill { border: 0; border-radius: 6px; background: var(--well); color: var(--ink-soft); }
:root .view .pill.ok { background: var(--well); }

/* ------------------------------------------------------------- learn + you */
:root .learn.learn-focus .recall-stop { padding: 8px 14px; color: var(--accent); font-weight: 600; }
:root .learn.learn-focus .recall-session .recall-card { padding: 20px; }
:root .learn .recall-card { border-top: 0; }
:root .learn.learn-focus .recall-stage > .recall-actions { padding-bottom: 3px; }
:root .learn .next-review { border-top-color: var(--hairline); }

:root .profile.profile-focus .profile-destinations { border: 0; background: none; padding: 0; gap: 10px; border-radius: 0; }
:root .profile-entry { padding: 10px 14px; }
:root .profile-entry + .profile-entry { border-top: 0; }
:root .profile-focus .profile-entry > .ico:first-child { background: var(--well); box-shadow: inset 0 1px 0 var(--well-shade); color: var(--ink); border-radius: 10px; width: 34px; height: 34px; }
:root .profile.profile-focus .allowance-link, :root .profile .allowance-link { padding: 10px 14px; border-block: 0; min-height: 50px; color: var(--ink-soft); }
:root .profile-focus .profile-keepsake { padding: 14px; }
:root .profile .mastery-row, :root .profile-empty .mastery-row { border-bottom-color: var(--hairline); }

/* ---------------------------------------------------------------- settings */
/* opened from the player, the back link names the puzzle */
:root .settings .card { padding: 0 14px; }
:root .settings .srow + .srow::before { border-color: var(--ui-settings-divider); }
:root .srow-tap:is(:active, .down) { background: none; }
:root .srow-tap:is(:active, .down) .switch { box-shadow: inset 0 1px 0 var(--well-shade), 0 0 0 1px var(--well-shade); }

/* ----------------------------------------------------------------- paywall */
:root .plan.featured { --card-lc: var(--accent-lip); }
:root .plan.current { --card-lc: var(--good); }
:root .plan.lifetime { border-style: none; }
:root .view .plan-tag { border-radius: 8px; top: -8px; font-size: 11px; letter-spacing: .02em; text-transform: none; box-shadow: 0 2px 0 var(--accent-lip); }
:root .paywall .allowance-balance { padding: 22px 20px; }
:root .buy-row { background: var(--tile); border-radius: 12px; box-shadow: 0 2px 0 var(--tile-lip); }

/* ---------------------------------------------------------- generation chrome */
:root .gencard, :root .gencard.done, :root .gencard.error { padding: 14px; }
:root .gencard.done { --card-lc: var(--good); }
:root .gencard.error { --card-lc: var(--bad); }
:root .gen-away { padding: 0 0 3px; align-items: stretch; background: none; box-shadow: none; border-radius: 0; }
:root .genbar { background: var(--floor); border-top: 0; box-shadow: inset 0 2px 0 var(--wall); min-height: 56px; padding: 8px 12px; }
:root .genbar.done { background: color-mix(in srgb, var(--good) 12%, var(--floor)); border-top: 0; }
:root .genbar.error { background: color-mix(in srgb, var(--bad) 10%, var(--floor)); border-top: 0; }
:root .genbar-act.strong { min-height: 36px; padding: 7px 14px; display: inline-flex; align-items: center; position: relative; }
:root .genbar-act.strong::after { content: ''; position: absolute; inset: -6px -2px; }
:root .genbar-x { width: 44px; height: 44px; margin: -6px -8px -6px 0; display: grid; place-items: center; }
:root .genbar-label, :root .genbar.done .genbar-label, :root .genbar.error .genbar-label {
  font-size: 12px; letter-spacing: 0; text-transform: none; font-weight: 700; color: var(--ink-soft);
}
:root .genbar.done .genbar-label, :root .genbar.error .genbar-label { color: var(--ink); }
:root .genbar-act:not(.strong) { color: var(--ink); }
:root .step-dot { border-radius: 3px; }

/* ------------------------------------------------------------------- trays
   Sheets dock to the bottom edge on a phone, rise on open and fall on close. */
.backdrop { padding: 0; background: var(--scrim); place-items: end center; transition: opacity 160ms ease; }
:root .sheet, :root .sheet.choice-sheet {
  max-width: 540px; width: 100%;
  background: var(--floor); border: 0; border-radius: 22px 22px 0 0;
  padding: 20px 16px max(20px, calc(14px + env(safe-area-inset-bottom)));
  box-shadow: inset 0 2px 0 var(--wall);
  transform: translateY(100%);
  transition: transform 150ms ease-in;
}
.backdrop.in .sheet { transform: none; transition: transform 220ms var(--settle); }
.sheet.choice-sheet::before { display: none; }
:root .sheet-x, :root .choice-sheet .sheet-x {
  width: 44px; height: 44px; margin: -4px 0 0 auto; font-size: inherit;
  display: grid; place-items: center;
}
:root .hub-sheet .sheet-x { min-width: 44px; min-height: 44px; margin-block: -4px; }
:root .sheet-actions { padding-bottom: 3px; }
:root .sheet-actions .btn { min-height: 50px; }
:root .choice-sheet .sheet-body { padding: 4px 4px 8px; margin: -4px; }
:root .choice-list { gap: 10px; }
:root .choice-option { border-radius: var(--radius); min-height: 60px; }
.choice-option[aria-pressed="true"] { --tile-lc: var(--accent-lip); }
:root .choice-mark { border: 0; border-radius: 8px; background: var(--well); box-shadow: inset 0 1px 0 var(--well-shade); }
:root .choice-option[aria-pressed="true"] .choice-mark { background: var(--accent); color: var(--ui-on-accent); box-shadow: 0 2px 0 var(--accent-lip); }
:root .sheet.clues .sheet-body { gap: 2px; }
:root .clues-h { background: var(--floor); color: var(--ink-soft); }
:root .clue-row { min-height: 44px; border-radius: 10px; padding: 10px 8px; align-items: center; }
:root .clue-row + .clue-row { border-top: 0; }
:root .clue-row.on { background: var(--tile); box-shadow: 0 2px 0 var(--tile-lip); }
:root .clue-row.themed { box-shadow: none; }
:root .clue-row.themed.on { box-shadow: 0 2px 0 var(--tile-lip); }
:root .clue-row:is(:active, .down) { background: var(--tile-2); }
:root .clue-row.done .clue-t, :root .clue-row.done .cc-enum { color: var(--ink-soft); }
:root .coach-dot { border-radius: 3px; }
:root .sheet .ad-art { background: var(--well); border-radius: 12px; box-shadow: inset 0 1px 0 var(--well-shade); }

/* Menus are small trays too */
:root .menu-pop {
  min-width: 188px; padding: 6px; gap: 2px;
  background: var(--floor); border: 0; border-radius: 16px;
  box-shadow: inset 0 2px 0 var(--wall), 0 3px 0 var(--wall), var(--shadow);
  animation: menu-rise 120ms ease-out;
}
@keyframes menu-rise { from { opacity: 0; transform: translateY(6px); } }
:root .menu-pop button { min-height: 44px; border: 0; border-radius: 10px; padding: 8px 12px; font-weight: 600; }
:root .menu-pop button:is(:active, .down) { background: var(--tile); }

:root .toast {
  border: 0; border-radius: var(--radius); font-weight: 600;
  box-shadow: 0 3px 0 color-mix(in srgb, var(--ui-feedback-bg) 70%, #000), var(--shadow);
  transition: opacity 160ms ease, transform 160ms ease;
}

/* -------------------------------------------------------------- bottom nav */
:root .bottomnav {
  position: relative; border-top: 0;
  background: var(--floor); box-shadow: inset 0 2px 0 var(--wall);
  padding: 8px 8px calc(6px + env(safe-area-inset-bottom));
}
:root .bottomnav .navitem { position: relative; z-index: 1; min-height: 52px; gap: 3px; color: var(--ink-soft); }
:root .bottomnav .navitem.on { color: var(--ink); }
:root .bottomnav .navitem.on::after { display: none; }
:root .bottomnav :is(.navicon, .navitem.center .navicon) { width: 56px; height: 30px; border-radius: 0; background: none; box-shadow: none; transition: transform var(--press) ease-out; }
:root .bottomnav .navitem.on .navicon { background: none; box-shadow: none; }
:root .bottomnav .navitem:is(:active, .down) .navicon { transform: translateY(2px); }
.nav-ind {
  --at: 0;
  position: absolute; z-index: 0; top: 8px; left: 8px; width: calc((100% - 16px) / 5); height: 30px;
  display: grid; place-items: center; pointer-events: none;
  transform: translateX(calc(var(--at) * 100%));
  transition: transform 180ms var(--settle);
}
.nav-ind::before {
  content: ''; width: 56px; height: 30px; border-radius: 11px; background: var(--tile);
  box-shadow: var(--hi), 0 2px 0 var(--tile-lip), 0 3px 1px var(--contact);
}
:root .nav-badge { border-color: var(--floor); }

/* ------------------------------------------------------------------ player
   The board sits in a frame; everything else lives in the tray below it. */
:root .player { background: var(--app-bg); }   /* it arrives through js/entry.js */

:root .play-head {
  border-bottom: 0; gap: 8px; padding: max(6px, env(safe-area-inset-top)) 8px 4px; min-height: 54px;
}
:root .iconbtn { width: 44px; height: 44px; margin-bottom: 3px; }
:root .iconbtn::after { display: none; }
:root .iconbtn svg { stroke: currentColor; }
:root .play-topic { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
:root .play-sub { font-size: 12px; line-height: 15px; }
:root .play-learn { color: var(--themed); font-weight: 600; margin-left: 0; }
:root .play-prog {
  height: 30px; padding: 0 9px; gap: 7px; border-radius: 10px; background: var(--well);
  box-shadow: inset 0 1px 0 var(--well-shade), 0 1px 0 var(--well-rim);
}
:root .progress-bar { width: 40px; height: 5px; background: var(--ui-line); box-shadow: none; }
:root #progress-label { font-size: 12px; font-weight: 600; color: var(--ink); min-width: 0; white-space: nowrap; }

/* --board-y is read by fitGrid: the frame top and bottom, then a pixel of air.
   The frame is an even ring; the board has no lip or shadow under it. */
:root .board, :root .player .board {
  --frame-w: 4px; --board-y: 9px;
  padding: 5px calc(8px + var(--frame-w)) 0; background: none;
}
:root .grid {
  gap: 1px; border: 1px solid var(--cell-line); background: var(--cell-line); border-radius: 2px;
  box-shadow: 0 0 0 var(--frame-w, 4px) var(--frame);
}
:root .grid:focus-visible { outline: 2px solid var(--accent); outline-offset: 7px; }
.cell.block { background: var(--cell-block); box-shadow: 0 0 0 1px var(--cell-block); }
/* Dark squares are close to the blocks, so each open square keeps its line on
   top of the block's edge. Adjacent blocks still merge into one shape. */
:root[data-grid="dark"] .cell:not(.block) { z-index: 1; box-shadow: 0 0 0 1px var(--cell-line); }
:root .cell { font-family: var(--ui-display); font-weight: 700; font-size: max(11px, calc(var(--sq, 24px) * .6)); color: var(--cell-ink); }
:root .cell .num { font-weight: 600; font-size: max(8px, calc(var(--sq, 24px) * .36)); top: 0; left: 1.5px; line-height: 1.15; }
:root .cell .ch { transform: translateY(.16em); }
.cell.in-word  { background: var(--cell-word); }
.cell.selected { background: var(--cell-sel); }
.cell.theme-sq.in-word  { background: var(--theme-word); }
.cell.theme-sq.selected { background: var(--theme-sel); }
:root .cell:is(.in-word, .selected) .num { opacity: 1; }

/* The key-term marker: one notch, top-right of the word's first square, well
   away from the number (top-left) and the letter (low and centred). */
.cell.notch::after {
  content: ''; position: absolute; top: 0; right: 0; z-index: 1;
  width: max(6px, calc(var(--sq, 24px) * .3)); height: max(6px, calc(var(--sq, 24px) * .3));
  background: var(--key-mark); clip-path: polygon(0 0, 100% 0, 100% 100%);
}

/* Wrong and right keep their ink and the diagonal; revealed gets a small dash,
   which is a mark and not a bevel. */
.cell.revealed {
  box-shadow: none; font-style: normal;
  background-image: linear-gradient(var(--cell-shown), var(--cell-shown));
  background-size: 42% 1.5px; background-position: 50% calc(100% - 1px); background-repeat: no-repeat;
}
.cell.wrong::before { opacity: 1; }

/* Overlays: the active word's outline, and the cursor's inset ring in letter ink */
:root .ov { border-radius: 0; }
:root .ov-word { border: 1.5px solid var(--word-line); }
:root .ov-word.themed { border-color: var(--key-mark); }
:root .ov-cell { border: 1.5px solid var(--cell-ink); }
:root .cell.selected .num { top: 1px; left: 2.5px; }

/* A finished key term flashes once, in place */
.cell.flash { animation: term-flash 420ms ease-out both; }
@keyframes term-flash { 0%, 35% { background: var(--cell-flash); } }

/* The solve: a colour wave, no scaling; each square returns to its own fill */
.player.celebrate .cell:not(.block) { animation: wave 620ms ease-out var(--wave, 0ms) 1 both; }
@keyframes wave { 40% { background: var(--cell-wave); } }
.solved-splash { animation: splash-calm 1.6s ease-out both; }
@keyframes splash-calm { 0% { opacity: 0; transform: translateY(6px); } 14% { opacity: 1; transform: none; } 80% { opacity: 1; } 100% { opacity: 0; } }
:root .solved-splash strong {
  font: 900 24px/1.1 var(--ui-headline); letter-spacing: -.03em; color: var(--ink); background: var(--tile);
  padding: 10px 18px; border-radius: var(--radius); box-shadow: 0 3px 0 var(--tile-lip), 0 4px 2px var(--contact);
}
:root .solved-splash span {
  font: 600 14px/1 var(--ui-display); color: var(--ink); background: var(--tile); border: 0; padding: 6px 10px; margin-top: 4px;
  border-radius: 9px; box-shadow: 0 2px 0 var(--tile-lip);
}

/* Learn note: a tile that floats over the board, so the grid never reflows */
:root .learn-panel {
  --card-lc: var(--learn-lip);
  left: 16px; right: 16px; padding: 14px 52px 16px 16px; border: 0;
  animation: rise 160ms ease-out;
}
@keyframes rise { from { opacity: 0; transform: translateY(calc(-50% + 8px)); } }
:root .learn-term { font-size: 18px; line-height: 1.2; letter-spacing: .02em; color: var(--ink); margin-bottom: 6px; }
:root .learn-body { font-size: 15px; line-height: 1.42; max-height: 34dvh; }
:root .learn-close { top: 8px; right: 8px; width: 44px; height: 44px; }

/* The tray: clue, tools, keys */
:root .dock {
  position: relative; background: var(--floor); border-radius: 22px 22px 0 0;
  box-shadow: inset 0 2px 0 var(--wall); padding: 9px 6px 0; margin-top: 2px;
}
/* Arrows and clue are one slab: it drops as a piece */
:root .cluebar {
  --lc: var(--tile-lip);
  gap: 0; padding: 0; border: 0; overflow: hidden; margin-bottom: 11px; min-height: clamp(60px, 9.5dvh, 80px);
  background: var(--tile); border-radius: var(--radius);
  box-shadow: var(--hi), 0 3px 0 var(--lc), 0 4px 2px var(--contact);
  transition: transform var(--press) ease-out, box-shadow var(--press) ease-out;
}
:root .cluebar:has(.arrow:active, .arrow.down, .clue-card:active, .clue-card.down) {
  transform: translateY(2px); box-shadow: var(--hi), 0 1px 0 var(--lc), 0 1px 1px var(--contact);
}
:root .arrow { width: 44px; border-radius: 0; color: var(--ink-soft); }
:root .arrow:first-child { box-shadow: 1px 0 0 var(--hairline); }
:root .arrow:last-child { box-shadow: -1px 0 0 var(--hairline); }
:root .arrow:is(:active, .down) { background: var(--tile-2); }
:root .clue-card { background: transparent; border: 0; border-radius: 0; min-height: 0; padding: 7px 12px; gap: 10px; }
:root .player.solved .clue-card { border: 0; }
:root .cc-num { font-size: 14px; font-weight: 700; color: var(--accent); }
:root .cc-text { font-size: 16px; line-height: 1.26; font-weight: 600; }
:root .cc-text.long { font-size: 14px; line-height: 1.28; }
:root .cc-text.xlong { font-size: 13px; line-height: 1.28; }
:root .clue-card:has(.cc-learn:not([hidden])) .cc-text:is(.long, .xlong) { font-size: 13px; }
:root .cc-flag { color: var(--themed); }
:root .cc-learn {
  --lc: var(--learn-lip);
  background: var(--themed); color: var(--app-bg); border-radius: 9px;
  padding: 7px 10px 6px; font-size: 12px; font-weight: 700; letter-spacing: .01em; text-transform: none;
  box-shadow: 0 2px 0 var(--lc); margin-bottom: 2px;
  transition: transform var(--press) ease-out, box-shadow var(--press) ease-out;
}
:root[data-theme="light"] .cc-learn { color: #fff; }
:root .cc-learn:is(:active, .down) { transform: translateY(1px); box-shadow: 0 1px 0 var(--lc); }
.cc-learn.pulse { animation: learn-nudge 700ms ease-in-out 2; }
@keyframes learn-nudge { 50% { transform: translateY(-2px); box-shadow: 0 4px 0 var(--lc); } }

:root .toolbar {
  background: none; border: 0; padding: 0 2px; gap: 6px; margin-bottom: 8px; min-height: 46px;
}
:root .timer { font-size: 14px; font-weight: 600; color: var(--ink); min-width: 36px; }
:root .tb-status { font-size: 12px; line-height: 1.2; font-weight: 500; color: var(--ink-soft); text-align: left; white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
/* a notice may take a third line: 3 x 14.4px still fits the 44-46px toolbar,
   and the slot is narrow now that the toolbar holds five buttons */
:root .tb-status.notice, :root .tb-status.warn { -webkit-line-clamp: 3; }
:root .tb-status.notice { color: var(--ink); font-size: 12px; font-weight: 600; }
:root .tb-status.warn { color: var(--bad-ink); }
:root .player.solved .tb-status { color: var(--ink); }
:root .tb-actions { gap: 6px; padding-bottom: 2px; }
:root .icon { min-width: 48px; height: 44px; padding: 0 2px; }
:root .icon svg { stroke: currentColor; width: 20px; height: 20px; }
:root .icon-l { color: inherit; font-size: 10px; font-weight: 600; }

/* Keys: the same tile, game-owned. Fired on pointerdown in player.js. */
:root .kbd {
  --key-h: clamp(44px, 6.5dvh, 58px);
  background: none; border: 0; gap: 7px;
  padding: 0 0 calc(7px + env(safe-area-inset-bottom));
}
:root .kbd-row { gap: 4px; }
:root .kbd-row:nth-child(2) { padding: 0 5%; }
:root .key, :root[data-theme="light"] .key {
  height: var(--key-h);
  font-family: var(--ui-display); font-size: clamp(17px, 5vw, 21px); font-weight: 600;
  transition: transform var(--press) ease-out, box-shadow var(--press) ease-out,
              background-color 200ms ease, color 200ms ease;
}
:root .key svg { display: block; }

:root .player.no-kbd .kbd-restore {
  width: calc(100% - 4px); margin: 0 2px calc(8px + env(safe-area-inset-bottom));
  min-height: 46px; padding: 8px; color: var(--accent); font-size: 14px; font-weight: 600;
}

/* The ending. The keys sink where they are, late in the wave. settle() then
   swaps in the bar, which rises, inert for its first 700ms (the ghost-tap guard
   in player.js). Nothing here moves the board. */
:root .player.locked:not(.settled) .key {
  transition: transform 220ms ease-in, box-shadow 220ms ease-in, background-color 240ms ease-in, color 160ms ease;
  transition-delay: calc(640ms + var(--i, 0) * 6ms);
  transform: translateY(2px); box-shadow: 0 0 0 transparent; background: var(--floor); color: transparent;
}
.player.locked:not(.settled) .key svg { opacity: 0; transition: opacity 160ms ease 640ms; }

:root .player.settled .dock { display: flex; flex-direction: column; min-height: var(--dock-h, 0); }
:root .player.settled .solved-bar { margin-top: auto; }
:root .player.locked .solved-bar, :root .player.settled .solved-bar {
  background: none; border: 0; padding: 2px 2px calc(8px + env(safe-area-inset-bottom)); gap: 8px;
  animation: bar-rise 240ms var(--settle);
}
@keyframes bar-rise { from { opacity: 0; transform: translateY(14px); } }
:root .solved-bar .solved-heading, :root .player.settled .solved-heading { gap: 10px; padding: 0 2px; }
:root .solved-bar .solved-heading h2, :root .player.settled .solved-heading h2 {
  font: 900 18px/22px var(--ui-headline); letter-spacing: -.03em;
}
:root .solved-bar .btn, :root .player.settled .solved-bar .btn { min-height: 44px; padding: 8px 10px; font-size: 14px; }
:root .solved-bar .btn.primary { flex-basis: 100%; }
/* Share, Play again and Another puzzle: one size, a third of the row each */
:root .solved-actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; width: 100%; }
:root .solved-actions .btn { min-width: 0; white-space: nowrap; }
/* the poster fills the room the keyboard gave back */
:root .player.settled .solved-heading .milestone-art { width: 112px; height: 84px; }
:root .player.settled .toolbar { min-height: 46px; margin-bottom: 6px; padding-block: 0; }
:root .player.settled .cluebar { min-height: 56px; margin-bottom: 9px; padding-block: 0; }
:root .player.settled .clue-card { min-height: 0; }

/* The zoom fog sits on the board, not the tray */
:root .boardwrap::after { inset: 0 0 2px; }
:root .player.zoomed .board { padding: 8px 12px 12px; }
:root .player.zoomed .grid { box-shadow: none; }

/* Ad bar keeps its place in the stack, in the tray's colour */
:root .adbar { border-top: 0; min-height: 44px; padding-block: 0; }
:root body.immersive .adbar { padding-block: 0 env(safe-area-inset-bottom); }
:root .ad-x { display: inline-flex; align-items: center; min-height: 44px; padding-inline: 8px; margin-right: -8px; }
:root .gen-details summary { display: flex; align-items: center; min-height: 44px; }

/* ------------------------------------------------------------- responsive */
/* Short phones: the keys hold 44px, so the chrome around them gives way, and
   the solved tray folds to the same height so the board doesn't move. */
@media (max-height: 700px) {
  :root .play-head { min-height: 0; padding: max(2px, env(safe-area-inset-top)) 8px 2px; }
  :root .play-sub { font-size: 11px; line-height: 13px; }
  :root .board, :root .player .board { padding-top: 2px; }
  :root .dock { padding-top: 6px; margin-top: 0; }
  :root .cluebar { margin-bottom: 6px; min-height: 56px; }
  :root .clue-card { padding-block: 3px; gap: 8px; }
  :root .cc-text { font-size: 14px; line-height: 1.2; }
  :root .cc-text.long, :root .cc-text.xlong { font-size: 13px; line-height: 1.2; }
  :root .toolbar { margin-bottom: 4px; min-height: 44px; }
  :root .tb-actions { padding-bottom: 2px; }
  :root .kbd { gap: 4px; padding-bottom: calc(4px + env(safe-area-inset-bottom)); }
  :root .kbd-row { gap: 3px; }
  :root .solved-bar .milestone-art { display: none; }
  :root .player.settled .cluebar { min-height: 48px; margin-bottom: 6px; }
  :root .player.settled .toolbar { margin-bottom: 2px; }
  :root .player.locked .solved-bar { padding-top: 0; gap: 4px 6px; }
  :root .solved-bar .solved-heading h2, :root .player.settled .solved-heading h2 { font-size: 16px; line-height: 18px; }
  :root .player.settled .solved-stats { margin-top: 0; font-size: 12px; line-height: 15px; }
  :root .player.settled .solved-bar .btn { font-size: 13px; padding-inline: 8px; flex: 1 1 auto; }
}
@media (max-width: 380px) {
  .home-tile-copy { padding-inline: 4px; }
  .home-tile-copy small { font-size: 11px; }
}
@media (max-width: 350px) {
  :root .play-prog { padding: 0 7px; }
  :root .tb-actions { gap: 4px; }
  :root .icon { min-width: 44px; }
}
/* Above a phone, a sheet is a tray on the table, not an edge drawer. */
@media (min-width: 560px) and (min-height: 561px) {
  .backdrop { place-items: center; padding: 24px; }
  :root .sheet, :root .sheet.choice-sheet {
    border-radius: 22px; max-height: calc(100dvh - 48px);
    padding-bottom: 20px; box-shadow: inset 0 2px 0 var(--wall), 0 4px 0 var(--wall);
    transform: translateY(16px); opacity: 0;
    transition: transform 150ms ease-in, opacity 150ms ease-in;
  }
  .backdrop.in .sheet { transform: none; opacity: 1; transition: transform 220ms var(--settle), opacity 150ms ease-out; }
}
/* Phone landscape: board on the left at full height, the tray beside it. */
@media (orientation: landscape) and (max-height: 500px) {
  :root .app { max-width: none; }
  :root .player {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 48%); grid-template-rows: auto minmax(0, 1fr);
    padding-right: env(safe-area-inset-right); padding-left: env(safe-area-inset-left);
  }
  :root .boardwrap { grid-column: 1; grid-row: 1 / 3; min-height: 0; }
  :root .play-head { grid-column: 2; grid-row: 1; min-height: 0; padding: max(3px, env(safe-area-inset-top)) 6px 2px; }
  :root .iconbtn { margin-bottom: 3px; }
  :root .player .dock, :root .player.settled .dock { grid-column: 2; grid-row: 2; min-height: 0; margin: 0; border-radius: 16px 0 0 0; padding: 6px 6px 0; overflow-y: auto; display: flex; flex-direction: column; }
  :root .board, :root .player .board { padding: 3px 8px 0 12px; }
  :root .cluebar { min-height: 44px; margin-bottom: 7px; flex: none; }
  :root .clue-card { padding-block: 2px; }
  :root .cc-text { font-size: 14px; line-height: 1.2; }
  :root .cc-text.long, :root .cc-text.xlong { font-size: 13px; line-height: 1.2; }
  :root .toolbar { flex: none; margin-bottom: 4px; min-height: 44px; }
  :root .kbd { --key-h: 44px; gap: 5px; margin-top: auto; flex: none; padding-bottom: calc(4px + env(safe-area-inset-bottom)); }
  :root .kbd-row { gap: 3px; }
  :root .kbd-row:nth-child(2) { padding: 0 4%; }
  :root .player.locked .solved-bar { flex: none; gap: 6px; }
  /* beside the board there is room again for the poster */
  :root .player.settled .solved-heading .milestone-art { display: block; width: 96px; height: 72px; }
  :root .player.settled .cluebar { min-height: 44px; }
  :root .bottomnav { padding: 4px 8px calc(3px + env(safe-area-inset-bottom)); padding-inline: max(8px, env(safe-area-inset-left)) max(8px, env(safe-area-inset-right)); }
  :root .bottomnav .navitem { min-height: 44px; }
  .nav-ind { top: 4px; }
  :root .view {
    width: 100%; max-width: 640px; margin-inline: auto;
    padding-left: max(20px, env(safe-area-inset-left)); padding-right: max(20px, env(safe-area-inset-right));
    padding-block: 12px;
  }
  :root .home.home-focus, :root .generate.create-flow { min-height: 0; }
  :root .home.home-focus { gap: 10px; }
  :root .home.home-focus .play-stage {
    flex: none; display: grid; grid-template-columns: 168px minmax(0, 1fr); column-gap: 16px;
    align-content: start; align-items: center; justify-items: start; text-align: left;
  }
  :root .home.home-focus .stage-art { grid-row: 1 / span 6; width: 168px; height: 168px; min-height: 0; flex: none; }
  :root .home .stage-meta, :root .home .stage-progress { justify-content: flex-start; }
  /* no height to spare, so the tiles lie flat with their art at the side */
  :root .home.home-focus .home-shortcuts { flex: none; height: 96px; min-height: 0; }
  :root .home.home-focus .home-shortcut { flex-direction: row; align-items: center; gap: 10px; }
  :root .home-tile-art { flex: 0 0 104px; height: 100%; }
  :root .home-tile-copy { flex: 1 1 0; }
}

/* ---------------------------------------------------------- reduced motion
   State still changes; nothing travels. The spinner stays: it is the only sign
   that work is still happening, as styles.css already says. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0s !important; transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
  *:not(.spinner), *::before, *::after { animation: none !important; }
  :root :is(.view, .sheet, .solved-bar, .dock, .bottomnav) :is(:active, .down):not(:disabled) { transform: none !important; }
  :root .cluebar:has(.arrow:active, .arrow.down, .clue-card:active, .clue-card.down) { transform: none; }
  :root .sheet, :root .sheet.choice-sheet { transform: none; }
  :root .key.down, :root[data-theme="light"] .key.down { transform: none; }
  .player.locked:not(.settled) .key { transform: none; }
}
