:root {
  --bg: #0d0f0b;
  --panel: rgba(16, 19, 13, 0.82);
  --panel-solid: #161a12;
  --panel-2: #1f2519;
  --line: #3a4230;
  --line-2: #4d5841;
  --text: #ece8dc;
  --muted: #a9ad98;
  --dim: #7d826c;
  --accent: #f2b33d;
  --accent-2: #ff8a3a;
  --bad: #e5483b;
  --good: #8ad46b;
  --cash: #9fe07a;
  --blue: #4fa3ff;
  --radius: 10px;
  --header-h: 48px;
  --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);
  --t-min: 14px;
  color-scheme: dark;
}

@media (pointer: coarse) {
  :root {
    --t-min: 15px;
  }
}

@media (pointer: coarse) and (max-width: 599px), (pointer: coarse) and (max-height: 599px) {
  :root {
    --t-min: 13px;
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Ubuntu, sans-serif;
  -webkit-text-size-adjust: 100%;
}

a {
  color: var(--accent);
}

button,
input {
  font: inherit;
  color: inherit;
}

button {
  touch-action: manipulation;
  cursor: pointer;
}

[hidden] {
  display: none !important;
}

.page {
  padding: 8px 8px 40px;
}

/* ---------- The game's frame ---------- */

.game-root {
  position: relative;
  margin: 0 auto;
  width: 100%;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  background: #070806;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
}

.stage {
  position: relative;
  width: 100%;
  height: calc(100vh - var(--header-h) - 18px);
  height: calc(100dvh - var(--header-h) - 18px);
  min-height: min(420px, calc(100vh - var(--header-h)));
  min-height: min(420px, calc(100dvh - var(--header-h)));
  /* Safe areas inside the stage, and how far the HUD keeps from its edges. */
  --in-t: 0px;
  --in-r: var(--safe-r);
  --in-b: var(--safe-b);
  --in-l: var(--safe-l);
  --gap: 10px;
  --tap: 10px;
  --corner: 0px;
  --side-l: max(var(--corner), calc(var(--in-l) + var(--gap)));
  --side-r: max(var(--corner), calc(var(--in-r) + var(--gap)));
  --top: calc(var(--in-t) + var(--gap));
  --bottom: calc(var(--in-b) + var(--gap));
  --exit-bottom: calc(max(8px, var(--safe-t)) + 44px);
}

@media (pointer: coarse) {
  .stage {
    --tap: 16px;
  }
}

@media (pointer: coarse) and (max-width: 599px), (pointer: coarse) and (max-height: 599px) {
  .stage {
    --gap: 8px;
    --corner: 24px;
  }
}

/* Phones: the stage takes the screen under the header. */
@media (max-width: 700px), (max-height: 500px) {
  .page {
    padding: 0 0 40px;
  }
  .game-root {
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }
  .stage {
    height: calc(100vh - var(--header-h));
    height: calc(100dvh - var(--header-h));
    max-height: none;
    /* Never taller than the screen under the header (Round 4: a 320 px phone held sideways had the
       weapon panel cut off below the screen). */
    min-height: min(300px, calc(100vh - var(--header-h)));
    min-height: min(300px, calc(100dvh - var(--header-h)));
  }
}

/* Full screen (the site's button; main.js sets .full): edge to edge, the HUD
   inside the safe areas, and "Leave full screen" at the top in the middle. */
.game-root.full {
  border: 0;
  border-radius: 0;
  max-width: none;
}

.game-root.full .stage {
  height: 100%;
  min-height: 0;
  max-height: none;
  --in-t: var(--safe-t);
}

.stage canvas#game {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  cursor: crosshair;
}

html.in-run,
html.in-run .stage,
html.in-run .stage * {
  touch-action: none;
}

html.in-run {
  overscroll-behavior: none;
}

/* What scrolls in a run (the shop's list and tabs, the menus over the game) keeps its pan, down to the
   cards and buttons in it (Matt, Oct 15: the shop wouldn't scroll on his phone). A touch's allowed
   gestures are those of the element under the finger and every ancestor up to the scroller, so a card
   left at none (the rule above) stopped the list's own pan-y. */
html.in-run .stage .shop-body,
html.in-run .stage .shop-body *,
html.in-run .stage .overlay,
html.in-run .stage .overlay * {
  touch-action: pan-y;
}

html.in-run .stage .shop-tabs,
html.in-run .stage .shop-tabs * {
  touch-action: pan-x;
}

/* ---------- HUD ---------- */

.hud {
  position: absolute;
  inset: 0;
  pointer-events: none;
  font-size: max(14px, var(--t-min));
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

.hud button {
  pointer-events: auto;
}

.panel {
  background: var(--panel);
  border: 1px solid rgba(160, 175, 120, 0.18);
  border-radius: 10px;
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}

.hud-tl {
  position: absolute;
  left: var(--side-l);
  top: var(--top);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  max-width: calc(50% - 40px);
}

.wave-box {
  padding: 5px 12px 6px;
  min-width: 120px;
}

.wave-n {
  font-size: 22px;
  font-weight: 900;
  letter-spacing: 1px;
  text-transform: uppercase;
  line-height: 1.1;
  color: #fff3d6;
}

.wave-sub {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.wave-sub b {
  color: var(--text);
}

.wave-sub .urgent {
  color: var(--accent);
}

/* The bosses on the field (Round 3: their health here, not a bar floating over them). */
.wave-boss {
  display: grid;
  gap: 2px;
  margin-top: 4px;
  font-size: max(11px, var(--t-min, 11px));
  color: var(--muted);
}

.wave-boss span {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.wave-boss i {
  display: block;
  height: 5px;
  min-width: 48px;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 3px;
  overflow: hidden;
}

.wave-boss i b {
  display: block;
  height: 100%;
  background: #e5483b;
}

/* His own reload, revive, repair or crate: a bar along the weapon panel's top edge (not a ring round him). */
.hud-br .act {
  position: absolute;
  left: 8px;
  right: 8px;
  top: 3px;
  height: 4px;
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.45);
  overflow: hidden;
  pointer-events: none;
}

.hud-br .act i {
  display: block;
  height: 100%;
  width: 0;
  background: #f2d27a;
}

.hud-br .act.revive i {
  background: #8ad46b;
}

.hud-br .act.repair i,
.hud-br .act.crate i {
  background: #f2b33d;
}

.btn {
  min-height: 44px;
  min-width: 44px;
  padding: 10px 18px;
  border-radius: 10px;
  border: 1px solid var(--line-2);
  background: var(--panel-2);
  font-weight: 800;
  letter-spacing: 0.4px;
  color: var(--text);
}

.btn:hover {
  border-color: var(--accent);
}

.btn:focus-visible,
.icon-btn:focus-visible,
.tbtn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.btn-primary {
  background: linear-gradient(#f4bb4a, #d8952a);
  border-color: #f6c867;
  color: #1a1407;
  text-shadow: none;
}

.btn-primary:hover {
  border-color: #fff0c8;
}

.btn-ready {
  background: linear-gradient(#5d7a31, #435a21);
  border-color: #8fb14f;
  color: #f4ffe0;
}

.btn-ready.on {
  background: linear-gradient(#2c3a18, #232e13);
  color: var(--good);
}

.btn[disabled] {
  opacity: 0.45;
  cursor: default;
}

.team {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.team li {
  display: grid;
  grid-template-columns: 10px auto auto;
  grid-template-rows: auto 5px;
  column-gap: 6px;
  align-items: center;
  padding: 3px 8px 5px 6px;
  background: rgba(10, 12, 8, 0.6);
  border-radius: 8px;
  font-size: max(13px, var(--t-min));
}

.team .dot {
  grid-row: 1 / 3;
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.team .nm {
  white-space: nowrap;
}

.team .st {
  color: var(--muted);
  font-size: max(12px, var(--t-min));
  justify-self: end;
  white-space: nowrap;
}

.team .st.bad {
  color: var(--bad);
  font-weight: 800;
}

.team .hb {
  grid-column: 2 / 4;
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.12);
  overflow: hidden;
}

.team .hb i {
  display: block;
  height: 100%;
  background: var(--good);
}

.hud-tr {
  position: absolute;
  right: var(--side-r);
  top: var(--top);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  max-width: calc(50% - 40px);
}

.hud-tr-row {
  display: flex;
  gap: 6px;
  align-items: center;
}

.cash {
  padding: 8px 12px;
  font-size: 20px;
  font-weight: 900;
  color: var(--cash);
  font-variant-numeric: tabular-nums;
  min-height: 44px;
  display: flex;
  align-items: center;
}

.cash.bump {
  animation: bump 0.3s ease-out;
}

@keyframes bump {
  0% {
    transform: scale(1.15);
  }
  100% {
    transform: scale(1);
  }
}

.icon-btn {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid rgba(160, 175, 120, 0.25);
  background: var(--panel);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.icon-btn svg,
.tbtn svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon-btn.hot {
  border-color: var(--accent);
  color: var(--accent);
}

.feed {
  position: absolute;
  right: var(--side-r);
  top: calc(var(--top) + 54px);
  max-width: calc(50% - 40px);
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
}

.feed li {
  padding: 3px 9px;
  border-radius: 7px;
  background: rgba(10, 12, 8, 0.66);
  font-size: max(13px, var(--t-min));
  max-width: min(300px, 100%);
  text-align: right;
  animation: feedin 0.25s ease-out;
}

.feed li.bad {
  color: #ffb3a8;
}

.feed li.good {
  color: #cdf5b4;
}

.feed li.call {
  color: #ffe2a3;
}

.feed li.fade {
  opacity: 0;
  transition: opacity 0.6s;
}

@keyframes feedin {
  from {
    transform: translateX(14px);
    opacity: 0;
  }
}

.hud-bl {
  position: absolute;
  left: var(--side-l);
  bottom: var(--bottom);
  width: min(260px, 40%);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.bar {
  position: relative;
  height: 18px;
  border-radius: 5px;
  background: rgba(8, 10, 6, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.1);
  overflow: hidden;
}

.bar i {
  position: absolute;
  inset: 0 auto 0 0;
  width: 100%;
  transition: width 0.15s;
}

.bar.hp i {
  background: linear-gradient(#e2504a, #a52a24);
}

.bar.hp.low i {
  animation: pulse 0.8s infinite alternate;
}

@keyframes pulse {
  to {
    filter: brightness(1.6);
  }
}

.bar.ap i {
  background: linear-gradient(#6fa8e8, #3d6fae);
}

.bar.st {
  height: 5px;
}

.bar.st i {
  background: #e8d48a;
}

/* Winded: sprint spent while held, back only once it's let go and pressed again. */
.bar.st i.winded {
  background: #9a7f52;
}

.bar .lbl,
.bar b {
  position: relative;
  z-index: 1;
  font-size: 12px;
  line-height: 16px;
  padding: 0 6px;
}

.bar b {
  position: absolute;
  right: 0;
  top: 0;
  font-variant-numeric: tabular-nums;
}

.hud-br {
  position: absolute;
  right: var(--side-r);
  bottom: var(--bottom);
  padding: 6px 10px 8px;
  display: grid;
  grid-template-columns: auto auto;
  grid-template-rows: auto auto auto;
  column-gap: 10px;
  align-items: center;
  max-width: calc(60% - 20px);
}

#hud-gun {
  grid-row: 1 / 3;
  width: 120px;
  height: 46px;
}

.gun-name {
  font-weight: 800;
  font-size: max(13px, var(--t-min));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 170px;
}

.gun-ammo {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.gun-ammo b {
  font-size: 24px;
  color: #fff;
  margin-right: 4px;
}

.gun-ammo b.low {
  color: var(--bad);
}

.gun-ammo .rl {
  color: var(--accent);
  font-weight: 800;
}

.slots {
  grid-column: 1 / 3;
  display: flex;
  gap: 4px;
  margin-top: 4px;
}

.slot {
  pointer-events: auto;
  flex: 1;
  min-width: 44px;
  height: 30px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(0, 0, 0, 0.35);
  position: relative;
  padding: 0;
}

/* Out of the flow: a canvas's own size must not widen its slot (WebKit). */
.slot canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.slot .k {
  position: absolute;
  left: 3px;
  top: 0;
  font-size: 12px;
  color: var(--dim);
}

.slot.on {
  border-color: var(--accent);
  background: rgba(242, 179, 61, 0.14);
}

.slot.empty {
  opacity: 0.4;
}

.kit {
  grid-column: 1 / 3;
  display: flex;
  gap: 10px;
  margin-top: 4px;
  font-size: max(13px, var(--t-min));
  color: var(--muted);
}

.kit b {
  color: var(--text);
}

.banner {
  position: absolute;
  left: 50%;
  top: calc(var(--exit-bottom) + 30px);
  transform: translateX(-50%);
  text-align: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s;
  max-width: 92%;
}

.banner.show {
  opacity: 1;
}

/* The shop covers it: its news is the shop itself. */
.banner.covered {
  visibility: hidden;
}

.banner .big {
  /* Held to the screen's height too: on a phone held sideways it stays above the vitals. */
  font-size: clamp(26px, min(6vw, 8vh), 64px);
  line-height: 1.1;
  font-weight: 900;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: #fff1cf;
  text-shadow: 0 2px 0 #4a2b0c, 0 0 24px rgba(242, 140, 40, 0.55);
}

.banner .small {
  font-size: clamp(14px, min(2.2vw, 3.6vh), 20px);
  max-width: 34em;
  margin: 0 auto;
  color: #f3e4be;
  font-weight: 700;
}

/* Kept above the soldier on a short screen (ui.js placeBanner). */
.banner.tight .big {
  font-size: clamp(18px, 5vh, 30px);
  letter-spacing: 2px;
}

.banner.tight .small {
  font-size: max(12px, var(--t-min));
  max-width: 30em;
}

.banner.tighter .small {
  display: none;
}

.banner.bad .big {
  color: #ffd2c8;
  text-shadow: 0 2px 0 #4a0c0c, 0 0 24px rgba(229, 72, 59, 0.6);
}

.netbar {
  position: absolute;
  left: 50%;
  bottom: calc(var(--bottom) + 92px);
  transform: translateX(-50%);
  padding: 8px 14px;
  border-radius: 10px;
  background: rgba(60, 14, 10, 0.88);
  border: 1px solid #a3432f;
  font-weight: 700;
  white-space: nowrap;
}

.netbar.ok {
  background: rgba(20, 50, 16, 0.88);
  border-color: #5f9a3f;
}

.downcard {
  position: absolute;
  left: 50%;
  top: 58%;
  transform: translateX(-50%);
  padding: 10px 18px;
  border-radius: 12px;
  background: rgba(40, 8, 6, 0.8);
  border: 1px solid #8f2d22;
  text-align: center;
  font-weight: 700;
  max-width: 90%;
}

.downcard .ring {
  font-size: 28px;
  font-weight: 900;
  color: #ff8a7a;
}

.usebar {
  position: absolute;
  left: 50%;
  top: 62%;
  transform: translateX(-50%);
  width: min(260px, 70%);
  height: 26px;
  border-radius: 8px;
  background: rgba(8, 10, 6, 0.8);
  border: 1px solid var(--line-2);
  overflow: hidden;
  text-align: center;
  font-size: 13px;
  line-height: 24px;
  font-weight: 800;
}

.usebar i {
  position: absolute;
  inset: 0 auto 0 0;
  background: rgba(242, 179, 61, 0.5);
}

.usebar span {
  position: relative;
  z-index: 1;
}

.callouts {
  position: absolute;
  right: var(--side-r);
  top: calc(var(--top) + 54px);
  padding: 6px;
  display: grid;
  grid-template-columns: repeat(2, minmax(120px, 1fr));
  gap: 6px;
  pointer-events: auto;
  z-index: 5;
}

.callouts button {
  min-height: 44px;
  padding: 6px 10px;
  border-radius: 8px;
  border: 1px solid var(--line-2);
  background: var(--panel-2);
  text-align: left;
  font-weight: 700;
}

.callouts button kbd {
  color: var(--dim);
  margin-right: 6px;
  font-family: inherit;
}

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

.touch {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.stick {
  position: absolute;
  width: 132px;
  height: 132px;
  margin: -66px 0 0 -66px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.22);
  background: radial-gradient(circle, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.12));
  opacity: 0.55;
  transition: opacity 0.15s;
}

.stick.on {
  opacity: 0.95;
}

.stick .knob {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 58px;
  height: 58px;
  margin: -29px 0 0 -29px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.55), rgba(200, 210, 170, 0.28));
  border: 2px solid rgba(255, 255, 255, 0.5);
}

#stick-r .knob {
  background: radial-gradient(circle at 35% 30%, rgba(255, 210, 140, 0.65), rgba(220, 120, 50, 0.32));
}

#stick-r.firing .knob {
  box-shadow: 0 0 18px rgba(255, 140, 60, 0.8);
}

.tbtns {
  position: absolute;
  inset: 0;
}

.tbtn {
  position: absolute;
  pointer-events: auto;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.28);
  background: rgba(16, 19, 13, 0.62);
  color: #f4ecd8;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-weight: 800;
  font-size: 12px;
}

.tbtn.on {
  background: rgba(242, 179, 61, 0.45);
  border-color: var(--accent);
}

.tbtn-use {
  border-color: var(--accent);
  background: rgba(70, 55, 20, 0.75);
}

.tbtn .cnt {
  position: absolute;
  right: -2px;
  top: -4px;
  min-width: 20px;
  padding: 0 4px;
  border-radius: 10px;
  background: #222;
  border: 1px solid #666;
  font-size: 12px;
  line-height: 18px;
}

html:not([data-input='touch']) .touch {
  display: none !important;
}

/* Touch, held sideways (Matt, Oct 17: on his phone "the current horizontal view for phones is awful": the
   vitals and the weapon panel sat in the middle of the fight and the buttons crowded the aim stick).
   The top row carries the wave, then health and armour beside it (the wave box a fixed width, so they never
   shift as its text changes); the weapon is a low strip at the foot of the screen between the sticks, where
   no thumb rests and nothing is fought over; the middle of the screen is the soldier's. On a tall tablet
   the weapon strip keeps its row of slots. (main.js layoutTouch keeps the button arc clear of all of it.) */
html[data-input='touch'] .hud {
  --wave-w: clamp(108px, 17vw, 128px);
}

html[data-input='touch'] .wave-box {
  width: var(--wave-w);
  min-width: 0;
  padding: 3px 9px 4px;
}

html[data-input='touch'] .wave-n {
  font-size: 18px;
}

html[data-input='touch'] .wave-sub {
  font-size: max(12px, var(--t-min));
  overflow: hidden;
  text-overflow: ellipsis;
}

html[data-input='touch'] .hud-bl {
  left: calc(var(--side-l) + var(--wave-w) + 8px);
  top: var(--top);
  bottom: auto;
  width: clamp(96px, calc(50% - 40px - var(--side-l) - var(--wave-w) - 8px), 200px);
  gap: 3px;
}

html[data-input='touch'] .hud-bl .bar:not(.st) {
  height: 16px;
}

html[data-input='touch'] .hud-bl .bar .lbl,
html[data-input='touch'] .hud-bl .bar b {
  line-height: 14px;
}

html[data-input='touch'] .hud-br {
  right: auto;
  left: var(--gun-c, 50%);
  transform: translateX(-50%);
  bottom: max(6px, var(--in-b));
  padding: 3px 10px 4px;
  width: auto;
  max-width: var(--gun-max, 240px);
  grid-template-columns: auto minmax(0, auto) auto;
  grid-template-rows: auto auto;
  grid-template-areas: 'gun name ammo' 'slots slots slots';
  column-gap: 8px;
}

html[data-input='touch'] .hud-br .gun-info {
  display: contents;
}

html[data-input='touch'] .hud-br > * {
  min-width: 0;
}

html[data-input='touch'] #hud-gun {
  grid-area: gun;
  grid-row: auto;
  width: 54px;
  height: 22px;
}

html[data-input='touch'] .hud-br .gun-name {
  grid-area: name;
  max-width: none;
  font-size: max(12px, var(--t-min));
}

html[data-input='touch'] .hud-br .gun-ammo {
  grid-area: ammo;
  white-space: nowrap;
}

html[data-input='touch'] .gun-ammo b {
  font-size: 19px;
}

html[data-input='touch'] .hud-br .slots {
  grid-area: slots;
  grid-column: auto;
}

html[data-input='touch'] .hud-br .slots .slot {
  min-width: 0;
}

html[data-input='touch'] .kit {
  display: none;
}

html[data-input='touch'] .feed li {
  max-width: min(200px, 100%);
}

html[data-input='touch'] .hud-br.narrow .gun-name {
  display: none;
}

/* A phone sideways: the strip is one line (the switch button cycles the weapons, the slots go). */
@media (orientation: landscape) and (max-height: 599px) {
  html[data-input='touch'] .hud-br .slots {
    display: none;
  }
}

/* Touch, held upright: the sticks take both lower corners, so the HUD goes up
   top, compact: a narrow column down the left (the wave, the vitals, the
   weapon, Ready, the team; main.js stacks them by their measured heights) and
   the buttons in a column down the right, the middle kept clear for "Leave
   full screen" and the fight. */
@media (orientation: portrait) {
  html[data-input='touch'] .hud {
    --col: min(calc(50% - 30px - var(--side-l)), 210px);
  }
  html[data-input='touch'] .hud-tl {
    max-width: var(--col);
    gap: 6px;
  }
  html[data-input='touch'] .wave-box {
    width: auto;
    padding: 3px 9px 4px;
    min-width: 0;
  }
  html[data-input='touch'] .wave-n {
    font-size: 17px;
  }
  html[data-input='touch'] .wave-sub {
    font-size: max(12px, var(--t-min));
  }
  html[data-input='touch'] .hud-bl {
    left: var(--side-l);
    right: auto;
    top: var(--vit-top, calc(var(--top) + 52px));
    bottom: auto;
    transform: none;
    width: var(--col);
    gap: 2px;
  }
  html[data-input='touch'] .hud-br {
    left: var(--side-l);
    right: auto;
    top: var(--gun-top, calc(var(--top) + 96px));
    bottom: auto;
    transform: none;
    width: var(--col);
    max-width: none;
    padding: 3px 8px 5px;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    grid-template-areas: 'name name' 'ammo gun';
    column-gap: 6px;
  }
  html[data-input='touch'] .hud-br .gun-info {
    display: contents;
  }
  html[data-input='touch'] .hud-br .gun-name {
    grid-area: name;
  }
  html[data-input='touch'] .hud-br .gun-ammo {
    grid-area: ammo;
    white-space: nowrap;
  }
  html[data-input='touch'] .hud-br > * {
    min-width: 0;
  }
  /* The slots are on the switch button's cycle; the weapon's name never cut: it wraps. */
  html[data-input='touch'] .hud-br .slots {
    display: none;
  }
  html[data-input='touch'] #hud-gun {
    grid-area: gun;
    width: 50px;
    height: 22px;
  }
  html[data-input='touch'] .hud-br .gun-name {
    max-width: 100%;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.15;
  }
  html[data-input='touch'] .hud-br .gun-ammo b {
    font-size: 17px;
  }
  /* Ready and the team, below the weapon. */
  html[data-input='touch'] .hud-tl .btn-ready,
  html[data-input='touch'] .hud-tl .btn-ready[hidden] + .team {
    margin-top: var(--stack, 130px);
  }
  html[data-input='touch'] .hud-tl .btn-ready:not([hidden]) + .team {
    margin-top: 0;
  }
  html[data-input='touch'] .team {
    gap: 3px;
  }
  html[data-input='touch'] .team li {
    padding: 1px 7px 2px 5px;
    row-gap: 1px;
    font-size: 12px;
    line-height: 1.25;
  }
  html[data-input='touch'] .team .hb {
    height: 3px;
  }
  html[data-input='touch'] .team .st.minor {
    display: none;
  }
  /* The buttons down the right; the cash beside the menu. */
  html[data-input='touch'] .hud-tr-row {
    display: grid;
    grid-template-columns: auto 44px;
    grid-auto-rows: 44px;
    gap: 6px;
    justify-items: end;
    align-items: center;
  }
  html[data-input='touch'] #hud-cash {
    grid-column: 1;
    grid-row: 1;
    min-height: 34px;
    padding: 4px 9px;
    font-size: 16px;
  }
  html[data-input='touch'] #btn-menu {
    grid-column: 2;
    grid-row: 1;
  }
  html[data-input='touch'] #btn-shop {
    grid-column: 2;
    grid-row: 2;
  }
  html[data-input='touch'] #btn-call {
    grid-column: 2;
    grid-row: 3;
  }
  /* The feed between the columns, under "Leave full screen". */
  html[data-input='touch'] .feed {
    top: calc(var(--top) + 54px);
    left: calc(var(--side-l) + var(--col) + 8px);
    right: calc(var(--side-r) + 52px);
    max-width: none;
    align-items: center;
  }
  html[data-input='touch'] .feed li {
    text-align: center;
  }
  html[data-input='touch'] .feed li:nth-child(n + 3) {
    display: none;
  }
  html[data-input='touch'] .banner {
    top: var(--banner-top, 38%);
    max-width: calc(100% - 2 * (var(--side-r) + 64px));
  }
}

/* ---------- Shop ---------- */

.shop {
  position: absolute;
  right: var(--side-r);
  top: calc(var(--top) + 54px);
  bottom: var(--bottom);
  width: min(560px, calc(100% - 2 * var(--gap)));
  display: flex;
  flex-direction: column;
  background: rgba(13, 15, 10, 0.94);
  border: 1px solid var(--line-2);
  border-radius: 12px;
  z-index: 6;
  overflow: hidden;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
}

.shop-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
}

.shop-head h2 {
  margin: 0;
  font-size: 18px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  flex: 1;
}

.shop-head .cash {
  padding: 4px 8px;
  min-height: 0;
  font-size: 17px;
  background: none;
}

.shop-tabs {
  display: flex;
  gap: 4px;
  padding: 6px 8px;
  overflow-x: auto;
  border-bottom: 1px solid var(--line);
  scrollbar-width: none;
}

.shop-tabs button {
  flex: none;
  min-height: 44px;
  padding: 6px 12px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  font-weight: 700;
  white-space: nowrap;
}

.shop-tabs button.on {
  border-color: var(--accent);
  color: var(--accent);
}

.shop-body {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
  touch-action: pan-y;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.shop-body h3 {
  margin: 10px 2px 6px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 1.4px;
  color: var(--muted);
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 8px;
}

.card {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 8px;
  padding: 8px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: linear-gradient(#1c2216, #151a10);
  text-align: left;
  min-height: 44px;
}

.card canvas {
  grid-column: 1 / 3;
  width: 100%;
  height: 64px;
  display: block;
}

.card .nm {
  font-weight: 800;
}

.card .price {
  font-weight: 900;
  color: var(--cash);
  font-variant-numeric: tabular-nums;
}

.card .price.no {
  color: var(--bad);
}

.card .meta {
  grid-column: 1 / 3;
  font-size: 13px;
  color: var(--muted);
}

.card .stats {
  grid-column: 1 / 3;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 6px;
  font-size: 12px;
  color: var(--dim);
  align-items: center;
}

.card .stats i {
  display: block;
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}

.card .stats i b {
  display: block;
  height: 100%;
  background: var(--accent);
}

.card.owned {
  border-color: #5f7d3a;
}

.card.locked,
.card.later {
  opacity: 0.55;
}

.card:not([disabled]):hover {
  border-color: var(--accent);
}

.card .tag {
  position: absolute;
  right: 8px;
  top: 8px;
  font-size: 12px;
  font-weight: 800;
  padding: 1px 6px;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.55);
  color: var(--muted);
}

.shop-foot {
  padding: 6px 10px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 13px;
  min-height: 30px;
}

.shop-foot.bad {
  color: #ffb3a8;
}

/* Sideways on a phone the shop has little height: its tabs and its cash and Close share one row
   (the title goes), it covers the HUD's top row, and its note is one small line. */
@media (max-height: 520px) {
  .shop {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto minmax(0, 1fr) auto;
    top: var(--top);
  }
  .shop-head {
    grid-column: 2;
    grid-row: 1;
    padding: 6px 8px;
  }
  .shop-head h2 {
    display: none;
  }
  .shop-tabs {
    grid-column: 1;
    grid-row: 1;
  }
  .shop-body {
    grid-column: 1 / 3;
    grid-row: 2;
  }
  .shop-foot {
    grid-column: 1 / 3;
    grid-row: 3;
    min-height: 0;
    padding: 3px 10px;
    font-size: 12px;
  }
}

/* The weapons' filters: a row that scrolls sideways. */
.shop-filter {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 2px 0 6px;
  touch-action: pan-x;
}

.shop-filter .chip {
  flex: none;
  min-height: 44px;
  min-width: 44px;
  padding: 4px 12px;
  border-radius: 22px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
}

.shop-filter .chip.on {
  border-color: var(--accent);
  color: var(--accent);
}

html.in-run .stage .shop-filter,
html.in-run .stage .shop-filter * {
  touch-action: pan-x;
}

.card:focus-visible,
.chip:focus-visible,
.shop-tabs button:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 1px;
}

/* On a phone either way round (Matt, Oct 15): compact rows, the drawing beside the name and price,
   two lines of what it is, no bars; sideways, two or three to a row. A card is 76 px, not 550. */
@media (max-width: 640px), (max-height: 520px) {
  .shop {
    left: var(--side-l);
    right: var(--side-r);
    width: auto;
    top: calc(var(--top) + 54px);
  }
  .cards {
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 6px;
  }
  .card {
    grid-template-columns: 84px 1fr auto;
    grid-template-rows: auto auto;
    align-items: center;
    gap: 0 8px;
    padding: 6px 8px;
    min-height: 64px;
  }
  .card canvas {
    grid-column: 1;
    grid-row: 1 / 3;
    width: 84px;
    height: 40px;
  }
  .card .nm {
    grid-column: 2;
    grid-row: 1;
    font-size: 15px;
    line-height: 1.2;
  }
  .card .price {
    grid-column: 3;
    grid-row: 1;
  }
  .card .meta {
    grid-column: 2 / 4;
    grid-row: 2;
    font-size: 12px;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .card .stats {
    display: none;
  }
  .card .tag {
    top: auto;
    bottom: 4px;
    right: 6px;
  }
  .shop-body h3 {
    margin: 8px 2px 4px;
  }
  .card:not(:has(canvas)) {
    grid-template-columns: 1fr auto;
  }
  .card:not(:has(canvas)) .nm {
    grid-column: 1;
  }
  .card:not(:has(canvas)) .price {
    grid-column: 2;
  }
  .card:not(:has(canvas)) .meta {
    grid-column: 1 / 3;
  }
}

/* ---------- Menus (overlay) ---------- */

.overlay {
  position: absolute;
  inset: 0;
  display: none;
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y;
  padding: calc(var(--in-t) + 14px) max(14px, calc(var(--in-r) + 10px)) calc(var(--in-b) + 14px) max(14px, calc(var(--in-l) + 10px));
  background: radial-gradient(ellipse at 50% 20%, rgba(13, 15, 11, 0.35), rgba(5, 6, 4, 0.82) 70%);
  z-index: 10;
}

.game-root.full .overlay {
  padding-top: calc(var(--exit-bottom) + 8px);
}

.overlay.show {
  display: block;
}

.menu {
  max-width: 760px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.menu.wide {
  max-width: 1100px;
}

.title {
  text-align: center;
  margin: 4px 0 2px;
}

.title h2 {
  margin: 0;
  font-size: clamp(34px, 7vw, 72px);
  font-weight: 900;
  letter-spacing: clamp(2px, 0.8vw, 8px);
  text-transform: uppercase;
  line-height: 1;
  color: #f3e3bb;
  text-shadow: 0 3px 0 #3d2a0e, 0 0 30px rgba(242, 150, 50, 0.35);
}

.title p {
  margin: 8px 0 0;
  color: var(--muted);
}

.menu h2.h {
  margin: 0;
  font-size: 22px;
  text-transform: uppercase;
  letter-spacing: 2px;
}

.menu p {
  margin: 0;
  line-height: 1.45;
}

.menu .small {
  font-size: max(13px, var(--t-min));
  color: var(--muted);
}

.modes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px;
}

.mode {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px;
  min-height: 88px;
  border-radius: 12px;
  border: 1px solid var(--line-2);
  background: linear-gradient(rgba(34, 41, 26, 0.95), rgba(22, 27, 17, 0.95));
  text-align: left;
}

.mode b {
  font-size: 19px;
  letter-spacing: 0.5px;
}

.mode span {
  color: var(--muted);
  font-size: max(13px, var(--t-min));
}

.mode.primary {
  border-color: #d39a33;
  background: linear-gradient(rgba(90, 64, 20, 0.95), rgba(52, 38, 14, 0.95));
}

.mode:hover {
  border-color: var(--accent);
}

.row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

.row.end {
  justify-content: flex-end;
}

.row.center {
  justify-content: center;
}

.who-line {
  text-align: center;
  font-size: max(14px, var(--t-min));
  line-height: 1.4;
  /* Two lines kept, so who is playing (the server's answer) never moves the title on a narrow phone. */
  min-height: 2.8em;
}

.who-line a {
  display: inline-block;
  padding: 12px 2px;
  margin: -12px 0;
  font-weight: 700;
}

.status-line {
  min-height: 1.4em;
  text-align: center;
  color: var(--dim);
  font-size: max(13px, var(--t-min));
}

.maps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}

@media (max-width: 640px) {
  .maps {
    grid-template-columns: 1fr;
  }
}

.mapcard {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: 12px;
  border: 2px solid var(--line);
  background: #11140d;
  overflow: hidden;
  padding: 0;
  text-align: left;
  min-height: 44px;
}

.mapcard canvas {
  width: 100%;
  aspect-ratio: 16 / 10;
  display: block;
  background: #0a0b08;
}

@media (max-width: 640px) {
  .mapcard {
    flex-direction: row;
    align-items: stretch;
  }
  .mapcard canvas {
    width: 42%;
    aspect-ratio: 4 / 3;
  }
}

.mapcard .mc-body {
  padding: 8px 10px 10px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
}

.mapcard b {
  font-size: 17px;
}

.mapcard .mc-blurb {
  font-size: 13px;
  color: var(--muted);
}

.mapcard .votes {
  display: flex;
  gap: 4px;
  min-height: 14px;
  align-items: center;
}

.mapcard .votes i {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 2px solid #000;
}

.mapcard .mc-best {
  font-size: 13px;
  color: var(--dim);
}

.mapcard.mine {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 18px rgba(242, 179, 61, 0.25);
}

.mapcard.won {
  border-color: var(--good);
}

.seats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

@media (max-width: 640px) {
  .seats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.seat {
  padding: 10px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: rgba(20, 24, 15, 0.9);
  min-height: 64px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.seat .nm {
  font-weight: 800;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.seat .st {
  font-size: 13px;
  color: var(--muted);
}

.seat.ready {
  border-color: #6b9a3b;
}

.seat.ready .st {
  color: var(--good);
}

.seat.empty {
  border-style: dashed;
  color: var(--dim);
}

.seat .bar-c {
  height: 4px;
  border-radius: 2px;
  margin-bottom: 4px;
}

.countdown {
  text-align: center;
  font-size: 18px;
  font-weight: 800;
  color: var(--accent);
  min-height: 26px;
}

.code {
  font-size: 30px;
  font-weight: 900;
  letter-spacing: 8px;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.code-in {
  width: 9ch;
  min-height: 48px;
  padding: 6px 10px;
  border-radius: 10px;
  border: 1px solid var(--line-2);
  background: #0c0e09;
  font-size: 26px;
  font-weight: 900;
  letter-spacing: 6px;
  text-transform: uppercase;
  text-align: center;
  user-select: text;
  -webkit-user-select: text;
}

.err {
  color: #ffb3a8;
  min-height: 1.3em;
}

.results-head {
  text-align: center;
}

.results-head .big {
  font-size: clamp(30px, 6vw, 56px);
  font-weight: 900;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: #f3e3bb;
}

.nums {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.num {
  padding: 10px;
  border-radius: 10px;
  background: rgba(20, 24, 15, 0.9);
  border: 1px solid var(--line);
  text-align: center;
}

.num b {
  display: block;
  font-size: 28px;
  font-variant-numeric: tabular-nums;
}

.num span {
  color: var(--muted);
  font-size: 13px;
}

.num .pb {
  color: var(--accent);
  font-weight: 800;
  font-size: 13px;
}

table.tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: max(14px, var(--t-min));
}

.tbl th,
.tbl td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--line);
  text-align: left;
}

.tbl th {
  color: var(--muted);
  font-weight: 700;
  font-size: 13px;
}

.tbl td.n,
.tbl th.n {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.tbl tr.me td {
  color: var(--accent);
  font-weight: 800;
}

/* The boards: names wrap (a team of four on a phone), the gap before the ranks around yours. */
.tbl.board td.who {
  overflow-wrap: anywhere;
}

.tbl.board td.who .more {
  color: var(--muted);
  font-weight: 400;
}

.tbl.board tr.gap td {
  text-align: center;
  color: var(--dim);
  padding: 2px;
  border-bottom: 0;
}

.tabs.cats {
  margin-top: 6px;
}

@media (max-width: 420px) {
  .tbl.board th,
  .tbl.board td {
    padding: 6px 4px;
  }
}

.board-note {
  text-align: center;
  font-weight: 700;
}

.tabs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.tabs button {
  min-height: 44px;
  padding: 6px 14px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  font-weight: 700;
}

.tabs button.on {
  border-color: var(--accent);
  color: var(--accent);
}

.xpbar {
  height: 10px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}

.xpbar i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #d8952a, #f4bb4a);
}

.splash {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  pointer-events: none;
}

.splash .big {
  font-size: clamp(34px, 7vw, 72px);
  font-weight: 900;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: #f3e3bb;
  text-shadow: 0 3px 0 #3d2a0e;
}

.check {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.check input {
  width: 22px;
  height: 22px;
}

input[type='range'] {
  width: min(260px, 60vw);
  min-height: 44px;
}

kbd {
  display: inline-block;
  padding: 0 6px;
  border-radius: 4px;
  border: 1px solid var(--line-2);
  background: #1b2015;
  font-family: inherit;
  font-size: 0.92em;
}

.about {
  max-width: 900px;
  margin: 26px auto 0;
  padding: 0 14px;
  line-height: 1.55;
}

.about h1 {
  margin: 0 0 8px;
}

/* Touch on a short screen held sideways: the feed under the health and armour, beside the wave's
   column, clear of the buttons round the right stick and of the middle of the screen. */
@media (orientation: landscape) and (max-height: 520px) {
  html[data-input='touch'] .feed {
    right: auto;
    left: calc(var(--side-l) + var(--wave-w) + 8px);
    transform: none;
    top: calc(var(--top) + 50px);
    align-items: flex-start;
  }
  html[data-input='touch'] .feed li {
    text-align: left;
    white-space: nowrap;
  }
  html[data-input='touch'] .feed li:nth-child(n + 3) {
    display: none;
  }
}

/* The lobby's countdown and Ready, kept at the foot of the screen while its maps scroll (Oct 13: on a
   phone they sat below the fold). */
.lobby-act {
  position: sticky;
  bottom: calc(-1 * (var(--in-b) + 14px));
  margin: 8px calc(-1 * max(14px, calc(var(--in-l) + 10px))) 0;
  padding: 10px max(14px, calc(var(--in-l) + 10px)) calc(var(--in-b) + 14px);
  background: linear-gradient(rgba(5, 6, 4, 0), rgba(5, 6, 4, 0.92) 28%);
  z-index: 1;
}

/* Sideways on a phone, the shop takes the HUD's top row too (its own head shows the cash). */
@media (max-height: 520px) {
  .shop {
    top: var(--top);
  }
}

/* The gamepad's place in the shop and the menus. */
html[data-input='pad'] .shop button:focus,
html[data-input='pad'] .overlay button:focus,
html[data-input='pad'] .overlay input:focus {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}


/* A phone held upright with a gamepad or a keyboard (no touch controls; Oct 17, round 3). The corner
   panels sized for a desktop met in the middle: the cash sat on the wave's box, and the weapon panel
   covered the health bars and ran past the right edge. The bars now run along the bottom, the weapon
   panel sits on them, and the cash goes under the three buttons. */
@media (orientation: portrait) and (max-width: 599px) {
  html:not([data-input='touch']) .hud-tr {
    max-width: none;
  }
  html:not([data-input='touch']) .hud-tr-row {
    flex-wrap: wrap;
    justify-content: flex-end;
    max-width: 150px;
  }
  html:not([data-input='touch']) .hud-tr-row .cash {
    order: 1;
  }
  html:not([data-input='touch']) .hud-tl {
    max-width: calc(100% - var(--side-l) - var(--side-r) - 160px);
  }
  html:not([data-input='touch']) .hud-bl {
    right: var(--side-r);
    width: auto;
  }
  html:not([data-input='touch']) .hud-br {
    bottom: calc(var(--bottom) + 57px);
    max-width: calc(100% - var(--side-l) - var(--side-r));
  }
}
