/* Path Patrol: terminal-minimal.
   One near-black canvas, hairline borders, one accent (aqua), one alarm (coral), amber for the target and,
   later, power-ups. DM Mono for everything you read, Space Grotesk only for the big numbers and the title.

   Layout is chosen by media queries on orientation, size and pointer type, never by sniffing the device:
     - portrait / narrow: a compact top bar, one HUD row, the board (rotated by view.js) filling the rest;
     - short landscape (a phone on its side): a left rail with the HUD, the board filling the height;
     - everything else (desktop, tablet): top bar, HUD, board, keyboard hints.
   html[data-input="touch|mouse"] follows the pointer actually being used, so a hybrid laptop switches. */

@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("../assets/fonts/dm-mono-400.woff2") format("woff2"); }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url("../assets/fonts/dm-mono-500.woff2") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-style: normal; font-weight: 300 700; font-display: swap; src: url("../assets/fonts/space-grotesk-variable.woff2") format("woff2"); }

:root {
  color-scheme: dark;
  --bg: #070b12;
  --raised: #0b111b;
  --ink: #e8f1ee;
  --ink-soft: #b9c8c7;
  --muted: #8b9ea2;
  --line: rgba(190, 224, 216, .13);
  --line-strong: rgba(190, 224, 216, .3);
  --aqua: #72f4d1;
  --aqua-dim: #2da98d;
  --coral: #ff765f;
  --amber: #ffb36a;
  --font-ui: "DM Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --font-display: "Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  --radius: 6px;
  --pad: clamp(12px, 2.4vw, 24px);
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --rail: clamp(206px, 25vw, 232px);          /* four 44px buttons and their gaps fit in one row */
  --tap: 44px;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  position: fixed;
  inset: 0;
  font: 400 13px/1.5 var(--font-ui);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  background:
    radial-gradient(circle at 12% 0%, rgba(42, 85, 95, .22), transparent 30rem),
    radial-gradient(circle at 98% 100%, rgba(32, 97, 81, .16), transparent 32rem),
    var(--bg);
}
button { font: inherit; color: inherit; }
h1, h2, h3, p, dl, dd, ol { margin: 0; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.noscript { margin: 0; padding: 24px 16px; color: var(--ink); font-size: 14px; text-align: center; }
@media (scripting: none) {                                   /* nothing in the game can work: the dead controls stay out of the way of the one sentence that matters */
  body > .app { display: none; }
  .noscript { display: grid; place-items: center; min-height: 100dvh; box-sizing: border-box; }
}
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Touch-first presentation by default; a fine pointer (or a mouse actually in use) gets the desktop one. */
.only-fine { --show: inline-flex; }
.btn-text.only-fine { --show: inline; }
kbd.only-fine { --show: inline-block; }
.only-fine, .btn.only-fine { display: none; }          /* two selectors: .btn.only-fine must beat .btn's display */
@media (pointer: fine) { :root:not([data-input="touch"]) .only-fine { display: var(--show); } }
:root[data-input="mouse"] .only-fine { display: var(--show); }

/* --- layout ------------------------------------------------------------------------------------ */

.app {
  position: absolute;
  inset: 0;
  height: 100%;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  padding: var(--safe-t) var(--safe-r) var(--safe-b) var(--safe-l);
}
@supports (height: 100dvh) { .app { height: 100dvh; } }

.chrome { display: grid; grid-template-columns: minmax(0, 1fr); padding: 0 var(--pad); min-width: 0; }   /* minmax(0, ...): no child can widen the column */
/* Fixed height whatever the input mode: a 44px touch button and a 36px mouse button both fit, so a hybrid
   device switching mode never moves the board. */
.bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; height: 56px; padding-top: 8px; }
.brand { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); font: 700 17px/1 var(--font-display); letter-spacing: -.045em; white-space: nowrap; }
.brand-name span { color: var(--aqua); }
.brand-name span:first-child { margin-inline: .04em; }
.brand-mark { display: flex; align-items: end; gap: 3px; width: 29px; height: 26px; transform: skewY(-18deg); }
.brand-mark i { display: block; width: 7px; background: var(--aqua); border-radius: 1px; }
.brand-mark i:nth-child(1) { height: 12px; opacity: .55; }
.brand-mark i:nth-child(2) { height: 25px; }
.brand-mark i:nth-child(3) { height: 18px; opacity: .76; }
.actions { display: flex; align-items: center; gap: 6px; }

.hud { display: flex; align-items: center; gap: 8px 28px; min-height: 46px; padding: 6px 0 4px; }
.stat { display: flex; align-items: baseline; gap: 8px; min-width: 0; white-space: nowrap; }
.stat-key { color: var(--muted); font: 500 10px/1 var(--font-ui); letter-spacing: .14em; }
.stat-val { color: var(--ink); font: 700 22px/1 var(--font-display); letter-spacing: -.04em; }
.stat--level .stat-val { color: var(--aqua); font-size: 28px; }
.stat--lives { align-items: center; }
.stat--clear { flex: 1 1 auto; align-items: center; gap: 10px; }
.stat--clear .stat-val { color: var(--aqua); min-width: 3.4ch; }
.stat--runners { margin-left: auto; color: var(--muted); }
.stat--score { align-items: center; }
.score-block { display: grid; justify-items: end; gap: 3px; line-height: 1; }
.stat--score .stat-val { min-width: 4.6ch; text-align: right; }
/* Always in the layout, only its visibility changes: the HUD must not change height when a combo starts. */
.combo { color: var(--amber); font: 500 10px/1 var(--font-ui); letter-spacing: .08em; white-space: nowrap; visibility: hidden; }
.combo.on { visibility: visible; }
.stat--runners .stat-val { color: var(--muted); font: 500 10px/1 var(--font-ui); letter-spacing: .12em; }
.stat-target { display: inline-flex; align-items: center; gap: 5px; color: var(--amber); font: 500 12px/1 var(--font-ui); }
.chevron { width: 0; height: 0; border-left: 5px solid currentColor; border-block: 3.5px solid transparent; }
.lives { display: inline-flex; gap: 4px; }
.life { width: 11px; height: 11px; border: 1.5px solid var(--coral); background: var(--coral); border-radius: 2px; box-shadow: 0 0 9px rgba(255, 118, 95, .35); }
.life.lost { background: transparent; box-shadow: none; opacity: .55; }
.meter { position: relative; flex: 1 1 60px; height: 4px; min-width: 60px; background: rgba(255, 255, 255, .09); border-radius: 2px; }
.meter i { position: absolute; inset: 0 auto 0 0; width: 0; background: linear-gradient(90deg, var(--aqua-dim), var(--aqua)); border-radius: inherit; box-shadow: 0 0 10px rgba(114, 244, 209, .4); transition: width .25s ease; }
.meter b { position: absolute; top: -4px; bottom: -4px; left: 65%; width: 2px; background: var(--amber); box-shadow: 0 0 8px rgba(255, 179, 106, .6); }
/* The three-star mark: where three stars begin, bright while they are still possible on this level, dim once a life is
   lost on it, solid gold once a trap has already earned the third. */
.meter b.star-mark { width: 2px; background: #f4e3a1; box-shadow: 0 0 8px rgba(244, 227, 161, .55); transition: opacity .2s ease; }
.meter b.star-mark.lost { opacity: .22; box-shadow: none; }
.meter b.star-mark.got { width: 4px; background: #ffd166; box-shadow: 0 0 10px rgba(255, 209, 102, .8); }

/* Messages appear on a single console line so they never sit on the board where routes start. */
.console { min-height: 20px; margin: 0; padding-bottom: 6px; overflow: hidden; color: var(--muted); font-size: 11.5px; white-space: nowrap; text-overflow: ellipsis; opacity: 0; transition: opacity .2s ease; }
.console.visible { opacity: 1; }
.console::before { content: "> "; color: var(--aqua-dim); }

.stage { display: grid; place-items: center; min-width: 0; min-height: 0; padding: 0 var(--pad) 10px; overflow: hidden; }
.board { position: relative; width: max-content; height: max-content; overflow: hidden; background: #0b1422; border-radius: 4px; box-shadow: 0 0 0 1px var(--line-strong), 0 26px 60px rgba(0, 0, 0, .4); }
#gameCanvas { display: block; touch-action: none; cursor: crosshair; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }

/* The keyboard hints follow the pointer media query only, not the live data-input switch: the footer
   appearing or vanishing mid-game would move the board between a touch landing and its coordinates being read. */
.hints { display: none; flex-wrap: wrap; align-items: center; gap: 6px 18px; padding: 4px var(--pad) 12px; color: var(--muted); font-size: 11px; }
@media (pointer: fine) { .hints { display: flex; } }
.hints-note { margin-left: auto; }

/* --- controls ---------------------------------------------------------------------------------- */

.icon { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: var(--tap); padding: 0 14px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: transparent; color: var(--ink); font: 500 12px/1 var(--font-ui); letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; cursor: pointer; touch-action: manipulation; transition: color .15s ease, border-color .15s ease, background .15s ease, transform .1s ease; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .38; pointer-events: none; }
.btn--icon { width: var(--tap); padding: 0; }
/* Square when only the icon shows, wider when the label and key hint come with it. */
.btn--adaptive { min-width: var(--tap); padding: 0 12px; }
.btn--ghost { border-color: var(--line); color: var(--ink-soft); }
.btn--primary { border-color: var(--aqua); background: var(--aqua); color: #04201b; }
.btn--big { min-height: 48px; padding: 0 22px; font-size: 13px; }
.btn--danger { color: var(--coral); border-color: rgba(255, 118, 95, .4); }
/* Hover styling only where hovering exists: on a touch screen :hover sticks to the last control tapped. */
@media (hover: hover) {
  .btn:hover { border-color: var(--aqua); color: var(--aqua); }
  .btn--primary:hover { background: #8ff7dc; border-color: #8ff7dc; color: #04201b; }
  .btn--danger:hover { border-color: var(--coral); color: var(--coral); background: rgba(255, 118, 95, .08); }
}
:focus-visible { outline: 2px solid var(--aqua); outline-offset: 2px; }
.btn:focus-visible { outline-offset: 2px; }
#gameCanvas:focus-visible { outline-offset: -4px; }
kbd { display: inline-block; min-width: 1.7em; margin-inline: 1px; padding: 2px 5px; border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: 4px; color: var(--ink-soft); font: 500 10px/1.2 var(--font-ui); text-align: center; text-transform: none; letter-spacing: 0; }

.icon-off, #pauseButton .icon-play, #pauseButton .icon-skip { display: none; }
#soundButton[aria-pressed="false"] .icon-on { display: none; }
#soundButton[aria-pressed="false"] .icon-off { display: inline; }
#soundButton[aria-pressed="false"] { color: var(--muted); }
#pauseButton[data-state="paused"] .icon-pause, #pauseButton[data-state="skip"] .icon-pause { display: none; }
#pauseButton[data-state="paused"] .icon-play { display: inline; }
#pauseButton[data-state="skip"] .icon-skip { display: inline; }
#pauseButton[data-state="skip"] kbd { display: none !important; }      /* P pauses; it does not skip, so no key hint on Skip */

@media (pointer: fine) { :root:not([data-input="touch"]) { --tap: 36px; } }
:root[data-input="mouse"] { --tap: 36px; }
:root[data-input="touch"] { --tap: 44px; }

/* --- overlays ---------------------------------------------------------------------------------- */

.overlay { position: absolute; inset: 0; z-index: 5; display: none; place-items: center; padding: 14px; overflow: auto; background: rgba(4, 8, 14, .66); text-align: center; }
.app[data-phase="title"] .overlay--title,
.app[data-phase="clear"] .overlay--clear,
.app[data-phase="paused"] .overlay--pause,
.app[data-phase="countdown"] .overlay--pause,
.app[data-phase="over"] .overlay--end,
.app[data-phase="crashed"] .overlay--crash { display: grid; }
.panel { display: grid; justify-items: center; gap: 12px; max-width: 420px; min-width: 0; }
.panel p { text-wrap: balance; }                      /* no orphaned last word; older browsers just wrap normally */
.start-symbol { position: relative; width: 43px; height: 43px; border: 1px solid rgba(114, 244, 209, .6); border-radius: 50%; animation: orbit 3s linear infinite; }
.start-symbol span { position: absolute; width: 6px; height: 6px; border-radius: 50%; background: var(--coral); box-shadow: 0 0 10px var(--coral); }
.start-symbol span:first-child { top: -3px; left: 17px; }
.start-symbol span:last-child { bottom: -3px; right: 8px; background: var(--aqua); box-shadow: 0 0 10px var(--aqua); }
.title { font: 700 clamp(30px, 8vmin, 54px)/.95 var(--font-display); letter-spacing: -.06em; }
.title .slash { color: var(--aqua); }
.title small { margin-left: 4px; color: var(--muted); font: 500 11px/1 var(--font-ui); letter-spacing: .08em; vertical-align: super; }
.tagline { color: var(--ink-soft); font-size: 13px; }
.caret { margin-left: 1px; color: var(--aqua); animation: blink 1.1s steps(1) infinite; }
.cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 4px; }
.cta-wide { flex: 1 1 100%; }                                  /* Resume takes a row of its own, above Start and Daily */
.btn--daily { border-color: var(--amber); color: var(--amber); }
.btn--expert { border-color: rgba(255, 118, 95, .7); color: var(--coral); }
.btn--quiet { max-width: 100%; padding-block: 8px; border-color: var(--line-strong); color: var(--ink-soft); font-size: 12px; line-height: 1.4; text-wrap: balance; }      /* the text may wrap (balanced), so it needs the room of lines */
.btn--quiet[data-mode="update"] { border-color: var(--aqua-dim); color: var(--aqua); }
.btn--daily span[aria-hidden] { margin-right: 8px; }
.daily-line { color: var(--amber); font-size: 11.5px; }
.daily-line:empty { display: none; }
.records { color: var(--muted); font-size: 11.5px; }
.records:empty { display: none; }
.saved { color: var(--amber); font-size: 11.5px; }
.app[data-saved="yes"] .overlay--title .fine, .app[data-daily="done"] .overlay--title .fine { display: none; }          /* someone resuming knows how to play; the room is needed for the second button */
.fine { color: var(--muted); font-size: 11px; }
.app:is([data-notice="update"], [data-notice="install"]) #settingsButton { position: relative; }
.app:is([data-notice="update"], [data-notice="install"]) #settingsButton::after { content: ""; position: absolute; top: 7px; right: 7px; width: 8px; height: 8px; border-radius: 50%; background: var(--amber); box-shadow: 0 0 0 2px var(--bg); }
/* A short screen with a saved run, a finished daily to share, or an offer from the app has no room for the decoration: the
   symbol and the tagline go. With a saved run and one of the others, the records line goes too; and with a saved run and a
   finished daily, the offer and the daily's line as well. */
@media (max-height: 640px) {
  .app:is([data-saved="yes"], [data-daily="done"], [data-notice="update"], [data-notice="install"], [data-notice="ios"]) .overlay--title :is(.start-symbol, .tagline) { display: none; }
  .app[data-saved="yes"]:is([data-daily="done"], [data-notice="update"], [data-notice="install"], [data-notice="ios"]) .overlay--title .records { display: none; }
  .app[data-saved="yes"][data-daily="done"] .overlay--title #appNotice { display: none; }      /* the tallest title: the same offer waits in Settings, marked by a dot on its button */
  .app[data-saved="yes"][data-daily="done"] .overlay--title .daily-line { display: none; }
  .overlay--end .panel { gap: 8px; }                                         /* the game-over card of a daily has six rows and two buttons: tighter */
}
/* 320 x 568 stacks Start, Daily and Expert: no decoration, and the offer waits in Settings with a saved run or a done daily. */
@media (max-height: 640px) and (max-width: 360px) {
  .overlay--title :is(.start-symbol, .tagline) { display: none; }
  .app:is([data-saved="yes"], [data-daily="done"]) .overlay--title #appNotice { display: none; }
}
/* 360 x 740: the tallest title drops the decoration. */
@media (max-height: 760px) and (max-width: 400px) {
  .app[data-saved="yes"][data-daily="done"] .overlay--title :is(.start-symbol, .tagline) { display: none; }
  .overlay--end .receipt dt, .overlay--end .receipt dd { padding: 3px 0; }
}
.eyebrow { color: var(--muted); font: 500 10px/1 var(--font-ui); letter-spacing: .14em; text-transform: uppercase; }
.big { font: 700 clamp(26px, 6vmin, 40px)/1 var(--font-display); letter-spacing: -.05em; }
.receipt { display: grid; grid-template-columns: 1fr auto; width: min(300px, 100%); text-align: left; font-size: 12px; }
.receipt dt, .receipt dd { padding: 6px 0; border-bottom: 1px dashed var(--line-strong); }
.receipt dt { padding-right: 14px; color: var(--muted); }
.receipt .flag { margin-right: 8px; color: var(--amber); font-size: 10px; letter-spacing: .1em; }
.receipt dd { color: var(--ink); font-weight: 500; text-align: right; }
.crash-detail { max-width: 440px; color: var(--ink-soft); font-size: 11px; white-space: pre-wrap; word-break: break-word; user-select: text; -webkit-user-select: text; }
.crash-detail:empty { display: none; }
/* Active power-ups: round chips in the board's bottom-left corner, laid over it so they never change the layout, and
   letting every touch through to the board underneath. */
.powers { position: absolute; left: 10px; bottom: 10px; z-index: 4; display: flex; gap: 6px; pointer-events: none; }
.power { display: block; width: 34px; height: 34px; }
.power svg { display: block; width: 100%; height: 100%; overflow: visible; }
.power-bg { fill: rgba(4, 8, 14, .82); stroke: rgba(255, 179, 106, .25); stroke-width: 2; }
.power-ring { fill: none; stroke: var(--amber); stroke-width: 2.6; stroke-linecap: round; transform: rotate(-90deg); transform-origin: 18px 18px; }
.power-glyph { fill: none; stroke: #f4fbf8; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.fps { position: absolute; top: 8px; left: 8px; z-index: 6; padding: 3px 6px; border: 1px solid var(--line); border-radius: 3px; background: rgba(4, 8, 14, .72); color: var(--aqua); font-size: 10px; pointer-events: none; }

/* --- dialogs ----------------------------------------------------------------------------------- */

.dialog { width: min(92vw, 440px); max-height: min(88vh, 700px); padding: 0; overflow: auto; border: 1px solid var(--line-strong); border-radius: 10px; background: var(--raised); color: var(--ink); box-shadow: 0 30px 80px rgba(0, 0, 0, .6); }
@supports (height: 100dvh) { .dialog { max-height: min(88dvh, 700px); } }
.dialog::backdrop { background: rgba(2, 5, 9, .76); }
.dialog-body { display: grid; gap: 14px; padding: 14px 18px 18px; }
.dialog-head { display: flex; align-items: center; justify-content: space-between; }
.dialog-head h2 { font: 700 20px/1 var(--font-display); letter-spacing: -.04em; }
.dialog-sub { margin-top: 4px; color: var(--muted); font: 500 10px/1 var(--font-ui); letter-spacing: .14em; text-transform: uppercase; }
.setting { display: flex; align-items: center; justify-content: space-between; gap: 14px; min-height: var(--tap); }
.setting-name { color: var(--ink-soft); }
/* The button is a full-height tap target; the visible track (::before) and knob (i) are drawn inside it. */
.switch { position: relative; flex: none; width: 58px; height: var(--tap); padding: 0; border: 0; background: none; cursor: pointer; touch-action: manipulation; }
.switch::before { content: ""; position: absolute; top: 50%; left: 6px; width: 46px; height: 28px; margin-top: -14px; border: 1px solid var(--line-strong); border-radius: 14px; transition: border-color .15s ease, background .15s ease; }
.switch i { position: absolute; top: 50%; left: 10px; width: 20px; height: 20px; margin-top: -10px; border-radius: 50%; background: var(--muted); transition: transform .18s ease, background .18s ease; }
.switch[aria-checked="true"]::before { border-color: var(--aqua-dim); background: rgba(45, 169, 141, .18); }
.switch[aria-checked="true"] i { background: var(--aqua); transform: translateX(18px); }
.seg { display: inline-flex; overflow: hidden; border: 1px solid var(--line-strong); border-radius: var(--radius); }
.seg button { min-height: var(--tap); padding: 0 13px; border: 0; background: transparent; color: var(--muted); font: 500 12px/1 var(--font-ui); cursor: pointer; touch-action: manipulation; }
.seg button + button { border-left: 1px solid var(--line); }
.seg button[aria-checked="true"] { background: rgba(114, 244, 209, .14); color: var(--aqua); }
.records-list, .keys { display: grid; }
.records-list > div, .keys > div { display: flex; justify-content: space-between; gap: 16px; padding: 7px 0; border-bottom: 1px solid var(--line); }
.records-list dt, .keys dt { color: var(--muted); }
.records-list dd, .keys dd { color: var(--ink); font-weight: 500; text-align: right; }
.how { display: grid; gap: 10px; padding-left: 20px; color: var(--ink-soft); }
.how b { color: var(--ink); font-weight: 500; }
.how-daily, .how-trap, .how-expert { color: var(--ink-soft); }
.how-daily b, .how-trap b { color: var(--amber); font-weight: 500; }
.how-expert b { color: var(--coral); font-weight: 500; }
.share-text { width: 100%; padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg); color: var(--ink); font: 500 12.5px/1.5 var(--font-ui); resize: none; }
.version-line { text-align: center; }

/* --- wide windows: the top bar, HUD and hints line up with the board's edges, not the window's ---- */

@media (min-width: 701px) {
  /* --board-w is set by view.js. The floor keeps a short, wide window (a small board) from squeezing the bar. */
  .chrome, .hints { width: 100%; max-width: calc(max(var(--board-w, 100vw), 720px) + 2 * var(--pad)); margin-inline: auto; }
}

/* --- narrow and portrait: a compact bar, the HUD on two rows ----------------------------------- */

@media (max-width: 700px) {
  /* Labels and key hints need room the bar does not have here, even with a mouse in use. */
  .btn-text.only-fine, kbd.only-fine { display: none !important; }
  /* A grid, not wrapping flex: however wide the score gets it cannot push anything onto a third row, so the
     board below never changes size while you play. */
  .hud { display: grid; grid-template-columns: auto auto minmax(0, 1fr); grid-template-areas: "level lives score" "clear clear clear"; align-items: center; gap: 6px 18px; }
  .stat--level { grid-area: level; }
  .stat--lives { grid-area: lives; }
  .stat--score { grid-area: score; justify-self: end; min-width: 0; }
  .stat--clear { grid-area: clear; }
  .stat--runners { display: none; }
  .stat--level .stat-val { font-size: 24px; }
  .title small { display: none; }
}
@media (max-width: 420px) {
  .brand-name { display: none; }
  .actions { gap: 4px; }
}
@media (max-width: 400px) {
  /* Room for five lives and a seven-digit score on one row: the pips and the number speak for themselves. */
  .stat--lives .stat-key, .stat--score .stat-key { display: none; }
  .stat--score .stat-val { font-size: 18px; }
  .lives { gap: 3px; }
  .life { width: 10px; height: 10px; }
}

/* --- a phone on its side: the HUD becomes a rail ------------------------------------------------ */

@media (orientation: landscape) and (max-height: 540px) {
  .app { grid-template-columns: var(--rail) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
  .chrome { align-content: start; gap: 4px; padding: 8px 8px 8px 10px; overflow-y: auto; }
  .bar { flex-wrap: wrap; height: auto; padding-top: 0; gap: 8px; }
  .brand-name { display: none; }
  .actions { flex-wrap: wrap; gap: 4px; }
  .hud { display: flex; flex-direction: column; align-items: stretch; gap: 8px; padding: 6px 0; }
  .stat--level { order: 0; }
  .stat--lives { order: 1; }
  .stat--score { order: 2; margin-left: 0; }
  .stat--clear { order: 3; flex-basis: auto; display: grid; grid-template-columns: auto 1fr auto; gap: 4px 8px; }
  .stat--clear .meter { grid-column: 1 / -1; }
  .stat--runners { display: flex; order: 4; margin-left: 0; }
  .console { white-space: normal; padding-bottom: 0; }
  .stage { padding: 8px 12px 8px 4px; }
  .hints { display: none !important; }
}

/* --- motion ------------------------------------------------------------------------------------- */

@keyframes orbit { to { transform: rotate(360deg); } }
@keyframes blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="full"]) *, :root:not([data-motion="full"]) *::before, :root:not([data-motion="full"]) *::after { animation: none !important; transition-duration: .01ms !important; }
}
:root[data-motion="reduced"] *, :root[data-motion="reduced"] *::before, :root[data-motion="reduced"] *::after { animation: none !important; transition-duration: .01ms !important; }

/* ---- splash ------------------------------------------------------------------- */

.egg { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; background: var(--bg); animation: egg-in 220ms ease-out both; }
.egg.out { animation: egg-out 450ms ease-in both; pointer-events: none; }
.egg-stage { display: flex; flex-direction: column; align-items: center; gap: 26px; }
.egg-key {
  display: grid; place-items: center; width: 128px; height: 128px; border-radius: 26px; background: var(--aqua); color: #04120e;
  font: 700 52px/1 var(--font-ui); letter-spacing: -.06em;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), 0 10px 26px -12px rgba(0, 0, 0, .6);
  animation: egg-press 500ms cubic-bezier(.2, .9, .2, 1) both;
}
.egg-meta { display: flex; flex-direction: column; align-items: center; gap: 7px; animation: egg-fade 600ms 200ms both; }
.egg-name { margin: 0; color: var(--ink); font: 700 17px/1.2 var(--font-display); letter-spacing: -.02em; }
.egg-sub { display: flex; align-items: center; gap: 7px; margin: 0; color: var(--muted); font: 400 10.5px/1.2 var(--font-ui); letter-spacing: .14em; text-transform: uppercase; }
.egg-heart { display: block; fill: var(--aqua); }
@keyframes egg-in { from { opacity: 0; } }
@keyframes egg-out { to { opacity: 0; } }
@keyframes egg-press { 0% { opacity: 0; transform: scale(.88) translateY(8px); } 55% { transform: scale(1.015) translateY(0); } }
@keyframes egg-fade { from { opacity: 0; transform: translateY(5px); } }
@media (prefers-reduced-motion: reduce) {
  .egg, .egg-key, .egg-meta { animation: none; }
  .egg.out { opacity: 0; }
}
:root[data-motion="reduced"] .egg.out { opacity: 0; }

/* ---- the extra board's colours ------------------------------------------------- */

:root[data-extra] { --bg: #0a0614; --raised: #100a1e; --aqua: #ff7bf0; --aqua-dim: #b23fa8; --line: rgba(232, 190, 255, .14); --line-strong: rgba(232, 190, 255, .32); }

/* Stars: on the win screen they arrive one by one (they simply appear with reduced motion); the level list shows the best of each. */
.stars { display: flex; justify-content: center; gap: 6px; margin: 2px 0 -2px; font: 700 24px/1 var(--font-ui); color: rgba(255, 255, 255, .16); }
.stars .on { color: #ffd166; text-shadow: 0 0 12px rgba(255, 209, 102, .55); }
.stars .on { animation: star-in .34s cubic-bezier(.2, 1.4, .4, 1) both; }          /* (the reduced-motion rules above switch it off) */
.stars .on:nth-child(2) { animation-delay: .22s; }
.stars .on:nth-child(3) { animation-delay: .44s; }
@keyframes star-in { from { transform: scale(.2); opacity: 0; } to { transform: none; opacity: 1; } }
.levels-note { margin-top: -4px; }
.levels-total { color: #ffd166; font: 500 12px/1 var(--font-ui); letter-spacing: .08em; }
.level-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); gap: 8px; }
.level-cell { display: grid; place-items: center; gap: 3px; min-height: 60px; padding: 6px 2px; border: 1px solid var(--line-strong); border-radius: 8px; background: transparent; color: var(--ink); font: 500 15px/1 var(--font-ui); cursor: pointer; }
.level-cell small { font-size: 11px; letter-spacing: .1em; color: rgba(255, 255, 255, .2); }
.level-cell small .on { color: #ffd166; }
.level-cell[data-special="boss"] { border-color: rgba(255, 92, 200, .45); }
.level-cell[data-special="shape"] { border-style: dashed; }
.level-cell:focus-visible { outline: 2px solid var(--aqua); outline-offset: 2px; }
@media (hover: hover) { .level-cell:hover { border-color: var(--aqua-dim); } }
