/* ============================================================================
   MAXGEAR — DOM chrome, STEAMPUNK re-theme (v1.1)
   Brass, iron and soot. Materials only: the gameplay color semantics below are
   load-bearing reads and their hexes MUST NOT drift —
     green = good gate · red = bad gate / boss · purple = trade-off
     gold  = chargeable "SHOOT ME" · cyan = player / progress
   Everything else (frames, plates, bezels, bars' chrome) is brass over iron.
   ========================================================================== */
:root {
  /* ---- gameplay semantics (do not retint) ---- */
  --cyan: #35e0ff;
  --good: #56b06c;
  --bad: #d2513c;
  --mixed: #a97bd1;
  --charge: #ffd166;

  /* ---- steampunk materials ---- */
  --iron: #1a1512;
  --coal: #0f0c09;
  --brass: #c9973b;
  --brass-lt: #f0b429;
  --brass-hi: #ffe9bd;
  --copper: #b0652f;
  --rust: #8a3324;
  --steam: rgba(230, 225, 215, 0.5);

  --bg: #0f0c09;
  --panel: rgba(22, 17, 12, 0.9);
  --ink: #f1e7d4;
  /* shared "iron plate" fill + brass rim, so every chip/plate matches */
  --plate: linear-gradient(180deg, rgba(42, 32, 22, 0.86), rgba(15, 12, 9, 0.9));
  --channel: linear-gradient(180deg, #120e0a, #251d15);
  --rim: rgba(201, 151, 59, 0.45);
  --rim-hot: rgba(240, 180, 41, 0.8);
  --sheen: inset 0 1px 0 rgba(255, 232, 186, 0.16);

  /* Engraved-brass display stack, system fonts only:
     Copperplate (macOS/iOS) → Copperplate Gothic / Engravers / Bodoni MT
     (Windows w/ Office) → Didot (macOS) → Georgia (Win+mac, always there) →
     generic serif (Android → Noto Serif). Every fallback is a caps-friendly
     serif, so the plaque read survives everywhere; never a sans. */
  --font-display: 'Copperplate', 'Copperplate Gothic Light', 'Engravers MT', 'Didot', 'Bodoni MT', Georgia, 'Times New Roman', serif;
  --font-serif: Georgia, 'Iowan Old Style', 'Palatino Linotype', 'Book Antiqua', 'Times New Roman', serif;
  --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* ---- gear ornaments: inline SVG data URIs, no external assets ---- */
  --gear-brass: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64' fill='none' stroke='%23c9973b' stroke-width='3'><circle cx='32' cy='32' r='19'/><circle cx='32' cy='32' r='7'/><g stroke-width='6'><path d='M32 5v9M32 50v9M5 32h9M50 32h9M12.9 12.9l6.4 6.4M44.7 44.7l6.4 6.4M51.1 12.9l-6.4 6.4M19.3 44.7l-6.4 6.4'/></g></svg>");
  --gear-hot: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64' fill='none' stroke='%23f0b429' stroke-width='4'><circle cx='32' cy='32' r='18'/><circle cx='32' cy='32' r='6'/><g stroke-width='7'><path d='M32 5v9M32 50v9M5 32h9M50 32h9M12.9 12.9l6.4 6.4M44.7 44.7l6.4 6.4M51.1 12.9l-6.4 6.4M19.3 44.7l-6.4 6.4'/></g></svg>");
  --gear-cyan: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64' fill='none' stroke='%2335e0ff' stroke-width='5'><circle cx='32' cy='32' r='17'/><circle cx='32' cy='32' r='5'/><g stroke-width='9'><path d='M32 4v10M32 50v10M4 32h10M50 32h10M12 12l7 7M45 45l7 7M52 12l-7 7M19 45l-7 7'/></g></svg>");

  /* THE CORNER CLUSTER, MEASURED ONCE. The HUD's top row has to know how much
     of its own right edge the plates are standing on, and the landscape and
     small-phone passes shrink them — so the width is derived from the plate
     size and the gap rather than written out as a number in two places that
     can drift. Anything that reserves room for the cluster reserves
     --corner-w, and it is right by construction. */
  --corner-inset: 12px;
  --corner-plate: 42px;
  --corner-gap: 8px;
  --corner-w: calc(var(--corner-plate) * 3 + var(--corner-gap) * 2);

  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  font-family: var(--font-ui);
  color: var(--ink);
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
  overscroll-behavior: none;
  text-rendering: optimizeSpeed;
}

/* The html/body block above is the CSS half of "a game is not a document"
   (hub CLAUDE.md §2); js/touch-guard.js is the other half. Body keeps
   touch-action: none rather than the hub's manipulation — nothing here
   scrolls or pinches, and the ship is steered by a drag anywhere. A real text
   field gets selection back so a typo can be fixed; there is none today. */
input, textarea, [contenteditable="true"] {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

#wrap { position: fixed; inset: 0; }

#game { display: block; width: 100%; height: 100%; touch-action: none; }

.hidden { display: none !important; }

button { font-family: inherit; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }

/* ================= HUD ================= */
#hud { position: absolute; inset: 0; pointer-events: none; }

#hud-top {
  display: flex;
  align-items: center;
  gap: 12px;
  /* The right padding RESERVES THE CORNER. The three plates are fixed page
     chrome standing over this row, so the score plate and the progress rail
     have to end before them — they were running underneath, which is what the
     HUD looked like until v1.9.1. Everything here is derived from the cluster's
     own tokens, so the narrow passes that shrink the plates shrink this too. */
  padding: calc(10px + var(--safe-t))
           calc(var(--corner-inset) * 2 + var(--corner-w) + var(--safe-r))
           0
           calc(14px + var(--safe-l));
}

/* ---- HP: boiler pressure gauge (brass bezel, green needle-fill unchanged) ---- */
#hp-wrap {
  position: relative;
  width: 160px; height: 20px;
  background: var(--channel);
  border: 1px solid var(--brass);
  border-radius: 10px;
  overflow: hidden;
  flex-shrink: 0;
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.85),
    0 0 0 1px rgba(48, 32, 14, 0.9),
    0 1px 3px rgba(0, 0, 0, 0.55);
}
/* trailing "damage ghost" — lags behind the real bar for a smooth drain read */
#hp-ghost {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 100%;
  background: rgba(255, 245, 225, 0.5);
  border-radius: 10px;
  transition: width 0.5s cubic-bezier(0.3, 0, 0.2, 1) 0.13s;
}
#hp-bar {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 100%;
  background: linear-gradient(90deg, #469a5c, #7cc48d);
  border-radius: 10px;
  transition: width 0.14s ease-out, background 0.3s linear;
}
#hp-bar.low { background: linear-gradient(90deg, #d2513c, #dd8a4c); }
/* gauge glass + pressure graduations, over the fill but under the readout */
#hp-wrap::after {
  content: '';
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none; border-radius: 10px;
  background:
    repeating-linear-gradient(90deg, rgba(24, 16, 8, 0.5) 0 1px, transparent 1px 16px),
    linear-gradient(180deg, rgba(255, 250, 235, 0.26), rgba(255, 250, 235, 0) 48%, rgba(0, 0, 0, 0.3));
}
#hp-text {
  position: absolute; inset: 0; z-index: 2;
  text-align: center; font-size: 12px; font-weight: 800; line-height: 20px;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.85);
}
#hp-wrap.danger {
  animation: hpPulse 0.62s ease-in-out infinite;
  border-color: rgba(210, 81, 60, 0.75);
}
@keyframes hpPulse {
  0%, 100% {
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(48, 32, 14, 0.9),
                0 0 0 0 rgba(210, 81, 60, 0);
  }
  50% {
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(48, 32, 14, 0.9),
                0 0 12px 2px rgba(210, 81, 60, 0.65);
  }
}

/* ---- Progress to boss: brass rail + travelling cog ---- */
#progress-wrap {
  position: relative; flex: 1; min-width: 60px; height: 8px;
  background: var(--channel); border-radius: 4px;
  box-shadow:
    inset 0 1px 2px rgba(0, 0, 0, 0.9),
    0 0 0 1px rgba(201, 151, 59, 0.5),
    0 1px 0 rgba(255, 232, 186, 0.08);
}
#progress-bar {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0%;
  background: linear-gradient(90deg, var(--cyan), #7cf1ff);
  border-radius: 4px;
  box-shadow: 0 0 10px rgba(53, 224, 255, 0.5);
  transition: width 0.2s linear;
}
/* the ▲ in the markup is a no-CSS fallback; here it's a spinning cyan cog */
#progress-marker {
  position: absolute; top: 5px; left: 0;
  width: 15px; height: 15px;
  font-size: 0; line-height: 0; color: var(--cyan);
  background: var(--gear-cyan) center / contain no-repeat;
  transform: translateX(-50%);
  filter: drop-shadow(0 0 4px rgba(53, 224, 255, 0.85));
  transition: left 0.2s linear;
  animation: cogSpin 7s linear infinite;
}
@keyframes cogSpin {
  from { transform: translateX(-50%) rotate(0deg); }
  to { transform: translateX(-50%) rotate(360deg); }
}
/* boss goal flag pinned to the end of the track */
#progress-goal {
  position: absolute; right: -3px; top: -12px;
  font-size: 12px; line-height: 1; color: var(--bad);
  text-shadow: 0 0 8px rgba(210, 81, 60, 0.7), 0 1px 0 rgba(0, 0, 0, 0.8);
}
#progress-goal.near { animation: goalPulse 0.55s ease-in-out infinite; }
@keyframes goalPulse {
  0%, 100% { transform: scale(1); opacity: 0.85; }
  50% { transform: scale(1.35); opacity: 1; }
}

/* ---- Score: riveted brass plate ---- */
#score-wrap {
  text-align: right; min-width: 70px; flex-shrink: 0;
  padding: 2px 9px 3px; border-radius: 7px;
  background:
    radial-gradient(circle at 4px 50%, rgba(255, 236, 196, 0.5) 0 1.2px, rgba(52, 34, 12, 0.85) 1.6px 2.2px, transparent 2.5px),
    radial-gradient(circle at calc(100% - 4px) 50%, rgba(255, 236, 196, 0.5) 0 1.2px, rgba(52, 34, 12, 0.85) 1.6px 2.2px, transparent 2.5px),
    var(--plate);
  border: 1px solid var(--rim);
  box-shadow: var(--sheen), 0 2px 6px rgba(0, 0, 0, 0.5);
}
#score {
  display: inline-block;
  font-size: 20px; font-weight: 800; letter-spacing: 1px;
  font-variant-numeric: tabular-nums;
  transform-origin: 100% 50%;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}
/* two identical keyframes so ui.js can retrigger the pop by alternating class */
#score.pop-a { animation: scorePop 0.24s ease-out; }
#score.pop-b { animation: scorePop2 0.24s ease-out; }
@keyframes scorePop {
  0% { transform: scale(1); color: var(--ink); }
  35% { transform: scale(1.32); color: #ffe6b0; }
  100% { transform: scale(1); color: var(--ink); }
}
@keyframes scorePop2 {
  0% { transform: scale(1); color: var(--ink); }
  35% { transform: scale(1.32); color: #ffe6b0; }
  100% { transform: scale(1); color: var(--ink); }
}
.hud-label {
  display: block;
  font-family: var(--font-display);
  font-size: 9px; letter-spacing: 2px;
  color: rgba(226, 197, 140, 0.85);
}

/* ---- Act / wave label: engraved plate ---- */
#act-label {
  position: absolute; top: calc(var(--safe-t) + 40px); left: 50%;
  transform: translateX(-50%);
  padding: 4px 14px; border-radius: 4px;
  background:
    radial-gradient(circle at 6px 50%, rgba(255, 236, 196, 0.55) 0 1.3px, rgba(52, 34, 12, 0.9) 1.7px 2.3px, transparent 2.6px),
    radial-gradient(circle at calc(100% - 6px) 50%, rgba(255, 236, 196, 0.55) 0 1.3px, rgba(52, 34, 12, 0.9) 1.7px 2.3px, transparent 2.6px),
    linear-gradient(180deg, rgba(48, 36, 24, 0.94), rgba(18, 14, 10, 0.94));
  border: 1px solid rgba(201, 151, 59, 0.6);
  box-shadow: var(--sheen), 0 2px 7px rgba(0, 0, 0, 0.6);
  font-family: var(--font-display);
  font-size: 10px; font-weight: 800; letter-spacing: 3px;
  color: #f4e3bd; white-space: nowrap;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.75);
  max-width: 52vw; overflow: hidden; text-overflow: ellipsis;
  animation: actIn 0.45s cubic-bezier(0.2, 1.4, 0.3, 1) both;
}
@keyframes actIn {
  0% { opacity: 0; transform: translateX(-50%) translateY(-8px); letter-spacing: 8px; }
  100% { opacity: 1; transform: translateX(-50%) translateY(0); letter-spacing: 3px; }
}

/* ---- Boss bar (IRONCLAD): iron bezel, red fill unchanged ---- */
#boss-wrap {
  position: absolute; top: calc(var(--safe-t) + 72px); left: 50%;
  transform: translateX(-50%);
  width: min(74vw, 480px); text-align: center;
}
#boss-name {
  font-family: var(--font-display);
  font-size: 13px; font-weight: 900; letter-spacing: 4px; color: var(--bad);
  text-shadow: 0 0 12px rgba(210, 81, 60, 0.6), 0 1px 0 rgba(0, 0, 0, 0.85);
}
#boss-bar-outer {
  position: relative;
  margin-top: 4px; height: 13px;
  background: var(--channel);
  border: 1px solid rgba(201, 151, 59, 0.55);
  border-radius: 7px; overflow: hidden;
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.9),
    0 0 0 1px rgba(48, 32, 14, 0.9),
    0 0 14px rgba(210, 81, 60, 0.22);
}
#boss-bar {
  position: absolute; left: 0; top: 0; bottom: 0; width: 100%;
  background: linear-gradient(90deg, #d2513c, #de9350);
  transition: width 0.12s linear;
}
/* phase markers at 66% / 33% of boss HP — riveted brass ticks */
#boss-ticks { position: absolute; inset: 0; pointer-events: none; }
#boss-ticks::before, #boss-ticks::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 2px;
  background: rgba(10, 8, 5, 0.9);
  box-shadow: 0 0 0 1px rgba(226, 190, 120, 0.45);
}
#boss-ticks::before { left: 33%; }
#boss-ticks::after { left: 66%; }
#boss-wrap.p2 #boss-bar { background: linear-gradient(90deg, #ff7a3c, #ffc14d); }
#boss-wrap.p3 #boss-bar {
  background: linear-gradient(90deg, #ffd166, #fff3b0);
  animation: bossRage 0.4s steps(2) infinite;
}
#boss-wrap.p3 #boss-name { animation: bossRage 0.4s steps(2) infinite; }
@keyframes bossRage { 0% { filter: brightness(1); } 100% { filter: brightness(1.5); } }

/* ---- Upgrade toast (single slot, ui.js queues) ---- */
#upgrade-toast {
  position: absolute; top: 22%; left: 50%;
  transform: translateX(-50%);
  padding: 9px 22px; border-radius: 7px;
  background:
    linear-gradient(180deg, rgba(48, 37, 25, 0.94), rgba(16, 12, 9, 0.94));
  border: 1px solid var(--good);
  box-shadow: 0 0 24px rgba(86, 176, 108, 0.3), var(--sheen), 0 4px 14px rgba(0, 0, 0, 0.55);
  /* deliberately the UI sans, not the display serif: this is a fast, in-run
     stat read and long trade-off labels must not truncate on small phones */
  font-size: 18px; font-weight: 900; letter-spacing: 0.5px;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7);
  white-space: nowrap;
  max-width: 90vw; overflow: hidden; text-overflow: ellipsis;
  animation: toast 1.35s ease-out forwards;
}
#upgrade-toast.bad { border-color: var(--bad); box-shadow: 0 0 24px rgba(210, 81, 60, 0.3), var(--sheen); color: #f2cfc2; }
#upgrade-toast.mixed { border-color: var(--mixed); box-shadow: 0 0 24px rgba(199, 125, 255, 0.3), var(--sheen); }
@keyframes toast {
  0% { opacity: 0; transform: translateX(-50%) scale(0.6); }
  14% { opacity: 1; transform: translateX(-50%) scale(1.12); }
  24% { transform: translateX(-50%) scale(1); }
  78% { opacity: 1; transform: translateX(-50%) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-22px) scale(0.98); }
}

/* ---- Build stats strip: thin brass rims ---- */
/* Power-up rail: a vertical stack on the LEFT edge (the bottom belongs to the
   gate legend — on phones the two used to collide) */
#stats-strip {
  position: absolute;
  left: calc(8px + var(--safe-l));
  top: calc(66px + var(--safe-t));
  /* A ONE-COLUMN GRID, not a flex column with align-items:flex-start, which is
     what it was until v1.9.2: every chip shrank to its own text, so DMG 18,
     ROF 9.3/s, DRAUGHT and HEAVY came down the left edge as four plates of
     four different widths with a ragged right edge. The grid column is as wide
     as the widest of them and every chip stretches to it — the same rule, and
     the same two lines, as the title screen's button stack. The strip is
     absolutely positioned, so the column is still only as wide as its own
     content: this lines the plates up, it does not stretch them across the
     screen. */
  display: grid; justify-items: stretch; gap: 4px;
  max-height: calc(100vh - 200px);
  overflow: hidden;
}

/* ---- approaching-gate legend: the TEXT for the icons shown in the field ---- */
#gate-legend {
  position: absolute; bottom: calc(10px + var(--safe-b)); left: 50%;
  transform: translateX(-50%);
  display: flex; gap: 10px; align-items: center;
  font-family: var(--font-display);
  font-size: 12px; font-weight: 700; letter-spacing: 1.2px;
  pointer-events: none; white-space: nowrap;
  max-width: calc(100vw - 16px);
}
/* THREE spans (left/mid/right) = up to three gate slots; ui.js hides the ones a
   row does not use, so a 1- or 2-slot row looks exactly as it did in v1.2 */
/* the spans are built by ui.init(): [canvas.gl-ico ×2][b.gl-txt] */
#gate-legend span {
  padding: 5px 14px; border-radius: 5px;
  background: linear-gradient(180deg, rgba(42, 32, 22, 0.9), rgba(15, 12, 9, 0.92));
  border: 1px solid var(--rim);
  box-shadow: var(--sheen), 0 2px 8px rgba(0, 0, 0, 0.4);
  overflow: hidden; text-overflow: ellipsis;
  display: inline-flex; align-items: center; gap: 6px;
  min-width: 0; /* so a long trade label ellipsises instead of pushing the row */
}
#gate-legend span.good { color: #8fd8a3; border-color: rgba(86, 176, 108, 0.65); }
#gate-legend span.bad { color: #eb9078; border-color: rgba(210, 81, 60, 0.65); }
#gate-legend span.mixed { color: #cfa9ec; border-color: rgba(169, 123, 209, 0.65); }
/* a bad gate shot down to levels 0 — dead panel, dead legend */
#gate-legend span.defused {
  color: #9aa4b3; border-color: rgba(150, 162, 179, 0.45);
  background: linear-gradient(180deg, rgba(30, 30, 34, 0.88), rgba(12, 12, 14, 0.9));
}
/* baked 16px glyph (icons.js sprite cache, one drawImage per legend change) */
.gl-ico { flex: 0 0 auto; display: block; width: 16px; height: 16px; }
.gl-txt {
  min-width: 0; font-weight: inherit; letter-spacing: inherit;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 600px) {
  /* phones: the power-up rail compacts to icon + pips (names hidden) and
     starts below the boss-bar zone so the two can never touch */
  #stats-strip { gap: 3px; top: calc(118px + var(--safe-t)); }
  #stats-strip i { font-size: 10px; padding: 2px 5px; border-radius: 5px; gap: 3px; }
  #stats-strip i em { display: none; } /* icons carry the meaning on phones */

  /* phones: two slots can't hold a whole label on one line, so the text WRAPS
     (max two lines) instead of ellipsising away the '→ LV5' that matters.
     The spans keep their left/mid/right order = the gate panels' order.
     THREE slots get ~112px per chip at 360px, so ui.js also drops that copy to
     the name alone (copyTier 2) — the CSS side just has to let them shrink. */
  #gate-legend {
    font-size: 10.5px; gap: 4px; bottom: calc(34px + var(--safe-b));
    white-space: normal; align-items: stretch; justify-content: center;
    /* a definite width: an abspos shrink-to-fit box only gets (100vw - left)
       to play with, which would squeeze both spans into half the screen */
    width: calc(100vw - 16px);
  }
  #gate-legend span {
    padding: 4px 7px; gap: 5px;
    /* shrink from the one-line width, and min-width:0 (base rule) lets three
       chips go below their min-content width instead of overflowing the
       viewport — .gl-txt then wraps, and clips with an ellipsis if it must */
    flex: 0 1 auto; min-width: 0; letter-spacing: 0.6px; text-align: left;
  }
  .gl-ico { width: 14px; height: 14px; }
  .gl-txt { white-space: normal; line-height: 1.22; max-height: 2.5em; }
}
#stats-strip i {
  font-style: normal;
  font-size: 11px; font-weight: 800; letter-spacing: 0.4px;
  padding: 3px 8px; border-radius: 6px;
  background: var(--plate);
  border: 1px solid var(--rim);
  color: #efe2c6;
  box-shadow: var(--sheen);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
  /* v1.2: chips are [icon][NAME][pips] — one brass plate, three parts */
  display: inline-flex; align-items: center; gap: 4px;
}
#stats-strip i.up { color: #c9e8cf; border-color: rgba(86, 176, 108, 0.55); }
/* a level went NEGATIVE (only ARMOUR PLATE can): rust-red plate */
#stats-strip i.down, .build-row i.down {
  color: #f2c3b4; border-color: rgba(210, 81, 60, 0.6); background: rgba(210, 81, 60, 0.14);
}
#stats-strip i.more, .build-row i.more { color: rgba(226, 197, 140, 0.85); letter-spacing: 0; }
/* The label takes up the slack inside a stretched plate, which puts every
   value — the number on DMG and ROF, the pips on a track — against the right
   edge. So the plates share an edge AND their contents line up in three
   columns: glyph, name, value. Without this the whole row would sit packed to
   the left of a plate that is wider than it needs. */
#stats-strip i em { font-style: normal; font-weight: 700; opacity: 0.72; flex: 1 1 auto; }

/* ---- baked icon glyphs in DOM chips (icons.js data-URL cache) ---- */
.chip-ico { flex: 0 0 auto; display: block; width: 12px; height: 12px; }
.build-row .chip-ico { width: 14px; height: 14px; }

/* ---- level pips: five brass boxes, hollow when unspent ---- */
.pips { display: inline-flex; align-items: center; gap: 2px; }
.pip {
  width: 5px; height: 5px; border-radius: 1px;
  background: rgba(0, 0, 0, 0.5);
  box-shadow: inset 0 0 0 1px rgba(111, 82, 32, 0.85);
}
.pip.on {
  background: linear-gradient(180deg, var(--brass-lt), var(--brass));
  box-shadow: inset 0 0 0 1px rgba(10, 8, 5, 0.7), 0 0 4px rgba(240, 180, 41, 0.45);
}
.pip.on.neg {
  background: linear-gradient(180deg, #e2705a, var(--bad));
  box-shadow: inset 0 0 0 1px rgba(10, 8, 5, 0.7), 0 0 4px rgba(210, 81, 60, 0.5);
}
.build-row .pip { width: 6px; height: 6px; }

/* the chip whose level just changed gets one brass thump */
#stats-strip i.bump { animation: chipBump 0.42s cubic-bezier(0.2, 1.4, 0.3, 1) 1; }
@keyframes chipBump {
  0% { transform: scale(1); }
  38% {
    transform: scale(1.16);
    border-color: var(--rim-hot);
    box-shadow: var(--sheen), 0 0 12px rgba(240, 180, 41, 0.55);
  }
  100% { transform: scale(1); }
}

/* THE HUD'S OWN PUSHBUTTONS ARE GONE. #mute-btn and #pause-btn were two more
   brass circles beside the two permanent ones, which made four in one corner —
   and two of the four were speakers, one muting and one opening a mixer, which
   read as the same control drawn twice. Pause is the menu plate in
   #corner-tools now and mute is the plate beside it, so the recipe below the
   cluster's own rules is the only copy of this styling that survives. */

/* ================= Screens ================= */
.screen {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 18px; text-align: center;
  background:
    radial-gradient(ellipse at 50% 38%, rgba(112, 76, 30, 0.34), rgba(16, 12, 9, 0.93) 68%),
    linear-gradient(180deg, #1b1613, #0c0906);
  /* brass double frame around the whole panel */
  box-shadow:
    inset 0 0 0 2px rgba(201, 151, 59, 0.34),
    inset 0 0 0 5px rgba(20, 15, 11, 0.9),
    inset 0 0 0 6px rgba(201, 151, 59, 0.14),
    inset 0 0 110px rgba(0, 0, 0, 0.6);
  padding: calc(16px + var(--safe-t)) calc(16px + var(--safe-r)) calc(16px + var(--safe-b)) calc(16px + var(--safe-l));
  z-index: 10;
  overflow-y: auto;
  overflow-x: hidden; /* lets the corner gears bleed off the edge without scroll */
  /* A centred flex column that outgrows its box overflows at BOTH ends, and
     the top end cannot be scrolled to — on a landscape phone that was the
     logo, cut off with no way to reach it. `safe center` falls back to start
     alignment when there is no room; a browser that does not know the
     keyword drops this line and keeps the plain `center` above. */
  justify-content: safe center;
}

.screen h1 {
  font-family: var(--font-display);
  font-size: clamp(42px, 11vw, 88px);
  font-weight: 900; letter-spacing: 6px; line-height: 1;
  color: #f4e5c4;
  text-rendering: optimizeLegibility;
  text-shadow:
    0 2px 0 rgba(0, 0, 0, 0.6),
    0 0 26px rgba(240, 180, 41, 0.38),
    0 0 80px rgba(176, 101, 47, 0.22);
}
.screen h2 {
  font-family: var(--font-display);
  font-size: clamp(30px, 7vw, 54px);
  font-weight: 900; letter-spacing: 4px; line-height: 1.1;
  text-rendering: optimizeLegibility;
}
/* Two headings are one long word in bokmål — INNSTILLINGER, OPPGRADERINGER —
   and a word cannot wrap, so at the shared size they ran off a 360px phone.
   They get a ceiling in vw as well: at 6.2vw fourteen Copperplate capitals
   and their tracking fit any portrait phone, and above ~870px the ordinary
   clamp is the smaller number again, so a tablet or desktop sees no change.
   English shrinks with them on a phone, which keeps the panel the same shape
   in both languages. */
#menu-title, #screen-powers h2 { font-size: min(clamp(30px, 7vw, 54px), 6.2vw); }
.accent { color: var(--brass-lt); }
.good { color: var(--good); }
.bad { color: var(--bad); }
.charge { color: var(--charge); }
.tagline { font-family: var(--font-serif); opacity: 0.78; font-style: italic; font-size: 13.5px; color: #e6d6b4; }
.hint { font-size: 12px; opacity: 0.55; line-height: 1.5; color: #ddcfb4; }

/* ---- v1.5 level-clear KEEP screen ---- */
.lc-card { width: min(96vw, 720px); }
.keep-note { font-size: 13px; letter-spacing: 1px; opacity: 0.85; }
.keep-note b { color: var(--charge); }
#lc-pick, #pw-pick {
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: 14px;
  width: 100%;
  align-items: start;
  text-align: left;
}
#lc-grid, #pw-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
  gap: 8px;
  max-height: 42vh;
  overflow-y: auto;
  padding: 2px;
}
/* The armoury has eighteen cards to the KEEP screen's handful, so on a desktop
   it may stand taller. This has to sit HERE, above the phone rules below: it
   used to live after them, and an id rule later in the file beats an id rule
   in a media query, so every phone got a grid half the screen tall with the
   detail pane and BACK pushed off the bottom. */
#pw-grid { max-height: 52vh; }
.keep-card {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 10px 6px 8px;
  background: var(--plate);
  border: 1px solid var(--rim);
  border-radius: 8px;
  color: var(--ink);
  cursor: pointer;
  transition: transform 0.08s, border-color 0.15s, box-shadow 0.2s;
}
.keep-card em {
  font-style: normal; font-size: 10px; font-weight: 800;
  letter-spacing: 0.6px; text-align: center;
}
.keep-card .chip-ico { width: 22px; height: 22px; }
.keep-card:hover { transform: translateY(-2px); border-color: var(--rim-hot); }
.keep-card.browse { border-color: rgba(53, 224, 255, 0.55); }
.keep-card.keep {
  border-color: var(--charge);
  box-shadow: 0 0 0 1px var(--charge), 0 0 16px rgba(255, 209, 102, 0.55),
              inset 0 0 10px rgba(255, 209, 102, 0.12);
  animation: keepGlow 1.4s ease-in-out infinite;
}
@keyframes keepGlow {
  0%, 100% { box-shadow: 0 0 0 1px var(--charge), 0 0 12px rgba(255, 209, 102, 0.4), inset 0 0 8px rgba(255, 209, 102, 0.1); }
  50% { box-shadow: 0 0 0 1px var(--charge), 0 0 22px rgba(255, 209, 102, 0.75), inset 0 0 12px rgba(255, 209, 102, 0.18); }
}
.keep-card.deny { animation: denyShake 0.3s; }
@keyframes denyShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}
#lc-detail, #pw-detail {
  display: flex; flex-direction: column; gap: 8px;
  background: rgba(12, 9, 6, 0.55);
  border: 1px solid var(--rim);
  border-radius: 8px;
  padding: 10px;
}
#lc-preview, #pw-preview {
  width: 100%; height: 132px; display: block;
  background: #14100b; border-radius: 6px;
  border: 1px solid rgba(201, 151, 59, 0.3);
}
#lc-detail h3, #pw-detail h3 {
  font-family: var(--font-display);
  font-size: 14px; letter-spacing: 1.5px; color: #ffe9bd;
}
#lc-detail p, #pw-detail p { font-size: 12px; line-height: 1.5; opacity: 0.85; }
.big-btn:disabled {
  opacity: 0.35; cursor: not-allowed; transform: none !important;
  box-shadow: none; animation: none;
}
@media (max-width: 640px) {
  #lc-pick, #pw-pick { grid-template-columns: 1fr; }
  #lc-grid, #pw-grid { max-height: 26vh; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  #lc-preview, #pw-preview { height: 110px; }
  .lc-card { padding: 14px 10px; }
}
@media (max-height: 700px) {
  #lc-grid, #pw-grid { max-height: 30vh; }
  .end-card.lc-card h2 { font-size: 26px; }
}

/* ---- v1.5.1 armoury (view-all-powers) extras ---- */
#pw-pick { width: min(94vw, 760px); }
.keep-card .tier-tag {
  position: absolute; top: 4px; right: 6px;
  font-size: 9px; font-weight: 800; letter-spacing: 1px;
  color: var(--brass-lt); opacity: 0.8;
}
.keep-card { position: relative; }
#pw-lvls { display: flex; gap: 6px; }
#pw-lvls button {
  width: 22px; height: 14px; border-radius: 3px; cursor: pointer;
  background: rgba(0, 0, 0, 0.45); border: 1px solid rgba(111, 82, 32, 0.8);
}
#pw-lvls button.on { background: var(--brass-lt); border-color: var(--brass-hi); }
#pw-dtier { letter-spacing: 1px; }

/* ---- v1.4 campaign cards: save slots + difficulty picks ---- */
#slot-list, #diff-list {
  display: flex; flex-direction: column; gap: 12px;
  width: min(92vw, 440px);
}
.pick-card {
  position: relative;
  display: flex; flex-direction: column; gap: 4px; align-items: flex-start;
  padding: 14px 18px; min-height: 56px;
  text-align: left;
  color: var(--ink);
  background: var(--plate);
  border: 1px solid var(--rim);
  border-radius: 8px;
  box-shadow: var(--sheen), 0 4px 14px rgba(0, 0, 0, 0.45);
  cursor: pointer;
  transition: transform 0.08s, border-color 0.15s;
  font-family: var(--font-ui);
}
.pick-card:hover { transform: scale(1.02); border-color: var(--rim-hot); }
.pick-card:active { transform: scale(0.98); }
.pick-card b {
  font-family: var(--font-display);
  font-size: 15px; letter-spacing: 1.5px; color: #ffe9bd;
}
.pick-card span { font-size: 12px; opacity: 0.75; }
.pick-card.empty b { color: #cfc4ac; }
.pick-card.empty span { color: #8fd8a3; }
.slot-resume {
  font-style: normal; font-size: 12px; font-weight: 800;
  letter-spacing: 1px; color: var(--cyan); margin-top: 2px;
}
.slot-del {
  position: absolute; top: 8px; right: 8px;
  width: 34px; height: 34px; border-radius: 50%;
  background: rgba(20, 14, 10, 0.8);
  border: 1px solid rgba(210, 81, 60, 0.5);
  color: #eb9078; font-size: 13px; cursor: pointer;
}
.slot-del.armed {
  background: rgba(120, 30, 18, 0.9); color: #fff;
  width: auto; padding: 0 10px; border-radius: 17px;
}
.diff-easy b { color: #8fd8a3; }
.diff-medium b { color: #ffd166; }
.diff-hard b { color: #eb9078; }
@media (max-height: 600px) {
  #slot-list, #diff-list { gap: 8px; }
  .pick-card { padding: 10px 14px; min-height: 46px; }
}

/* ---- Title: brass plaque + slow gearworks ---- */
#screen-title {
  background:
    radial-gradient(ellipse at 50% 34%, rgba(140, 94, 34, 0.4), rgba(18, 13, 10, 0.94) 66%),
    linear-gradient(180deg, #1f1813, #0c0906);
  box-shadow:
    inset 0 0 0 2px rgba(201, 151, 59, 0.5),
    inset 0 0 0 5px rgba(20, 15, 11, 0.92),
    inset 0 0 0 7px rgba(201, 151, 59, 0.22),
    inset 0 0 120px rgba(0, 0, 0, 0.66);
}
/* two big, faint, slowly turning gears behind the panel content */
#screen-title::before, #screen-title::after {
  content: '';
  position: absolute; pointer-events: none;
  background-image: var(--gear-brass);
  background-repeat: no-repeat; background-position: center; background-size: contain;
  opacity: 0.13;
}
#screen-title::before {
  width: 280px; height: 280px; left: -78px; top: -66px;
  animation: gearSpin 88s linear infinite;
}
#screen-title::after {
  width: 340px; height: 340px; right: -96px; bottom: 0;
  opacity: 0.1;
  animation: gearSpinRev 132s linear infinite;
}
@keyframes gearSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes gearSpinRev { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } }

.logo {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 4px 2px 2px;
}
#screen-title h1 { animation: logoIn 0.6s cubic-bezier(0.15, 1.35, 0.35, 1) both; }
#screen-title h1 .accent {
  color: var(--brass-lt);
  text-shadow: 0 2px 0 rgba(60, 34, 6, 0.7);
}
@supports (-webkit-background-clip: text) or (background-clip: text) {
  #screen-title h1 .accent {
    background-image: linear-gradient(100deg, #b0652f 18%, #f0b429 34%, #fff4d6 46%, #f0b429 58%, #a35d24 78%);
    background-size: 300% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: shine 4.5s linear infinite;
  }
}
@keyframes logoIn {
  0% { opacity: 0; transform: translateY(14px) scale(0.9); letter-spacing: 22px; filter: blur(6px); }
  100% { opacity: 1; transform: none; letter-spacing: 6px; filter: blur(0); }
}
@keyframes shine {
  0% { background-position: 130% 0; }
  100% { background-position: -130% 0; }
}
/* brass rule, split around a turning cog */
.logo-rule {
  position: relative;
  width: min(72vw, 340px); height: 2px;
  background: linear-gradient(90deg,
    transparent, var(--brass) 14%, var(--brass-lt) 38%, transparent 46%,
    transparent 54%, var(--brass-lt) 62%, var(--brass) 86%, transparent);
  box-shadow: 0 0 12px rgba(240, 180, 41, 0.45);
  transform-origin: 50% 50%;
  animation: ruleIn 0.7s 0.15s cubic-bezier(0.2, 1, 0.3, 1) both, ruleGlow 3s 0.9s ease-in-out infinite;
}
.logo-rule::before {
  content: '';
  position: absolute; left: 50%; top: 50%;
  width: 22px; height: 22px; margin: -11px 0 0 -11px;
  background: var(--gear-hot) center / contain no-repeat;
  filter: drop-shadow(0 0 5px rgba(240, 180, 41, 0.5));
  animation: gearSpin 16s linear infinite;
}
@keyframes ruleIn { 0% { transform: scaleX(0); opacity: 0; } 100% { transform: scaleX(1); opacity: 1; } }
@keyframes ruleGlow { 0%, 100% { opacity: 0.6; } 50% { opacity: 1; } }


/* ---- one-time steer hint at the start of the first run ---- */
#steer-hint {
  position: absolute; top: 34%; left: 50%; transform: translateX(-50%);
  padding: 9px 22px; border-radius: 6px;
  background: linear-gradient(180deg, rgba(46, 35, 24, 0.85), rgba(15, 12, 9, 0.85));
  border: 1px solid rgba(201, 151, 59, 0.55);
  box-shadow: var(--sheen), 0 6px 20px rgba(0, 0, 0, 0.45);
  font-family: var(--font-display);
  font-size: 13px; letter-spacing: 2px; color: #f2e8d5;
  white-space: nowrap; text-align: center;
  animation: steerHint 4.5s ease-in-out forwards;
  pointer-events: none;
}
#steer-hint b { color: var(--charge); }
@media (max-width: 600px) {
  #steer-hint {
    top: 45%; /* below the left power-up rail so the two never cross */
    font-size: 10px; letter-spacing: 1px; padding: 8px 12px;
    max-width: 94vw; overflow: hidden; text-overflow: ellipsis;
  }
}
@keyframes steerHint {
  0% { opacity: 0; transform: translateX(-50%) translateY(8px); }
  10%, 78% { opacity: 1; transform: translateX(-50%); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-10px); }
}
@media (prefers-reduced-motion: reduce) {
  #steer-hint { animation: steerHintStill 4.5s linear forwards; }
}
@keyframes steerHintStill { 0%, 90% { opacity: 1; } 100% { opacity: 0; } }

@keyframes fadeUp { 0% { opacity: 0; transform: translateY(10px); } 100% { opacity: 1; transform: none; } }

/* ---- Buttons: cast brass ---- */
.big-btn {
  min-height: 48px;
  padding: 14px 42px;
  font-family: var(--font-display);
  font-size: 19px; font-weight: 900; letter-spacing: 2px;
  color: #2c1c05;
  text-rendering: optimizeLegibility;
  text-shadow: 0 1px 0 rgba(255, 244, 214, 0.55);
  background:
    radial-gradient(circle at 15px 50%, rgba(96, 62, 20, 0.6) 0 2.4px, rgba(255, 244, 214, 0.55) 2.9px 3.8px, transparent 4.2px),
    radial-gradient(circle at calc(100% - 15px) 50%, rgba(96, 62, 20, 0.6) 0 2.4px, rgba(255, 244, 214, 0.55) 2.9px 3.8px, transparent 4.2px),
    linear-gradient(180deg, #ffeab5 0%, #f0b429 26%, #cb9a3d 60%, #94611e 100%);
  border: 1px solid #6d4715; border-radius: 12px; cursor: pointer;
  box-shadow:
    inset 0 1px 0 rgba(255, 250, 228, 0.8),
    inset 0 -4px 9px rgba(84, 52, 12, 0.5),
    0 4px 18px rgba(0, 0, 0, 0.55),
    0 0 22px rgba(240, 180, 41, 0.28);
  transition: transform 0.1s ease-out;
}
.big-btn:hover { transform: scale(1.04); }
.big-btn:active { transform: scale(0.96); }
.big-btn.pulse { animation: btnPulse 1.5s ease-in-out infinite; }
@keyframes btnPulse {
  0%, 100% {
    box-shadow: inset 0 1px 0 rgba(255, 250, 228, 0.8), inset 0 -4px 9px rgba(84, 52, 12, 0.5),
                0 4px 16px rgba(0, 0, 0, 0.5), 0 0 0 0 rgba(240, 180, 41, 0.5);
  }
  50% {
    box-shadow: inset 0 1px 0 rgba(255, 250, 228, 0.8), inset 0 -4px 9px rgba(84, 52, 12, 0.5),
                0 4px 26px rgba(0, 0, 0, 0.5), 0 0 0 12px rgba(240, 180, 41, 0);
  }
}
.big-btn.pulse:hover, .big-btn.pulse:active { animation-play-state: paused; }

.small-btn {
  min-height: 40px;
  padding: 9px 24px; font-size: 13px; font-weight: 700;
  font-family: var(--font-display); letter-spacing: 1.4px;
  color: #ecdcb6;
  background: linear-gradient(180deg, rgba(52, 40, 27, 0.92), rgba(20, 15, 11, 0.92));
  border: 1px solid rgba(201, 151, 59, 0.55); border-radius: 8px; cursor: pointer;
  box-shadow: var(--sheen), 0 2px 8px rgba(0, 0, 0, 0.5);
}
.small-btn:active { transform: scale(0.96); }

/* Leaving the game, as opposed to quitting to the title.

   ONE BUTTON, THE SAME IN EVERY GAME (hub CLAUDE.md §2, v1.11). Until then
   this was brass caps behind a ◂ with no outline at all; the way out is
   chrome now, like the corner plates, so it has the hub's shape — an outline
   with the plate taken away, never the gradient START and RESUME wear,
   because leaving is never the recommended thing to do — and the hub's arrow
   in front of sentence-case words. The colours are still MAXGEAR's brass.

   Georgia rather than the display face, deliberately: Copperplate's lower
   case IS small capitals, so "Tilbake til arkaden" set in it reads as the
   all-caps this button has just given up. The serif is the game's own second
   face, the one its hints and blurbs are already set in.

   The extra margin is the gap that keeps it from reading as one more menu
   item: always last in its column, always a little apart. */
.exit-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  margin-top: 8px;
  background: transparent;
  border-color: rgba(201, 151, 59, 0.45);
  box-shadow: none;
  color: rgba(236, 220, 182, 0.82);
  font-family: var(--font-serif);
  font-size: 15px; font-weight: 600; letter-spacing: 0.2px;
}
.exit-glyph {
  width: 18px; height: 18px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
.exit-btn:not(:disabled):hover,
.exit-btn:focus-visible { color: #ecdcb6; border-color: rgba(201, 151, 59, 0.8); background: rgba(201, 151, 59, 0.08); }
.exit-btn:disabled { color: rgba(236, 220, 182, 0.4); border-color: rgba(201, 151, 59, 0.2); cursor: default; }

/* The menu's stack is one column as wide as the sound board it shares the
   panel with, the same one-column-one-width rule the title's stack follows:
   RESUME, END RUN, BACK and the way out are one list, and the way out in
   particular is the full width of it. */
#btn-resume, #btn-quit, #btn-menu-close, #btn-exit-pause { width: min(92vw, 380px); }

/* ---- Title: version tag + opt-in update pill (v1.5.2) ---- */
.version-tag {
  position: absolute;
  right: calc(14px + var(--safe-r)); bottom: calc(10px + var(--safe-b));
  font-family: var(--font-display);
  font-size: 11px; letter-spacing: 1.6px;
  color: #ddcfb4; opacity: 0.45;
  pointer-events: none;
}
.update-btn {
  color: #ffe9b0;
  border-color: rgba(240, 180, 41, 0.85);
  box-shadow: var(--sheen), 0 2px 8px rgba(0, 0, 0, 0.5), 0 0 14px rgba(240, 180, 41, 0.3);
  animation: updateGlow 2.2s ease-in-out infinite;
}
.update-btn:disabled { opacity: 0.6; cursor: default; animation: none; }
@keyframes updateGlow {
  0%, 100% { box-shadow: var(--sheen), 0 2px 8px rgba(0, 0, 0, 0.5), 0 0 8px rgba(240, 180, 41, 0.2); }
  50% { box-shadow: var(--sheen), 0 2px 8px rgba(0, 0, 0, 0.5), 0 0 20px rgba(240, 180, 41, 0.5); }
}
@media (prefers-reduced-motion: reduce) {
  .update-btn { animation: none; }
}

/* ---- v1.6 sound board: two pressure dials on a brass plate ----
   It has a screen of its own behind the corner speaker (v1.8) and sits INLINE
   on the pause menu; ui.showScreen moves the one node between the two slots.
   Either way it has to read as a piece of the machine bolted into a menu
   rather than a settings page — hence the engraved caption, and hence a layout
   tight enough that it never needed a screen to fit on in the first place.
   The sliders are real <input type="range">, restyled from the shell out: an
   OS slider here would be the one control in MAXGEAR that belongs to no
   machine. The channel is the same recess as the HP bar, filled with brass up
   to the setting (--fill, written by ui.js), and the thumb is the same
   cast-brass pushbutton as the HUD's mute and pause. */
.board-slot { display: flex; justify-content: center; width: 100%; }
#sound-board {
  display: flex; flex-direction: column; gap: 11px;
  width: min(92vw, 380px);
  padding: 12px 16px 14px;
  text-align: left;
  background: var(--plate);
  border: 1px solid var(--rim);
  border-radius: 10px;
  box-shadow: var(--sheen), 0 4px 16px rgba(0, 0, 0, 0.5);
}
.board-cap {
  font-family: var(--font-display);
  font-size: 10.5px; letter-spacing: 2.4px;
  color: var(--brass); opacity: 0.9;
  padding-bottom: 3px;
  border-bottom: 1px solid rgba(201, 151, 59, 0.22);
}
.dial-row { display: flex; flex-direction: column; gap: 1px; }
.dial-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.dial-label {
  font-family: var(--font-display);
  font-size: 13px; font-weight: 700; letter-spacing: 1.6px;
  color: #ffe9bd;
}
.dial-val {
  font-family: var(--font-display);
  font-size: 12px; letter-spacing: 1.2px;
  color: var(--brass-lt);
  font-variant-numeric: tabular-nums;
}
/* ---- v1.10 the language row: SPRÅK / LANGUAGE ----
   The last row on the board, ruled off from the two levels above it —
   caption left, controls right. (ALL SOUND used to sit between them; it was
   the corner's mute plate twice and went in v1.12.) Two equal buttons (flex: 1 1 0, the hub's equal rule: Norsk and
   English are alternatives, so neither may look like the lesser one), and the
   chosen one is cast brass, the same metal as PLAY, while the other stays a
   dark plate. When the caption and both buttons cannot share a line — a
   narrow portrait phone, or ENGLISH's longer caption — the pair wraps under
   the caption and keeps its right edge, rather than squeezing an endonym. */
.board-lang {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 8px 12px;
  padding-top: 9px;
  border-top: 1px solid rgba(201, 151, 59, 0.22);
}
.lang-seg {
  display: flex; gap: 6px;
  flex: 1 1 210px; max-width: 260px; margin-left: auto;
}
.lang-btn {
  flex: 1 1 0; min-width: 0;
  min-height: 36px; padding: 6px 8px;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font-size: 12px; letter-spacing: 1px; white-space: nowrap;
}
.lang-btn .flag {
  flex: none; width: 20px; height: 14px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
}
.lang-btn[aria-pressed="true"] {
  color: #2a1806;
  text-shadow: 0 1px 0 rgba(255, 244, 214, 0.55);
  background: linear-gradient(180deg, #ffeab5 0%, #f0b429 30%, #cb9a3d 70%, #94611e 100%);
  border-color: #6d4715;
  box-shadow: inset 0 1px 0 rgba(255, 250, 228, 0.8), 0 0 12px rgba(240, 180, 41, 0.3);
}
.lang-btn:focus-visible { outline: 2px solid rgba(53, 224, 255, 0.7); outline-offset: 2px; }

#sound-board input[type="range"] {
  -webkit-appearance: none; appearance: none;
  flex: 1; min-width: 0;
  height: 36px;            /* the touch target, not the visible channel */
  margin: 0; padding: 0;
  background: transparent; cursor: pointer;
}
/* One declaration per engine: a browser drops the whole rule if it does not
   recognise the pseudo-element, so ::-webkit- and ::-moz- cannot be grouped. */
#sound-board input[type="range"]::-webkit-slider-runnable-track {
  height: 12px; border-radius: 6px;
  background:
    linear-gradient(90deg, var(--brass-lt) 0 var(--fill, 50%), rgba(0, 0, 0, 0) var(--fill, 50%)),
    var(--channel);
  border: 1px solid rgba(201, 151, 59, 0.45);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.75);
}
#sound-board input[type="range"]::-moz-range-track {
  height: 12px; border-radius: 6px;
  background:
    linear-gradient(90deg, var(--brass-lt) 0 var(--fill, 50%), rgba(0, 0, 0, 0) var(--fill, 50%)),
    var(--channel);
  border: 1px solid rgba(201, 151, 59, 0.45);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.75);
}
#sound-board input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 26px; height: 26px; border-radius: 50%;
  margin-top: -8px;        /* (track 12 + 2 border - thumb 26) / 2 */
  background: radial-gradient(circle at 50% 30%, #e0ac53, #a06f27 62%, #5e3f16);
  border: 1px solid rgba(255, 236, 196, 0.45);
  box-shadow: inset 0 1px 0 rgba(255, 246, 218, 0.65), 0 2px 7px rgba(0, 0, 0, 0.6);
}
#sound-board input[type="range"]::-moz-range-thumb {
  width: 26px; height: 26px; border-radius: 50%;
  background: radial-gradient(circle at 50% 30%, #e0ac53, #a06f27 62%, #5e3f16);
  border: 1px solid rgba(255, 236, 196, 0.45);
  box-shadow: inset 0 1px 0 rgba(255, 246, 218, 0.65), 0 2px 7px rgba(0, 0, 0, 0.6);
}
/* Keyboard focus has to be visible on a control with no border of its own. */
#sound-board input[type="range"]:focus { outline: none; }
#sound-board input[type="range"]:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px rgba(53, 224, 255, 0.6), 0 2px 7px rgba(0, 0, 0, 0.6);
}
#sound-board input[type="range"]:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 3px rgba(53, 224, 255, 0.6), 0 2px 7px rgba(0, 0, 0, 0.6);
}
/* Short viewports are the real constraint, not narrow ones: the board shares
   the title screen with the logo, START RUN and the armoury. Tighten it rather
   than let the screen start scrolling. */
@media (max-width: 480px) {
  #sound-board { padding: 11px 13px 12px; }
}
@media (max-height: 640px) {
  #sound-board { gap: 8px; padding: 9px 13px 10px; }
  .board-cap { display: none; }   /* the labels already say what this is */
  #sound-board input[type="range"] { height: 30px; }
}

/* ---- v1.7 the corner plates: the title screen's top right ----
   Two more of the HUD's brass pushbuttons, deliberately built from the same
   recipe the HUD's own pushbuttons used rather than a soft glass pill
   borrowed off another game in the arcade: MAXGEAR's answer to "a small round
   control" already exists, and a player who has learnt it mid-run should not
   have to learn a second one on the menu. index.html says why the pair is on
   the title screen and on no other.
   42px, so a thumb on a tablet has somewhere to land, and both insets are
   respected so the pair clears a notch on a phone held either way up. */
#corner-tools {
  /* FIXED, and a sibling of the screens rather than a child of one, because
     this pair never goes anywhere: same two plates in the same place on the
     title, in the slot list, on the armoury, mid-run and on the pause menu.
     `absolute` inside #screen-title is what used to make them a title-screen
     ornament that vanished the moment you went anywhere. */
  position: fixed;
  /* Level with the HUD's top row, not below it. It used to sit 38px down,
     which put it across the bottom of the score plate and the right end of the
     progress rail — the row starts at 10px, so anything lower than that lands
     ON it. Aligned here, the two are one band: readouts running left to right,
     then the three plates, and #hud-top's padding-right below keeps the gap
     between them honest. */
  top: calc(var(--safe-t) + var(--corner-inset) - 2px);
  right: calc(var(--corner-inset) + var(--safe-r));
  display: flex;
  gap: var(--corner-gap);
  /* Above the screens (10) AND above the HUD's plates (20): these outlive
     both, so nothing either of them does may cover them. */
  z-index: 30;
}
/* THE `hidden` ATTRIBUTE HAS TO WIN HERE, AND ON ITS OWN IT DOES NOT: the UA
   sheet's `[hidden] { display: none }` is a type-less rule and .corner-btn sets
   `display: flex`, which outranks it. Without this line the fullscreen plate
   would be visible on an iPhone — the one browser the attribute exists to hide
   it from — and pressing it would do precisely nothing. */
#corner-tools .corner-btn[hidden] { display: none; }

/* THE OPENING STING. js/intro.js's canvas, which the script creates and
   removes. Above everything, the corner plates included, because for its
   three seconds it is a curtain over the whole page; a tap anywhere on it
   skips, and touch-action keeps that tap from becoming a scroll or a zoom.
   Reduced motion never creates it at all. */
#intro {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 50;
  touch-action: none;
  cursor: pointer;
}

/* ---- The title's one column ----
   A single implicit grid column, so every cell comes out as wide as the widest
   of them and the stack lines up without anybody maintaining a magic width
   against the longest label. START RUN, THE ARMOURY, the controls line and the
   way out used to size themselves to their own text, which read as four
   unrelated things stacked up rather than one menu.
   The container is a flex item in a centred column, so it is still only as
   wide as its own widest child — this aligns the stack, it does not stretch
   it across the screen. */
.title-actions {
  display: grid;
  gap: 12px;
  justify-items: stretch;
  max-width: 92vw;
}

.corner-btn {
  width: var(--corner-plate); height: var(--corner-plate); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  background: radial-gradient(circle at 50% 30%, #e0ac53, #a06f27 62%, #5e3f16);
  border: 1px solid rgba(255, 236, 196, 0.4);
  color: #2a1c06;      /* the engraving is dark ink cut into the brass */
  box-shadow:
    inset 0 1px 0 rgba(255, 246, 218, 0.65),
    inset 0 -3px 6px rgba(70, 44, 12, 0.6),
    0 2px 7px rgba(0, 0, 0, 0.6);
  cursor: pointer;
}
.corner-btn:active {
  transform: scale(0.92);
  background: radial-gradient(circle at 50% 30%, #b8873c, #7a5219 65%, #472f10);
}
/* Stroked and never filled, so one `currentColor` drives the whole glyph. */
.corner-btn svg { display: block; width: 21px; height: 21px; }
.corner-btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

/* One <svg> carries BOTH states of the fullscreen plate — four corners pushing
   out, and the same four pulled in — and aria-pressed chooses. js/screen.js
   writes that attribute and the accessible label from one paint(), so what is
   engraved and what is announced cannot drift apart. */
#btn-screen .ico-in { display: none; }
#btn-screen[aria-pressed="true"] .ico-out { display: none; }
#btn-screen[aria-pressed="true"] .ico-in { display: inline; }

/* The mute plate works the same way: one <svg> carrying a speaker, its waves
   and a slash, with aria-pressed choosing. ui.setMuted() writes that attribute
   and the accessible label together, so what is engraved and what is announced
   cannot drift — which an emoji swapped into textContent could not manage
   either way round, since no screen reader announces 🔇 as "muted". */
#btn-mute .ico-slash { display: none; }
#btn-mute[aria-pressed="true"] .ico-waves { display: none; }
#btn-mute[aria-pressed="true"] .ico-slash { display: inline; }

/* The cap names the two dials, and it always shows now. It used to be hidden
   while the board stood on its own SOUND BOARD screen, where the <h2> said the
   same two words forty pixels higher; that screen is gone — the board lives in
   the one menu panel whose heading says PAUSED or SETTINGS, and neither of
   those is a word for a mixer. */

/* ---- End screens: brass-framed cards ---- */
.end-card {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  width: min(96vw, 540px);
  padding: 22px 18px;
  border-radius: 12px;
  /* The card is the screen's only child, so auto margins centre it exactly
     as the screen's justify-content does — and unlike that, they collapse to
     zero when the card is taller than the screen, so it scrolls from the top
     instead of losing its heading above the fold. Works in every browser,
     which the `safe center` on .screen does not yet. */
  margin: auto 0;
}
.end-card.party {
  background:
    linear-gradient(180deg, rgba(240, 180, 41, 0.16), rgba(24, 18, 12, 0.42) 62%),
    radial-gradient(ellipse at 50% 0%, rgba(255, 232, 168, 0.14), rgba(14, 11, 8, 0.2) 70%);
  border: 1px solid rgba(226, 178, 74, 0.7);
  box-shadow:
    0 0 60px rgba(240, 180, 41, 0.16) inset,
    inset 0 1px 0 rgba(255, 244, 214, 0.35),
    0 10px 34px rgba(0, 0, 0, 0.5);
  animation: winIn 0.55s cubic-bezier(0.15, 1.4, 0.35, 1) both;
}
/* brass flecks / confetti twinkle over the polished plate */
.end-card.party::before {
  content: '';
  position: absolute; inset: 0; border-radius: 12px; pointer-events: none;
  background:
    radial-gradient(circle at 10% 16%, rgba(255, 232, 168, 0.9) 0 2px, transparent 2.6px),
    radial-gradient(circle at 88% 12%, rgba(240, 180, 41, 0.75) 0 1.8px, transparent 2.4px),
    radial-gradient(circle at 24% 78%, rgba(255, 209, 102, 0.8) 0 1.6px, transparent 2.2px),
    radial-gradient(circle at 72% 86%, rgba(255, 232, 168, 0.75) 0 2px, transparent 2.6px),
    radial-gradient(circle at 50% 5%, rgba(255, 252, 238, 0.8) 0 1.4px, transparent 2px),
    radial-gradient(circle at 6% 52%, rgba(240, 180, 41, 0.7) 0 1.6px, transparent 2.2px),
    radial-gradient(circle at 95% 58%, rgba(240, 180, 41, 0.7) 0 1.6px, transparent 2.2px),
    radial-gradient(circle at 38% 33%, rgba(255, 232, 168, 0.5) 0 1.2px, transparent 1.8px),
    radial-gradient(circle at 64% 67%, rgba(255, 232, 168, 0.55) 0 1.2px, transparent 1.8px);
  animation: fleck 2.8s ease-in-out infinite;
}
@keyframes fleck { 0%, 100% { opacity: 0.6; } 50% { opacity: 1; } }
/* Headings in brass/soot, not gate colors: win/lose mood comes from the card
   chrome (polished brass vs rust), so the big text stays in the metal palette */
.end-card.party h2 {
  color: var(--brass-hi);
  background: linear-gradient(180deg, #fff3d6, #f0b429 55%, #9c7327);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow: none;
  filter: drop-shadow(0 0 18px rgba(240, 180, 41, 0.55)) drop-shadow(0 2px 0 rgba(0, 0, 0, 0.5));
  animation: winTitle 1.6s ease-in-out infinite;
}
@supports not (background-clip: text) {
  .end-card.party h2 { color: var(--brass-lt); }
}
.end-card.somber {
  background:
    linear-gradient(180deg, rgba(64, 28, 18, 0.42), rgba(10, 8, 6, 0.18)),
    radial-gradient(ellipse at 50% 0%, rgba(138, 51, 36, 0.24), rgba(8, 6, 5, 0.12) 72%);
  border: 1px solid rgba(138, 51, 36, 0.6);
  box-shadow: inset 0 0 70px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(180, 120, 80, 0.14);
  animation: loseIn 0.9s ease-out both;
}
.end-card.somber h2 {
  color: #cbb8a4; /* cold ash, rust-lit from the card behind it */
  text-shadow: 0 0 22px rgba(138, 51, 36, 0.6), 0 2px 0 rgba(0, 0, 0, 0.6);
  opacity: 0.92;
}
@keyframes winIn {
  0% { opacity: 0; transform: scale(0.82) translateY(24px); }
  100% { opacity: 1; transform: none; }
}
@keyframes winTitle {
  /* filter is not additive: the drop-shadow glow must live inside the keyframes
     or the brightness pulse would strip it for the animation's whole lifetime */
  0%, 100% {
    transform: scale(1);
    filter: drop-shadow(0 0 14px rgba(240, 180, 41, 0.45)) drop-shadow(0 2px 0 rgba(0, 0, 0, 0.5)) brightness(1);
  }
  50% {
    transform: scale(1.035);
    filter: drop-shadow(0 0 24px rgba(240, 180, 41, 0.7)) drop-shadow(0 2px 0 rgba(0, 0, 0, 0.5)) brightness(1.2);
  }
}
@keyframes loseIn {
  0% { opacity: 0; transform: translateY(-14px); filter: blur(7px) saturate(0.3); }
  100% { opacity: 1; transform: none; filter: blur(0) saturate(1); }
}

#screen-victory {
  background:
    radial-gradient(ellipse at 50% 38%, rgba(150, 106, 34, 0.5), rgba(12, 10, 7, 0.94) 68%),
    linear-gradient(180deg, #241a12, #0c0906);
}
#screen-defeat {
  background:
    radial-gradient(ellipse at 50% 42%, rgba(74, 30, 20, 0.72), rgba(7, 6, 5, 0.96) 70%),
    linear-gradient(180deg, #16100d, #070605);
}

.end-stats {
  display: flex; justify-content: center; gap: 10px; flex-wrap: wrap;
  font-size: 16px; line-height: 1.4;
}
.end-stats div {
  min-width: 88px;
  padding: 8px 12px; border-radius: 7px;
  background: var(--plate);
  border: 1px solid var(--rim);
  box-shadow: var(--sheen), 0 2px 7px rgba(0, 0, 0, 0.45);
}
.end-stats b {
  display: block; font-size: 24px; font-weight: 900;
  font-variant-numeric: tabular-nums;
  color: #f8ecd2;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.6);
}
.end-stats span {
  font-family: var(--font-display);
  font-size: 9px; letter-spacing: 2px; color: rgba(226, 197, 140, 0.85);
}

/* Full width so the rows below have something real to be a percentage OF:
   nested shrink-to-fit columns would make `max-width: 100%` resolve to the
   content's own width, which caps nothing. */
.build { display: flex; flex-direction: column; align-items: center; gap: 7px; width: 100%; }
.build-cap {
  font-family: var(--font-display);
  font-size: 9px; letter-spacing: 3px; font-weight: 800;
  color: rgba(226, 197, 140, 0.7);
}
.build-row {
  /* TWO COLUMNS FOR THE WHOLE BLOCK: captions in the first, chips in the
     second. Each group used to be a full-width flex row centring its own
     caption and chips, so CORE, OFFENSE and DEFENCE each found their own
     centre and the three came out starting at three different x — a stack of
     rows that are plainly one table, laid out as if they were unrelated.
     `display: contents` on the groups is what lets all three share these two
     columns; the grid is centred as a whole, so the block still sits in the
     middle of the card. */
  display: grid;
  /* The caption column takes what it needs; the chips column takes the rest
     AND IS ALLOWED TO BE SMALLER THAN ITS CONTENT — that is what `minmax(0,
     1fr)` buys over a second `max-content`, which sizes to the longest run of
     chips and then cheerfully overflows the card carrying it. OFFENSE with
     three tracks was doing exactly that: wider than CORE, and out through the
     right edge of the panel. Bounded, the run wraps inside its column instead.
     `max-width: 100%` rather than a pixel cap, so the block follows the card
     it is in — 540px normally, 760px on a wide short screen — without a number
     here that has to be kept in step with one over there. It is a max and not
     a width so the table stays tight and centred while it fits, and only
     spreads to the full card when a row has grown too long for that. */
  max-width: 100%;
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: center;
  gap: 7px 10px;
}
.build-row .grp-chips {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
}
.build-row i {
  font-style: normal;
  font-size: 12px; font-weight: 800; letter-spacing: 0.3px;
  padding: 4px 10px; border-radius: 6px;
  background: var(--plate);
  border: 1px solid var(--rim);
  color: #efe2c6;
  box-shadow: var(--sheen);
  display: inline-flex; align-items: center; gap: 5px;
}
.build-row i.up { color: #c9e8cf; border-color: rgba(86, 176, 108, 0.55); background: rgba(86, 176, 108, 0.12); }
.build-row i em { font-style: normal; opacity: 0.6; font-weight: 700; font-size: 10px; }
/* The group is a bracket in the markup and nothing in the layout: `contents`
   hands its caption and its chip run straight to the grid above, so all three
   groups fill the same two columns instead of each being its own centred row.
   It is also why this element may never carry a background, a border or a
   padding of its own — `contents` would throw them away. */
.build-row .build-grp { display: contents; }
.grp-cap {
  /* Right-aligned so the captions end on one edge and the chips begin on the
     next, which is what makes the three rows read as one table. */
  text-align: right;
  font-family: var(--font-display);
  font-size: 8.5px; letter-spacing: 2.4px; font-weight: 800;
  color: rgba(226, 197, 140, 0.62);
}

/* ================= Responsive ================= */
/* Short viewports / landscape phones: tighten everything vertically */
@media (max-height: 560px) {
  .screen { gap: 10px; justify-content: center; }
  .screen h1 { font-size: clamp(30px, 7.5vh, 54px); letter-spacing: 4px; }
  .screen h2 { font-size: clamp(22px, 6.5vh, 40px); }
  #menu-title, #screen-powers h2 { font-size: min(clamp(22px, 6.5vh, 40px), 6.2vw); }
  .tagline { display: none; }
  .logo-rule { width: min(50vw, 260px); }
  .logo-rule::before { width: 17px; height: 17px; margin: -8.5px 0 0 -8.5px; }
  .big-btn { min-height: 44px; padding: 11px 32px; font-size: 17px; }
  .end-card { gap: 10px; padding: 12px; }
  .end-stats b { font-size: 19px; }
  .end-stats div { min-width: 72px; padding: 5px 9px; }
  .hint { font-size: 10px; }
  /* keep the gearworks from crowding a short panel */
  #screen-title::before { width: 190px; height: 190px; left: -60px; top: -50px; }
  #screen-title::after { width: 230px; height: 230px; right: -70px; }
}

@media (max-width: 600px) {
  /* Smaller plates buy the row back the width they were costing it: the
     reservation above is derived from these, so there is one number to change
     and it is here. */
  :root { --corner-plate: 36px; --corner-gap: 7px; --corner-inset: 10px; }
  .corner-btn svg { width: 18px; height: 18px; }
  #hp-wrap { width: 92px; }
  /* The rail absorbs whatever is left once the plates, the bar and the score
     have taken theirs, so from here down it has to be allowed to get genuinely
     short rather than forcing the row to overflow. At 400px — the worst case
     in this band — it comes out at about 60. */
  #progress-wrap { min-width: 44px; }
  #upgrade-toast { font-size: 16px; padding: 8px 18px; }
  #boss-wrap { width: 84vw; }
}

/* Small phones. The breakpoint moved from 380 to 420 in v1.9.1: with the
   corner reserved out of #hud-top, a 400px phone was 5px short of fitting the
   bar, the rail and the score beside the plates, and 380 let it fall through
   to the wider numbers. Checked by arithmetic at 601, 600, 420, 400, 360. */
@media (max-width: 420px) {
  :root { --corner-plate: 34px; --corner-gap: 6px; --corner-inset: 8px; }
  .corner-btn svg { width: 17px; height: 17px; }
  /* padding-right is NOT overridden here: it is the corner reservation and it
     has already shrunk with the plates above. Only the left gutter and the gap
     between the readouts give way. */
  #hud-top { gap: 8px; padding-left: calc(9px + var(--safe-l)); }

  #hp-wrap { width: 92px; height: 17px; }
  #hp-text { font-size: 10px; line-height: 17px; }
  #score { font-size: 17px; }
  #score-wrap { min-width: 54px; padding: 1px 7px 2px; }
  .hud-label { font-size: 8px; letter-spacing: 1px; }
  #act-label { font-size: 9px; letter-spacing: 2px; padding: 3px 10px; max-width: 44vw; }
  #boss-wrap { top: calc(var(--safe-t) + 82px); }
  #boss-name { font-size: 11px; letter-spacing: 2px; }
  #progress-marker { width: 13px; height: 13px; top: 4px; }
  /* small phones: ui.js also drops to 5 track chips */
  .chip-ico { width: 11px; height: 11px; }
  .pips { gap: 1.5px; }
  .pip { width: 4px; height: 4px; }
  .build-row .pip { width: 5px; height: 5px; }
  #upgrade-toast { font-size: 15px; padding: 6px 14px; }
  .big-btn { padding: 13px 30px; font-size: 17px; letter-spacing: 1px; }
  .end-stats { gap: 7px; }
  .end-stats div { min-width: 74px; padding: 6px 9px; }
  .end-stats b { font-size: 20px; }
  .build-row i { font-size: 11px; padding: 3px 8px; }
  #screen-title::before { width: 200px; height: 200px; }
  #screen-title::after { width: 240px; height: 240px; right: -80px; }
}

/* The narrowest phones still in the wild. Everything above fits a
   360 comfortably and runs about 5px short between 341 and 350, so this band buys that back from
   the three things that can spare it: the bar, the rail and the score plate.
   Nothing here touches the plates — a finger is still the pointer. */
@media (max-width: 350px) {
  #hp-wrap { width: 80px; }
  #hud-top { gap: 6px; }
  #progress-wrap { min-width: 36px; }
  #score-wrap { min-width: 48px; padding: 1px 6px 2px; }
}

/* Landscape phones: keep HUD out of the notch and the toast higher */
@media (orientation: landscape) and (max-height: 480px) {
  #upgrade-toast { top: 14%; }
  #boss-wrap { top: calc(var(--safe-t) + 60px); width: min(60vw, 420px); }
  #act-label { top: calc(var(--safe-t) + 36px); }
}

/* ================= Landscape phones: the menus turn sideways =================
   A phone on its side is 300–430px tall, and a browser toolbar can take fifty
   of those. Every menu here was laid out as one column, and the column that
   fits a portrait phone with room to spare runs to ~450px sideways — so the
   title scrolled, the armoury's detail pane and BACK button hung below the
   fold, and the pause menu did the same. What a sideways phone has instead is
   width, so each screen becomes a grid that spends it: menu beside sound
   board, heading beside back button, card grid beside detail pane. The grids
   are laid over the existing markup by area — nothing moves in index.html, so
   portrait is untouched and ui.js keeps moving the one sound board between
   the two menus as before. Tablets are taller than 500px both ways and keep
   the stacked layout; so does a desktop window until it is squashed flat. */
@media (orientation: landscape) and (max-height: 500px) {
  /* ---- Title: the plaque left, everything you can press right ----
     Until v1.8 the right column was the sound board and the whole menu ran
     down the left. The board is behind a door now, so the column it used to
     fill is free and the buttons move into it — which is the better split
     anyway: sideways this screen is a brass plaque beside a row of controls,
     and the stack that used to run off the bottom is now two short columns
     neither of which does. The logo spans, because it is one object. */
  #screen-title {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "logo   start"
      "logo   powers"
      "logo   update"
      "logo   hint"
      "logo   exit";
    align-content: center;
    align-content: safe center;
    align-items: center;
    justify-items: center;
    gap: 8px 28px;
  }
  #screen-title .logo { grid-area: logo; }
  /* The portrait stack's wrapper gets out of the way entirely. `display:
     contents` hands its four children straight back to #screen-title, so
     every grid-area below addresses the button itself exactly as it did
     before the wrapper existed and this whole block needed no other change.
     It is also why the wrapper may never carry a border, a background or a
     padding of its own — `contents` would throw them away. */
  .title-actions { display: contents; }
  #btn-start { grid-area: start; }
  #btn-powers { grid-area: powers; }
  #btn-update { grid-area: update; }
  #screen-title .hint { grid-area: hint; }
  #btn-exit-title { grid-area: exit; margin-top: 6px; }
  /* The column keeps the portrait stack's one width: without the wrapper's
     grid every button would shrink to its own words and centre itself, which
     is the three-widths stack v1.8.1 got rid of, come back sideways. */
  #btn-start, #btn-powers, #btn-update, #btn-exit-title { width: min(100%, 330px); }
  /* THE CORNER PLATES STAY IN THE CORNER SIDEWAYS TOO. They used to become a
     grid cell of their own here, which fitted the layout and broke the rule:
     the pair must be in the same place on every screen and in every
     orientation, or it is not a corner, it is a menu item that moves. So they
     stay fixed, and every screen buys them the room instead — the padding-top
     below is what keeps a centred column from running underneath them. That
     costs about the same height the tools row used to, and it costs it on
     every screen rather than on the title alone, which is the honest price of
     a control that is always there. */
  /* Thirty-eight, and no lower: this query only ever fires on a phone, where
     the pointer is still a finger. Set as tokens rather than as widths, so the
     HUD row's reservation and the padding below both follow on their own. */
  :root { --corner-plate: 38px; --corner-gap: 6px; --corner-inset: 8px; }
  .corner-btn svg { width: 19px; height: 19px; }
  /* The inset, the plate and a little air. Every screen, because the plates
     are on every screen. */
  .screen {
    padding-top: calc(var(--corner-inset) + var(--corner-plate) + 8px + var(--safe-t));
  }
  .logo-rule { width: min(40vw, 260px); }

  /* ---- The menu: words left, the board right ----
     One block now, where there used to be two nearly identical ones — a
     #screen-sound grid and a #screen-pause grid, same two columns, same board
     in the same place. The two screens are one screen, so this is one grid.

     The board is the tallest thing here by a factor of three, so standing the
     words beside it rather than above it is what keeps the last row on screen
     on a 300px phone. Every row keeps an area even though RESUME, QUIT and
     CLOSE are each hidden half the time: a menu element without one lands in
     an auto row the moment somebody shows it again, which is the rule this
     whole block exists to serve. */
  #screen-pause {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    grid-template-areas:
      "h2     board"
      "resume board"
      "quit   board"
      "close  board"
      "exit   board";
    align-content: center;
    align-content: safe center;
    align-items: center;
    justify-items: center;
    gap: 10px 28px;
  }
  /* Half a sideways phone is ~240px; INNSTILLINGER at the short-screen h2
     size is ~255. 3.2vw keeps it inside its column from 568px up. */
  #screen-pause h2 { grid-area: h2; }
  #menu-title { font-size: min(clamp(22px, 6.5vh, 40px), 3.2vw); letter-spacing: 2.5px; }
  #btn-resume { grid-area: resume; }
  #btn-quit { grid-area: quit; }
  #btn-menu-close { grid-area: close; }
  #btn-exit-pause { grid-area: exit; margin-top: 6px; }
  #btn-resume, #btn-quit, #btn-menu-close, #btn-exit-pause { width: min(100%, 300px); }
  #screen-pause #sound-board { grid-area: board; width: min(100%, 380px); }
  /* The language row made the board ~50px taller, which a sideways phone
     does not have. It is bought back by standing MUSIC and EFFECTS side by
     side — neonfox's fix for the same problem — so the plate is no taller
     than it was before the row arrived. The captions shrink a little to
     share a half-width cell with their readouts; the sliders are still
     36px-tall touch targets. Everything else on the plate spans both
     columns. */
  #sound-board {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 8px 14px;
  }
  .board-cap, .board-lang { grid-column: 1 / -1; }
  #sound-board .dial-head { gap: 6px; }
  #sound-board .dial-row .dial-label { font-size: 12px; letter-spacing: 0.8px; }

  /* ---- Armoury: heading and BACK share the top row; below it the card grid
     and the detail pane split the width and take ALL the remaining height,
     scrolling inside their own boxes rather than growing the page ---- */
  #screen-powers {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas:
      "head back"
      "pick pick";
    align-items: center;
    gap: 8px 16px;
  }
  #screen-powers h2 { grid-area: head; text-align: left; }
  #btn-powers-back { grid-area: back; }
  #pw-pick {
    grid-area: pick;
    align-self: stretch; justify-self: stretch;
    width: auto; min-height: 0;
    grid-template-columns: minmax(0, 1fr) minmax(220px, 0.55fr);
    grid-template-rows: minmax(0, 1fr);
    align-items: stretch;
  }
  #pw-grid {
    max-height: none; min-height: 0;   /* the row is the limit now */
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  }
  #pw-detail { min-height: 0; overflow-y: auto; gap: 6px; }
  /* the vignette keeps the room it can get; previews.js reads the canvas's
     CSS size when it starts, and ui.js restarts it when the phone turns */
  #pw-preview, #lc-preview { flex: 0 0 auto; height: clamp(56px, 24vh, 132px); }
  #pw-detail p, #lc-detail p { font-size: 11px; }
  .keep-card { padding: 7px 5px 6px; gap: 4px; }

  /* ---- Level clear: the KEEP card fills the screen. #lc-pick dissolves so
     its grid and detail pane become cells of the card's own grid: everything
     about the level on the left, the pane the player is reading on the right
     with CONTINUE under it ---- */
  .lc-card {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(220px, 1fr);
    grid-template-rows: auto auto auto minmax(0, 1fr) auto;
    grid-template-areas:
      "head  detail"
      "stats detail"
      "note  detail"
      "grid  detail"
      "saved go";
    width: 100%; height: 100%;
    padding: 10px 12px;
    gap: 8px 14px;
    align-items: center; justify-items: center;
  }
  #lc-heading { grid-area: head; }
  #lc-stats { grid-area: stats; }
  #lc-note { grid-area: note; font-size: 12px; }
  #lc-pick { display: contents; }
  #lc-grid {
    grid-area: grid;
    align-self: stretch; justify-self: stretch;
    max-height: none; min-height: 0;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  }
  #lc-detail {
    grid-area: detail;
    align-self: stretch; justify-self: stretch;
    min-height: 0; overflow-y: auto; gap: 6px;
  }
  #lc-saved { grid-area: saved; }
  #btn-continue { grid-area: go; }

  /* ---- End cards: wider, and the build's three groups flow on one line
     instead of each taking a row of their own ---- */
  .end-card:not(.lc-card) { width: min(96vw, 760px); padding: 12px 16px; gap: 8px; }
  .build-row { max-width: none; }
  /* (the landscape pass no longer has anything to say about the groups: they
     are `display: contents` and the two columns above hold in every size) */
  /* stat plates read as one line, "1234 SCORE", instead of a two-storey tile */
  .end-stats div { display: flex; align-items: baseline; gap: 6px; padding: 4px 10px; min-width: 0; }
  .end-stats b { font-size: 16px; }

  /* ---- Save slots and difficulties: three cards in a row ---- */
  #slot-list, #diff-list {
    flex-direction: row; align-items: stretch;
    width: min(94vw, 760px);
  }
  #slot-list .pick-card, #diff-list .pick-card { flex: 1 1 0; min-width: 0; }
  #slot-list .pick-card { padding-right: 46px; } /* room for the ✕ */
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  /* these rely on animations for their resting state — keep them readable */
  #upgrade-toast { animation: none !important; opacity: 1; }
  #screen-title h1 .accent { -webkit-text-fill-color: var(--brass-lt); }
  /* gears / cogs: no rotation at all, just sit still in their brass frames */
  #screen-title::before, #screen-title::after,
  .logo-rule::before, #progress-marker { animation: none !important; }
  .end-card.party::before { animation: none !important; opacity: 0.8; }
}
