/* Double Up */

: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 with `el.hidden = true` stays on screen while the
   code reads as correct. `.tbtn` and `.overlay` both set display, so without
   this reset the touch buttons and the start panel would never go away. */
[hidden] { display: none !important; }

html, body { height: 100%; }

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: 14px;
  flex-wrap: wrap;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(21, 21, 42, 0.72);
}
.hud-back { color: var(--muted); text-decoration: none; font-size: 14px; }
.hud-back::before { content: "< "; }
.hud-back:hover { color: var(--text); }

.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; }
.power {
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(46, 196, 182, 0.16);
  color: var(--teal);
  font-size: 12.5px;
}

.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;
}
.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;
}
/* The board. A square that takes whatever the shorter side of the screen
   allows, so it is the same board on a phone and a desktop. */
.board-wrap {
  width: min(92vw, 460px, calc(100vh - 300px));
  min-width: 240px;
}
.board {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  touch-action: none;          /* the board is a control, not a scroll surface */
}
.tile {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  color: #0b0b16;
  font-weight: 700;
  font-size: clamp(15px, 4.6vw, 30px);
  line-height: 1;
  /* A number that has just doubled should be seen to have doubled. */
  transition: background-color 120ms ease, color 120ms ease;
}
.t0 { background: rgba(255, 255, 255, 0.04); }
.t2 { background: #d9d7ea; }
.t4 { background: #c9c6e6; }
.t8 { background: #8f8fff; color: #0b0b16; }
.t16 { background: #6f6fff; color: #fff; }
.t32 { background: #5858FD; color: #fff; }
.t64 { background: #2ec4b6; color: #0b0b16; }
.t128 { background: #37d6a8; color: #0b0b16; }
.t256 { background: #ffd166; color: #0b0b16; }
.t512 { background: #ffb703; color: #0b0b16; }
.t1024 { background: #ff9505; color: #0b0b16; font-size: clamp(13px, 4vw, 26px); }
.t2048 { background: #ff6b8b; color: #0b0b16; font-size: clamp(13px, 4vw, 26px); }
.tbig { background: #ff3d6e; color: #fff; font-size: clamp(12px, 3.6vw, 24px); }

/* Overlays. Fixed rather than absolute: an absolute overlay centres itself on
   the canvas while sizing itself with vh against the whole viewport, and the
   two disagree on any short screen, which puts the footer button off the
   bottom edge with nothing able to scroll to it. */
.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(560px, 100%);
  max-height: calc(100vh - 36px);
  max-height: calc(100dvh - 36px);
  display: flex;
  flex-direction: column;
  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(420px, 100%); }
.modal-head { padding: 18px 22px 6px; }
.modal-head h1, .modal-head h2 { margin: 0; font-size: 22px; letter-spacing: -0.4px; }
.modal-body { 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: 14px; letter-spacing: 0.6px; text-transform: uppercase; color: var(--muted); }
.modal-foot {
  padding: 14px 22px 18px;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.best-line { color: var(--amber) !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;
}
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 {
  display: inline-grid;
  place-items: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  color: #0b0b16;
  font-size: 13px;
}
.pw-w { background: var(--teal); }
.pw-m { background: var(--amber); }
.pw-s { background: var(--accent); color: #fff; }
.pw-x { background: var(--rose); }

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

/* Touch controls. A cross rather than a row: the four turns are opposite pairs,
   and a row of four arrows makes up and down neighbours, which is how a thumb
   turns the wrong way. Swiping the board does the same job for one hand. */
.touch-pad { display: none; }
body.has-touch .touch-pad {
  display: grid;
  grid-template-columns: repeat(3, auto);
  grid-template-rows: repeat(2, auto);
  justify-content: center;
  align-items: center;
  gap: clamp(6px, 2vw, 12px);
  padding: 6px calc(10px + env(safe-area-inset-right)) calc(6px + env(safe-area-inset-bottom)) calc(10px + env(safe-area-inset-left));
}
.tbtn-up { grid-column: 2; grid-row: 1; }
.tbtn-left { grid-column: 1; grid-row: 2; }
.tbtn-down { grid-column: 2; grid-row: 2; }
.tbtn-right { grid-column: 3; grid-row: 2; }
.tbtn {
  display: grid;
  place-items: center;
  width: clamp(58px, 17vw, 74px);
  height: clamp(46px, 12vw, 58px);
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(28, 28, 54, 0.9);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.tbtn:active { background: var(--accent); }
/* A latched control has to look latched, or its state is a guess. */
.tbtn[aria-pressed="true"] { background: var(--rose); color: #0b0b16; border-color: var(--rose); }

/* 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;
}

/* A short landscape screen has no room for prose under the board. */
@media (max-height: 520px) {
  .foot { display: none; }
  .shell { padding: 8px 10px 10px; gap: 8px; }
}

/* ===================================================================
   Touch targets. Same block as the other six games, gated on a coarse
   pointer so a desktop keeps its compact chrome exactly as it was.
   =================================================================== */
@media (pointer: coarse) {

  /* The way out. It is the control a lost player reaches for. */
  .hud-back, .link-back {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 10px 0 6px;
    margin-left: -6px;
    border-radius: 10px;
  }
  .hud-back:active, .link-back:active { background: rgba(255, 255, 255, 0.06); }

  .hud-btn, .btn, .tbtn { min-height: 44px; }

  /* A link inside a sentence cannot be 44px without wrecking the line, so the
     line is opened up instead and the link padded into it. */
  .foot p a { display: inline-block; padding: 8px 0; }
  .foot p { line-height: 2.05; }
}


/* 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; }

/* In fullscreen the game is the only thing on the screen. The two prefixes
   cannot share a rule: one selector a browser does not know invalidates the
   whole list, so they are written out separately. */
:fullscreen .foot { display: none !important; }
:-webkit-full-screen .foot { display: none !important; }

/* ===================================================================
   The way out is one icon button, the same in every game - 14/09/2026.

   It used to be a text link reading "All games" in six games, "Home"
   in Race Dash, each at its own size and with a "< " glued on in CSS.
   A chevron into a line reads as back at any size, costs no width on a
   narrow HUD, and is the same shape on all eight pages.

   It stays a link, not a button, so middle click and open in a new tab
   behave. The label is still in the markup for a screen reader and as
   the tooltip, so nothing is lost by dropping the visible words.
   =================================================================== */
.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:active { background: rgba(255, 255, 255, 0.16); }
.icon-back svg { display: block; }
/* The old text link glued its arrow on with a pseudo element. */
.icon-back::before, .icon-back::after { content: none !important; }

/* Its own copy of the screen reader label, so the icon carries a name in
   every game whatever that game calls its hidden text class. */
.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;
}

@media (pointer: coarse) {
  .icon-back { width: 44px; height: 44px; padding: 0; margin: 0; }
}

/* The mode picker */
.segmented {
  display: flex;
  gap: 6px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel-2);
}
.segmented button {
  flex: 1 1 0;
  min-height: 38px;
  padding: 8px 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; }
.hint { margin: 8px 0 4px; color: var(--muted); font-size: 13.5px; }

@media (pointer: coarse) {
  .segmented button { min-height: 44px; }
}

/* The rules, under the board */
.rules {
  max-width: 560px;
  margin: 6px auto 0;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.65;
}
.rules h2 { margin: 0 0 6px; font-size: 14px; letter-spacing: 0.6px; text-transform: uppercase; }
.rules p { margin: 0 0 10px; }

/* Only the guide for the input in use. The gate needs !important: the elements
   carry layout rules of their own, and a plain attribute selector loses that
   fight silently, showing both guides at once. */
.keys[data-input="touch"] { display: none !important; }
body.has-touch .keys[data-input="key"] { display: none !important; }
body.has-touch .keys[data-input="touch"] { display: block !important; }

.hud-btn[disabled] { opacity: 0.4; cursor: default; }

.stage { align-items: center; flex-direction: column; }


/* Cheat mode. A second mode on the start screen: pick what to start with or
   what to switch off, and nothing the run does is written to the records. Tick
   boxes rather than a segmented row, because the cheats are not alternatives
   and picking several is the point of the mode. */
.seg-mode button { min-width: 92px; }
.cheats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 8px;
  margin: 8px 0;
}
.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, rgba(255, 255, 255, 0.04));
  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-mark {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border: 1.5px solid currentColor;
  border-radius: 5px;
  position: relative;
}
.cheat.is-on .cheat-mark::after {
  content: "";
  position: absolute;
  left: 5px;
  top: 1px;
  width: 5px;
  height: 10px;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.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, .cheat-flag {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  background: rgba(255, 183, 3, 0.22);
  color: #ffe0a3;
  font-size: 11.5px;
  font-weight: 600;
}
@media (pointer: coarse) {
  .cheat { min-height: 52px; }
}

.cheat-row { margin-top: 4px; }


/* ===================================================================
   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; }

/* ===================================================================
   The button that starts the game has to be on the screen.

   A start panel is taller than a phone once it carries a picker or a
   score table, and `100vh` counts the strip behind the browser's own
   toolbar as if it were usable. So the footer - which is where the
   Start button lives - could sit below the visible screen while
   measuring perfectly in an emulator, which has no toolbar. That
   shipped in four games and was reported as "play button not working".

   On a touch screen the panel is therefore measured in `dvh`, which is
   the space actually visible, it keeps clear of the home bar, and the
   primary button spans the footer so it cannot be taken for one option
   among several. The `vh` line above each `dvh` line is the fallback
   for a browser that does not know the newer unit.
   =================================================================== */
@media (pointer: coarse) {
  .overlay {
    height: 100vh;
    height: 100dvh;
    bottom: auto;
    padding: 10px 10px calc(10px + env(safe-area-inset-bottom));
  }
  .modal {
    max-height: calc(100vh - 20px);
    max-height: calc(100dvh - 20px - env(safe-area-inset-bottom));
  }
  .modal-foot { padding: 10px 14px 12px; }
  .modal-foot .btn-primary { flex: 1 1 100%; min-height: 50px; font-size: 16px; }
}

/* 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 */

/* A double tap must never zoom the page mid game */
html { touch-action: manipulation; }

/* 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) - Normal / Cheat is not what a player came for, so it
   sits in a quiet disclosure under the board. ON shows in the closed state when
   cheats are running, because a cheat run saves nothing. */
.cheat-det { width: 100%; max-width: 560px; margin: 16px auto 0; box-sizing: border-box; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); }
.cheat-det > summary { display: flex; align-items: center; gap: 8px; list-style: none; cursor: pointer; padding: 0 16px; min-height: 46px; font-size: 14px; color: var(--muted); }
.cheat-det > summary::-webkit-details-marker { display: none; }
.cheat-det > 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-det[open] > summary::after { transform: rotate(-135deg); }
.cheat-det:has([data-mode="cheat"].is-on) > summary::before { content: "ON"; padding: 2px 8px; border-radius: 999px; background: var(--amber); color: #0b0b16; font-size: 11px; font-weight: 700; letter-spacing: 0.4px; }
.cheat-det .size-row, .cheat-det #cheatBox { padding: 0 14px 14px; }
@media (prefers-reduced-motion: reduce) { .cheat-det > summary::after { transition: none; } }

/* A phone has no use for a Fullscreen button, and it was what pushed the top
   bar onto a second row. */
body.has-touch #btnFull { display: none; }

/* START SCREEN (22/10/2026) - the game opens on a card with one obvious action:
   Continue when there is a game to go back to, otherwise Play. The board behind
   is softened so the card is the only thing to do. */
.stage:has(#ovStart:not([hidden])) .board-wrap { filter: blur(7px) saturate(0.9); opacity: 0.7; pointer-events: none; transition: filter 0.2s; }
.start-card { width: min(400px, 100%); }
.start-card .modal-head h2 { font-size: 26px; letter-spacing: -0.5px; }
.start-card .kicker { margin: 2px 0 0; font-size: 13.5px; color: var(--muted); }
.start-card .modal-body { padding-top: 14px; }
.sec-label { margin: 18px 0 8px; font-size: 12px; letter-spacing: 0.6px; text-transform: uppercase; color: var(--muted); }
.resume {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px; width: 100%;
  padding: 14px 18px; border: 0; border-radius: 14px;
  background: var(--accent); color: #fff; font: inherit; text-align: left; cursor: pointer;
  box-shadow: 0 6px 18px rgba(88, 88, 253, 0.3); transition: transform 0.08s ease;
}
.resume:active { transform: scale(0.98); }
.resume .rs-t { font-size: 18px; font-weight: 700; }
.resume .rs-s { font-size: 13px; opacity: 0.88; }
.resume[hidden] { display: none; }
.lvl { width: 100%; }
.lvl button { min-height: 46px; font-size: 15px; }
.lvl-note { margin: 10px 2px 0; font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.start-card .modal-foot { padding-top: 6px; }
.start-card .modal-foot .btn { width: 100%; min-height: 52px; font-size: 17px; border-radius: 14px; }
.btn-ghost { background: transparent; border: 1px solid var(--line); color: var(--text); }
@keyframes cardIn { from { opacity: 0; transform: translateY(10px) scale(0.98); } to { opacity: 1; transform: none; } }
.overlay:not([hidden]) .modal { animation: cardIn 0.22s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .overlay:not([hidden]) .modal { animation: none; }
  .stage:has(#ovStart:not([hidden])) .board-wrap { transition: none; }
}
