/* Blast Maze */

:root {
  --bg: #0b0b16;
  --panel: #15152a;
  --panel-2: #1c1c36;
  --line: #2a2a4a;
  --text: #eceaf6;
  --muted: #9a9ac0;
  --accent: #5858FD;
  --amber: #ffb703;
  --teal: #2ec4b6;
  --rose: #ff6b8b;
}

* { box-sizing: border-box; }

/* A class that sets `display` beats the browser's own `[hidden]` rule, so an
   element hidden from script stays on screen while the code reads as correct.
   The overlays and the Trigger button both set display. */
[hidden] { display: none !important; }

html, body { height: 100%; }

/* No double tap zoom anywhere on the page: a quick second tap is exactly what a
   bomb drop looks like, and a zoomed page has no reliable way back. Pinch zoom
   is kept for the menus; the play area itself sets touch-action none below. */
html { touch-action: manipulation; }

body {
  margin: 0;
  background:
    radial-gradient(800px 400px at 15% -10%, rgba(88, 88, 253, 0.16), transparent 60%),
    radial-gradient(700px 400px at 90% 0%, rgba(255, 183, 3, 0.08), transparent 60%),
    var(--bg);
  color: var(--text);
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.shell {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  padding: 14px 18px 22px;
  gap: 12px;
}

/* HUD */
.hud {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(21, 21, 42, 0.72);
}
.hud-stats { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.stat { display: inline-flex; align-items: baseline; gap: 6px; font-size: 13px; }
.stat em { color: var(--muted); font-style: normal; letter-spacing: 0.4px; }
.stat b { font-size: 16px; font-variant-numeric: tabular-nums; }
.chips { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.chip {
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(88, 88, 253, 0.18);
  color: #c9c9ff;
  font-size: 12px;
  white-space: nowrap;
}
.chip-hot { background: rgba(226, 59, 59, 0.2); color: #ffb3b3; }
.chip-cool { background: rgba(58, 155, 216, 0.22); color: #bfe6ff; }

.hud-btns { display: flex; gap: 8px; }
.hud-btn {
  padding: 7px 13px;
  min-height: 34px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
}
.hud-btn:hover { color: var(--text); border-color: var(--accent); }
.hud-btn .sound-off { display: none; }
.hud-btn .sound-on svg, .hud-btn .sound-off svg { width: 16px; height: 16px; vertical-align: -3px; }
.hud-btn[aria-pressed="true"] .sound-on { display: none; }
.hud-btn[aria-pressed="true"] .sound-off { display: inline; }
.hud-btn[aria-pressed="true"] { color: #ff8c8c; border-color: rgba(255, 140, 140, 0.35); }

/* Stage */
.stage {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  min-height: 0;
}
canvas {
  display: block;
  border-radius: 10px;
  background: #10131f;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
  touch-action: none;
  max-width: 100%;
}

/* Touch layer. Absent on a desktop; on a phone it is a band of its own below
   the maze rather than a sheet over it.

   It used to lie over the whole play area, board included, on the reasoning
   that a thumb should find a control without looking. What that actually did
   was put the joystick, the bomb button and three smaller ones on top of the
   thing being played, and the report was the plain one: the controls block the
   view. A band costs some cell size and gives back the whole maze unobstructed,
   and because cells are sized off the height, smaller cells mean MORE of the 31
   columns on screen at once - so the view gets wider as well as clearer.
   fitCanvas sets this band's height and takes the same number out of the height
   it gives the canvas, so the two can never overlap. */
.touch { display: none; }
body.has-touch .touch {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 0 0 auto;
  width: 100%;
  padding: 6px max(10px, env(safe-area-inset-left)) calc(6px + env(safe-area-inset-bottom))
           max(10px, env(safe-area-inset-right));
  box-sizing: border-box;
  z-index: 20;
}
body.has-touch .stage { flex-direction: column; align-items: center; }
/* The band never swallows a tap meant for the board: only the zones take
   pointers, and in landscape the middle of this element is the board. */
body.has-touch .touch { pointer-events: none; }
.zone { position: relative; touch-action: none; height: 100%; pointer-events: auto; }
.zone-move {
  flex: 1 1 44%;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.03);
}
.zone-bomb {
  flex: 1 1 56%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
}

.stick {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 112px;
  height: 112px;
  margin: -56px 0 0 -56px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.22);
  background: rgba(10, 10, 22, 0.28);
  opacity: 0.35;
  pointer-events: none;
  transition: opacity 0.12s;
}
.stick.is-on { opacity: 1; transition: none; }
.stick-knob {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 50px;
  height: 50px;
  margin: -25px 0 0 -25px;
  border-radius: 50%;
  background: rgba(88, 88, 253, 0.75);
  border: 2px solid rgba(255, 255, 255, 0.55);
}
.zone-hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 6px;
  text-align: center;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.35);
  pointer-events: none;
}
body.is-playing .zone-hint { display: none; }

.bomb-btn {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: min(100%, clamp(66px, 19vw, 96px));
  aspect-ratio: 1;
  border-radius: 50%;
  border: 2px solid rgba(255, 214, 120, 0.7);
  background: rgba(255, 122, 26, 0.42);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  pointer-events: none;
}
.zone-bomb.is-down .bomb-btn { background: rgba(255, 183, 3, 0.8); color: #1a1400; }
/* The optional buttons sit between the pad and the bomb button, inside the
   band, and wrap into two columns on a narrow phone rather than squeezing the
   bomb button or reaching back across the pad. 12px between thumb targets
   throughout, which is the house rule and is measured, not assumed. */
.tbtn-stack {
  flex: 0 1 auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-content: center;
  gap: 12px;
  max-height: 100%;
}
.tbtn {
  display: grid;
  place-items: center;
  width: clamp(38px, 10vw, 56px);
  height: clamp(38px, 10vw, 56px);
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.5);
  background: rgba(88, 88, 253, 0.5);
  color: #fff;
  font: inherit;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: -0.2px;
  touch-action: none;
}
/* Landscape is the other shape of the problem. A band under the maze spends
   height, which is the scarce dimension when a phone is on its side, and leaves
   half the width empty: the maze came out at 12px a cell across 372 of 740
   pixels. Either side of the board instead, the maze gets the whole height and
   still fits across - 16px a cell, a third bigger, with the controls beside it
   rather than over it or under it. fitCanvas takes the two columns off the
   width the same way it takes the band off the height. */
@media (orientation: landscape) {
  body.has-touch .stage { flex-direction: row; justify-content: center; align-items: center; }
  body.has-touch .touch {
    position: absolute;
    inset: 0;
    height: auto !important;
    justify-content: space-between;
    padding: 4px max(6px, env(safe-area-inset-right)) calc(4px + env(safe-area-inset-bottom))
             max(6px, env(safe-area-inset-left));
  }
  body.has-touch .zone-move,
  body.has-touch .zone-bomb { flex: 0 0 clamp(96px, 17vw, 150px); }
  body.has-touch .zone-bomb {
    flex-direction: column-reverse;
    justify-content: center;
    align-items: center;
  }
  body.has-touch .tbtn-stack { justify-content: center; max-width: 100%; }
}

.tbtn-trigger { border-color: rgba(255, 154, 168, 0.75); background: rgba(226, 59, 59, 0.5); }
.tbtn-trigger:active { background: rgba(226, 59, 59, 0.9); }
.tbtn-punch { border-color: rgba(255, 214, 120, 0.75); background: rgba(232, 163, 61, 0.5); }
.tbtn-punch:active { background: rgba(232, 163, 61, 0.9); }
.tbtn-line { border-color: rgba(160, 196, 255, 0.75); background: rgba(74, 122, 216, 0.5); }
.tbtn-line:active { background: rgba(74, 122, 216, 0.9); }

/* Overlays. Fixed rather than absolute, so a modal is centred on and sized to
   the same box, and its footer can never end up below the bottom edge. */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  background: rgba(7, 7, 16, 0.78);
  backdrop-filter: blur(4px);
}
.modal {
  width: min(580px, 100%);
  max-height: calc(100vh - 36px);
  max-height: calc(100dvh - 36px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--panel);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.modal-slim { width: min(440px, 100%); }
.modal-head { flex-shrink: 0; padding: 18px 22px 6px; }
.modal-head h1, .modal-head h2 { margin: 0; font-size: 22px; letter-spacing: -0.4px; }
.kicker { margin: 0 0 2px; font-size: 11px; letter-spacing: 1.6px; text-transform: uppercase; color: var(--muted); }
.modal-body { flex: 1 1 auto; min-height: 0; padding: 8px 22px 16px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.modal-body p { margin: 0 0 12px; color: var(--muted); line-height: 1.6; font-size: 14.5px; }
.modal-body h2 { margin: 16px 0 8px; font-size: 13px; letter-spacing: 0.6px; text-transform: uppercase; color: var(--muted); }
.modal-foot {
  flex-shrink: 0;
  padding: 14px 22px 18px;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.best-line { margin-top: 10px !important; color: var(--amber) !important; }
.hint { margin: 8px 0 0 !important; font-size: 13px !important; }

.btn {
  padding: 10px 18px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-size: 14.5px;
  cursor: pointer;
}
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.btn-ghost { background: transparent; color: var(--muted); }
.btn:hover { filter: brightness(1.08); }
.link-back { color: var(--muted); font-size: 13.5px; text-decoration: none; }
.link-back:hover { color: var(--text); }

.controls ul, .powers { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.controls li, .powers li {
  display: flex; align-items: center; gap: 10px;
  color: var(--muted); font-size: 14px; line-height: 1.5;
}
.powers b { color: var(--text); font-weight: 600; }
kbd {
  display: inline-block;
  min-width: 26px;
  padding: 3px 7px;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  text-align: center;
}
.pw { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 5px; }
.pw-bomb { background: #5858FD; }
.pw-fire { background: #ff7a1a; }
.pw-remote { background: #e23b3b; }
.pw-shield { background: #3a9bd8; }
.pw-full { background: #d64545; }
.pw-kick { background: #ff6b8b; }
.pw-punch { background: #e8a33d; }
.pw-line { background: #4a7ad8; }
.pw-pierce { background: #9b5de5; }
.pw-flamepass { background: #ff5a3c; }
.pw-bombpass { background: #7a7a92; }
.pw-wallpass { background: #b98a52; }
.pw-life { background: #3fbf5f; }
/* The cheat picker names the counted powers rather than the items, so its
   first three rows reuse the colours of the items they max out. */
.pw-bombs { background: #5858FD; }
.pw-speed { background: #2ec4b6; }
.en-soft { background: #ff6b8b; border-radius: 50%; }
.en-tank { background: #8a6f5a; border-radius: 50%; }
.en-split { background: #6fd66f; border-radius: 50%; }
.en-blink { background: #2ec4b6; border-radius: 50%; }
.en-boss { background: #6a3a8a; border-radius: 50%; box-shadow: inset 0 3px 0 #ffd166; }

/* The stage picker */
.segmented {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel-2);
}
.segmented button {
  min-width: 40px;
  min-height: 38px;
  padding: 6px 10px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}
.segmented button.is-on { background: var(--accent); color: #fff; font-weight: 600; }
.seg-mode button { min-width: 96px; }

/* Cheat mode. Tick boxes rather than a segmented row: the powers are not
   alternatives, and picking several is the whole point of the mode. */
.cheats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 8px;
}
.cheat {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--muted);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.cheat.is-on { border-color: var(--accent); background: rgba(88, 88, 253, 0.16); color: var(--text); }
.cheat-txt { display: grid; gap: 1px; }
.cheat-txt b { color: var(--text); font-size: 13.5px; font-weight: 600; }
.cheat-txt em { font-style: normal; font-size: 11.5px; color: var(--muted); }
.chip-cheat { background: rgba(255, 183, 3, 0.22); color: #ffe0a3; }

/* Input specific guides. The gate needs !important: `.controls ul` sets its own
   display, which outranks a plain attribute selector. */
[data-input="touch"] { display: none !important; }
body.has-touch [data-input="key"] { display: none !important; }
body.has-touch [data-input="touch"] { display: block !important; }

/* Footer */
.foot { margin-top: auto; color: var(--muted); font-size: 12.5px; line-height: 1.7; }
.foot p { margin: 4px 0; }
.foot a { color: var(--muted); }
.foot a:hover { color: var(--text); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Controls are controls, not text: a thumb held on one must not raise a
   selection or an iOS copy callout. Every game here carries the same list, and
   tools/verify.js fails if one of them loses a line of it. Prose is left out on
   purpose - One Over's share card is a textarea a player copies from - and so
   is any text input, which has to stay selectable to be usable. */
button, kbd, canvas, summary, label,
.tbtn, .tbtn-stack, .touch, .touch-left, .touch-right, .touch-row, .touch-pad,
.zone, .stick, .bomb-btn, .board, .tiles, .swatches,
.hud, .hud-btn, .hud-btns, .hud-stats, .chips, .topbar, .topbar-actions,
.segmented, .cheats, .more-sheet,
a.hud-back, a.icon-back, a.link-back, a.btn,
[role="button"], [role="radio"], [role="gridcell"], [role="checkbox"], [role="switch"] {
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/* While a run is on, the page is the game. */
body.is-playing .foot { display: none !important; }
:fullscreen .foot { display: none !important; }
:-webkit-full-screen .foot { display: none !important; }

/* On a phone every pixel of chrome is picture lost, so the frame goes and the
   HUD becomes one slim row. */
body.has-touch .shell {
  padding: max(4px, env(safe-area-inset-top)) max(6px, env(safe-area-inset-right))
           max(4px, env(safe-area-inset-bottom)) max(6px, env(safe-area-inset-left));
  gap: 4px;
}
body.has-touch .hud { padding: 3px 8px; gap: 8px; border-radius: 8px; flex-wrap: nowrap; }
body.has-touch .hud-stats { gap: 10px; flex-wrap: nowrap; overflow: hidden; }
/* A run carrying nine powers wrapped the chips onto a second row, and on a
   phone that second row comes straight out of the height of the board. They
   run off the end instead: the chips are a reminder, the board is the game. */
body.has-touch .chips { flex-wrap: nowrap; overflow: hidden; }
body.has-touch .stat { font-size: 11px; gap: 4px; white-space: nowrap; }
body.has-touch .stat b { font-size: 14px; }
body.has-touch .chip { font-size: 10.5px; padding: 1px 7px; }
body.has-touch .hud-btn { padding: 4px 8px; font-size: 11.5px; }
body.has-touch canvas { border-radius: 0; box-shadow: none; }
@media (orientation: portrait) {
  body.has-touch .chips { display: none; }
  body.has-touch #btnSound { display: none; }
  /* A phone held upright has no room for all four counters beside two buttons:
     the row clipped mid word, so "Lives" read as "Liv" and the stage number
     wrapped onto a second line. The score is the one a player checks least
     during a run, and it is on the results screen either way. */
  body.has-touch .stat-score { display: none; }
}

/* In fullscreen the maze is the screen: a hairline HUD and nothing else. */
:fullscreen .shell { padding: 2px 4px; gap: 2px; }
:-webkit-full-screen .shell { padding: 2px 4px; gap: 2px; }
:fullscreen .hud { padding: 2px 8px; border-radius: 6px; background: rgba(21, 21, 42, 0.9); }
:-webkit-full-screen .hud { padding: 2px 8px; border-radius: 6px; background: rgba(21, 21, 42, 0.9); }
:fullscreen canvas { border-radius: 0; box-shadow: none; }
:-webkit-full-screen canvas { border-radius: 0; box-shadow: none; }

@media (max-height: 520px) {
  .foot { display: none; }
  .shell { padding: 6px 10px 6px; gap: 6px; }
}

/* The way out is one icon button, the same in every game. */
.icon-back {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  margin: 0;
  flex: 0 0 auto;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.04);
  color: inherit;
  opacity: 0.82;
  text-decoration: none;
}
.icon-back:hover { opacity: 1; background: rgba(255, 255, 255, 0.10); }
.icon-back svg { display: block; }
.icon-back .visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
body.has-touch .icon-back { width: 34px; height: 34px; }

@media (pointer: coarse) {
  .hud-btn, .btn { min-height: 40px; }
  .segmented button { min-height: 44px; }
  .cheat { min-height: 52px; }
  .link-back { display: inline-flex; align-items: center; min-height: 44px; }
  .foot p a { display: inline-block; padding: 8px 0; }
  .foot p { line-height: 2.05; }
}

/* On a phone 100vh counts the space behind the browser's own address bar, so a
   modal sized to it ran its footer, and the Start button in it, below the
   bottom of the screen. The overlay is sized to the visible height instead
   (dvh, with the vh rule above as the fallback), keeps clear of the home bar,
   and the primary button spans the footer so it cannot be missed. */
body.has-touch .overlay {
  height: 100vh;
  height: 100dvh;
  bottom: auto;
  padding: 10px 10px calc(10px + env(safe-area-inset-bottom));
}
body.has-touch .modal { max-height: calc(100vh - 20px); max-height: calc(100dvh - 20px - env(safe-area-inset-bottom)); }
body.has-touch .modal-foot { padding: 10px 14px 12px; }
body.has-touch .modal-foot .btn-primary { flex: 1 1 100%; min-height: 50px; font-size: 16px; }


/* ===================================================================
   The way out, in every panel that covers the game.

   A start, pause or result panel sits on top of the HUD, and so on top
   of the HUD's own back icon: while a panel was open the only way back
   to the games list was the browser's own back button. The same icon
   now leads the panel's header, left of the title. `has-back` lays the
   header out as a row - the icon, the title block taking the room, then
   anything the header already carried on its right, such as a close X.
   =================================================================== */
.has-back {
  display: flex !important;
  align-items: center;
  gap: 12px;
}
.has-back > .panel-back { flex: 0 0 auto; }
.has-back > h1, .has-back > h2, .has-back > div { flex: 1 1 auto; min-width: 0; margin: 0; }
.has-back > .head-text > .kicker { margin-bottom: 2px; }

/* THEME START - generated by tools/gen-theme.js, do not edit here */
/* Light theme. Every game was drawn dark first, and every one of them names
   its colours through the same handful of variables, so the light theme is
   mostly those variables redefined. What follows the variables are the few
   surfaces that carry a colour of their own. A game's own light fixes sit
   below the END marker, in that game's stylesheet. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f4f4f8;
  --panel: #ffffff;
  --panel-2: #eceef6;
  --line: #d6d8e6;
  --text: #1c1c2b;
  --muted: #585a74;
  --accent: #4a4ae8;
  --amber: #b86a00;
  --teal: #0b8a80;
  --saffron: #c25f00;
  --green: #17864a;
  --red: #c42b2b;
  --rose: #c9365a;
}
:root[data-theme="light"] body { background: var(--bg); color: var(--text); }
:root[data-theme="light"] .topbar,
:root[data-theme="light"] .hud { background: rgba(255, 255, 255, 0.94); }
:root[data-theme="light"] .hud-btn[aria-pressed="true"] { color: #b3261e; border-color: rgba(179, 38, 30, 0.35); }
:root[data-theme="light"] .overlay { background: rgba(28, 28, 43, 0.45); }
:root[data-theme="light"] .modal,
:root[data-theme="light"] .panel,
:root[data-theme="light"] .intro-card,
:root[data-theme="light"] .done-card { background: var(--panel); box-shadow: 0 18px 50px rgba(28, 28, 60, 0.14); }
:root[data-theme="light"] .btn-primary { color: #fff; }
:root[data-theme="light"] kbd { background: var(--panel-2); color: var(--text); border-color: var(--line); }
:root[data-theme="light"] .beta { background: #fff4e5; border-color: #f0c48a; color: #5c3a0b; }
:root[data-theme="light"] .beta a { color: #8a4b00; }
:root[data-theme="light"] .feedback.is-right { color: #146b3a; }
:root[data-theme="light"] .feedback.is-wrong { color: #a4231f; }
:root[data-theme="light"] .foot-bar a,
:root[data-theme="light"] .cross a { color: #0b7a71; }
:root[data-theme="light"] .foot-steps a.is-here .step-n { color: #fff; }

/* The toggle itself: a sun in the dark, a moon in the light, so it always
   shows what pressing it will do - the icon alone says that, so the label
   is announced to a screen reader (title/aria-label, set in the script
   below) rather than spelled out next to it on every single page. */
.theme-toggle { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.theme-toggle svg { width: 16px; height: 16px; flex: 0 0 auto; }
.theme-toggle .ico-moon { display: none; }
:root[data-theme="light"] .theme-toggle .ico-sun { display: none; }
:root[data-theme="light"] .theme-toggle .ico-moon { display: inline; }
.theme-toggle .theme-label {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The Play button. Every game's way into play is the same button: the widest,
   tallest thing on its start screen, with a play triangle, so nobody has to
   work out which of the options starts the game. It lives in this block
   because this block already goes into every game. */
.btn-play:not([hidden]) {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex: 1 1 auto;
  min-height: 54px !important;
  font-size: 17px !important;
  font-weight: 700;
  letter-spacing: 0.2px;
  box-shadow: 0 8px 22px rgba(74, 74, 232, 0.35);
}
/* On a Sanskrit start screen it is the whole width of the card. */
.intro-card .btn-play:not([hidden]) { display: flex !important; width: 100%; margin-top: 6px; }
.btn-play::before {
  content: "";
  width: 14px;
  height: 16px;
  flex: 0 0 auto;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.btn-play:focus-visible { outline: 3px solid #ffd166; outline-offset: 3px; }
@media (prefers-reduced-motion: no-preference) {
  .btn-play { animation: btn-play-glow 2.4s ease-in-out infinite; }
  .btn-play:hover, .btn-play:focus-visible { animation: none; }
}
@keyframes btn-play-glow {
  0%, 100% { box-shadow: 0 8px 22px rgba(74, 74, 232, 0.35); }
  50% { box-shadow: 0 8px 30px rgba(74, 74, 232, 0.6); }
}
/* THEME END */

/* COMPACT PANELS (13/10/2026): start, pause and result panels use less room. Paddings and
   type only; buttons and their 12px spacing are left to the rules above. */
.overlay .modal-head, .overlay .panel-head, .overlay .m-head { padding-top: 10px; padding-bottom: 6px; }
.overlay .modal-head h1, .overlay .panel-head h1 { font-size: 20px; line-height: 1.15; }
.overlay .modal-head h2, .overlay .panel-head h2, .overlay .m-head h2 { font-size: 16px; }
.overlay .modal-body, .overlay .panel-body, .overlay .m-body { padding-top: 4px; padding-bottom: 10px; }
.overlay .modal-body p, .overlay .panel-body p, .overlay .m-body p { margin-bottom: 8px; font-size: 13.5px; line-height: 1.45; }
.overlay .modal-body h2, .overlay .panel-body h2, .overlay .modal-body h3, .overlay .panel-body h3 { margin-top: 10px; margin-bottom: 6px; }
.overlay .modal-foot, .overlay .panel-foot, .overlay .m-foot { padding-top: 8px; padding-bottom: 8px; }

/* CHEAT FOLD (22/10/2026) - the Normal / Cheat switch is not what a first time
   player is here for, so it sits in a quiet disclosure under the real options.
   It says ON in the closed state when cheats are running, because a cheat run
   saves nothing and that must never be a surprise. */
.cheat-fold { margin: 20px 0 6px; border: 1px solid var(--line, rgba(128, 128, 160, 0.3)); border-radius: 12px; }
.cheat-fold > summary {
  display: flex; align-items: center; gap: 8px; min-height: 46px; padding: 0 14px;
  list-style: none; cursor: pointer; font-size: 14px; color: var(--muted, #9a9ac0);
}
.cheat-fold > summary::-webkit-details-marker { display: none; }
.cheat-fold > summary::after {
  content: ""; margin-left: auto; width: 8px; height: 8px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform 0.15s;
}
.cheat-fold[open] > summary::after { transform: rotate(-135deg); }
.cheat-fold:has([data-mode="cheat"].is-on) > summary::before {
  content: "ON"; padding: 2px 8px; border-radius: 999px;
  background: var(--amber, #ffb703); color: #0b0b16; font-size: 11px; font-weight: 700; letter-spacing: 0.4px;
}
.cheat-fold > *:not(summary) { margin-left: 14px; margin-right: 14px; }
.cheat-fold > *:last-child { margin-bottom: 14px; }
@media (prefers-reduced-motion: reduce) { .cheat-fold > summary::after { transition: none; } }

/* The stage picker's world headers had no styling at all, so the number, the
   name and the star count ran together as "1Meadow0 / 15". */
.world { margin: 0 0 6px; }
.world-head { display: flex; align-items: baseline; gap: 8px; padding: 12px 2px 6px; }
.world-n { min-width: 18px; font-weight: 700; color: var(--accent); }
.world-name { font-weight: 600; color: var(--text); }
.world-stars { margin-left: auto; font-size: 12px; color: var(--muted); }
.ref-fold { margin-top: 14px; }

/* HOW TO PLAY FOLD (22/10/2026) - reference text sits behind one disclosure
   so the first screen is the options and the Play button, not a manual. */
.ref-fold { margin-top: 14px; }
.ref-fold > summary::before { content: none !important; }
.ref-fold > h2:first-of-type { margin-top: 4px; }
