/* Iron Ridge */

: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;
}
canvas {
  display: block;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  touch-action: none;          /* the board is a control, not a scroll surface */
  max-width: 100%;
}

/* 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-s { background: var(--rose); }
.pw-r { background: var(--teal); }
.pw-l { background: #8f8fff; }
.pw-b { background: var(--amber); }

.hint { font-size: 13px !important; }

.segmented { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 6px; }
.segmented button {
  min-height: 40px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--muted);
  font: inherit;
  font-size: 13.5px;
  cursor: pointer;
}
.segmented button.is-on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.segmented button:disabled { opacity: 0.45; cursor: not-allowed; }

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

html { touch-action: manipulation; }

/* The play area. On a desktop it is only the canvas. On a touch screen the
   controls get space of their own and never sit on the picture: a band under
   the canvas when the phone is upright, a column either side when it is on its
   side. fitCanvas() in game.js measures the same two zones and takes their
   size off the canvas, which is the one thing keeping them apart. */
.arena {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas: "stage";
  justify-items: center;
  align-items: start;
  gap: 12px;
  min-height: 0;
}
.arena .stage { grid-area: stage; }
.touch-left, .touch-right { display: none; }

body.has-touch .arena {
  grid-template-columns: 1fr 1fr;
  grid-template-areas: "stage stage" "left right";
}
body.has-touch .touch-left,
body.has-touch .touch-right {
  display: flex;
  align-items: center;
  padding-bottom: env(safe-area-inset-bottom);
}
body.has-touch .touch-left { grid-area: left; justify-self: start; padding-left: env(safe-area-inset-left); }
body.has-touch .touch-right { grid-area: right; justify-self: end; gap: 14px; padding-right: env(safe-area-inset-right); }

@media (orientation: landscape) {
  body.has-touch .arena {
    grid-template-columns: auto 1fr auto;
    grid-template-areas: "left stage right";
    align-items: center;
  }
  body.has-touch .touch-right { flex-direction: column-reverse; }
}

.pad {
  position: relative;
  width: clamp(118px, 34vw, 150px);
  height: clamp(118px, 34vw, 150px);
  border-radius: 50%;
  touch-action: none;
}
@media (orientation: landscape) {
  body.has-touch .pad { width: min(40vh, 140px); height: min(40vh, 140px); }
}
.pad-ring {
  position: absolute;
  inset: 0;
  border: 2px solid var(--line);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(88, 88, 253, 0.10), rgba(21, 21, 42, 0.85) 70%);
  pointer-events: none;
}
.pad-knob {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 40%;
  height: 40%;
  margin: -20% 0 0 -20%;
  border-radius: 50%;
  background: rgba(88, 88, 253, 0.55);
  border: 2px solid rgba(143, 143, 255, 0.8);
  pointer-events: none;
}

.tbtn {
  display: grid;
  place-items: center;
  width: clamp(64px, 19vw, 78px);
  height: clamp(64px, 19vw, 78px);
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(28, 28, 54, 0.9);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
@media (orientation: landscape) {
  body.has-touch .tbtn { width: min(22vh, 74px); height: min(22vh, 74px); }
}
.tbtn-fire { border-color: rgba(255, 107, 139, 0.5); }
.tbtn-jump { border-color: rgba(46, 196, 182, 0.5); }
.tbtn[data-down] { background: var(--accent); }
.tbtn-fire[data-down] { background: var(--rose); color: #0b0b16; }

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


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

/* 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: reported as the play button not working. 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. Same block as Blast Maze. */
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; } }

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