/* WORLD 1-T, comic-book issue.
   Rule of the file: the default (no-JS, reduced-motion) CSS state is the finished story.
   Motion-only initial states live at the bottom, gated behind html.js and
   prefers-reduced-motion: no-preference.
   The comic system: heavy ink outlines (4px desktop, 3px phone), flat fills with one
   darker shadow tone, cream paper captions, halftone used sparingly, speech balloons for
   lines, starburst action words for sound effects. */

:root {
  --ink: #141008;
  --paper: #fff6dc;
  --paper-d: #efd9a4;
  --yel: #ffe12b;
  --yel-d: #e3a900;
  --pur: #8e2d9e;
  --pur-d: #5a1769;
  --wood: #c98a3f;
  --wood-d: #8a5a24;
  --wood-l: #e9b56b;
  --sky: #58bdff;
  --sky-l: #b6e6ff;
  --sky-d: #2f8fe0;
  --grass: #62d45f;
  --grass-d: #2f9f3c;
  --dirt: #b9782e;
  --dirt-d: #7d4d1c;
  --brick: #d8713a;
  --brick-d: #9a4620;
  --gold: #ffd23f;
  --gold-d: #d4960c;
  --gold-l: #fff2a8;
  --pipe: #4cd35a;
  --pipe-d: #2a9a3a;
  --pipe-l: #9df0a0;
  --red: #ff3b30;
  --red-d: #b8201a;
  --white: #ffffff;
  --cyan: #3fd2ff;
  --up: #58e25c;
  --green-t: #1d6e2a;
  --steel: #d7dde3;
  --steel-d: #8f9aa5;
  --night: #1c1a3a;
  --mars: #c7452b;

  --line: 4px;
  --hud-h: 60px;
  --blk: 56px;
  --ground-h: 72px;
  --runner-h: max(24svh, 150px);
  --sink-h: min(46svh, 400px);
  --score-w: 150px;

  --f-display: 'Bangers', 'W1T Display Fallback', Impact, 'Arial Narrow Bold', sans-serif;
  --f-body: 'Patrick Hand', 'W1T Body Fallback', 'Chalkboard', 'Segoe Print', cursive;

  --star: polygon(50% 0%, 61% 14%, 76% 4%, 78% 22%, 96% 20%, 86% 36%, 100% 50%, 86% 64%, 96% 80%, 78% 78%, 76% 96%, 61% 86%, 50% 100%, 39% 86%, 24% 96%, 22% 78%, 4% 80%, 14% 64%, 0% 50%, 14% 36%, 4% 20%, 22% 22%, 24% 4%, 39% 14%);
  --halftone: radial-gradient(circle at 50% 50%, rgba(20, 16, 8, .16) 1.3px, transparent 1.7px) 0 0 / 9px 9px;

  --svg-clouds: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 64'%3E%3Cg fill='%23fff' stroke='%23141008' stroke-width='4' stroke-linejoin='round'%3E%3Cpath d='M18 50c-10 0-14-14-2-18 0-16 24-20 30-6 8-10 26-6 24 8 10 0 12 16 0 16z'/%3E%3Cpath d='M160 56c-8 0-10-10-1-13 2-12 20-14 24-4 6-6 18-3 16 6 8 0 9 11 0 11z'/%3E%3C/g%3E%3C/svg%3E");
  --svg-hills-far: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 84'%3E%3Cpath d='M-4 84V60C20 60 30 14 70 14S120 64 150 64 170 30 215 30 270 70 300 70 324 60 324 60V84z' fill='%232f9f3c' stroke='%23141008' stroke-width='4' stroke-linejoin='round'/%3E%3C/svg%3E");
  --svg-hills-near: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 480 120'%3E%3Cpath d='M-4 120V88C40 88 60 10 130 10S200 98 240 98 270 46 330 46 400 110 440 110 484 90 484 90V120z' fill='%2362d45f' stroke='%23141008' stroke-width='4' stroke-linejoin='round'/%3E%3C/svg%3E");
  --svg-wood: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 160'%3E%3Crect width='160' height='160' fill='%23c98a3f'/%3E%3Cpath d='M0 0h160v8H0zM0 80h160v8H0z' fill='%238a5a24'/%3E%3Cpath d='M0 8h160v4H0zM0 88h160v4H0z' fill='%23e9b56b'/%3E%3Cpath d='M10 30c40 4 80-6 140 2M14 54c50-4 90 4 136-2M10 110c40 4 80-6 140 2M14 134c50-4 90 4 136-2' fill='none' stroke='%238a5a24' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E");
}

@media (max-width: 760px) {
  :root {
    --line: 3px;
    --hud-h: 52px;
    --blk: 40px;
    --ground-h: 56px;
    --sink-h: min(36svh, 280px);
    --score-w: 120px;
  }
}

/* Self-hosted web fonts (latin subset of Bangers and Patrick Hand, both OFL). */
@font-face { font-family: 'Bangers'; font-style: normal; font-weight: 400; font-display: swap; src: url('fonts/bangers-latin-400.woff2') format('woff2'); }
@font-face { font-family: 'Patrick Hand'; font-style: normal; font-weight: 400; font-display: swap; src: url('fonts/patrick-hand-latin-400.woff2') format('woff2'); }

/* Local fallbacks sized to the web fonts so the swap does not re-wrap lines. */
@font-face {
  font-family: 'W1T Display Fallback';
  src: local('Impact'), local('Arial Narrow Bold'), local('Helvetica Neue Condensed Bold');
  size-adjust: 88%;
}
@font-face {
  font-family: 'W1T Body Fallback';
  src: local('Chalkboard'), local('Marker Felt'), local('Segoe Print'), local('Trebuchet MS');
  size-adjust: 92%;
}

/* ---------- base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--ink);
  scroll-padding-top: var(--hud-h);
  overflow-x: clip;
}

body {
  margin: 0;
  font-family: var(--f-body);
  font-size: 19px;
  line-height: 1.4;
  color: var(--ink);
  overflow-x: clip;
}

h1, h2, h3, p, ul, ol, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { display: block; }
button { font: inherit; cursor: pointer; }
[hidden] { display: none !important; }

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

.skip {
  position: fixed;
  top: 8px; left: 8px;
  z-index: 100;
  transform: translateY(-200%);
  background: var(--ink);
  color: #fff;
  font: 16px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  padding: 10px 14px;
  border: 3px solid #fff;
  border-radius: 10px;
  text-decoration: none;
}
.skip:focus { transform: none; }

:focus-visible {
  outline: 4px solid var(--ink);
  outline-offset: 3px;
  box-shadow: 0 0 0 7px #fff;
}

/* ---------- type helpers: captions, bursts, balloons, buttons ---------- */

.eyebrow {
  display: inline-block;
  font: 15px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 6px;
  padding: 7px 10px;
  box-shadow: 3px 3px 0 var(--ink);
}

.chip {
  display: inline-block;
  font: 22px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #fff;
  background: var(--pur);
  border: var(--line) solid var(--ink);
  border-radius: 10px;
  padding: 8px 12px 7px;
  box-shadow: 4px 4px 0 var(--ink), inset 0 -4px 0 var(--pur-d);
}
.chip--sm { font-size: 15px; padding: 5px 8px 4px; box-shadow: 3px 3px 0 var(--ink), inset 0 -3px 0 var(--pur-d); vertical-align: middle; }

/* a comic caption box: cream paper, ink frame, hard shadow */
.box {
  background: var(--paper);
  color: var(--ink);
  border: var(--line) solid var(--ink);
  border-radius: 6px;
  box-shadow: 8px 8px 0 var(--ink);
  padding: 20px 22px;
}

.btn {
  display: inline-block;
  font: 22px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--yel);
  border: var(--line) solid var(--ink);
  border-radius: 12px;
  padding: 12px 20px 10px;
  box-shadow: 4px 4px 0 var(--ink), inset 0 -4px 0 var(--yel-d);
  text-decoration: none;
}
.btn:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 var(--ink), inset 0 -4px 0 var(--yel-d); }
.btn[aria-disabled="true"] { background: #bfb8a8; color: var(--ink); cursor: not-allowed; box-shadow: 4px 4px 0 var(--ink), inset 0 -4px 0 #8f8878; }
.btn--copy { font-size: 16px; padding: 8px 10px 7px; margin-left: 10px; box-shadow: 3px 3px 0 var(--ink), inset 0 -3px 0 var(--yel-d); }

/* starburst action word: an ink burst behind a yellow burst behind the lettering */
.burst {
  position: relative;
  isolation: isolate;
  display: inline-block;
  padding: .42em 1.05em;
  font: 1em/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
}
.burst::before, .burst::after { content: ''; position: absolute; z-index: -1; clip-path: var(--star); }
.burst::before { inset: -5px; background: var(--ink); }
.burst::after { inset: 0; background: var(--yel); }

/* speech balloon with a tail */
.balloon {
  position: relative;
  font: 17px/1.15 var(--f-body);
  color: var(--ink);
  background: #fff;
  border: 3px solid var(--ink);
  border-radius: 14px;
  padding: 7px 11px 6px;
  box-shadow: 3px 3px 0 var(--ink);
  white-space: nowrap;
}
.balloon::before, .balloon::after {
  content: '';
  position: absolute;
  left: 14px; top: 100%;
  border-left: 10px solid var(--ink);
  border-bottom: 11px solid transparent;
}
.balloon::after { left: 17px; margin-top: -4px; border-left: 7px solid #fff; border-bottom: 8px solid transparent; }

/* ---------- HUD: a caption strip pinned to the top ---------- */

.hud {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  height: var(--hud-h);
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 18px;
  background: var(--paper);
  border-bottom: var(--line) solid var(--ink);
  box-shadow: inset 0 -4px 0 var(--paper-d);
  color: var(--ink);
}
/* one bar, two faces: html.hero-on (the game on screen) shows the game face, otherwise the page face */
.hud__face { display: flex; align-items: center; gap: inherit; flex: 1 1 auto; min-width: 0; height: 100%; }
html.hero-on .hud__face--page, html:not(.hero-on) .hud__face--game { display: none; }
.hud__cell { display: flex; flex-direction: column; line-height: 1; flex: 0 0 auto; }
.hud__lbl {
  align-self: flex-start; /* the label's box hugs its word, so hit-tests see the word, not the cell */
  font: 12px/1 var(--f-display);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--wood-d);
}
.hud__val { font: 26px/1 var(--f-display); color: var(--ink); margin-top: 3px; white-space: nowrap; letter-spacing: .5px; }
.hud__x { color: var(--wood-d); font-size: .8em; }
.hud__coins .hud__val b { color: var(--pur); font-weight: 400; }
.hud__score { position: relative; margin-left: auto; }
.hud__box {
  position: relative;
  isolation: isolate;
  display: block;
  width: var(--score-w); height: 26px;
  margin-top: 9px;
  /* busted: the left wall is gone. The frame is cut straight at --cut (measured from the
     frame's own left edge) and the number bursts out through the gap; the break itself is
     drawn by the .tear pieces on the bottom frame line and below it, never on the digits */
  --cut: 20px;
}
.hud__box::before, .hud__box::after {
  content: '';
  position: absolute;
  z-index: -1;
  pointer-events: none;
}
.hud__box::before {
  inset: -5px -8px -3px -8px;
  border: 3px solid var(--ink);
  border-radius: 8px;
  background: var(--ink);
  /* busted: the left end is broken off along a jagged line */
  clip-path: polygon(calc(var(--cut) + 2px) 0, 100% 0, 100% 100%, calc(var(--cut) - 2px) 100%, calc(var(--cut) + 12px) 84%, calc(var(--cut) + 4px) 68%, calc(var(--cut) + 16px) 50%, calc(var(--cut) + 3px) 33%, calc(var(--cut) + 14px) 17%);
}
.hud__box::after {
  inset: -2px -5px 0 -5px;
  border-radius: 5px;
  background: #fff;
  /* the same jagged line in this box's own coordinates, which start 3px further right, so the
     ink shows as an outline along the break */
  clip-path: polygon(calc(var(--cut) + 2px) 0, 100% 0, 100% 100%, calc(var(--cut) - 2px) 100%, calc(var(--cut) + 12px) 84%, calc(var(--cut) + 4px) 68%, calc(var(--cut) + 16px) 50%, calc(var(--cut) + 3px) 33%, calc(var(--cut) + 14px) 17%);
}
/* the break: the bottom frame line ends torn with impact strokes, and the knocked-out wall
   lies tilted under the HUD edge. Both sit outside the number's glyph box. */
.tear { position: absolute; display: none; pointer-events: none; }
.hud__score.is-busted .tear { display: block; }
.tear--btm {
  /* the bottom frame line, snapped at the break and bent down and away, with impact ticks */
  left: calc(var(--cut) - 8px - 30px + 2px); top: calc(100% + 1px);
  width: 30px; height: 16px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 16'%3E%3Cpath d='M30 .5V4L13 12.5 11 15 9.5 12 6.5 13.5 7.5 10 11 8.5Z' fill='%23141008' stroke='%23141008' stroke-width='.8' stroke-linejoin='round'/%3E%3Cpath d='M27 2.6 13.5 9.4' stroke='%23fff' stroke-width='1' stroke-linecap='round'/%3E%3Cpath d='M5 3.5 1 1.8M5.5 7 1 8M8.5 1.5 6.5-.5' fill='none' stroke='%23141008' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat 0 0 / 100% 100%;
}
.tear--bit {
  left: calc(var(--cut) - 8px - 36px); top: calc(100% + 3px);
  width: 14px; height: 15px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 15'%3E%3Cpath d='M1.5 2.5Q1.5 1.5 2.5 1.5H12L9.5 4 12.5 6.5 9 8.5 11.5 13.5H2.5Q1.5 13.5 1.5 12.5Z' fill='%23141008'/%3E%3Cpath d='M4.5 4.5H8L7 6 8.5 7.5 6.5 9 7.5 11H4.5Z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 0 0 / 100% 100%;
  rotate: -28deg;
}
.hud__counter {
  position: absolute;
  right: 4px; bottom: 0;
  font: 26px/1 var(--f-display);
  font-variant-numeric: tabular-nums;
  letter-spacing: .5px;
  color: var(--pur);
  white-space: nowrap;
  transform-origin: 100% 100%;
  /* busted: the trillion is too big for the box in both senses */
  transform: scale(1.18);
}
/* wall fragments: born at the break under the frame line, they fly down and left, never over the digits */
.shard {
  position: absolute;
  /* low enough that a big chunk's rotated box stays under the frame line from its first frame */
  left: 6px; top: calc(100% + 7px);
  width: 10px; height: 10px;
  background: no-repeat 0 0 / 100% 100%;
  z-index: 2;
  opacity: 0;
  pointer-events: none;
}
.shard:nth-of-type(1) { width: 17px; height: 16px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 3 10 1 11 8 6 11 1 9Z' fill='%23fff' stroke='%23141008' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.shard:nth-of-type(2) { width: 12px; height: 12px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 2 11 4 7 11Z' fill='%23141008'/%3E%3C/svg%3E"); }
.shard:nth-of-type(3) { width: 18px; height: 18px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 2 10 2 10 6 6 6 6 10 2 10Z' fill='%23fff' stroke='%23141008' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.shard:nth-of-type(4) { width: 11px; height: 11px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 5 6 1 11 6 5 11Z' fill='%23fff' stroke='%23141008' stroke-width='1.8' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.shard:nth-of-type(5) { width: 14px; height: 14px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 1 11 3 9 10 2 11 4 6Z' fill='%23fff' stroke='%23141008' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.shard:nth-of-type(6) { width: 8px; height: 8px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 1 11 6 1 11 4 6Z' fill='%23141008'/%3E%3C/svg%3E"); }
/* the impact at the moment of the break: ink strokes and dust puffs below the frame line, down
   and left of the break, never over the digits */
.impact {
  position: absolute;
  left: calc(var(--cut) - 8px - 36px); top: calc(100% + 2px);
  width: 40px; height: 26px;
  overflow: visible;
  opacity: 0;
  pointer-events: none;
}
.impact path { fill: none; stroke: var(--ink); stroke-width: 2.5px; stroke-linecap: round; }
.puff {
  position: absolute;
  left: calc(var(--cut) - 8px - 6px); top: calc(100% + 6px);
  width: 12px; height: 12px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: #fff;
  opacity: 0;
  z-index: -1;
  pointer-events: none;
}
/* KRAK! hangs off the broken corner of the box, below the HUD line, clear of every HUD label */
.burst--krak {
  position: absolute;
  left: -26px; top: calc(100% + 12px);
  font-size: 22px;
  opacity: 0;
  pointer-events: none;
}
.hud__sfx {
  flex: 0 0 auto;
  font: 15px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink);
  background: #fff;
  border: 3px solid var(--ink);
  border-radius: 8px;
  padding: 8px 10px 7px;
  min-height: 32px;
  box-shadow: 2px 2px 0 var(--ink);
}
.hud__sfx[aria-pressed="true"] { background: var(--yel); box-shadow: 2px 2px 0 var(--ink), inset 0 -3px 0 var(--yel-d); }

@media (max-width: 760px) {
  .hud { gap: 10px; padding: 0 10px; }
  .hud__val { font-size: 21px; }
  .hud__box { height: 21px; margin-top: 7px; }
  .hud__counter { font-size: 21px; }
  .hud__box::before { inset: -4px -6px -3px -6px; }
  .hud__box::after { inset: -1px -3px 0 -3px; }
  .hud__box { --cut: 18px; }
  .tear--btm { left: calc(var(--cut) - 6px - 26px + 2px); width: 26px; height: 14px; }
  .tear--bit { left: calc(var(--cut) - 6px - 32px); top: calc(100% + 2px); width: 10px; height: 11px; }
  .hud__lbl { font-size: 10px; letter-spacing: 1px; }
  .hud__sfx { font-size: 13px; padding: 7px 7px 6px; margin-left: 2px; }
  /* phones: the title fills the width under the HUD, so KRAK! sits inside the HUD band on the
     box's top-right corner, above the digits and clear of the SCORE label and the SFX button */
  .burst--krak { font-size: 11px; padding: .25em .8em; left: auto; right: -4px; top: -26px; }
  .burst--krak::before { inset: -3px; }
}

/* ---------- scenery components ---------- */

.sky { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.sky--level {
  background:
    linear-gradient(to bottom, transparent 0 58%, rgba(255, 255, 255, .22) 58% 100%),
    var(--sky);
}
.sky--level::after {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 34%;
  background: var(--halftone);
  mask-image: linear-gradient(90deg, rgba(0, 0, 0, .6), transparent);
  -webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, .6), transparent);
}

.par {
  position: absolute;
  left: 0;
  z-index: 1;
  pointer-events: none;
  background-repeat: repeat-x;
  background-position: 0 100%;
}
.par--clouds {
  top: calc(var(--hud-h) + 28px);
  height: 160px;
  width: 8192px;
  background-image: var(--svg-clouds);
  background-size: 512px 128px;
  background-position: 0 0;
}
@media (max-width: 760px) {
  .par--clouds { height: 100px; background-size: 320px 80px; }
}
.par--static { width: 100%; }
.lvl-panel .par--clouds { top: 20px; }

/* ground: a flat grass band on brown earth, one darker tone for the dirt lines */
.ground {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  height: var(--ground-h);
  background:
    linear-gradient(var(--ink) 0 4px, var(--grass) 4px 20px, var(--grass-d) 20px 24px, var(--ink) 24px 28px, transparent 28px),
    radial-gradient(ellipse 14px 5px at 30px 46px, var(--dirt-d) 0 90%, transparent 100%),
    radial-gradient(ellipse 10px 4px at 92px 60px, var(--dirt-d) 0 90%, transparent 100%),
    var(--dirt);
  background-size: auto, 120px 72px, 120px 72px, auto;
}

.pipe {
  position: absolute;
  z-index: 3;
  bottom: var(--ground-h);
  width: var(--pw, 120px);
  height: var(--ph, 150px);
  pointer-events: none;
}
.pipe::before, .pipe::after {
  content: '';
  position: absolute;
  background: linear-gradient(90deg, var(--pipe-l) 0 16%, var(--pipe) 16% 64%, var(--pipe-d) 64%);
  border: var(--line) solid var(--ink);
}
.pipe::before { top: 0; left: -8%; width: 116%; height: 30%; border-radius: 8px; }
.pipe::after { top: 30%; left: 0; right: 0; bottom: -4px; border-top: 0; }
.pipe--dive { left: 10%; --pw: calc(var(--runner-h) * .86); --ph: calc(var(--runner-h) * .3); }
/* the pipe he climbs out of at the start of stage 1, standing at the right end of the ledge;
   JS sizes it to the page player's stance (he grows inside it, fully masked) */
.pipe--start { bottom: calc(100% + 4px); right: 8px; --pw: 140px; --ph: 85px; }
.pipe--mini { position: relative; display: inline-block; vertical-align: middle; bottom: auto; width: 22px; height: 18px; margin-right: 8px; --pw: 22px; --ph: 18px; }
.pipe--mini::before { height: 40%; border-width: 3px; border-radius: 4px; }
.pipe--mini::after { top: 40%; border-width: 3px; border-top: 0; bottom: 0; }
.pipe--side {
  right: 0; bottom: 56px;
  width: 170px; height: 90px;
}
.pipe--side::before, .pipe--side::after {
  background: linear-gradient(180deg, var(--pipe-l) 0 16%, var(--pipe) 16% 64%, var(--pipe-d) 64%);
}
.pipe--side::before { top: -8%; left: 0; width: 30%; height: 116%; border-radius: 8px; }
.pipe--side::after { top: 0; bottom: 0; left: 30%; right: -4px; border-top: var(--line) solid var(--ink); border-left: 0; }
@media (max-width: 760px) {
  .pipe--side { width: 110px; height: 60px; bottom: 40px; }
}

.brick {
  position: absolute;
  z-index: 2;
  left: var(--x);
  bottom: calc(var(--ground-h) + var(--runner-h) + var(--blk) * .6 + var(--lift, 0) * var(--blk) * 1.2);
  width: calc(var(--blk) * var(--n, 1));
  height: var(--blk);
  border: var(--line) solid var(--ink);
  border-radius: 4px;
  background:
    repeating-linear-gradient(90deg, var(--ink) 0 3px, transparent 3px calc(var(--blk) / 2)),
    repeating-linear-gradient(0deg, var(--ink) 0 3px, var(--brick) 3px calc(var(--blk) / 2));
  box-shadow: inset 0 -5px 0 var(--brick-d), inset 0 4px 0 #f2a06a;
}

.blk {
  position: absolute;
  z-index: 3;
  left: var(--x);
  bottom: calc(var(--ground-h) + var(--runner-h) + var(--blk) * .6 + var(--lift, 0) * var(--blk) * 1.2);
  width: var(--blk);
  height: var(--blk);
}
.blk__face {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  border: var(--line) solid var(--ink);
  border-radius: 8px;
  font: calc(var(--blk) * .62)/1 var(--f-display);
  /* default = spent block */
  background: #9a5a28;
  box-shadow: inset -6px -6px 0 #6a3a14, inset 5px 5px 0 #c48a52;
  color: var(--ink);
}
.blk__face::after {
  content: '';
  width: 52%; height: 52%;
  border: 3px solid #6a3a14;
  border-radius: 4px;
}

/* a coin, drawn as a comic ellipse carrying the ticker's mark */
.coin {
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: calc(100% + 8px);
  width: calc(var(--blk) * .62);
  height: calc(var(--blk) * .8);
  margin-left: calc(var(--blk) * -.31);
}
.coin i {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--gold);
  border: 3px solid var(--ink);
  border-radius: 50%;
  box-shadow: inset -5px 0 0 var(--gold-d), inset 5px 0 0 var(--gold-l);
}
/* the ticker's mark on every coin face, from a variable so it is drawing, not copy */
.coin i::after {
  content: var(--tk-mark, 'T');
  font: calc(var(--blk) * .4)/1 var(--f-display);
  color: var(--ink);
  text-transform: uppercase;
  padding-top: 2px;
}

.item--sink {
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: calc(100% + 8px);
  width: calc(var(--blk) * 1.1);
  height: calc(var(--blk) * .8);
  margin-left: calc(var(--blk) * -.55);
}
.item--sink::before {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 58%;
  background: linear-gradient(#fff 0 55%, #c6d3de 55%);
  border: 3px solid var(--ink);
  border-radius: 6px 6px 40% 40% / 6px 6px 60% 60%;
}
.item--sink::after {
  content: '';
  position: absolute;
  left: 25%; right: 25%; bottom: -2px;
  height: 22%;
  background: #c6d3de;
  border: 3px solid var(--ink);
  border-top: 0;
  border-radius: 0 0 6px 6px;
}
.item--sink i {
  position: absolute;
  left: 50%; top: 0;
  width: 12px; height: 46%;
  margin-left: -6px;
  background: var(--steel-d);
  border: 3px solid var(--ink);
  border-radius: 6px 6px 0 0;
  box-shadow: 8px 0 0 -1px var(--ink);
}

.pop {
  position: absolute;
  z-index: 4;
  left: 50%;
  bottom: calc(100% + var(--blk) * 1.1);
  transform: translateX(-50%);
  font-size: 15px;
}
.pop--up { font-size: 17px; }
.pop--up::after { background: var(--up); }
.blk--cap .pop, [data-sink-block] .pop { bottom: calc(100% + var(--blk) * 1.3); }
@media (max-width: 760px) { .pop { font-size: 13px; } .pop--up { font-size: 14px; } }

.cap {
  position: absolute;
  z-index: 2;
  left: 0; right: 0;
  top: 21%;
  height: 40px;
  --seg-x: calc(38% - 28px);
  --seg-w: calc(var(--blk) + 56px);
}
.cap::before, .cap::after, .cap__seg {
  position: absolute;
  top: 0; bottom: 0;
  background: var(--red);
  border: var(--line) solid var(--ink);
  box-shadow: inset 0 6px 0 #ff9b94, inset 0 -6px 0 var(--red-d);
}
.cap::before { content: ''; left: 0; width: var(--seg-x); border-radius: 0 6px 6px 0; }
.cap::after { content: ''; left: calc(var(--seg-x) + var(--seg-w)); right: 0; border-radius: 6px 0 0 6px; }
.cap__seg { left: var(--seg-x); width: var(--seg-w); visibility: hidden; }
.cap__shard {
  position: absolute;
  top: 4px; bottom: 4px;
  width: 30%;
  background: var(--red);
  border: 3px solid var(--ink);
  border-radius: 3px;
  visibility: visible;
  opacity: 0;
}
.cap__shard:nth-child(1) { left: 2%; }
.cap__shard:nth-child(2) { left: 35%; }
.cap__shard:nth-child(3) { left: 68%; }
.cap__txt {
  position: absolute;
  z-index: 2;
  left: 3%;
  top: 50%;
  transform: translateY(-50%);
  background: var(--paper);
  color: var(--ink);
  border: 3px solid var(--ink);
  border-radius: 6px;
  font: 14px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  padding: 6px 8px 5px;
  white-space: nowrap;
}
.burst--smash {
  position: absolute;
  z-index: 3;
  left: calc(var(--seg-x) + var(--seg-w) / 2);
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 30px;
  opacity: 0;
  pointer-events: none;
}
@media (max-width: 760px) {
  .cap { height: 30px; top: 14%; }
  .cap__txt { font-size: 11px; padding: 5px 6px 4px; }
  .burst--smash { font-size: 24px; }
}

.sign {
  position: absolute;
  z-index: 2;
  /* on tall posts, above the runner's head, so a stop never leaves him over a sign */
  bottom: calc(var(--ground-h) + var(--runner-h) + 24px);
  left: var(--sx, 8%);
  width: 190px;
  padding: 10px 10px 8px;
  background: var(--wood);
  border: var(--line) solid var(--ink);
  border-radius: 10px;
  box-shadow: inset 0 -5px 0 var(--wood-d), inset 0 4px 0 var(--wood-l);
  text-align: center;
  color: var(--ink);
  line-height: 1;
}
.sign::after {
  content: '';
  position: absolute;
  left: 50%; top: 100%;
  width: 14px; height: calc(var(--runner-h) + 24px);
  margin-left: -7px;
  background: var(--wood-d);
  border: var(--line) solid var(--ink);
  border-top: 0;
}
.sign span { display: block; font: 13px/1 var(--f-display); letter-spacing: 1.5px; text-transform: uppercase; margin-bottom: 5px; color: var(--wood-d); }
.sign b { display: block; font: 28px/1 var(--f-display); letter-spacing: 1px; text-transform: uppercase; }
.sign--start { --sx: 30%; bottom: calc(var(--ground-h) + var(--runner-h) + 140px); }
.sign--start::after { height: calc(var(--runner-h) + 140px); }
.sign--mid { --sx: 6%; }
.sign--warp { --sx: 60%; }
@media (max-width: 760px) {
  .sign { width: 120px; padding: 8px 6px 6px; bottom: calc(var(--ground-h) + var(--runner-h) + 20px); }
  .sign::after { height: calc(var(--runner-h) + 20px); }
  .sign b { font-size: 22px; }
  .sign--start { --sx: 1%; bottom: calc(var(--ground-h) + var(--runner-h) + 180px); }
  .sign--start::after { left: 12px; height: calc(var(--runner-h) + 180px); }
  .sign--mid { --sx: 2%; }
  .sign--warp { --sx: 52%; }
}

/* floating ledge: a rest surface for the player near the top of stage 1 */
.ledge {
  position: absolute;
  z-index: 2;
  left: 3%;
  top: 320px;
  width: 300px;
  height: 22px;
  border: var(--line) solid var(--ink);
  border-radius: 6px;
  background:
    repeating-linear-gradient(90deg, var(--ink) 0 3px, transparent 3px 26px),
    linear-gradient(#f2a06a 0 4px, var(--brick) 4px);
}
/* phone: low enough that a full-size player on the start pipe keeps his head out of the hero's ground strip */
@media (max-width: 760px) { .ledge { top: 240px; width: 290px; } }
/* short landscape: the level panel is about 330px tall, so the start ledge stands a little above
   the ground and he climbs out of its pipe while the whole box is still on screen. It stands as
   high as his box allows under the hero's ground strip, so the start pipe's top comes into view
   almost as the hero pipe's leaves it and a stop inside the hero warp settles on a pipe top */
@media (orientation: landscape) and (max-height: 500px) { .lvl-panel .ledge { top: calc(100% - var(--ground-h) - 113px); } }

/* phone warp chain pipes (sink room, scores, coin pile, finale gutters) */
.sink__exit, .pipe--scores, .pipe--pile, .pipe--gut, .pipe--bar, .crt__ledge { display: none; }
.pipe--stub { position: absolute; }
/* desktop warp from the sink room to the leaderboard: a dive pipe on the courtroom floor under
   the sink figure, and an exit pipe at the right of the panel whose top is the #1 bar line
   (JS places it); the copy column fills the room's lower right, so he travels by pipe */
.pipe--sinkdive, .pipe--barx { display: none; }
@media (min-width: 761px) {
  .pipe--sinkdive { display: block; left: max(16px, calc(50% - 550px)); bottom: 28px; --pw: 150px; --ph: 150px; z-index: 1; }
  .pipe--barx { display: block; position: absolute; bottom: auto; --pw: 150px; --ph: 190px; z-index: 1; }
}
/* desktop: a ledge in the finale's right page margin, between the coin floor and the footer */
.clear__sideledge { left: auto; right: 24px; top: 60%; }
@media (max-width: 760px) { .clear__sideledge { display: none; } }

/* ---------- 1. HERO: the game is the first screen ---------- */

/* The stage is the viewport under the HUD: no frame, no gutter, no page scenery around it. The
   canvas draws its own sky, hills and ground; the title is a wooden sign hanging in that sky. */
.hero {
  position: relative;
  height: 100svh;
  padding-top: var(--hud-h);
  overflow: clip;
  display: flex;
}
.hero__inner {
  position: relative;
  z-index: 3;
  width: 100%;
  height: 100%;
  min-height: 0;
  display: flex;
}
.hero .stage { flex: 1 1 auto; width: 100%; height: 100%; margin: 0; --gl: 19%; }

/* the title sign: two ropes from the stage HUD, a wooden board, the logo, the NES-style player menu
   and one blinking start line, which is the play button */
.stage__plaque {
  position: absolute;
  z-index: 3;
  top: 24px;
  left: 3.5%;
  width: max-content;
  max-width: 62%;
  padding: 14px 18px 16px;
  background: var(--svg-wood) 0 0 / 120px 120px;
  border: var(--line) solid var(--ink);
  border-radius: 8px;
  box-shadow: 6px 6px 0 var(--ink), inset 0 0 0 3px var(--yel-d);
  text-align: left;
  transform: rotate(-1.2deg);
  transform-origin: 50% 0;
}
.stage__plaque::before, .stage__plaque::after {
  content: '';
  position: absolute;
  top: calc(var(--rope, 22px) * -1 - 2px);
  width: 6px;
  height: var(--rope, 22px);
  background: repeating-linear-gradient(0deg, var(--ink) 0 3px, #a8792f 3px 6px);
  border: 2px solid var(--ink);
  border-radius: 2px;
}
.stage__plaque::before { left: 18%; }
.stage__plaque::after { right: 18%; }
/* the logo keeps the board wide enough for the start strip in both the web font and its
   fallback (the strip's text can be the wider of the two), so the sign never widens
   when the strip appears at game-ready */
.stage__plaque .h1 { min-width: 254px; margin: 0 0 12px; font-size: clamp(64px, 7vw, 104px); }
/* the start line: INSERT $WELON · PRESS START (TAP TO PLAY on touch screens, set by main.js) on an
   ink strip across the board, the way a cabinet asks for a coin. Its words blink, the strip stays.
   It needs the game, so it is not there until the game is ready (never without JS) */
.plaque__start {
  position: relative;
  display: block;
  width: 100%;
  margin: 10px 0 0;
  padding: 8px 12px 6px;
  font: 19px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  white-space: nowrap;
  text-align: center;
  color: var(--yel);
  background: var(--ink);
  border: 0;
  border-radius: 4px;
  box-shadow: 0 3px 0 var(--wood-d);
}
.plaque__ins { color: var(--paper); }
.plaque__dot { color: var(--wood-l); }
.plaque__start:hover { background: var(--pur-d); }
.plaque__start:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--wood-d); }
.stage:not(.is-ready) .plaque__start { display: none; }
/* the sign is for the title and the attract loop only: it is gone during a run and while paused.
   On the end screen it shrinks to the 1 PLAYER / 2 PLAYERS menu, which stays reachable above the
   card (its rows carry their own ink outline, so they read on the sky) */
.stage[data-game-state="playing"] .stage__plaque,
.stage[data-game-state="paused"] .stage__plaque { display: none; }
.stage[data-game-state="over"] .stage__plaque {
  z-index: 5;
  top: 8px; left: 8px; right: auto;
  width: auto; max-width: none;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
  transform: none;
}
.stage[data-game-state="over"] .stage__plaque :is(.h1, .plaque__start),
.stage[data-game-state="over"] .stage__plaque::before,
.stage[data-game-state="over"] .stage__plaque::after { display: none; }
.h1 {
  margin: 0 0 10px;
  font: clamp(50px, 14vw, 150px)/.86 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #fff;
  text-shadow:
    -3px 0 0 var(--ink), 3px 0 0 var(--ink), 0 -3px 0 var(--ink), 0 3px 0 var(--ink),
    -3px -3px 0 var(--ink), 3px -3px 0 var(--ink), -3px 3px 0 var(--ink), 3px 3px 0 var(--ink),
    6px 6px 0 var(--pur);
}
.h1__a, .h1__b { display: block; white-space: nowrap; }
.h1__b { color: var(--yel); }

/* the scroll cue: a chevron in a small yellow badge, centred at the bottom of the sky just above
   the ground line (--deck-band, set by main.js, is the ground band's height; the static scene's
   ground is --gl), on the title screen and in attract only */
.plaque__more {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: calc(var(--deck-band, var(--gl)) + 12px);
  width: 34px;
  height: 28px;
  margin-left: -17px;
  display: grid;
  place-items: center;
  color: var(--ink);
  background: var(--yel);
  border: 2px solid var(--ink);
  border-radius: 6px;
  box-shadow: 3px 3px 0 var(--ink);
  text-decoration: none;
}
.plaque__more svg { display: block; width: 16px; height: 12px; fill: currentColor; }
.plaque__more:hover, .plaque__more:focus-visible { background: #fff; }
/* a 48 x 44 px hit area around the badge */
.plaque__more::after { content: ''; position: absolute; left: -7px; right: -7px; top: -8px; bottom: -8px; }
.stage:is([data-game-state="playing"], [data-game-state="paused"], [data-game-state="over"]) .plaque__more { display: none; }
/* The trailer's cue leaves when scrolling freezes the stage, before the jump-out crosses it. */
.stage.is-frozen .plaque__more { visibility: hidden; }

/* the title card (title state) and the league's prompt (attract, league on) sit to the right of
   the sign, never under it */
@media (min-width: 761px) {
  .stage[data-game-state="attract"] [data-card="title"],
  .stage[data-game-state="title"] [data-card="title"],
  .stage__card--nojs { left: 62%; }
  .stage__card--nojs, .stage[data-game-state="title"] [data-card="title"] { width: min(520px, 54%); }
}

/* phones: the stage is a tall portrait screen and the sign spans it */
@media (max-width: 760px) {
  .stage__plaque { --rope: 14px; top: 16px; left: 8px; right: 8px; width: auto; max-width: none; padding: 10px 12px 12px; }
  .stage__plaque .h1 { min-width: 0; font-size: clamp(64px, 22.5vw, 90px); line-height: .78; text-align: center; margin-bottom: 6px; }
  .stage__plaque::before { left: 14%; }
  .stage__plaque::after { right: 14%; }
  .plaque__start { min-height: 44px; margin-top: 8px; padding: 6px 8px 4px; font-size: 18px; letter-spacing: 1.5px; }
}

/* short landscape phones (about 852x393): the stage takes the full width and the full height under
   the HUD, so the sign is one tight row high in the sky (the logo, the two menu rows, the start
   line) and the runner's lane stays clear */
@media (orientation: landscape) and (max-height: 500px) {
  /* the end card fills this short stage, so the menu goes with the rest of the sign */
  .stage[data-game-state="over"] .stage__plaque { display: none; }
  .stage__plaque { --rope: 4px; top: 6px; left: 12px; display: flex; align-items: center; gap: 12px; padding: 6px 12px; max-width: none; }
  .stage__plaque .h1 { min-width: 0; font-size: clamp(22px, 6.4svh, 26px); margin: 0; }
  .plaque__start { width: auto; margin: 0; padding: 8px 10px 6px; font-size: 15px; letter-spacing: 1.5px; }
  /* a 44 px tall hit area */
  .plaque__start::after { content: ''; position: absolute; left: 0; right: 0; top: -7px; bottom: -7px; }
  /* the 2 Players message stands beside the board, in the sky right of it, so it is never over the
     demo runner under the board */
  .stage .stage__plaque .menu__err { left: calc(100% + 10px); top: 6px; margin-top: 0; font-size: 13px; width: max-content; max-width: calc(100vw - 100% - 40px); }
  .stage[data-game-state="attract"] [data-card="title"], .stage[data-game-state="title"] [data-card="title"], .stage__card--nojs { left: 68%; }
}

/* ---------- 2. LEVEL (side-scroll) ---------- */

.level {
  position: relative;
  padding-top: var(--hud-h);
  background: var(--sky);
}
.level__view { position: relative; overflow: clip; }
.level__track { position: relative; z-index: 1; display: flex; flex-wrap: wrap; }
.lvl-panel {
  position: relative;
  flex: 0 0 auto;
  width: 100%;
  height: calc(100svh - var(--hud-h));
  overflow: clip;
}
/* Each panel draws both hill layers and offsets the tile phase by its index,
   so the scenery is continuous across panel seams while the track scrolls. */
.lvl-panel::before, .lvl-panel::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  z-index: 1;
  pointer-events: none;
  bottom: calc(var(--ground-h) - 4px);
  background-repeat: repeat-x;
  background-position: calc(-1 * var(--i, 0) * var(--vw, 100vw)) 100%;
}
.lvl-panel::before { height: 168px; background-image: var(--svg-hills-far); background-size: 640px 168px; }
.lvl-panel::after { height: 120px; background-image: var(--svg-hills-near); background-size: 480px 120px; }
.lvl-panel .par--clouds { z-index: 0; background-position: calc(-1 * var(--i, 0) * var(--vw, 100vw)) 0; }
.lvl-panel .ground { background-position-x: 0, calc(-1 * var(--i, 0) * var(--vw, 100vw)), calc(-1 * var(--i, 0) * var(--vw, 100vw)), 0; }
@media (max-width: 760px) {
  .lvl-panel::before { height: 110px; background-size: 420px 110px; }
  .lvl-panel::after { height: 80px; background-size: 320px 80px; }
}

.runner {
  position: absolute;
  z-index: 5;
  left: 10%;
  top: calc(100svh - var(--hud-h) - var(--ground-h) - var(--runner-h));
  height: var(--runner-h);
  width: calc(var(--runner-h) * .64);
  pointer-events: none;
}
.runner__bob, .runner__body { position: absolute; inset: 0; }
.runner__body { transform-origin: 50% 100%; }
.runner__body img { position: absolute; left: 50%; bottom: 0; height: 100%; width: auto; transform: translateX(-50%); }

/* ---------- the courtroom (sink room, scores): wood panelling ---------- */

.sink, .scores {
  position: relative;
  background-color: var(--wood);
  background-image: var(--svg-wood);
  background-size: 160px 160px;
  color: var(--ink);
}
.sink::after, .scores::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 28px;
  background: linear-gradient(var(--ink) 0 4px, var(--wood-l) 4px 10px, var(--wood-d) 10px);
}

/* ---------- 3. SINK ---------- */

.sink {
  min-height: 100svh;
  padding: calc(var(--hud-h) + 8px) 24px 92px;
  overflow: clip;
}
.sink__inner {
  position: relative;
  z-index: 1;
  width: min(1100px, 100%);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(220px, 560px) minmax(0, 1fr);
  align-items: end;
  gap: 40px;
  min-height: calc(100svh - var(--hud-h) - 24px - 92px);
}
.sink__char {
  position: relative;
  align-self: start;
  justify-self: start;
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  gap: 20px;
}
.sink__char img { height: var(--sink-h); width: auto; position: relative; z-index: 2; }
/* the warp pipe he rises out of after diving in at the end of stage 1: as wide as his
   stance, standing on the room's floor strip */
.pipe--rise { position: relative; bottom: auto; flex: 0 0 var(--pw); --pw: 250px; --ph: 200px; z-index: 1; }
.sink__floor {
  position: absolute;
  left: -12px; right: -12px; top: 100%;
  height: 24px;
  border-radius: 4px;
  background: linear-gradient(var(--ink) 0 4px, var(--wood-l) 4px 10px, var(--wood-d) 10px 20px, var(--ink) 20px);
}
.thud {
  position: absolute;
  z-index: 3;
  right: calc(100% + 6px);
  bottom: 30%;
  margin-right: 0;
  font-size: clamp(34px, 4.6vw, 60px);
  opacity: 0;
}
.dust { position: absolute; left: 0; right: 0; bottom: -4px; height: 20px; }
.dust i {
  position: absolute;
  bottom: 0;
  width: 16px; height: 16px;
  background: #fff;
  border: 3px solid var(--ink);
  border-radius: 50%;
  opacity: 0;
}
.dust i:nth-child(1) { left: -6%; }
.dust i:nth-child(2) { left: 18%; }
.dust i:nth-child(3) { left: 70%; }
.dust i:nth-child(4) { left: 96%; }
.sink__copy { padding-bottom: 10px; }
.sink__h {
  font: clamp(52px, 8vw, 120px)/.86 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #fff;
  text-shadow:
    -3px 0 0 var(--ink), 3px 0 0 var(--ink), 0 -3px 0 var(--ink), 0 3px 0 var(--ink),
    -3px -3px 0 var(--ink), 3px -3px 0 var(--ink), -3px 3px 0 var(--ink), 3px 3px 0 var(--ink),
    7px 7px 0 var(--pur);
  margin-bottom: 28px;
}
.box--quote { font-size: clamp(20px, 2vw, 27px); line-height: 1.35; max-width: 640px; }
.box--quote p { font-weight: 400; }
.box__credit { margin-top: 12px; font: 15px/1 var(--f-display); letter-spacing: 1px; color: var(--pur); }

@media (max-width: 760px) {
  .sink { padding: calc(var(--hud-h) + 36px) 12px 36px; }
  .sink__copy { display: grid; grid-template-columns: 56% minmax(0, 1fr); gap: 0 10px; align-items: start; }
  .sink__h { grid-column: 1 / -1; }
  .box--quote { grid-column: 1; }
  .sink__exit { display: flex; flex-direction: column; align-items: flex-end; grid-column: 2; padding-top: 196px; }
  .pipe--sinkexit { position: relative; bottom: auto; --pw: 150px; --ph: 150px; }
  .sink__floor--exit { position: static; width: 100%; }
  .sink__inner { grid-template-columns: 1fr; gap: 24px; min-height: 0; }
  .sink__char { width: auto; margin-left: 0; gap: 4px; --pw-rise: 170px; --ph-rise: 150px; }
  .pipe--rise { --pw: var(--pw-rise); --ph: var(--ph-rise); }
  .sink__floor { left: 0; right: 0; }
  .sink__h { margin-bottom: 18px; }
  /* phone: the sink lands on the pipe top (his station there), so the thud and the dust sit
     beside and on the pipe mouth rather than on the floor */
  .thud { font-size: 28px; left: auto; right: calc(var(--pw-rise) + 10px); bottom: calc(var(--ph-rise) - 8px); margin: 0; }
  .dust { left: auto; right: 0; width: var(--pw-rise); bottom: calc(var(--ph-rise) - 4px); }
  .sink { padding-bottom: 36px; }
}

/* ---------- 4. HIGH SCORES: the leaderboard panel ---------- */

.scores {
  padding: 64px 20px 40px;
  overflow: clip;
}
.cab {
  position: relative;
  z-index: 1;
  width: min(860px, 100%);
  margin: 0 auto;
  background: var(--wood-d);
  border: var(--line) solid var(--ink);
  border-radius: 10px;
  box-shadow: inset 0 0 0 4px var(--wood-l), 8px 8px 0 var(--ink);
  padding: 22px 22px 40px;
}
.crt {
  position: relative;
  overflow: clip;
  background: var(--paper);
  border: var(--line) solid var(--ink);
  border-radius: 6px;
  padding: 26px 24px 18px;
}
.crt::before {
  content: '';
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: 26%;
  background: var(--halftone);
  mask-image: linear-gradient(90deg, transparent, rgba(0, 0, 0, .5));
  -webkit-mask-image: linear-gradient(90deg, transparent, rgba(0, 0, 0, .5));
  pointer-events: none;
}
.crt__title {
  font: clamp(48px, 7vw, 84px)/.9 var(--f-display);
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--yel);
  text-shadow:
    -3px 0 0 var(--ink), 3px 0 0 var(--ink), 0 -3px 0 var(--ink), 0 3px 0 var(--ink),
    -3px -3px 0 var(--ink), 3px -3px 0 var(--ink), -3px 3px 0 var(--ink), 3px 3px 0 var(--ink),
    6px 6px 0 var(--pur);
  text-align: center;
}
.crt__sub {
  font: 16px/1 var(--f-display);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--pur);
  text-align: center;
  margin: 10px 0 24px;
}
.hs { display: grid; gap: 2px; }
.hs__row {
  position: relative;
  display: grid;
  grid-template-columns: 3.4em 1fr auto auto;
  align-items: baseline;
  gap: 0 12px;
  padding: 6px 0 16px;
  font: clamp(17px, 1.9vw, 22px)/1.2 var(--f-body);
  color: var(--ink);
}
.hs__rank { font-family: var(--f-display); letter-spacing: 1px; color: var(--wood-d); }
.hs__dots {
  align-self: end;
  height: .7em;
  background: repeating-linear-gradient(90deg, var(--ink) 0 3px, transparent 3px 9px) 0 100% / 100% 3px no-repeat;
}
.hs__val { font-family: var(--f-display); letter-spacing: .5px; color: var(--pur); }
.hs__bar {
  position: absolute;
  left: 0; bottom: 4px;
  height: 9px;
  width: calc(var(--w) * 100%);
  transform-origin: 0 50%;
}
.hs__bar i { position: absolute; inset: 0; background: var(--cyan); border: 2px solid var(--ink); border-radius: 4px; box-shadow: inset 0 -3px 0 #1a8ab0; }
.hs__row--one {
  font-size: clamp(21px, 2.6vw, 32px);
  padding-bottom: 22px;
}
.hs__row--one .hs__rank { color: var(--pur); }
.hs__row--one .hs__name { font-family: var(--f-display); letter-spacing: 1px; }
.hs__row--one .hs__val { color: var(--pur); }
.hs__row--one .hs__bar { height: 13px; }
.hs__row--one .hs__bar i { background: var(--gold); box-shadow: inset 0 -4px 0 var(--gold-d); }
.hs__rider {
  position: absolute;
  bottom: 100%;
  left: 36%;
  height: 56px;
  width: auto;
}
.crt__insert {
  margin-top: 16px;
  text-align: center;
  font: 16px/1 var(--f-display);
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--ink);
}
/* PLAY AGAIN: a warp-pipe link back up to the hero panel */
.crt__again {
  /* the visible button itself is at least 44 px tall, not only its hit area */
  display: flex;
  align-items: center;
  width: max-content;
  box-sizing: border-box;
  min-height: 44px;
  margin: 10px auto 0;
  font: 16px/1 var(--f-display);
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #fff;
  text-decoration: none;
  padding: 6px 10px 5px 8px;
  border: 3px solid var(--ink);
  border-radius: 8px;
  background: var(--pur);
  box-shadow: 3px 3px 0 var(--ink);
}
.crt__again:hover, .crt__again:focus-visible { background: var(--pur-d); }
/* a 44 px tall hit area around the link, whatever its type size */
.crt__again { position: relative; }
.crt__again::after { content: ''; position: absolute; left: -4px; right: -4px; top: 50%; height: 48px; transform: translateY(-50%); }
.cab__note {
  margin-top: 14px;
  text-align: center;
  font: 14px/1.4 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--paper);
}

.gap {
  position: relative;
  z-index: 1;
  width: min(860px, 100%);
  margin: 48px auto 0;
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  gap: 40px;
}
.gap__big { position: relative; display: grid; grid-template-columns: auto auto; align-items: end; gap: 18px; line-height: 1; width: max-content; max-width: 100%; }
.ledge--gap { left: auto; right: 0; top: 100%; width: calc(max(24svh, 150px) * .64 + 28px); }
.gap__numwrap { display: flex; flex-direction: column; }
.gap__char { height: max(24svh, 150px); width: auto; justify-self: start; }
.gap__lbl { font: 16px/1 var(--f-display); letter-spacing: 1.5px; text-transform: uppercase; color: var(--paper); margin-bottom: 18px; }
.gap__num {
  font: clamp(56px, 9vw, 120px)/1 var(--f-display);
  letter-spacing: 1px;
  color: var(--yel);
  text-shadow:
    -3px 0 0 var(--ink), 3px 0 0 var(--ink), 0 -3px 0 var(--ink), 0 3px 0 var(--ink),
    -3px -3px 0 var(--ink), 3px -3px 0 var(--ink), -3px 3px 0 var(--ink), 3px 3px 0 var(--ink),
    7px 7px 0 var(--pur);
}
.gap__facts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 28px; max-width: 640px; font-size: clamp(17px, 1.5vw, 20px); color: var(--ink); }
.gap__facts li { position: relative; padding: 8px 12px 7px 32px; background: var(--paper); border: 3px solid var(--ink); border-radius: 6px; box-shadow: 4px 4px 0 var(--ink); }
.gap__facts li::before { content: ''; position: absolute; left: 10px; top: .75em; width: 12px; height: 12px; background: var(--gold); border: 3px solid var(--ink); border-radius: 50%; }
.gap__facts b { color: var(--pur); font-family: var(--f-display); letter-spacing: .5px; font-weight: 400; }

@media (max-width: 760px) {
  .scores { padding: 40px 4px 100px; }
  .cab { padding: 6px; }
  .crt { padding: 18px 6px 8px; }
  .pipe--side { display: none; }
  .pipe--bar { display: block; position: absolute; right: 0; bottom: 4px; z-index: 1; --pw: 150px; --ph: 40px; }
  .crt__ledge { display: block; position: absolute; left: auto; right: 10px; bottom: 14px; top: auto; width: 150px; z-index: 1; }
  .cab { padding: 10px; }
  .crt { padding: 18px 10px 14px; }
  .crt::before { display: none; }
  .crt__title {
    font-size: 30px; text-align: left; letter-spacing: 1px; width: max-content; max-width: 100%;
    text-shadow:
      -2px 0 0 var(--ink), 2px 0 0 var(--ink), 0 -2px 0 var(--ink), 0 2px 0 var(--ink),
      -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink), 2px 2px 0 var(--ink),
      4px 4px 0 var(--pur);
  }
  /* the panel's left column (text) stops short of his 150px lane at the right */
  .crt__sub { font-size: 12px; letter-spacing: 1px; text-align: left; margin: 8px 0 14px; width: max-content; max-width: 200px; white-space: nowrap; }
  .crt { padding-bottom: 8px; }
  .hs { gap: 0; }
  .hs__row { grid-template-columns: 2.4em 1fr auto; gap: 0 6px; font-size: 12px; padding: 2px 150px 17px 0; }
  .hs__bar { bottom: 3px; height: 8px; }
  .hs__row--you { margin-top: 2px; padding-top: 6px; }
  .crt__gap { margin-top: 6px; }
  .crt__insert { margin-top: 8px; }
  .crt__again { margin: 6px 0 0; font-size: 12px; }
  .hs__dots { display: none; }
  /* the #1 row is a tall lane: the bar runs off the screen and the player rides it at the right */
  .hs__row--one { font-size: 15px; min-height: 150px; padding-right: 150px; align-content: start; grid-template-columns: 2.4em 1fr; position: relative; }
  .hs__row--one .hs__name { white-space: nowrap; }
  .hs__row--one .hs__val { grid-column: 2; }
  .hs__row--one .hs__bar { height: 12px; }
  .hs__rider { height: 40px; }
  /* the note stays in the cabinet's left column, clear of his 150px drop lane at the right */
  .cab__note { margin-top: 10px; font-size: 12px; text-align: left; max-width: 180px; }
  .gap { grid-template-columns: 1fr; gap: 34px; margin-top: 20px; }
  .gap__big { justify-content: space-between; gap: 10px; width: auto; padding-right: 18px; }
  .ledge--gap { right: 18px; }
  .gap__facts { grid-template-columns: 1fr; max-width: 212px; font-size: 15px; }
  .gap__facts li { padding: 6px 8px 5px 26px; }
  .gap__facts li::before { left: 7px; width: 10px; height: 10px; }
  .crt__gap { font-size: 12px; text-align: left; max-width: 156px; }
  .crt__insert { text-align: left; width: max-content; max-width: 156px; font-size: 12px; }
  .scores { padding-bottom: 40px; }
  .pipe--scores { display: block; right: 12px; bottom: 28px; --pw: 150px; --ph: 60px; z-index: 2; }
}

.hs__spill {
  position: absolute;
  z-index: 0;
  left: calc(50% + 430px);
  right: 0;
  top: 0;
  height: 13px;
  background: var(--gold);
  border-top: 3px solid var(--ink);
  border-bottom: 3px solid var(--ink);
  box-shadow: inset 0 -4px 0 var(--gold-d);
  display: none;
}
.hs__spill--you { height: 9px; background: var(--up); box-shadow: inset 0 -3px 0 #2a8a2a; }

/* ---------- 4b. FOES ---------- */

/* Rogues' gallery on the brick between the board and the sky finale.
   From 760px up, the right padding is the page player's lane: max(24vh, 150px) * 0.64
   is his width, plus 40px so his box stays clear of the posters on the way down.
   On a phone the posters run under him. Their right column is the same 150px the
   score rows and the finale pipes keep clear, and the copy stays in the left column. */
.foes {
  position: relative;
  overflow: clip;
  color: var(--ink);
  padding: calc(var(--hud-h) + 16px) calc(max(24vh, 150px) * 0.64 + 40px) 78px 12px;
  border-bottom: 8px solid var(--ink);
  background:
    repeating-linear-gradient(90deg, var(--ink) 0 3px, transparent 3px 46px),
    repeating-linear-gradient(0deg, var(--ink) 0 3px, var(--brick) 3px 28px);
  box-shadow: inset 0 8px 0 var(--brick-d);
}
.foes__head {
  width: fit-content;
  max-width: 100%;
  margin-bottom: 16px;
  padding: 10px 14px 12px;
  background: var(--paper);
  border: var(--line) solid var(--ink);
  border-radius: 6px;
  box-shadow: 6px 6px 0 var(--ink);
}
.foes__h {
  display: inline-block;
  max-width: 100%;
  margin-bottom: 8px;
  padding: 4px 10px 2px;
  font: clamp(32px, 8vw, 84px)/1.05 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--yel);
  border: 3px solid var(--ink);
  border-radius: 4px;
  box-shadow: 4px 4px 0 var(--ink);
}
.foes__dek {
  max-width: 36em;
  font-size: 18px;
  line-height: 1.3;
  color: var(--ink);
}
.foes__wall {
  display: grid;
  gap: 14px;
  margin-top: 16px;
}
.foes__poster {
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: var(--line) solid var(--ink);
  border-radius: 6px;
  box-shadow: 6px 6px 0 var(--ink);
}
/* The fixed portrait window reserves its height before the full-body frame loads. */
.foes__portrait {
  position: relative;
  flex: none;
  align-self: start;
  width: 100%;
  height: 156px;
  min-height: 156px;
  max-height: 156px;
  overflow: hidden;
  border-bottom: var(--line) solid var(--ink);
  background-color: var(--yel);
  background-repeat: no-repeat;
  background-position: center 30%;
  background-size: auto 108%;
}
.foes__portrait::before {
  content: '';
  position: absolute;
  z-index: 1;
  top: 8px;
  left: 50%;
  width: 52px;
  height: 14px;
  transform: translateX(-50%) rotate(-3deg);
  background: var(--paper-d);
  border: 2px solid var(--ink);
  box-shadow: 2px 2px 0 var(--ink);
}
.foes__face {
  position: absolute;
  inset: 28px 8px 6px;
  width: calc(100% - 16px);
  height: calc(100% - 34px);
  object-fit: contain;
  object-position: center bottom;
  /* above the page's rest ledges (.ledge--foe is z-index 4), so a platform passes behind the figure, never across his face */
  z-index: 5;
}
.foes__copy {
  min-width: 0;
  padding: 12px 12px 14px;
}
.foes__name {
  font: clamp(22px, 5vw, 36px)/1.05 var(--f-display);
  letter-spacing: .5px;
}
.foes__role {
  margin-top: 2px;
  font-size: 16px;
  line-height: 1.2;
  color: var(--pur-d);
}
.foes__plates {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
  min-width: 0;
}
.foes__plate {
  display: inline-block;
  max-width: 100%;
  font: 14px/1.05 var(--f-display);
  letter-spacing: .4px;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--yel);
  border: 2px solid var(--ink);
  border-radius: 2px;
  padding: 4px 6px 3px;
}
.foes__brief {
  margin-top: 10px;
  font-size: 18px;
  line-height: 1.35;
  overflow-wrap: break-word;
}
.foes__src {
  display: inline-block;
  max-width: 100%;
  margin-top: 8px;
  font-size: 15px;
  line-height: 1.3;
  color: var(--pur-d);
  overflow-wrap: anywhere;
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}
.ledge--foe { z-index: 4; pointer-events: none; }

@media (min-width: 760px) {
  .foes { padding-top: calc(var(--hud-h) + 20px); padding-left: 20px; padding-bottom: 84px; }
  .foes__dek { font-size: 20px; }
  .foes__wall { grid-template-columns: 1fr 1fr; gap: 16px; }
  .foes__brief { font-size: 19px; }
}
@media (min-width: 1100px) {
  .foes { padding-top: calc(var(--hud-h) + 24px); padding-left: 40px; }
  .foes__h { letter-spacing: 2px; }
  .foes__wall {
    grid-template-columns: 1fr 1fr 1fr;
    gap: 18px;
    padding-bottom: 22px;
  }
  /* hung off the mortar line, the way a poster pinned by hand sits */
  .foes__poster:nth-child(3n + 2) { transform: translateY(22px); }
}
/* Phone: the posters fill the screen. The right 150px of each one is portrait and
   paper, the same lane the score rows and the gut pipes keep clear, and he stands
   on that edge. The copy lives in the left column, so a leg down the lane crosses
   no text. The caption strip stops short of the same lane. */
@media (max-width: 760px) {
  .foes { padding-left: 8px; padding-right: 8px; }
  .foes__head { max-width: calc(100% - 158px); }
  .foes__poster {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 150px;
    align-items: start;
  }
  .foes__portrait {
    grid-column: 2;
    grid-row: 1;
    align-self: stretch;
    width: 150px;
    height: auto;
    min-height: 156px;
    max-height: none;
    justify-self: end;
    border-bottom: 0;
    border-left: var(--line) solid var(--ink);
  }
  .foes__face { bottom: auto; height: 136px; max-height: calc(100% - 36px); }
  .foes__copy { grid-column: 1; grid-row: 1; padding: 10px 8px 12px 10px; }
}
@media (orientation: landscape) and (max-height: 500px) {
  .foes { padding-top: calc(var(--hud-h) + 8px); padding-bottom: 56px; }
  .foes__h { font-size: 34px; }
  .foes__dek { margin-top: 6px; font-size: 16px; }
  .foes__portrait,
  .foes__portrait--altman { height: 112px; min-height: 112px; max-height: 112px; }
  .foes__brief { font-size: 16px; }
  .foes__plate { font-size: 13px; }
}
/* A short phone turned sideways still uses the right-edge lane, not the portrait column. */
@media (max-width: 760px) and (orientation: landscape) and (max-height: 500px) {
  .foes { padding-right: 150px; }
  .foes__head { max-width: 100%; }
  .foes__poster { display: flex; flex-direction: column; }
  .foes__portrait { width: auto; border-left: 0; border-bottom: var(--line) solid var(--ink); background-size: auto 108%; background-position: center 30%; }
}

/* ---------- 5. FINALE ---------- */

.clear {
  position: relative;
  background: var(--sky);
  overflow: clip;
  text-align: center;
  padding-top: calc(var(--hud-h) + 20px);
}
.clear__banner { position: relative; z-index: 3; padding: 0 16px; }
.eyebrow--dark { margin-bottom: 14px; }
.clear__h {
  width: max-content;
  max-width: 100%;
  margin: 0 auto;
  font: clamp(60px, 12vw, 170px)/.86 var(--f-display);
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #fff;
  text-shadow:
    -4px 0 0 var(--ink), 4px 0 0 var(--ink), 0 -4px 0 var(--ink), 0 4px 0 var(--ink),
    -4px -4px 0 var(--ink), 4px -4px 0 var(--ink), -4px 4px 0 var(--ink), 4px 4px 0 var(--ink),
    8px 8px 0 var(--pur);
}
.throne {
  position: relative;
  z-index: 2;
  width: min(560px, 100%);
  margin: max(150px, 16vh) auto 0;
}
.clear__gutter { display: none; }
/* covers the crown painted on the empty throne once the player wears his own */
.throne__cover {
  position: absolute;
  left: 46%;
  top: 8%;
  width: 8%;
  height: 6%;
  background: #c72a22;
  display: none;
}
.throne.is-crowned .throne__cover { display: block; }
.throne img { width: 100%; height: auto; }
.coinfall { position: absolute; z-index: 1; left: 0; right: 0; top: var(--hud-h); height: 70%; pointer-events: none; }
.coinfall i {
  position: absolute;
  top: -40px;
  left: calc(4% + var(--i) * 5.2%);
  width: 18px; height: 24px;
  background: var(--gold);
  border: 3px solid var(--ink);
  border-radius: 50%;
  box-shadow: inset -4px 0 0 var(--gold-d), inset 4px 0 0 var(--gold-l);
  opacity: 0;
}
.clear__floor {
  position: relative;
  z-index: 2;
  height: 56px;
  margin-top: -2px;
  background:
    radial-gradient(ellipse 10px 6px at 14px 14px, var(--gold-l) 0 2px, var(--gold) 2px 7px, var(--ink) 7px 9px, transparent 9.5px) 0 0 / 28px 28px,
    radial-gradient(ellipse 10px 6px at 14px 14px, var(--gold-l) 0 2px, var(--gold) 2px 7px, var(--ink) 7px 9px, transparent 9.5px) 14px 14px / 28px 28px,
    var(--gold-d);
  border-top: var(--line) solid var(--ink);
  border-bottom: var(--line) solid var(--ink);
}
.clear__panels {
  position: relative;
  z-index: 2;
  background: var(--night);
  padding: 48px 20px 40px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 460px));
  justify-content: center;
  gap: 32px;
  text-align: left;
}
.clear__panels::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--halftone);
  opacity: .5;
  pointer-events: none;
}
.box--tally { border-color: var(--ink); }
.tally__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  font: clamp(22px, 2.4vw, 30px)/1.1 var(--f-display);
  letter-spacing: .5px;
  text-transform: uppercase;
  padding: 6px 0;
  border-bottom: 3px dotted var(--paper-d);
}
.tally__row span { font: 14px/1 var(--f-display); letter-spacing: 1.5px; color: var(--wood-d); }
.tally__row b { font-weight: 400; color: var(--pur); text-align: right; }
.tally__row--cont b { color: var(--green-t); }
.tally__row--cont em { font-style: normal; color: var(--ink); text-decoration: underline; text-decoration-thickness: 3px; text-underline-offset: 4px; }
.cont i { font-style: normal; display: inline-block; min-width: 1ch; color: var(--ink); }
.tally__src { margin-top: 14px; font: 15px/1.4 var(--f-body); color: var(--wood-d); }
.buy__name { font: clamp(24px, 2.6vw, 32px)/1.1 var(--f-display); letter-spacing: 1px; text-transform: uppercase; margin-bottom: 16px; }
.buy__btn { margin-bottom: 18px; }
.ca { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 0; font-size: 16px; }
.ca__txt { font: 17px/1.4 var(--f-body); color: var(--ink); background: #fff; border: 2px solid var(--ink); border-radius: 6px; padding: 2px 8px; word-break: break-all; }
.chain { font: 15px/1 var(--f-display); color: var(--wood-d); letter-spacing: 1.5px; text-transform: uppercase; margin: 12px 0 18px; }
.links { display: flex; flex-wrap: wrap; gap: 10px 22px; }
.link { font: 18px/1 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--pur); }
a.link { text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 3px; }
@media (max-width: 760px) {
  .clear { padding-top: calc(var(--hud-h) + 8px); }
  /* phone: the title keeps to the left so the player's right-edge lane down to the throne is
     clear of it; no pile pipe, he drops in from the scores stub along that lane */
  .clear__banner { text-align: left; }
  .clear__h { font-size: 52px; margin: 0; max-width: 240px; }
  .throne { margin-top: 156px; }
  .clear__panels { grid-template-columns: 1fr; gap: 0; padding: 0 16px 48px; }
  .clear__gutter { display: block; position: relative; height: var(--gut, 250px); }
  .clear__gutter--top { --gut: 280px; }
  .pipe--gut { display: block; right: 8px; bottom: 22px; --pw: 150px; --ph: 40px; z-index: 2; }
  .tally__row { padding: 4px 0; font-size: 20px; }
  .tally__src { margin-top: 10px; }
  .clear__ledge {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 22px;
    border: var(--line) solid var(--ink);
    border-radius: 6px;
    background:
      repeating-linear-gradient(90deg, var(--ink) 0 3px, transparent 3px 26px),
      linear-gradient(#f2a06a 0 4px, var(--brick) 4px);
  }
  .box { padding: 16px 16px; }
}
/* short landscape: his lane runs down the right edge, so the leaderboard and the finale boxes
   stop short of it (the scores exit pipe and the finale side ledge stand inside it); the boxes
   stack in one column right of the launch tower; THUD sits above the landing, on screen */
@media (orientation: landscape) and (max-height: 500px) {
  .scores { padding-right: 150px; }
  .pipe--barx { --pw: 110px; }
  .gap__facts { max-width: 540px; }
  .clear__panels { grid-template-columns: minmax(0, 1fr); justify-content: stretch; padding: 32px 150px 40px 168px; }
  .clear__sideledge { right: 8px; width: 120px; }
  .sink__char .thud { right: auto; left: 0; bottom: 100%; }
  /* the headline starts lower than his landing, so it is below the HUD whenever he stands there */
  .sink__copy { padding-top: 48px; }
}
/* short landscape, desktop route: the warp into the scores runs between two pipes side by side
   in a two-pipe lane, the dive pipe at the top right and the exit pipe on the #1 bar line, so
   both tops stay on screen through the whole warp. The sink room's own dive pipe is not used */
@media (orientation: landscape) and (max-height: 500px) and (min-width: 760px) {
  .scores { padding-right: 276px; }
  .pipe--scores { display: block; left: auto; right: 8px; bottom: auto; --pw: 110px; --ph: 90px; z-index: 1; }
  .pipe--sinkdive { display: none; }
  /* the finale's side ledge gives way to the lane ledges, which are spaced to his in-view band */
  .clear__sideledge { display: none; }
}

/* ---------- footer: the last panel ---------- */

.foot {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  text-align: center;
  padding: 0 20px 56px;
  font-size: 17px;
  border-top: var(--line) solid var(--ink);
}
.foot__scene {
  position: relative;
  height: max(180px, 21svh);
  margin: 0 -20px 36px;
  overflow: clip;
  background: var(--night);
}
.foot__scene::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--halftone);
  opacity: .6;
}
.foot__ground {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 24px;
  background: linear-gradient(var(--ink) 0 4px, var(--grass) 4px 14px, var(--grass-d) 14px 18px, var(--ink) 18px 20px, var(--dirt) 20px);
}
.pipe--foot { right: 6%; bottom: 20px; --pw: 110px; --ph: 100px; }
.foot__char {
  position: absolute;
  z-index: 4;
  right: calc(6% + 136px);
  bottom: 20px;
  height: max(24svh, 150px);
  width: auto;
}
/* THE END? hangs in the last panel's sky on wide screens; on phones the scene is his, so the
   burst drops below it, above the disclaimer */
.foot__end {
  position: absolute;
  z-index: 3;
  left: 50%;
  top: 22px;
  transform: translateX(-50%);
  font-size: 30px;
}
@media (max-width: 760px) {
  .foot__scene { height: max(220px, 28svh); }
  .pipe--foot { right: 4%; --pw: 150px; --ph: 80px; }
  .foot__char { right: calc(4% + 178px); }
  /* relative, not static: the burst's star pseudo-elements size themselves on the word, never on the footer */
  .foot__end { position: relative; left: auto; top: auto; display: inline-block; transform: none; font-size: 24px; margin: -14px 0 18px; }
}
/* Short landscape keeps the same total footer height: scene space replaces bottom padding, giving
   the settled player room to stand inside the ground strip instead of being clamped into the copy. */
@media (orientation: landscape) and (max-height: 500px) {
  .foot { padding-bottom: 0; }
  .foot__scene { height: 236px; }
  .foot__char { height: 135px; }
}
@media (orientation: landscape) and (max-height: 500px) and (max-width: 760px) {
  .foot__scene { height: 276px; }
}
.foot__legal { max-width: 640px; margin: 0 auto 12px; }
.foot__credit { font: 15px/1.6 var(--f-display); letter-spacing: 1px; color: var(--paper-d); }
.foot__links { margin: 0 auto 14px; font-size: 17px; }
.foot__links a { color: var(--paper); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.foot__links a:hover { color: var(--yel); }

/* ---------- title screen menu (hero) ---------- */

/* the player menu, NES style: two rows of display type on the wood, no boxes. The rows line up on
   their left edge and the block is centred under the logo; a yellow cursor left of a row marks the
   pressed one (aria-pressed). ↑ and ↓ move it while focus is in the menu (main.js). Each row keeps
   an ink outline, so it also reads on the sky above the end card */
.title { display: flex; justify-content: center; }
.menu { display: grid; gap: 2px; }
.menu__opt {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 32px;
  margin: 0;
  padding: 3px 10px 0 30px;
  font: 24px/1 var(--f-display);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
  color: var(--paper);
  background: none;
  border: 0;
  border-radius: 4px;
  text-shadow:
    -2px 0 0 var(--ink), 2px 0 0 var(--ink), 0 -2px 0 var(--ink), 0 2px 0 var(--ink),
    -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink), 2px 2px 0 var(--ink),
    3px 3px 0 var(--pur);
}
.menu__opt::before {
  content: '';
  position: absolute;
  left: 3px; top: 50%;
  width: 20px; height: 22px;
  margin-top: -12px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 20'%3E%3Cpath d='M3 2.5 15.5 10 3 17.5z' fill='%23ffe12b' stroke='%23141008' stroke-width='2.5' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
  filter: drop-shadow(2px 2px 0 var(--ink));
  opacity: 0;
}
.menu__opt[aria-pressed="true"] { color: var(--yel); }
.menu__opt[aria-pressed="true"]::before { opacity: 1; }
.menu__opt:not([aria-pressed="true"]):hover::before { opacity: .45; }
/* touch screens: every row is a 44 px target */
.stage[data-touch="1"] .menu__opt { min-height: 44px; }
@media (max-width: 760px) {
  .menu { gap: 0; }
  .menu__opt { min-height: 44px; font-size: 22px; }
}
/* short landscape: two short rows beside the logo; each row's hit area grows away from the other
   one, so both are 44 px tall and neither covers the other */
@media (orientation: landscape) and (max-height: 500px) {
  .stage__plaque .menu { gap: 0; }
  .stage .stage__plaque .menu__opt { min-height: 22px; padding: 2px 6px 0 22px; font-size: 16px; letter-spacing: 1px; }
  .menu__opt::before { left: 3px; width: 13px; height: 15px; margin-top: -8px; }
  .menu__opt::after { content: ''; position: absolute; left: 0; right: 0; }
  .menu__opt[data-players="1"]::after { top: -22px; bottom: 0; }
  .menu__opt[data-players="2"]::after { top: 0; bottom: -22px; }
}
/* the 2 PLAYERS error floats under the menu so it never shifts the stage */
.menu__err {
  position: absolute;
  left: 0; top: 100%;
  z-index: 5;
  margin-top: 4px;
  font: 15px/1.3 var(--f-display);
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--red);
  pointer-events: none;
}
.menu__err:not(:empty) { background: var(--ink); border-radius: 6px; padding: 4px 8px 3px; }
/* under the board it stops well short of the board's right end (it wraps instead), so on a wide
   stage it stays out of the demo runner's column */
.stage__plaque .menu__err { max-width: calc(100% - 104px); }

/* hidden 1-T block in the scroll level: a secret, so it only exists with motion + JS */
.blk--hidden { display: none; appearance: none; background: transparent; border: 0; padding: 0; margin: 0; cursor: pointer; pointer-events: auto; }
.blk--hidden:focus { outline: 0; }

/* ---------- the stage: the game lives in the hero ---------- */

.stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  margin: 0 auto;
  --gl: 26%;
  background: linear-gradient(to bottom, var(--sky-d) 0 18%, var(--sky) 18% 62%, var(--sky-l) 62%);
  overflow: clip;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  text-align: center;
}
/* a run owns every touch on the stage (a swipe is a jump, never a page scroll); pause to leave */
.stage[data-game-state="playing"] { touch-action: none; }
.stage__canvas { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; display: block; }
.stage:not(.is-ready) .stage__canvas { display: none; }
/* once the canvas paints, the static scene under it is retired (it would otherwise count as
   scenery under the player's feet at the hero pipe) */
.stage.is-ready .stage__scene { display: none; }

/* static first frame: the scene under the canvas is the no-JS picture and what paints
   before the first canvas frame */
.stage__scene { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.scene__hills {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(var(--gl) - 4px);
  height: 80px;
  background: var(--svg-hills-near) repeat-x 0 100% / 320px 80px;
}
.scene__ground {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: var(--gl);
  background:
    linear-gradient(var(--ink) 0 4px, var(--grass) 4px 22px, var(--grass-d) 22px 26px, var(--ink) 26px 30px, transparent 30px),
    radial-gradient(ellipse 14px 5px at 30px 52px, var(--dirt-d) 0 90%, transparent 100%) 0 0 / 120px 80px,
    var(--dirt);
}
.scene__pipe { bottom: var(--gl); right: 12%; --pw: 60px; --ph: 72px; }
.scene__coin {
  position: absolute;
  bottom: calc(var(--gl) + 90px + var(--i) * 14px);
  left: calc(48% + var(--i) * 34px);
  width: 16px; height: 22px;
  background: var(--gold);
  border: 3px solid var(--ink);
  border-radius: 50%;
  box-shadow: inset -4px 0 0 var(--gold-d), inset 4px 0 0 var(--gold-l);
}
.stage__poster {
  position: absolute;
  z-index: 1;
  left: 24%;
  bottom: var(--gl);
  height: 22%;
  width: auto;
}

/* the game face of the HUD: the run's score, $WELON, time, power, stage and pause */
.shud__cell { display: flex; flex-direction: column; line-height: 1; flex: 0 0 auto; }
.shud__lbl { align-self: flex-start; font: 12px/1 var(--f-display); letter-spacing: 1.5px; text-transform: uppercase; color: var(--wood-d); white-space: nowrap; }
.shud__val { font: 26px/1 var(--f-display); color: var(--ink); margin-top: 3px; white-space: nowrap; text-transform: uppercase; letter-spacing: .5px; }
/* the expiry warning: the Power cell grows a bar that drains over the last seconds of a timed effect
   (absolutely placed, so the HUD's height does not change); the cell's colour follows the effect */
.shud__cell--power { position: relative; }
.shud__drain { position: absolute; left: 0; right: 0; bottom: -6px; height: 4px; border-radius: 2px; background: rgba(27, 20, 16, .22); overflow: hidden; opacity: 0; pointer-events: none; }
.shud__drain i { display: block; height: 100%; width: calc(var(--left, 0) * 100%); background: #00a6c2; }
.shud__cell--power[data-warn] .shud__drain { opacity: 1; }
.shud__cell--power[data-warn="ratio"] .shud__drain i { background: #1d9bf0; }
.shud__cell--power[data-warn="boost"] .shud__drain i { background: #e0a000; }
.shud__cell--power[data-warn] .shud__val { color: var(--red, #c4221b); }
.shud__score { color: var(--pur); min-width: 8ch; }
.shud__tk { color: var(--pur); letter-spacing: .5px; max-width: 110px; overflow: hidden; text-overflow: clip; }
.shud__tkval { color: var(--pur); min-width: 3ch; }
.shud__x { color: var(--wood-d); font-size: .8em; }
/* the payout multiplier (zone × tier × stomp chain) rides on the Score label */
.shud__mult { color: var(--pur); letter-spacing: .5px; }
.shud__pause {
  margin-left: auto;
  flex: 0 0 auto;
  min-width: 44px;
  min-height: 32px;
  padding: 7px 10px 6px;
  font: 15px/1 var(--f-display);
  letter-spacing: 1px;
  color: var(--ink);
  background: #fff;
  border: 3px solid var(--ink);
  border-radius: 8px;
  box-shadow: 2px 2px 0 var(--ink);
}

.stage__card {
  position: absolute;
  left: 50%;
  top: 44%;
  transform: translate(-50%, -50%);
  width: min(580px, 76%);
  max-height: calc(100% - 60px);
  z-index: 4;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px 18px;
  background: var(--paper);
  border: var(--line) solid var(--ink);
  border-radius: 8px;
  box-shadow: 6px 6px 0 var(--ink);
  color: var(--ink);
  overflow: auto;
}
.stage__card > * { flex-shrink: 0; }
.stage[data-game-state="over"] .stage__card,
.stage[data-game-state="paused"] .stage__card { top: 50%; width: min(620px, 92%); }
.stage[data-game-state="over"] .stage__card { justify-content: flex-start; max-height: calc(100% - 40px); }
.stage.is-ready [data-card="nojs"] { display: none; }
.stage.is-ready[data-game-state="title"] [data-card="title"],
.stage.is-ready[data-game-state="paused"] [data-card="paused"],
.stage.is-ready[data-game-state="over"] [data-card="over"] { display: flex; }
/* attract mode: the demo plays under the sign alone. The title card shows only when the league
   is on, bare (no card box), to carry the league's prompt (league.js puts it in the card) */
.lg-on .stage.is-ready[data-game-state="attract"] [data-card="title"] { display: flex; }
.stage[data-game-state="attract"] [data-card="title"] {
  top: 25%;
  width: max-content;
  max-width: 94%;
  gap: 6px;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
}
.stage[data-game-state="attract"] .card__h,
.stage[data-game-state="attract"] .card__p { display: none; }
.card__ins { font: 16px/1 var(--f-display); letter-spacing: 2px; text-transform: uppercase; color: var(--pur); }
.card__h {
  font: clamp(34px, 5vw, 64px)/.9 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #fff;
  text-shadow:
    -3px 0 0 var(--ink), 3px 0 0 var(--ink), 0 -3px 0 var(--ink), 0 3px 0 var(--ink),
    -3px -3px 0 var(--ink), 3px -3px 0 var(--ink), -3px 3px 0 var(--ink), 3px 3px 0 var(--ink),
    5px 5px 0 var(--pur);
}
.card__h--score b { font-weight: 400; color: var(--yel); }
.card__p { max-width: 460px; font-size: 17px; line-height: 1.35; color: var(--ink); }
.btn--play { font-size: 24px; padding: 12px 26px 10px; }
.card__stack { font: 16px/1.3 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--pur); }
.card__stack b { color: var(--ink); font-weight: 400; }
.card__gap { font: 15px/1.4 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--ink); max-width: 520px; }
.card__runs { min-height: 1.5em; font: 13px/1.5 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--wood-d); }
.initials { display: grid; gap: 6px; justify-items: center; }
.initials__lbl { font: 14px/1 var(--f-display); letter-spacing: 1.5px; text-transform: uppercase; color: var(--ink); }
.initials__row { display: flex; gap: 8px; align-items: center; justify-content: center; }
.initials__slot { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.initials__ltr {
  display: grid;
  place-items: center;
  width: 40px; height: 44px;
  font: 32px/1 var(--f-display);
  color: var(--ink);
  background: #fff;
  border: 3px solid var(--ink);
  border-radius: 6px;
}
.initials__slot.is-cur .initials__ltr { border-color: var(--pur); background: var(--yel); }
.initials__up, .initials__dn {
  width: 40px; height: 22px;
  font: 11px/1 var(--f-display);
  color: var(--ink);
  background: #fff;
  border: 2px solid var(--ink);
  border-radius: 4px;
  padding: 0;
}
.btn--ok { font-size: 18px; padding: 10px 14px 9px; align-self: center; }
.card__entered { min-height: 1.5em; font: 14px/1.5 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--green-t); }
.card__actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.card__actions .btn { font-size: 16px; padding: 9px 12px 8px; }
.btn--share { background: #fff; box-shadow: 4px 4px 0 var(--ink), inset 0 -4px 0 var(--paper-d); }
.btn--again { background: var(--up); box-shadow: 4px 4px 0 var(--ink), inset 0 -4px 0 var(--grass-d); }

/* the paused card: PAUSED and RESUME, then the controls map (beside it on a wide stage, where it
   stands high enough to leave him in view) */
.paused__head { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.stage__card--paused .ctl { width: min(100%, 440px); }
@media (min-width: 761px) {
  .stage.is-ready[data-game-state="paused"] [data-card="paused"] { top: 42%; flex-direction: row; align-items: center; gap: 28px; width: min(720px, 92%); padding: 18px 24px; }
  .stage__card--paused .ctl { width: auto; flex: 1 1 auto; }
}
/* phones, upright: the paused card keeps to the right of his lane (the page player stands over the
   left of the stage while the game is paused), with the same compact map as the controls card */
@media (max-width: 760px) and (orientation: portrait) {
  .stage.is-ready[data-game-state="paused"] [data-card="paused"] { left: auto; right: 8px; transform: translateY(-50%); width: calc(100% - 192px); padding: 10px 6px; }
  .stage__card--paused .ctl { width: 100%; }
  .stage__card--paused .ctl__t td { padding: 3px 2px 2px; }
  .stage__card--paused .ctl__t .ctl__keys { padding-right: 6px; }
  .stage__card--paused .ctl__act { font-size: 12px; letter-spacing: .3px; }
  .stage__card--paused :is(.ctl__pad, .ctl__ab) { width: 22px; height: 22px; }
  .stage__card--paused .ctl__ab { font-size: 13px; }
}

/* the controls card (the prompt bar's [?] or the ? key, title screen and attract): a wooden header
   over a paper sheet, like the weekly board, in the sky right of the sign and his lane. The demo
   keeps playing. While it is open the 2 Players message steps aside */
.stage.is-ready .stage__card--controls:not([hidden]) { display: flex; }
.stage:has([data-card="controls"]:not([hidden])) .menu__err { display: none; }
.stage .stage__card--controls {
  z-index: 6;
  top: 40%;
  left: auto;
  right: 4%;
  transform: translateY(-50%);
  width: min(460px, 46%);
  max-height: calc(100% - 24px);
  gap: 0;
  padding: 0;
  align-items: stretch;
  justify-content: flex-start;
  overflow: hidden auto;
}
.stage__card--controls:focus, .stage__card--controls:focus-visible { outline: 0; box-shadow: 6px 6px 0 var(--ink); }
.ctlc__head {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 8px 6px 16px;
  background: var(--svg-wood) 0 0 / 120px 120px;
  border-bottom: var(--line) solid var(--ink);
  box-shadow: inset 0 0 0 3px var(--yel-d);
}
.ctlc__h {
  margin: 0;
  font: 32px/.95 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #fff;
  text-shadow: -2px 0 0 var(--ink), 2px 0 0 var(--ink), 0 -2px 0 var(--ink), 0 2px 0 var(--ink), -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink), 2px 2px 0 var(--ink), 4px 4px 0 var(--pur);
}
.ctlc__x {
  flex: none;
  width: 44px; height: 44px;
  padding: 0;
  font: 30px/1 var(--f-display);
  color: var(--ink);
  background: var(--yel);
  border: 3px solid var(--ink);
  border-radius: 8px;
  box-shadow: 3px 3px 0 var(--ink);
}
.ctlc__x:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }
.stage__card--controls .ctl { padding: 4px 16px 10px; }
/* phones: under the sign, right of his lane */
@media (max-width: 760px) {
  .stage .stage__card--controls { top: var(--sign-b, 256px); right: 8px; transform: none; width: min(236px, calc(100% - 162px)); max-height: calc(100% - var(--sign-b, 256px) - var(--deck-band, var(--gl, 120px)) - 52px); }
  .ctlc__head { padding: 4px 4px 3px 10px; }
  .ctlc__h { font-size: 24px; }
  .ctlc__x { width: 40px; height: 40px; font-size: 26px; }
  .stage__card--controls .ctl { padding: 2px 8px 6px; }
  .stage__card--controls .ctl__t td { padding: 3px 2px 2px; }
  .stage__card--controls .ctl__t .ctl__keys { padding-right: 8px; }
  .stage__card--controls .ctl__act { font-size: 13px; letter-spacing: .5px; }
  .stage__card--controls :is(.ctl__pad, .ctl__ab) { width: 24px; height: 24px; }
  .stage__card--controls .ctl__ab { font-size: 14px; }
}

/* the controls map (main.js builds it from the keyboard map, or the touch controls on a touch
   screen): the keys on the left, what they do on the right */
.ctl__t { width: 100%; border-collapse: collapse; }
.ctl__t td { padding: 6px 4px 5px; text-align: left; vertical-align: middle; border-bottom: 2px dotted var(--wood-d); }
.ctl__t tr:last-child td { border-bottom: 0; }
.ctl__t .ctl__keys { width: 1%; padding-right: 16px; white-space: nowrap; line-height: 0; }
.ctl__act { font: 18px/1.1 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--ink); }
.ctl kbd {
  display: inline-block;
  min-width: 26px;
  margin: 0 4px 2px 0;
  padding: 4px 6px 2px;
  font: 14px/1 var(--f-display);
  letter-spacing: .5px;
  text-align: center;
  color: var(--ink);
  background: #fff;
  border: 2px solid var(--ink);
  border-radius: 3px;
  box-shadow: 0 2px 0 var(--ink);
}
.ctl__or { margin: 0 6px 0 2px; font: 12px/1 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--wood-d); }
.ctl__pad { display: inline-block; width: 28px; height: 28px; margin-right: 4px; vertical-align: middle; overflow: visible; }
.ctl__pad .ctl__cross { fill: var(--pur); stroke: var(--ink); stroke-width: 1.6; stroke-linejoin: round; }
.ctl__pad .ctl__arm { fill: var(--yel); stroke: var(--ink); stroke-width: 1.2; }
.ctl__ab {
  display: inline-grid;
  place-items: center;
  width: 28px; height: 28px;
  margin-right: 4px;
  vertical-align: middle;
  font: 16px/1 var(--f-display);
  color: #fff;
  text-shadow: -1.5px 0 0 var(--ink), 1.5px 0 0 var(--ink), 0 -1.5px 0 var(--ink), 0 1.5px 0 var(--ink);
  border: 2px solid var(--ink);
  border-radius: 50%;
  box-shadow: 2px 2px 0 var(--ink);
}
.ctl__ab--a { background: var(--red); }
.ctl__ab--b { background: var(--yel); }
.ctl__hud {
  display: inline-block;
  margin-right: 4px;
  padding: 5px 8px 3px;
  font: 13px/1 var(--f-display);
  letter-spacing: 1px;
  color: var(--ink);
  background: #fff;
  border: 2px solid var(--ink);
  border-radius: 6px;
  box-shadow: 2px 2px 0 var(--ink);
}

/* the button-prompt bar (keyboard and mouse screens only; main.js sets data-touch on a touch
   screen): bottom right on the ground band, what the keys do right now. Title and attract: SPACE
   play, ? controls; a run: ESC pause and, the first time each matters, a hint (main.js) */
.prompts {
  position: absolute;
  z-index: 3;
  right: 16px;
  bottom: max(8px, calc((var(--deck-band, 96px) - 40px) / 2));
  display: none;
}
.stage.is-ready:not([data-touch="1"]):is([data-game-state="title"], [data-game-state="attract"], [data-game-state="playing"]) .prompts { display: block; }
.prompts__set {
  display: none;
  align-items: center;
  gap: 12px;
  padding: 5px 12px 4px;
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 6px;
  box-shadow: 4px 4px 0 var(--ink);
}
.stage:is([data-game-state="title"], [data-game-state="attract"]) .prompts__set--title,
.stage[data-game-state="playing"] .prompts__set--play { display: flex; }
.prompt {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  padding: 0;
  font: 16px/1 var(--f-display);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink);
  background: none;
  border: 0;
}
.prompt + .prompt { padding-left: 12px; border-left: 2px dotted var(--wood-d); }
.prompt kbd {
  display: inline-block;
  min-width: 24px;
  padding: 4px 6px 2px;
  font: 13px/1 var(--f-display);
  letter-spacing: 1px;
  text-align: center;
  color: var(--ink);
  background: #fff;
  border: 2px solid var(--ink);
  border-radius: 3px;
  box-shadow: inset 0 -2px 0 var(--paper-d);
}
.prompt--btn { cursor: pointer; }
.prompt--btn:hover kbd { background: var(--yel); }
.prompt--hint kbd { background: var(--yel); box-shadow: inset 0 -2px 0 var(--yel-d); }

/* the control deck, a handheld's controls in the comic style: a D-pad on the left, B and A on the
   right. Touch screens only (data-touch, set by main.js from (pointer: coarse)), and only during a
   run or while paused. main.js sets --deck-u (one D-pad arm: 44 px on phones, sized to the ground
   band on wide stages), --deck-band (ground line to canvas bottom) and data-deck-mode (phone: under
   the ground line; land: D-pad in the lower-left corner, B and A on the ground band; wide: inside
   the ground band) */
.deck {
  --u: var(--deck-u, 44px);
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 3;
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  height: calc(var(--u) * 3 + 12px);
  padding: 6px;
  pointer-events: none;
}
.stage.is-ready[data-touch="1"][data-game-state="playing"] .deck,
.stage.is-ready[data-touch="1"][data-game-state="paused"] .deck { display: flex; }
.deck__pad, .deck__ab { position: relative; flex: none; pointer-events: auto; touch-action: none; }
.deck button {
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
}
.deck__pad { width: calc(var(--u) * 3); height: calc(var(--u) * 3); }
.deck__cross { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(3px 3px 0 var(--ink)); }
.deck__cross path { fill: var(--pur); stroke: var(--ink); stroke-width: 3px; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.deck__cross circle { fill: var(--pur-d); stroke: var(--ink); stroke-width: 2px; vector-effect: non-scaling-stroke; }
.deck__dir { position: absolute; width: var(--u); height: var(--u); border-radius: 3px; }
.deck__dir--up { left: var(--u); top: 0; --r: 0deg; }
.deck__dir--left { left: 0; top: var(--u); --r: -90deg; }
.deck__dir--right { left: calc(var(--u) * 2); top: var(--u); --r: 90deg; }
.deck__dir--down { left: var(--u); top: calc(var(--u) * 2); --r: 180deg; }
.deck__dir i {
  position: absolute;
  left: 50%; top: 50%;
  width: 46%; height: 40%;
  background: var(--ink);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  transform: translate(-50%, -50%) rotate(var(--r));
}
.deck__dir i::after {
  content: '';
  position: absolute;
  inset: 26% 18% 12%;
  background: var(--yel);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.deck .deck__dir.is-down, .deck .deck__dir.is-key { background: rgba(20, 16, 8, .3); }
.deck__dir.is-down i, .deck__dir.is-key i { transform: translate(-50%, -50%) rotate(var(--r)) scale(.86); }
.deck__ab { width: calc(var(--u) * 2.65); height: calc(var(--u) * 2.3); }
.deck .deck__btn {
  position: absolute;
  width: calc(var(--u) * 1.25);
  height: calc(var(--u) * 1.25);
  border-radius: 50%;
  border: 3px solid var(--ink);
  font: calc(var(--u) * .62)/1 var(--f-display);
  color: #fff;
  text-shadow: -2px 0 0 var(--ink), 2px 0 0 var(--ink), 0 -2px 0 var(--ink), 0 2px 0 var(--ink);
  transition: transform .05s, box-shadow .05s;
}
.deck .deck__btn--a { right: 0; top: 0; background: var(--red); box-shadow: 3px 3px 0 var(--ink), inset 0 -4px 0 var(--red-d); }
.deck .deck__btn--b { left: 0; bottom: 0; background: var(--yel); box-shadow: 3px 3px 0 var(--ink), inset 0 -4px 0 var(--yel-d); }
.deck .deck__btn.is-down, .deck .deck__btn.is-key { transform: translate(3px, 3px); box-shadow: 0 0 0 var(--ink), inset 0 4px 0 rgba(20, 16, 8, .25); }
.stage:not([data-power="fire"]) .deck__btn--b { opacity: .45; }
/* a first-run hint (main.js): a yellow ring round the control to use now (it pulses with motion on) */
.deck .is-hint::after {
  content: '';
  position: absolute;
  inset: -4px;
  border: 4px solid var(--yel);
  border-radius: 50%;
  box-shadow: 0 0 0 2px var(--ink);
  pointer-events: none;
}
.deck .deck__dir.is-hint::after { inset: -2px; border-radius: 7px; box-shadow: 0 0 0 2px var(--ink), inset 0 0 0 2px var(--ink); }
/* short landscape: the play area keeps its size; the D-pad stands in the lower-left corner (the
   run frames him clear of it), B and A sit on the ground band */
.stage[data-deck-mode="land"] .deck { align-items: flex-end; padding: 0 6px 6px; height: calc(var(--u) * 3 + 6px); }
.stage[data-deck-mode="land"] .deck__pad { opacity: .85; transition: opacity .3s; }
/* the boss arena stands him at its left, where the D-pad is; he cannot steer there, so it fades */
.stage[data-deck-mode="land"][data-phase="boss"] .deck__pad { opacity: .3; }
.stage[data-deck-mode="land"] .deck__ab { --d: min(calc(var(--u) * 1.1), calc(var(--deck-band) - 8px)); display: flex; gap: 10px; align-items: center; width: auto; height: auto; margin-bottom: max(0px, calc((var(--deck-band) - var(--d)) / 2 - 6px)); }
.stage[data-deck-mode="land"] .deck .deck__btn { position: relative; inset: auto; width: var(--d); height: var(--d); font-size: calc(var(--d) * .55); }

@media (min-width: 1100px) {
  .stage__poster { height: 17%; left: 26%; }
}
@media (max-width: 760px) {
  .shud__val { font-size: 19px; }
  .shud__score { min-width: 6ch; }
  .shud__tk { max-width: 72px; }
  .shud__cell--phase { display: none; }
  .stage__card { width: 92%; max-height: calc(100% - 50px); gap: 8px; padding: 12px 10px; }
  .card__h { font-size: 30px; }
  /* at phone size the purple drop reads as a doubled ghost: ink outline only */
  .card__h--score {
    font-size: 24px;
    text-shadow:
      -3px 0 0 var(--ink), 3px 0 0 var(--ink), 0 -3px 0 var(--ink), 0 3px 0 var(--ink),
      -3px -3px 0 var(--ink), 3px -3px 0 var(--ink), -3px 3px 0 var(--ink), 3px 3px 0 var(--ink);
  }
  .card__gap { font-size: 13px; }
  .card__stack { font-size: 14px; }
  .stage[data-game-state="over"] .stage__card { gap: 6px; padding: 10px 8px 12px; }
  .stage[data-game-state="over"] .card__ins { font-size: 13px; }
  .card__runs, .card__entered { min-height: 0; }
  .initials { gap: 4px; }
  .initials__hint { display: none; }
  .card__actions { gap: 6px; }
  .card__actions .btn { font-size: 14px; padding: 8px 9px 7px; }
  .card__p { font-size: 15px; }
  .initials__ltr { width: 32px; height: 38px; font-size: 26px; }
  .initials__up, .initials__dn { width: 32px; height: 24px; }
  .initials__row { gap: 6px; }
  .btn--ok { font-size: 15px; padding: 10px 10px 9px; }
  .ctl__t td { padding: 5px 4px 4px; }
  .ctl__act { font-size: 16px; }
}
/* short landscape: the stage is low, so the cards use the phone type sizes and the end panel
   sets the score beside the initials, with the actions in one row underneath */
@media (orientation: landscape) and (max-height: 500px) {
  .initials__hint { display: none; }
  .stage__card { max-height: calc(100% - 44px); gap: 6px; padding: 10px 12px; }
  .card__h { font-size: 28px; }
  .card__p { font-size: 15px; }
  /* the paused card sets RESUME beside the controls map, between the D-pad and B / A */
  .stage.is-ready[data-game-state="paused"] [data-card="paused"] { flex-direction: row; align-items: center; gap: 18px; width: min(560px, calc(100% - 300px)); }
  .stage__card--paused .ctl { width: auto; flex: 1 1 auto; }
  .ctl__t td { padding: 3px 4px 2px; }
  .ctl__act { font-size: 15px; }
  .ctl kbd, .ctl__hud { padding-top: 3px; padding-bottom: 1px; }
  .ctl__pad, .ctl__ab { width: 24px; height: 24px; }
  .stage__card--controls .ctl { padding: 2px 12px 6px; }
  /* the controls card stands at the right, beside the one-row sign and clear of his lane */
  .stage .stage__card--controls { top: 6px; right: 8px; transform: none; width: min(340px, 42%); max-height: calc(100% - 12px); }
  .ctlc__head { padding: 3px 4px 2px 12px; }
  .ctlc__h { font-size: 22px; }
  .ctlc__x { position: relative; width: 34px; height: 34px; font-size: 24px; }
  .ctlc__x::after { content: ''; position: absolute; inset: -5px; }
  .stage.is-ready[data-game-state="over"] [data-card="over"] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-content: center;
    justify-items: center;
    gap: 4px 14px;
    width: 94%;
    padding: 8px 10px 10px;
  }
  .stage__card--over > * { grid-column: 1; }
  .stage__card--over .initials { grid-column: 2; grid-row: 1 / span 4; align-self: center; }
  .stage__card--over .card__entered { grid-column: 2; grid-row: 5; }
  .stage__card--over .card__actions { grid-column: 1 / -1; grid-row: 6; margin-top: 4px; }
  .stage[data-game-state="over"] .card__ins { font-size: 13px; }
  .card__h--score {
    font-size: 24px;
    line-height: 1.1;
    text-shadow:
      -3px 0 0 var(--ink), 3px 0 0 var(--ink), 0 -3px 0 var(--ink), 0 3px 0 var(--ink),
      -3px -3px 0 var(--ink), 3px -3px 0 var(--ink), -3px 3px 0 var(--ink), 3px 3px 0 var(--ink);
  }
  .card__stack { font-size: 14px; }
  .card__gap { font-size: 13px; }
  .card__runs, .card__entered { min-height: 0; }
  .initials { gap: 4px; }
  .initials__row { gap: 6px; }
  .initials__ltr { width: 32px; height: 38px; font-size: 26px; }
  .initials__up, .initials__dn { width: 32px; height: 24px; }
  .btn--ok { font-size: 15px; padding: 10px 10px 9px; }
  .card__actions { gap: 8px; }
  .card__actions .btn { font-size: 14px; padding: 8px 9px 7px; }
}

/* ---------- player row in HIGH SCORES ---------- */

.hs__row--you { color: var(--green-t); border-top: 3px dotted var(--paper-d); margin-top: 6px; padding-top: 10px; }
.hs__row--you .hs__rank, .hs__row--you .hs__val { color: var(--green-t); }
.hs__row--you .hs__bar i { background: var(--up); box-shadow: inset 0 -3px 0 #2a8a2a; }
.crt__gap {
  margin-top: 10px;
  text-align: center;
  font: 14px/1.6 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--green-t);
}

/* F16: the jump-out. He falls through the game screen's bottom edge and leaves a crack behind. */
.hero__tear { position: absolute; z-index: 5; visibility: hidden; pointer-events: none; }
.hero__tear.is-on { visibility: visible; }
.tear__notch { position: absolute; inset: 0; background: var(--ink); clip-path: polygon(0 100%, 6% 30%, 20% 70%, 38% 6%, 57% 58%, 76% 14%, 100% 100%); }
.tear__chip { position: absolute; width: 4px; height: 8px; background: var(--ink); border-radius: 1px; }
.burst--rip { position: absolute; z-index: 7; font-size: 26px; visibility: hidden; pointer-events: none; }
.burst--rip.is-on { visibility: visible; }
.hud { z-index: 102; }
@media (max-width: 760px) { .burst--rip { font-size: 18px; } }

/* ---------- the player: one fixed Elon for the whole page (motion + JS only) ---------- */

.player {
  position: fixed;
  top: 0; left: 0;
  z-index: 40;
  display: none;
  height: 200px;
  width: 128px;
  pointer-events: none;
  will-change: transform;
}
.player__bob, .player__body { position: absolute; inset: 0; }
.player__body { transform-origin: 50% 100%; }
/* every frame sits feet-down and centred in the box; the shown one is picked by data-frame */
.player__body img { position: absolute; left: 50%; bottom: 0; height: 100%; width: auto; transform: translateX(-50%); opacity: 0; }
.player[data-frame="idle"] .f-idle,
.player[data-frame="run-1"] .f-run-1,
.player[data-frame="run-2"] .f-run-2,
.player[data-frame="run-3"] .f-run-3,
.player[data-frame="run-4"] .f-run-4,
.player[data-frame="run-5"] .f-run-5,
.player[data-frame="run-6"] .f-run-6,
.player[data-frame="jump"] .f-jump,
.player[data-frame="sink"] .f-sink,
.player[data-frame="pipe"] .f-pipe,
.player[data-frame="throne"] .f-throne,
.player[data-frame="victory"] .f-victory { opacity: 1; }
.player__say {
  position: absolute;
  left: 60%;
  bottom: calc(100% + 10px);
  font-size: 18px;
  opacity: 0;
  transform: scale(.4);
  transform-origin: 0 100%;
}
.player.is-say .player__say { opacity: 1; transform: none; transition: transform .18s cubic-bezier(.2, 1.4, .5, 1), opacity .1s; }
.player.say-left .player__say { left: auto; right: 60%; transform-origin: 100% 100%; }
.player.say-left .player__say::before { left: auto; right: 14px; border-left: 0; border-right: 10px solid var(--ink); }
.player.say-left .player__say::after { left: auto; right: 17px; border-left: 0; border-right: 7px solid #fff; }
.player.is-ingame, .player.is-inpipe { visibility: hidden; }
/* the throne frame carries its own crown; this element stays for the station hook only */
.player__crown { display: none; }

/* ---------- lore props: original comic art, static by default, quiet motion under html.js ----------
   Every prop sits in a lane measured clear of text and of the player's stations at 1440 and 390. */


/* the bird sign: a bird that gets an X painted over it (stays painted) */
.sign--x { --sx: 8%; }
.sign--x .xsign__face { position: relative; display: block; width: 56px; height: 40px; margin: 0 auto; }
.xsign__face svg { position: absolute; left: 0; top: 0; width: 100%; height: 100%; }
.xsign__face .lore__xmark { left: 12%; width: 76%; transform-origin: 50% 50%; }
.xsign__face::after {
  content: '';
  position: absolute;
  left: 46%; top: 84%;
  width: 5px; height: 14px;
  background: #e0202a;
  border-radius: 0 0 3px 3px;
}

/* the parked wedge truck on the brick platform, window cracked, a steel ball on the hood */
.truck {
  position: absolute;
  z-index: 3;
  left: calc(var(--x) - var(--blk) * .3);
  bottom: calc(var(--ground-h) + var(--runner-h) + var(--blk) * 1.6 + var(--lift, 0) * var(--blk) * 1.2 - 4px);
  width: calc(var(--blk) * 2.6);
  height: calc(var(--blk) * 1.04);
  pointer-events: none;
}
.truck .lore__truck { position: absolute; left: 0; bottom: 0; width: 100%; height: 100%; }
.truck .lore__ball { position: absolute; left: 72%; bottom: 52%; width: 12px; height: 12px; }
.truck__plate {
  position: absolute;
  left: 3%; bottom: 32%;
  font: 10px/1 var(--f-display);
  letter-spacing: 1px;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--ink);
  border-radius: 2px;
  padding: 1px 3px 0;
}

/* a boring-machine cutter head, half buried beside the tunnel pipe */
.drill {
  position: absolute;
  z-index: 1;
  left: calc(10% + var(--runner-h) * .86 + 14px);
  bottom: calc(var(--ground-h) - 24px);
  width: 56px; height: 56px;
  pointer-events: none;
}
.drill svg { display: block; width: 100%; height: 100%; }

/* a Hyperloop tube along the courtroom wall; a pod passes through now and then */
.loop {
  position: absolute;
  z-index: 0;
  top: calc(var(--hud-h) + 24px);
  left: 56%; right: 0;
  height: 26px;
  --run: 760px;
  border-top: 3px solid var(--ink);
  border-bottom: 3px solid var(--ink);
  border-radius: 13px 0 0 13px;
  background:
    repeating-linear-gradient(90deg, transparent 0 44px, var(--ink) 44px 47px),
    linear-gradient(var(--steel) 0 35%, var(--steel-d) 35% 75%, #5a6470 75%);
  overflow: clip;
  pointer-events: none;
}
.loop::before, .loop::after { content: ''; position: absolute; top: 0; bottom: 0; width: 14px; background: var(--ink); }
.loop::before { left: 0; }
.loop::after { right: 0; }
.loop__pod {
  position: absolute;
  top: 3px; left: 16px;
  width: 52px; height: 12px;
  background: linear-gradient(#fff 0 50%, var(--steel) 50%);
  border: 2px solid var(--ink);
  border-radius: 6px;
}
.loop__pod::before { content: ''; position: absolute; left: 8px; right: 8px; top: 1px; height: 3px; background: var(--cyan); border-radius: 2px; }
.loop__tag {
  position: absolute;
  z-index: 1;
  left: 14px; top: -3px; bottom: -3px;
  display: flex; align-items: center;
  font: 11px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #fff;
  background: var(--ink);
  padding: 0 6px;
}

.pipe__tag {
  position: absolute;
  z-index: 1;
  left: 50%; bottom: 14%;
  transform: translateX(-50%);
  font: 12px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  white-space: nowrap;
  color: #fff;
  background: var(--ink);
  border-radius: 4px;
  padding: 5px 7px 4px;
}

.doge {
  display: inline-block;
  width: 13px; height: 13px;
  margin: 0 6px -1px 0;
  background: var(--gold);
  border: 2px solid var(--ink);
  border-radius: 50%;
  box-shadow: inset 3px 0 0 var(--gold-l), inset -3px 0 0 var(--gold-d);
}

/* a pennant planted on the coin pile's slope */
.pennant {
  position: absolute;
  z-index: 3;
  left: 14%; bottom: 24%;
  width: 96px; height: 100px;
  pointer-events: none;
}
.pennant__pole { position: absolute; left: 0; bottom: 0; width: 8px; height: 100%; background: var(--steel); border: 2px solid var(--ink); border-radius: 3px 3px 0 0; box-shadow: inset -2px 0 0 var(--steel-d); }
.pennant__flag {
  position: absolute;
  left: 8px; top: 0;
  font: 13px/1.15 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  text-align: center;
  color: #fff;
  background: var(--mars);
  border: 3px solid var(--ink);
  padding: 7px 16px 6px 8px;
  clip-path: polygon(0 0, 100% 0, 84% 50%, 100% 100%, 0 100%);
  transform-origin: 0 50%;
}

/* a launch tower with two arms that catch a stainless booster */
.tower {
  position: absolute;
  z-index: 1;
  left: 28px; bottom: 36px;
  width: 124px; height: 230px;
  pointer-events: none;
}
.tower__mast {
  position: absolute;
  left: 0; bottom: 0;
  width: 18px; height: 100%;
  background: repeating-linear-gradient(0deg, #3b3b4a 0 10px, #5a6470 10px 12px);
  border: 3px solid var(--ink);
  border-radius: 3px;
}
.tower__mast::before { content: ''; position: absolute; left: -8px; right: -8px; top: -8px; height: 10px; background: var(--ink); border-radius: 3px; }
.tower__mast::after { content: ''; position: absolute; left: 1px; top: -16px; width: 8px; height: 8px; background: var(--red); border: 2px solid var(--ink); border-radius: 50%; }
.tower__arm {
  position: absolute;
  left: 14px;
  width: 92px; height: 10px;
  background: var(--steel-d);
  border: 3px solid var(--ink);
  border-radius: 5px;
  box-shadow: inset 0 -3px 0 #5a6470;
  transform-origin: 0 50%;
}
.tower__arm--a { top: 86px; }
.tower__arm--b { top: 98px; }
.tower__booster { position: absolute; left: 44px; top: 66px; width: 36px; height: 114px; }
.tower__booster svg { display: block; width: 100%; height: 100%; }
.tower__flame {
  position: absolute;
  left: 9px; right: 9px; top: 100%;
  height: 22px;
  background: linear-gradient(var(--yel) 0 40%, #ff8c1a 40% 75%, transparent 75%);
  clip-path: polygon(0 0, 100% 0, 70% 100%, 30% 100%);
  opacity: 0;
}
.tower__say {
  position: absolute;
  left: 10px; top: 36px;
  font-size: 15px;
}

/* a poster on the footer wall */
.poster {
  position: absolute;
  z-index: 2;
  left: 48px; bottom: 44px;
  width: 96px; height: 118px;
  padding: 10px 6px 8px;
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 4px;
  box-shadow: 4px 4px 0 var(--ink);
  text-align: center;
  pointer-events: none;
}
.poster__planet {
  display: block;
  width: 40px; height: 40px;
  margin: 0 auto 8px;
  background: var(--mars);
  border: 3px solid var(--ink);
  border-radius: 50%;
  box-shadow: inset -8px -6px 0 #7d2516, inset 6px 4px 0 #ff8c6a;
}
.poster b { display: block; font: 14px/1.15 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--ink); }

@media (max-width: 760px) {
  .sign--x { --sx: 4%; }
  .drill { width: 44px; height: 44px; bottom: calc(var(--ground-h) - 18px); }
  .loop { top: auto; bottom: 110px; left: 12px; right: auto; width: 206px; --run: 280px; border-radius: 0 13px 13px 0; }
  /* phone: planted at the foot of the pile, between the floor station's lane and the pile pipe */
  .pennant { left: 42%; bottom: 0; width: 64px; height: 64px; }
  .pennant__flag { font-size: 10px; padding: 5px 8px 4px 5px; letter-spacing: .5px; }
  .tower { left: 16px; top: 36px; bottom: auto; width: 110px; height: 220px; }
  .poster { left: 4px; bottom: 34px; width: 60px; height: 84px; padding: 6px 3px 4px; border-width: 3px; box-shadow: 3px 3px 0 var(--ink); }
  .poster__planet { width: 26px; height: 26px; margin-bottom: 5px; }
  .poster b { font-size: 10px; letter-spacing: .5px; }
}

/* ---------- achievement toasts, trillionaire mode ---------- */

.toasts {
  position: fixed;
  z-index: 60;
  top: calc(var(--hud-h) + 10px);
  right: 10px;
  display: grid;
  gap: 8px;
  justify-items: end;
  pointer-events: none;
}
.toast {
  font: 17px/1.2 var(--f-body);
  color: var(--ink);
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 10px;
  padding: 8px 12px;
  box-shadow: 4px 4px 0 var(--ink);
  max-width: 260px;
  text-align: left;
}
.toast b { display: block; font: 13px/1 var(--f-display); letter-spacing: 1.5px; text-transform: uppercase; color: var(--pur); margin-bottom: 3px; }
/* the script places the stack in open sky, clear of the game's controls and the runner's lane;
   compact (no room for the whole stack) shows the newest toast only */
.toasts.is-compact .toast:not(:last-child) { display: none; }
@media (max-width: 760px) {
  .toast { max-width: 236px; font-size: 16px; }
}
.hud.is-tmode { background: var(--yel); box-shadow: inset 0 -4px 0 var(--yel-d); }
.rain { position: fixed; inset: 0; z-index: 45; pointer-events: none; display: none; overflow: clip; }
.rain i {
  position: absolute;
  top: -30px;
  left: calc(var(--l) * 1%);
  width: 16px; height: 22px;
  background: var(--gold);
  border: 3px solid var(--ink);
  border-radius: 50%;
  box-shadow: inset -4px 0 0 var(--gold-d), inset 4px 0 0 var(--gold-l);
}

/* ---------- motion-only initial states and idle life ----------
   Nothing below runs for reduced-motion visitors or without JS. */

@media (prefers-reduced-motion: no-preference) {

  html.js .hud__score:not(.is-busted) .hud__box::before { clip-path: none; background: #fff; }
  html.js .hud__score:not(.is-busted) .hud__box::after { display: none; }
  /* before the bust the box holds the whole count-up, $999,999,999,999 included: the box was
     built for twelve digits. Only the trillion breaks out, at full size. */
  html.js .hud__score:not(.is-busted) .hud__counter { transform: none; font-size: 20px; }
  @media (max-width: 760px) {
    html.js .hud__score:not(.is-busted) .hud__counter { font-size: 15.5px; }
  }

  html.js .blk:not(.is-popped) .blk__face {
    background: var(--yel);
    box-shadow: inset -6px -6px 0 var(--yel-d), inset 5px 5px 0 #fff59a;
  }
  html.js .blk:not(.is-popped) .blk__face::after {
    content: '?';
    width: auto; height: auto;
    border: 0;
    padding-top: 3px;
    animation: qshine 1.8s steps(1) infinite;
  }
  html.js .blk:not(.is-popped) .coin,
  html.js .blk:not(.is-popped) .item,
  html.js .blk:not(.is-popped) .pop { opacity: 0; }

  html.js .cap:not(.is-broken) .cap__seg { visibility: visible; }

  html.js .level__track { flex-wrap: nowrap; width: max-content; }
  html.js .lvl-panel { width: var(--vw, 100vw); }

  html.js .box--quote:not(.is-shown) { opacity: 0; }
  html.js .is-taken { visibility: hidden; }
  html.js .player.is-on { display: block; }
  html.js .player[data-frame="sink"].is-run .player__bob { animation: runbob .32s steps(2) infinite; }
  html.js .hs__spill.is-on { display: block; }

  html.js .hs__row:not(.is-shown) { opacity: 0; }
  html.js .hs__row:not(.is-shown) .hs__bar { transform: scaleX(0); }

  html.js .clear__banner:not(.is-shown),
  html.js .throne:not(.is-shown),
  html.js .clear__panels:not(.is-shown) { opacity: 0; }

  html.js .clear.is-clear .coinfall i {
    animation: coinfall 2.2s cubic-bezier(.3, 0, .8, .4) both;
    animation-delay: calc(var(--i) * 70ms);
  }

  /* idle life: slow, low amplitude */
  html.js .coin i { animation: coinspin .7s steps(6) infinite; }
  html.js .crt__insert { animation: blink 1s steps(1) infinite; }
  html.js .crt__again { animation: blink 1.4s steps(1) infinite; }
  /* the start line's words blink on their ink strip; the scroll cue bobs; a first-run hint pulses
     (a ring round the touch control, the prompt bar's keycap pressing itself) */
  html.js .plaque__start > span { animation: blink 1.1s steps(1) infinite; }
  html.js .plaque__more { animation: bob 1.6s ease-in-out infinite; }
  html.js .deck .is-hint::after { animation: hintring .9s ease-in-out infinite; }
  html.js .prompt--hint kbd { animation: hintkey .9s steps(1) infinite; }
  html.js .hs__row--one .hs__val { animation: flash 1s steps(1) infinite; }

  /* game layer */
  html.js .blk--hidden { display: block; }
  html.js .blk--hidden:not(.is-found) .blk__face,
  html.js .blk--hidden:not(.is-found) .coin,
  html.js .blk--hidden:not(.is-found) .pop { opacity: 0; }
  html.js .stage:not([data-game-state="attract"]) .card__ins { animation: blink 1.1s steps(1) infinite; }
  /* toasts pop in and out where they stand: they are placed anywhere clear, so a slide would cross what they avoid */
  html.js .toast { animation: toastpop .28s cubic-bezier(.2, 1.3, .5, 1) both; }
  html.js .toast.is-out { animation: toastdrop .28s ease-in both; }
  html.js .rain.is-on { display: block; }
  html.js .rain i { animation: rainfall var(--d, 2.4s) linear infinite; animation-delay: calc(var(--i) * -.41s); }
  html.js .hud.is-tmode .hud__coins .hud__val b { animation: flash .5s steps(1) infinite; }

  /* lore props: idle life is slow and small; the one-shot (the X) and the catch are the events */
  html.js .sign--x:not(.is-x) .lore__xmark,
  html.js .sign--x:not(.is-x) .xsign__face::after { opacity: 0; }
  html.js .sign--x.is-x .lore__xmark { animation: stamp .3s cubic-bezier(.2, 1.4, .5, 1) both; }
  html.js .sign--x.is-x .xsign__face::after { animation: drip .5s ease-out .25s both; }
  html.js .drill svg { animation: spin 9s linear infinite; }
  html.js .loop__pod { animation: pod 7s linear infinite; }
  html.js .pennant__flag { animation: wave 1.6s ease-in-out infinite; }
  html.js .tower__booster { animation: boost 12s linear infinite; }
  html.js .tower__flame { animation: flame 12s steps(1) infinite; }
  html.js .tower__arm { animation: arms 12s ease-in-out infinite; }
  html.js .tower__arm--b { animation-delay: .12s; }
  html.js .tower__say { animation: caught 12s steps(1) infinite; }
}

@keyframes bob { 50% { transform: translateY(-3px); } }
@keyframes blink { 50% { opacity: .08; } }
@keyframes hintring { 50% { transform: scale(1.1); opacity: .55; } }
@keyframes hintkey { 50% { transform: translateY(2px); box-shadow: none; } }
@keyframes flash { 50% { color: var(--pur-d); } }
@keyframes qshine {
  0%, 62% { color: var(--ink); }
  70% { color: #fff; }
  78% { color: var(--pur); }
  86% { color: var(--ink); }
}
@keyframes coinspin {
  0% { transform: scaleX(1); }
  25% { transform: scaleX(.55); }
  50% { transform: scaleX(.14); }
  75% { transform: scaleX(-.55); }
}
@keyframes runbob { 50% { transform: translateY(-6px); } }
@keyframes coinfall {
  0% { opacity: 1; transform: translateY(0) scaleX(1); }
  30% { transform: translateY(26vh) scaleX(.3); }
  60% { transform: translateY(52vh) scaleX(1); }
  90% { opacity: 1; }
  100% { opacity: 0; transform: translateY(76vh) scaleX(.3); }
}
@keyframes rainfall {
  0% { transform: translateY(0) scaleX(1); }
  25% { transform: translateY(28vh) scaleX(.3); }
  50% { transform: translateY(56vh) scaleX(1); }
  75% { transform: translateY(84vh) scaleX(.3); }
  100% { transform: translateY(112vh) scaleX(1); }
}
@keyframes stamp { from { transform: scale(2.6); opacity: 0; } 40% { opacity: 1; } to { transform: none; opacity: 1; } }
@keyframes drip { from { transform: scaleY(0); opacity: 1; transform-origin: 50% 0; } to { transform: none; opacity: 1; transform-origin: 50% 0; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pod { 0% { transform: translateX(-80px); } 20%, 100% { transform: translateX(var(--run)); } }
@keyframes wave { 50% { transform: skewY(-4deg); } }
@keyframes boost {
  0%, 8% { transform: translateY(-62%); }
  30%, 86% { transform: none; }
  92%, 100% { transform: translateY(-62%); }
}
@keyframes flame { 0%, 7% { opacity: 0; } 8%, 30% { opacity: 1; } 31%, 86% { opacity: 0; } 87%, 93% { opacity: 1; } 94%, 100% { opacity: 0; } }
@keyframes arms { 0%, 24% { transform: rotate(-28deg); } 32%, 86% { transform: none; } 90%, 100% { transform: rotate(-28deg); } }
@keyframes caught { 0%, 31% { opacity: 0; } 32%, 86% { opacity: 1; } 87%, 100% { opacity: 0; } }

/* ---------- phones (portrait and short landscape): tap targets, type sizes, the 2 PLAYERS
   error row, toasts. Nothing here reaches a desktop width. ---------- */

@media (max-width: 760px), (orientation: landscape) and (max-height: 500px) {
  /* every control gets a 44x44 hit area */
  .hud__sfx { min-width: 44px; min-height: 44px; }
  .menu__opt, .btn--play { min-height: 44px; }
  .btn--ok, .card__actions .btn { min-width: 44px; min-height: 44px; }
  .shud__pause { min-width: 44px; min-height: 44px; padding: 0 8px; }
  /* initials: the arrows are 44 wide and reach 10px above and below their faces */
  .initials__ltr { width: 40px; }
  .initials__up, .initials__dn { position: relative; width: 44px; height: 24px; }
  .initials__up::after, .initials__dn::after { content: ''; position: absolute; left: 0; right: 0; top: -12px; bottom: -12px; }
  /* type: HUD labels 12px, nothing under 11px */
  .hud__lbl, .shud__lbl { font-size: 12px; }
  .truck__plate, .pennant__flag, .poster b { font-size: 11px; }
}

@media (max-width: 760px) {
  .hud__lbl, .shud__lbl { letter-spacing: .5px; }
  .hs__row { font-size: 14px; }
  /* the busted score keeps bursting out of its box, but at its peak it stops short of TIME */
  .hud__counter { font-size: 19px; }
  /* the cards hang just under the title sign (--sign-b, its bottom, set by main.js; the fallback
     clears the sign without JS): the league's prompt as high as it goes, which leaves the attract
     demo the most room for its (capped) jumps below it */
  .stage[data-game-state="attract"] [data-card="title"] { top: var(--sign-b, 256px); transform: translate(-50%, 0); }
  .stage[data-game-state="title"] [data-card="title"], .stage__card--nojs { top: calc(var(--sign-b, 256px) + 12px); transform: translate(-50%, 0); }
  .menu__err { font-size: 13px; }
  /* with no full-size spot in open sky, the newest toast collapses to a compact strip */
  .toasts.is-compact .toast { max-width: none; padding: 3px 8px; font-size: 13px; line-height: 1.2; box-shadow: 2px 2px 0 var(--ink); }
  .toasts.is-compact .toast b { display: inline; font-size: 11px; margin: 0 6px 0 0; }
  .toasts.is-compact .toast:not(:last-child) { display: none; }
}

@media (orientation: landscape) and (max-height: 500px) {
  .toasts.is-compact .toast { max-width: 325px; padding: 3px 8px; font-size: 13px; line-height: 1.2; box-shadow: 2px 2px 0 var(--ink); }
  .toasts.is-compact .toast b { display: inline; font-size: 11px; margin: 0 6px 0 0; }
  .toasts.is-compact .toast:not(:last-child) { display: none; }
}

@keyframes toastpop { from { transform: scale(.6); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes toastdrop { from { transform: none; opacity: 1; } to { transform: scale(.6); opacity: 0; } }

/* ---------- the holder league (league.js). Everything here hangs off elements league.js injects
   or the lg-* classes it sets on <html>, so with the league off none of it matches. ---------- */

.lg[hidden], .lg [hidden], .lg-board[hidden], .lg__over[hidden], .lg__retry[hidden] { display: none !important; }
.lg { display: flex; flex-direction: column; align-items: center; gap: 8px; width: 100%; max-width: 520px; }
.lg__msg {
  margin: 0;
  font: 15px/1.25 var(--f-display);
  letter-spacing: .5px;
  text-transform: uppercase;
  text-align: center;
  color: var(--yel);
  background: var(--ink);
  border-radius: 6px;
  padding: 5px 10px 4px;
}
.lg__row { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.lg__btn { display: inline-flex; align-items: center; gap: 7px; font-size: 18px; padding: 10px 14px 8px; min-height: 44px; cursor: pointer; }
.lg__btn--connect { background: var(--up); box-shadow: 4px 4px 0 var(--ink), inset 0 -4px 0 var(--grass-d); }
.lg__btn--connect:active { box-shadow: 2px 2px 0 var(--ink), inset 0 -4px 0 var(--grass-d); }
.lg__btn--connect.is-busy { background: var(--paper-d); box-shadow: 4px 4px 0 var(--ink), inset 0 -4px 0 var(--wood-l); }
.lg__btn--connect:disabled { cursor: progress; }
.lg__btn--buy { background: var(--pur); color: #fff; box-shadow: 4px 4px 0 var(--ink), inset 0 -4px 0 var(--pur-d); }
.lg__btn--buy:active { box-shadow: 2px 2px 0 var(--ink), inset 0 -4px 0 var(--pur-d); }
.lg__ico { flex: none; color: var(--yel); }
.lg__pick { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.lg__wal { display: inline-flex; align-items: center; gap: 7px; font-size: 16px; padding: 8px 12px 7px; min-height: 44px; background: var(--paper); box-shadow: 3px 3px 0 var(--ink), inset 0 -3px 0 var(--paper-d); cursor: pointer; }
.lg__walico { width: 20px; height: 20px; border-radius: 4px; }
.lg__who {
  margin: 0;
  font: 16px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--up);
  border: 3px solid var(--ink);
  border-radius: 8px;
  padding: 6px 10px 5px;
  box-shadow: 3px 3px 0 var(--ink);
}
.lg__links { display: flex; gap: 8px; }
.lg__link {
  position: relative;
  font: 14px/1.2 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 6px;
  padding: 4px 10px 3px;
  box-shadow: 2px 2px 0 var(--ink);
  cursor: pointer;
}
.lg__link::after { content: ''; position: absolute; left: -4px; right: -4px; top: -8px; bottom: -8px; }
.lg__link:hover, .lg__link:focus-visible { background: #fff; }
.lg__link--out { background: var(--paper-d); }
.lg :is(button, a):focus-visible, .lg-board :is(button, a):focus-visible { outline: 3px solid var(--cyan); outline-offset: 2px; }

/* blocked: the sign's start line carries the hold prompt (league.js writes it there) and holds still */
.lg-gate .plaque__start { cursor: default; }
.lg-gate .plaque__start:hover { background: var(--ink); }
.lg-gate .plaque__start:active { transform: none; box-shadow: 0 3px 0 var(--wood-d); }
.lg-off .plaque__start { color: var(--red); }
.stage[data-game-state="attract"] .lg__msg { max-width: 460px; }
@media (min-width: 761px) {
  .lg-on .stage[data-game-state="attract"] [data-card="title"] { width: min(520px, 54%); }
  .lg-on .stage[data-game-state="title"] [data-card="title"] { top: 46%; }
}
@media (max-width: 760px) {
  .lg__btn { font-size: 16px; padding: 9px 11px 7px; }
  .lg__msg { font-size: 13px; }
  .lg-on .stage[data-game-state="title"] [data-card="title"] .card__p { display: none; }
}
@media (orientation: landscape) and (max-height: 500px) {
  /* the card sits at the right edge, clear of the one-row sign: label, one row of buttons, a short message */
  .lg-on .stage[data-game-state="attract"] [data-card="title"], .lg-on .stage[data-game-state="title"] [data-card="title"] { top: 6px; left: auto; right: 10px; transform: none; width: min(270px, 40%); gap: 4px; }
  .lg-on .stage[data-game-state="title"] [data-card="title"] .card__p, .lg-on .stage[data-game-state="title"] [data-card="title"] .card__h { display: none; }
  .lg { gap: 4px; }
  .lg__row { gap: 6px; flex-wrap: nowrap; }
  .lg__btn { font-size: 14px; padding: 6px 8px 5px; min-height: 44px; }
  .lg__ico { display: none; }
  .lg__msg { font-size: 12px; padding: 3px 7px 2px; }
  .lg__who { font-size: 14px; padding: 4px 8px 3px; }
}

@media (prefers-reduced-motion: no-preference) {
  .lg.is-nudge { animation: lgnudge .38s steps(2, end); }
}
@keyframes lgnudge { 0%, 100% { transform: none; } 25% { transform: translateX(-7px); } 75% { transform: translateX(7px); } }

/* the end card */
.lg__over { margin: 0; min-height: 0; font: 14px/1.3 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--green-t); text-align: center; }
.lg__over:empty { display: none; }
.lg__retry { font-size: 14px; padding: 6px 10px 5px; min-height: 44px; }
.lg__boardbtn { background: var(--paper); }

/* the weekly board: a wooden sign header over a paper score sheet, inside the stage */
.lg-board {
  position: absolute;
  z-index: 8;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, 94%);
  max-height: calc(100% - 20px);
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: var(--line) solid var(--ink);
  border-radius: 8px;
  box-shadow: 6px 6px 0 var(--ink);
  color: var(--ink);
  overflow: hidden;
}
.lgb__head {
  position: relative;
  flex: none;
  padding: 10px 56px 8px 16px;
  background: var(--svg-wood) 0 0 / 120px 120px;
  border-bottom: var(--line) solid var(--ink);
  box-shadow: inset 0 0 0 3px var(--yel-d);
}
.lgb__h {
  margin: 0;
  font: 34px/.95 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #fff;
  text-shadow: -2px 0 0 var(--ink), 2px 0 0 var(--ink), 0 -2px 0 var(--ink), 0 2px 0 var(--ink), -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink), 2px 2px 0 var(--ink), 4px 4px 0 var(--pur);
}
.lgb__sub { margin: 4px 0 0; font: 15px/1.2 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--yel); text-shadow: 1px 1px 0 var(--ink); }
.lgb__sub:empty { display: none; }
.lgb__x {
  position: absolute; right: 8px; top: 8px;
  width: 44px; height: 44px;
  font: 30px/1 var(--f-display);
  color: var(--ink);
  background: var(--yel);
  border: 3px solid var(--ink);
  border-radius: 8px;
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
}
.lgb__x:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }
.lgb__scroll { overflow: auto; flex: 1 1 auto; min-height: 60px; }
.lgb__list { list-style: none; margin: 0; padding: 4px 12px; }
.lgb__sep { margin: 6px 12px 0; padding: 4px 0 0; font: 14px/1 var(--f-display); letter-spacing: 2px; text-transform: uppercase; color: var(--wood-d); border-top: 3px double var(--ink); }
.lgb__sep[hidden] { display: none; }
.lgb__row.is-pending { opacity: .8; }
.lgb__row.is-pending .lgb__rank { color: var(--wood-d); }
.lgb__row {
  display: grid;
  grid-template-columns: 52px 1fr auto 78px;
  align-items: center;
  gap: 8px;
  padding: 7px 4px 6px;
  border-bottom: 2px dotted var(--wood-d);
  font: 20px/1 var(--f-display);
  letter-spacing: 1px;
}
.lgb__rank { text-align: center; color: var(--wood-d); }
.lgb__wallet { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lgb__score { text-align: right; color: var(--pur); }
.lgb__flag { justify-self: end; font-size: 12px; padding: 3px 6px 2px; border: 2px dashed var(--wood-d); border-radius: 5px; color: var(--wood-d); }
.lgb__flag.is-ok { border-style: solid; border-color: var(--ink); background: var(--up); color: var(--ink); }
.lgb__row.is-top .lgb__rank { background: var(--gold); border: 3px solid var(--ink); border-radius: 50%; color: var(--ink); padding: 6px 0 4px; width: 42px; justify-self: center; box-shadow: 2px 2px 0 var(--ink); }
.lgb__row.is-top2 .lgb__rank { background: var(--steel); }
.lgb__row.is-top3 .lgb__rank { background: var(--brick); }
.lgb__row.is-me { background: var(--gold-l); }
.lgb__note { flex: none; margin: 0; padding: 8px 14px 10px; font: 14px/1.3 var(--f-body); color: var(--wood-d); border-top: 2px solid var(--ink); background: var(--paper-d); }
@media (max-width: 760px), (orientation: landscape) and (max-height: 500px) {
  .lgb__h { font-size: 28px; }
  .lgb__row { grid-template-columns: 40px 1fr auto 66px; font-size: 16px; gap: 6px; }
  .lgb__row.is-top .lgb__rank { width: 34px; padding: 5px 0 3px; }
  .lgb__flag { font-size: 11px; padding: 2px 4px 1px; }
  .lgb__note { font-size: 13px; padding: 6px 10px 8px; }
}
@media (orientation: landscape) and (max-height: 500px) {
  .lgb__head { padding: 6px 56px 5px 12px; }
  .lgb__h { font-size: 24px; }
  .lgb__sub { font-size: 13px; margin-top: 2px; }
  .lgb__row { padding: 4px 4px 3px; }
}

/* The dedicated cabinet has no document scrolling. Its stage fills the viewport under the HUD
   on every screen. */
html[data-page="play"], html[data-page="play"] body { height: 100%; overflow: hidden; overscroll-behavior: none; background: var(--ink); }
.play-screen { position: fixed; inset: var(--hud-h) 0 0; display: grid; place-items: center; }
.play-screen .stage { width: 100%; height: 100%; aspect-ratio: auto; margin: 0; touch-action: none; }
/* Reserve both prompt rows so auto-start cannot move the bar when its title row changes. */
html[data-page="play"] .stage.is-ready:not([data-touch="1"]):is([data-game-state="title"], [data-game-state="attract"], [data-game-state="playing"]) .prompts { display: grid; }
html[data-page="play"] .prompts__set { display: flex; grid-area: 1 / 1; justify-self: end; visibility: hidden; }
html[data-page="play"] .stage:is([data-game-state="title"], [data-game-state="attract"]) .prompts__set--title,
html[data-page="play"] .stage[data-game-state="playing"] .prompts__set--play { visibility: visible; }
.hud__story { flex: none; padding: 6px 8px; border: 3px solid var(--ink); border-radius: 3px; box-shadow: 2px 2px 0 var(--ink); color: var(--ink); background: var(--yel); font: 16px/1 var(--f-display); text-transform: uppercase; text-decoration: none; white-space: nowrap; }
.hud__story:focus-visible { outline: 3px solid var(--pur); outline-offset: 3px; }
.card__story { color: var(--ink); font: 16px/1.2 var(--f-display); text-transform: uppercase; text-underline-offset: 3px; }
html[data-page="play"] .card__actions { flex-wrap: wrap; }
/* The controls card is a modal dialog: while it is open the title sign (with its start line and the
   2 Players message) is neither painted nor reachable. Closing the card unhides it before focus returns. */
html[data-page="play"] .stage:has([data-card="controls"]:not([hidden])) .stage__plaque { visibility: hidden; }
@media (max-width: 760px) and (orientation: portrait) {
  html[data-page="play"] .hud__story { font-size: 13px; padding: 6px 4px; }
  html[data-page="play"] .hud { gap: 6px; padding: 0 6px; }
  html[data-page="play"] .shud__val { font-size: 17px; }
  html[data-page="play"] .shud__lbl { font-size: 10px; letter-spacing: .5px; }
  html[data-page="play"] .shud__score { min-width: 5ch; }
  html[data-page="play"] .hud__face--game { gap: 6px; }
}

/* A practice start (zone, skip, power or god on the URL). Yellow fill, ink outline, the same
   display face as the rest of the HUD. No box: a pill would read as a new control. Hidden until
   the run is playing, paused or over, so a normal run does not move the bar. */
.shud__practice[hidden] { display: none !important; }
.shud__practice:not([hidden]) {
  flex: 0 0 auto;
  align-self: center;
  margin: 0 2px;
  font: 13px/1 var(--f-display);
  letter-spacing: .4px;
  color: var(--yel);
  white-space: nowrap;
  text-shadow:
    -1px 0 0 var(--ink), 1px 0 0 var(--ink),
    0 -1px 0 var(--ink), 0 1px 0 var(--ink);
}
/* Phone width: the long label (PRACTICE · BIRDCAGE · SINK · GOD) does not fit in the row beside
   the score, so it sits on the bottom of the same fixed-height bar and the cells move up. The
   bar's height does not change. Wider than 760, including 844x390, keeps it in the row. */
@media (max-width: 760px) {
  html[data-page="play"] .hud:has(.shud__practice:not([hidden])) { align-items: flex-start; padding-top: 2px; }
  /* the face is the full bar height; start its cells at the top so they clear the tag along the bottom */
  html[data-page="play"] .hud:has(.shud__practice:not([hidden])) .hud__face--game { align-items: flex-start; height: auto; }
  html[data-page="play"] .hud:has(.shud__practice:not([hidden])) .shud__val { font-size: 13px; margin-top: 0; }
  html[data-page="play"] .hud:has(.shud__practice:not([hidden])) .shud__pause {
    min-height: 0;
    padding: 2px 8px 1px;
    font-size: 13px;
  }
  html[data-page="play"] .hud:has(.shud__practice:not([hidden])) .hud__story,
  html[data-page="play"] .hud:has(.shud__practice:not([hidden])) .hud__sfx {
    padding: 2px 4px;
    font-size: 12px;
    min-height: 0;
  }
  html[data-page="play"] .shud__practice:not([hidden]) {
    position: absolute;
    left: 50%;
    bottom: 4px;
    transform: translateX(-50%);
    width: max-content;
    max-width: calc(100% - 8px);
    margin: 0;
    font-size: 11px;
    letter-spacing: 0;
    text-align: center;
    pointer-events: none;
  }
}

/* ---------- "How it works" pop-up (F24): a native <dialog>, three steps, one button ---------- */

/* the two triggers need the script: the sign's appears with the start line (not rendered until the
   game is ready, which needs the script); the buy box's carries [hidden] until main.js shows it,
   which happens before first paint, so its space is there from the first frame */
/* on the sign: one quiet ink line under the start strip, lettered like the rest of the board */
.plaque__how {
  display: block;
  position: relative;
  width: 100%;
  margin: 6px 0 0;
  padding: 4px 0 1px;
  font: 16px/1 var(--f-display);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  color: var(--ink);
  background: none;
  border: 0;
  text-decoration: underline dotted var(--wood-d);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.plaque__how:hover { color: var(--pur-d); text-decoration-color: var(--pur-d); }
/* a 44 px tall hit area, grown downward into the board's padding so it never covers the start line */
.plaque__how::after { content: ''; position: absolute; left: 0; right: 0; top: -2px; bottom: -12px; }
.stage:not(.is-ready) .plaque__how { display: none; }
.stage[data-game-state="over"] .stage__plaque .plaque__how { display: none; }
@media (orientation: landscape) and (max-height: 500px) {
  /* the sign is one row wide here and the controls card stands right of it, so the trigger takes a
     short second row under the start line (a grid row that spans the three columns, so it adds no
     width) instead of widening the row */
  .stage__plaque { display: grid; grid-template-columns: auto auto auto; column-gap: 12px; row-gap: 0; }
  .plaque__how { grid-column: 1 / -1; margin: 3px 0 0; padding: 5px 0 2px; font-size: 14px; }
  .plaque__how::after { top: -6px; bottom: -14px; }
}

/* in the buy box: a text link under the buy button */
.buy__how { margin: -6px 0 18px; }
.buy__how[hidden] { display: none; }
.buy__howbtn {
  padding: 4px 0;
  font: 18px/1 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--pur);
  background: none;
  border: 0;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 3px;
}
.buy__howbtn:hover { color: var(--pur-d); }

/* the dialog itself is only a frame: the card inside is the paper, and the strip of padding on its
   right and bottom holds the card's hard shadow (a click on it counts as a click on the backdrop) */
.how {
  width: min(448px, 100vw - 16px);
  max-width: none;
  max-height: calc(100dvh - 16px);
  margin: auto;
  padding: 0 8px 8px 0;
  color: var(--ink);
  background: none;
  border: 0;
  overflow: visible;
}
.how:not([open]) { display: none; }
.how::backdrop { background: rgba(20, 16, 8, .62); }
.how__card {
  display: flex;
  flex-direction: column;
  max-height: calc(100dvh - 24px);
  overflow: hidden auto;
  overscroll-behavior: contain;
  background: var(--paper);
  border: var(--line) solid var(--ink);
  border-radius: 6px;
  box-shadow: 8px 8px 0 var(--ink);
}
.how__head {
  position: sticky;
  top: 0;
  z-index: 1;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 8px 6px 18px;
  background: var(--svg-wood) 0 0 / 120px 120px;
  border-bottom: var(--line) solid var(--ink);
  box-shadow: inset 0 0 0 3px var(--yel-d);
}
.how__h {
  margin: 0;
  font: 38px/.95 var(--f-display);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #fff;
  text-shadow: -2px 0 0 var(--ink), 2px 0 0 var(--ink), 0 -2px 0 var(--ink), 0 2px 0 var(--ink), -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink), 2px 2px 0 var(--ink), 4px 4px 0 var(--pur);
}
.how__h:focus { outline: 0; }
.how__x {
  flex: none;
  width: 44px; height: 44px;
  padding: 0;
  font: 30px/1 var(--f-display);
  color: var(--ink);
  background: var(--yel);
  border: 3px solid var(--ink);
  border-radius: 8px;
  box-shadow: 3px 3px 0 var(--ink);
}
.how__x:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }
.how__steps { padding: 4px 18px 0; }
.how__step {
  display: grid;
  grid-template-columns: 58px 1fr;
  align-items: center;
  gap: 14px;
  padding: 10px 0 9px;
  border-bottom: 2px dotted var(--wood-d);
}
.how__step:last-child { border-bottom: 0; }
.how__pic {
  width: 58px; height: 58px;
  object-fit: contain;
  object-position: 50% 100%;
  padding: 3px;
  background: var(--sky-l);
  border: 3px solid var(--ink);
  border-radius: 6px;
  box-shadow: 3px 3px 0 var(--ink);
}
.how__n { font: 26px/1 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--pur); }
.how__p { margin-top: 3px; font: 19px/1.2 var(--f-body); }
.how__buy { display: inline-block; margin-top: 4px; font: 18px/1 var(--f-display); letter-spacing: 1px; text-transform: uppercase; color: var(--pur); text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 3px; }
.how__play { display: block; flex: none; margin: 8px 18px 0; padding: 13px 20px 11px; font-size: 26px; text-align: center; }
.how__rules { display: inline-block; margin-top: 2px; color: var(--pur); font-size: 17px; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }
.how__fine { flex: none; padding: 10px 18px 14px; font: 15px/1.2 var(--f-body); text-align: center; color: var(--wood-d); }

@media (max-width: 760px) {
  .how__h { font-size: 32px; }
  .how__head { padding: 6px 6px 5px 14px; }
  .how__steps { padding: 2px 14px 0; }
  .how__step { grid-template-columns: 52px 1fr; gap: 12px; padding: 9px 0 8px; }
  .how__pic { width: 52px; height: 52px; }
  .how__n { font-size: 24px; }
  .how__p { font-size: 18px; }
  .how__play { margin: 6px 14px 0; }
}
@media (orientation: landscape) and (max-height: 500px) {
  .how__h { font-size: 28px; }
  .how__head { padding: 4px 6px 3px 14px; }
  .how__x { width: 40px; height: 40px; }
  .how__steps { padding: 0 14px; }
  .how__step { grid-template-columns: 44px 1fr; gap: 12px; padding: 6px 0 5px; }
  .how__pic { width: 44px; height: 44px; }
  .how__n { font-size: 22px; }
  .how__p { margin-top: 1px; font-size: 17px; }
  .how__play { margin: 4px 14px 0; padding: 9px 20px 7px; font-size: 22px; }
  .how__fine { padding: 6px 14px 8px; font-size: 14px; }
}

/* motion: a comic pop in, a quick fade out. Reduced motion (and ?fx=0, which main.js marks with
   data-still) gets neither: the card simply appears and disappears */
@media (prefers-reduced-motion: no-preference) {
  .how:not([data-still])[open] .how__card { animation: how-pop 220ms cubic-bezier(.34, 1.56, .64, 1) both; }
  .how:not([data-still])[open] .how__step,
  .how:not([data-still])[open] .how__play,
  .how:not([data-still])[open] .how__fine { animation: how-in 200ms ease-out both; }
  .how:not([data-still])[open] .how__step:nth-child(1) { animation-delay: 90ms; }
  .how:not([data-still])[open] .how__step:nth-child(2) { animation-delay: 150ms; }
  .how:not([data-still])[open] .how__step:nth-child(3) { animation-delay: 210ms; }
  .how:not([data-still])[open] .how__play { animation-delay: 270ms; }
  .how:not([data-still])[open] .how__fine { animation-delay: 300ms; }
  .how:not([data-still])[open]::backdrop { animation: how-fade 160ms ease-out both; }
  .how:not([data-still])[open].is-closing, .how:not([data-still])[open].is-closing::backdrop { animation: how-out 110ms ease-in both; }
  .how:not([data-still])[open].is-closing .how__card,
  .how:not([data-still])[open].is-closing .how__step,
  .how:not([data-still])[open].is-closing .how__play,
  .how:not([data-still])[open].is-closing .how__fine { animation: none; }
}
@keyframes how-pop { from { opacity: 0; transform: scale(.92); } to { opacity: 1; transform: none; } }
@keyframes how-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes how-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes how-out { from { opacity: 1; } to { opacity: 0; } }

/* Country-restricted visitors keep open play and only the league's explanatory line. */
.lg-geo .stage.is-ready[data-game-state="attract"] [data-card="title"] { display: flex; }
.lg__links { flex-wrap: wrap; justify-content: center; }
a.lg__link { display: inline-block; text-decoration: none; }
.lgb__note { display: flex; align-items: center; gap: 10px; }
.lgb__note .lg__link { flex: none; }
@media (min-width: 761px) {
  .lg-geo .stage[data-game-state="attract"] [data-card="title"] { width: min(520px, 54%); }
}
@media (orientation: landscape) and (max-height: 500px) {
  .lg-geo .stage:is([data-game-state="attract"], [data-game-state="title"]) [data-card="title"] { top: 6px; left: auto; right: 10px; transform: none; width: min(270px, 40%); }
}
