/* RANK — premium abstract tactical board game.
   Dark neutral ground, muted slate tiles as raised plates, ivory vs
   graphite pieces, one amber accent for Command and resources, one coral
   warning for danger and capture. Everything else is neutral light. */

/* ------------------------------------------------------------ tokens */

:root {
  /* ground and surfaces */
  --bg: #0f1216;
  --bg-deep: #0a0c10;
  --surface: #161a21;
  --surface-2: #1c2129;
  --surface-3: #232933;
  --line: #262d38;
  --line-2: #323a47;

  /* text */
  --text: #eef1f5;
  --text-2: #c4ccd8;
  --muted: #8d97a6;
  --muted-2: #67717f;

  /* board tiles (plates): pulled further apart in lightness (was a
     fairly close #4c586c/#3b4557 pair) so light and dark squares read
     apart at a glance without leaving the same neutral slate hue. */
  --tile-a: #616f89;
  --tile-b: #2a3140;
  --tile-edge: rgba(255, 255, 255, 0.15);
  --tile-gap: 4px;

  /* player materials */
  --ivory: #eadfc6;
  --ivory-rim: #7b6947;
  --ivory-soft: rgba(234, 223, 198, 0.16);
  --graphite: #323b48;
  --graphite-rim: #c6d3e6;
  --graphite-soft: rgba(198, 211, 230, 0.16);

  /* accent (Command / resources) and warning (danger / capture) */
  --accent: #f0b34a;
  --accent-2: #ffd27c;
  --accent-soft: rgba(240, 179, 74, 0.16);
  --accent-glow: rgba(240, 179, 74, 0.45);
  --warn: #ff5f5f;
  --warn-soft: rgba(255, 95, 95, 0.18);
  --warn-glow: rgba(255, 95, 95, 0.5);

  /* neutral highlight for selection / moves */
  --focus: rgba(236, 240, 246, 0.92);
  --focus-soft: rgba(236, 240, 246, 0.14);
  --focus-dot: rgba(236, 240, 246, 0.64);

  /* shadows */
  --shadow-s: 0 1px 2px rgba(0, 0, 0, 0.45);
  --shadow-m: 0 6px 18px -8px rgba(0, 0, 0, 0.7);
  --shadow-l: 0 30px 70px -30px rgba(0, 0, 0, 0.9);
  --tile-shadow: inset 0 1px 0 var(--tile-edge), inset 0 0 0 1px rgba(255, 255, 255, 0.035), inset 0 -2px 0 rgba(0, 0, 0, 0.34), 0 1px 0 rgba(0, 0, 0, 0.55), 0 3px 5px rgba(0, 0, 0, 0.55);

  /* spacing and radii */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --r-s: 6px;
  --r-m: 10px;
  --r-l: 14px;

  /* typography */
  --font: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  --fs-xs: 11px;
  --fs-s: 12px;
  --fs-m: 13px;
  --fs-l: 15px;
  --track: 0.16em;

  /* motion */
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-pop: cubic-bezier(0.2, 1.3, 0.4, 1);
  --t-fast: 140ms;
  --t-move: 260ms;

  /* board */
  --board-size: min(calc(100vh - 222px), calc(100vw - 652px), 880px);
  --cols: 8;
  --rows: 8;

  font-family: var(--font);
  color-scheme: dark;
}

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

html { overflow-x: hidden; }
html, body {
  margin: 0;
  height: 100%;
  background:
    radial-gradient(1100px 600px at 50% -20%, #171e27 0%, rgba(23, 30, 39, 0) 60%),
    var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  font-size: var(--fs-m);
}

button { font: inherit; color: inherit; }
button:focus-visible, .ov-map:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

.app { min-height: 100vh; display: flex; flex-direction: column; }

/* ------------------------------------------------------------ top bar */

.topbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: var(--s-3) var(--s-5);
  border-bottom: 1px solid var(--line);
  background: rgba(15, 18, 22, 0.75);
  backdrop-filter: blur(8px);
}

.brand { display: flex; align-items: center; gap: 9px; user-select: none; }
.brand-mark { width: 18px; height: 18px; fill: var(--accent); }
.brand-word {
  font-weight: 900;
  font-size: 17px;
  letter-spacing: 0.34em;
  margin-right: -0.34em;
  color: var(--text);
}

.status {
  justify-self: center;
  font-size: var(--fs-s);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: var(--s-2);
  white-space: nowrap;
  animation: fade-in 220ms ease-out;
}
.status .who {
  color: var(--text);
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: var(--surface);
}
.status .who.white { border-color: var(--ivory-rim); box-shadow: inset 0 0 0 1px rgba(234, 223, 198, 0.12); }
.status .who.black { border-color: var(--line-2); background: var(--bg-deep); }
.status .thinking { color: var(--accent); text-transform: none; letter-spacing: 0.04em; animation: breathe 1.4s ease-in-out infinite; }
.status .map-tag { color: var(--text-2); text-transform: none; letter-spacing: 0.04em; font-weight: 600; }
.status .sep { color: var(--muted-2); }

.topbar-actions { justify-self: end; }

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

.layout {
  flex: 1;
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr) 290px;
  gap: var(--s-5);
  padding: var(--s-5);
  align-items: start;
}

.panel { display: flex; flex-direction: column; gap: var(--s-4); position: relative; min-width: 0; }
.player-card, .side-section { min-width: 0; }
.panel-left { min-height: calc(var(--board-size) * var(--rows) / var(--cols)); }
.panel-spacer { flex: 1; }

.board-area { display: flex; flex-direction: column; align-items: center; gap: var(--s-4); }
.board-stage { display: flex; justify-content: center; align-items: flex-start; position: relative; isolation: isolate; }
.board-stage::after {
  /* the viewer's edge of the board is lit in their material */
  content: "";
  position: absolute;
  left: 4%; right: 4%; bottom: -8%;
  height: 34%;
  background: radial-gradient(ellipse at 50% 100%, var(--side-glow), rgba(0, 0, 0, 0) 70%);
  pointer-events: none;
  z-index: -1;
  transition: opacity 0.3s;
}
.app[data-view="white"] { --side-glow: rgba(234, 223, 198, 0.16); }
.app[data-view="black"] { --side-glow: rgba(198, 211, 230, 0.15); }
.board-stage.turning::after { animation: glow-swap 340ms ease-out; }
.board-stage::before {
  /* soft ambient light so the board reads as the lit object in the room */
  content: "";
  position: absolute;
  inset: -10% -14%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0) 72%);
  pointer-events: none;
  z-index: -1;
}

/* turn pill under the board, on the viewer's side */
.board-turn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px 5px 9px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: var(--surface);
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text);
  box-shadow: var(--shadow-s);
}
.board-turn.in { animation: turn-pill 320ms var(--ease); }
.bt-swatch { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25); }
.board-turn.white .bt-swatch { background: linear-gradient(180deg, #f3ebd9, #c9b48d); }
.board-turn.black .bt-swatch { background: linear-gradient(180deg, #46505f, #12161d); box-shadow: inset 0 0 0 1px var(--graphite-rim); }
.board-turn.white { border-color: rgba(234, 223, 198, 0.45); }
.board-turn.black { border-color: rgba(198, 211, 230, 0.4); }

/* the viewer's card sits nearest the board (bottom of the left panel) */
#card-black { order: 1; }
.panel-spacer { order: 2; }
#card-white { order: 3; }
.app[data-view="black"] #card-black { order: 3; }
.app[data-view="black"] #card-white { order: 1; }
.panel-left.swapping .player-card { animation: card-swap 380ms var(--ease); }

@media (max-width: 1080px) {
  :root { --board-size: min(calc(100vw - 32px), 68vh); }
  .layout { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); padding: var(--s-4); }
  /* One column: board, then the panel you act in (shop, deploy, moves),
     then the player cards, so a phone never scrolls past two cards to
     reach the shop. */
  .board-area { order: 1; }
  .panel-right { order: 2; }
  .panel-left { order: 3; min-height: 0; flex-direction: row; }
  .panel-left .player-card { flex: 1; }
  .panel-spacer { display: none; }
  .board-stage::before { inset: -4% -2%; }
  .topbar { padding: var(--s-2) var(--s-4); }
}
@media (max-width: 640px) {
  .panel-left { gap: var(--s-2); }
  .player-card { padding: var(--s-3); }
  .pc-clock-time { font-size: 22px; }
  .pc-clock-tc { display: none; }
  .pcs-time { font-size: var(--fs-m); }
  .pc-cmd-value { font-size: 28px; }
}

/* -------------------------------------------------------- player cards */

.player-card {
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line);
  border-radius: var(--r-l);
  padding: var(--s-4);
  position: relative;
  box-shadow: var(--shadow-m);
  opacity: 0.74;
  transition: border-color 0.25s, box-shadow 0.25s, opacity 0.3s, background 0.25s, transform 0.3s;
}
.player-card::before {
  /* material stripe on the leading edge */
  content: "";
  position: absolute;
  left: 0; top: 14px; bottom: 14px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--line-2);
  transition: background 0.25s;
}
.player-card.white::before { background: linear-gradient(180deg, #f3ebd9, #c9b48d); }
.player-card.black::before { background: linear-gradient(180deg, #8ea0ba, #46505f); }
.player-card.active {
  opacity: 1;
  background: linear-gradient(180deg, var(--surface-3), var(--surface-2));
  border-color: var(--line-2);
  box-shadow: var(--shadow-m), 0 0 0 1px var(--focus-soft);
}
.player-card.active.white { border-color: rgba(234, 223, 198, 0.6); box-shadow: var(--shadow-m), 0 0 0 1px rgba(234, 223, 198, 0.16), 0 0 40px -10px rgba(234, 223, 198, 0.42); }
.player-card.active.black { border-color: rgba(198, 211, 230, 0.55); box-shadow: var(--shadow-m), 0 0 0 1px rgba(198, 211, 230, 0.14), 0 0 40px -10px rgba(198, 211, 230, 0.36); }
.player-card.active .pc-name { letter-spacing: 0.16em; }
.player-card.active.white .pc-name { color: var(--ivory); }
.player-card.active.black .pc-name { color: #d5dde8; }
.player-card:not(.active) .pc-cmd-value { opacity: 0.82; text-shadow: none; }
.pc-name { transition: color 0.25s, letter-spacing 0.25s; }
.pc-cmd-value { transition: opacity 0.3s; }
.player-card.winner, .player-card.loser, .player-card.danger { opacity: 1; }
.player-card.turn-in { animation: card-in 480ms var(--ease); }
.player-card.winner { border-color: var(--accent); box-shadow: var(--shadow-m), 0 0 0 1px var(--accent-soft), 0 0 40px -12px var(--accent-glow); }
.player-card.loser { opacity: 0.5; }

.pc-head { display: flex; align-items: center; gap: var(--s-2); }
.pc-swatch {
  width: 12px; height: 12px; border-radius: 3px;
  background: linear-gradient(180deg, #f3ebd9, #c9b48d);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);
}
#card-black .pc-swatch { background: linear-gradient(180deg, #46505f, #12161d); box-shadow: inset 0 0 0 1px var(--graphite-rim); }
.pc-name { font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; font-size: var(--fs-m); color: var(--text); }
.pc-bot {
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--line-2);
  border-radius: 999px;
  padding: 1px 7px;
}
.pc-badge {
  margin-left: auto;
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bg-deep);
  background: var(--text);
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 3px 9px;
  opacity: 0;
  transform: translateX(4px);
  transition: none;
}
.player-card.white .pc-badge { background: var(--ivory); }
.player-card.black .pc-badge { background: var(--graphite-rim); }
.player-card.active .pc-badge { opacity: 1; transform: none; transition: opacity 0.2s, transform 0.2s; }

.pc-danger {
  display: none;
  align-items: center;
  gap: 8px;
  margin-top: var(--s-3);
  padding: 6px 10px;
  border-radius: var(--r-s);
  background: var(--warn-soft);
  border: 1px solid rgba(255, 95, 95, 0.4);
  font-size: var(--fs-s);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--warn);
  font-weight: 800;
}
.pc-danger-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--warn); box-shadow: 0 0 8px var(--warn-glow); flex: 0 0 auto; }
.player-card.danger .pc-danger { display: flex; animation: fade-in 200ms ease-out; }
.player-card.danger { border-color: rgba(255, 95, 95, 0.5); }

/* setup clock: the minute each side has to build its force. Deliberately
   unlike the battle clock (a small labelled strip, not a big number) so
   the two are never confused; it exists only during setup and only for a
   side that has not confirmed. Emphasis under 30 s, coral under 10 s. */
.pc-setup {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-2);
  min-width: 0;
  margin-top: var(--s-3);
  padding: 5px 10px;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-m);
  background: rgba(10, 12, 16, 0.3);
  color: var(--muted);
  transition: border-color 0.25s, background 0.25s, color 0.25s;
}
.pcs-label { font-size: var(--fs-xs); font-weight: 800; letter-spacing: var(--track); text-transform: uppercase; color: var(--muted-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pcs-time { font-size: var(--fs-l); font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; color: var(--text-2); white-space: nowrap; }
/* Running: a touch more presence than the idle dashed strip (solid
   border, a hairline glow, a slightly larger readout) without competing
   with the battle clock's own emphasis — still a labelled strip, not a
   big number. */
.pc-setup.running {
  border-style: solid;
  border-color: var(--line-2);
  background: rgba(20, 24, 31, 0.66);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.03), 0 2px 10px rgba(0, 0, 0, 0.22);
}
.pc-setup.running .pcs-label { color: var(--muted); }
.pc-setup.running .pcs-time { color: var(--text); font-size: calc(var(--fs-l) * 1.12); }
.pc-setup.low .pcs-time { color: var(--text); }
.pc-setup.low.running { border-color: var(--focus); box-shadow: 0 0 0 1px var(--focus-soft), 0 2px 10px rgba(0, 0, 0, 0.22); }
.pc-setup.warn { border-color: rgba(255, 95, 95, 0.55); background: var(--warn-soft); }
.pc-setup.warn .pcs-time, .pc-setup.warn .pcs-label { color: var(--warn); }
.pc-setup.warn.running { box-shadow: 0 0 0 1px rgba(255, 95, 95, 0.25), 0 2px 10px rgba(0, 0, 0, 0.22); }

/* chess clock: neutral at rest, brighter while running, coral only when
   time is short (the warning colour), a slow pulse in the last ten seconds.
   The time is the card; the control (and "out of time") is a small row
   beneath it, contained to the card's width whatever the panel is. */
.pc-clock {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  min-width: 0;
  margin-top: var(--s-3);
  padding: 7px 11px 6px;
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: rgba(10, 12, 16, 0.45);
  color: var(--muted);
  transition: border-color 0.25s, background 0.25s, box-shadow 0.25s;
}
.pc-clock-time { font-size: 28px; font-weight: 800; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--text-2); transition: color 0.25s; }
.pc-clock-tc { max-width: 100%; font-size: var(--fs-xs); font-weight: 700; letter-spacing: var(--track); text-transform: uppercase; color: var(--muted-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pc-clock.running { border-color: var(--line-2); background: var(--surface-3); box-shadow: inset 0 0 0 1px var(--focus-soft); }
.pc-clock.running .pc-clock-time { color: var(--text); }
.pc-clock.running .pc-clock-tc { color: var(--muted); }
.pc-clock.low .pc-clock-time { color: var(--text); }
.pc-clock.low.running { border-color: var(--focus); }
.pc-clock.warn .pc-clock-time { color: var(--warn); }
.pc-clock.warn.running { border-color: rgba(255, 95, 95, 0.55); box-shadow: inset 0 0 0 1px rgba(255, 95, 95, 0.2); }
.pc-clock.danger { border-color: var(--warn); background: var(--warn-soft); }
.pc-clock.danger .pc-clock-time { color: var(--warn); }
.pc-clock.danger.running .pc-clock-time { animation: clock-pulse 1s ease-in-out infinite; }
.pc-clock.flagged { border-color: var(--warn); }
.pc-clock.flagged .pc-clock-time { color: var(--warn); }
.pc-clock.flagged .pc-clock-tc { color: var(--warn); }
.player-card:not(.active) .pc-clock-time { text-shadow: none; }

.pc-command { position: relative; margin-top: var(--s-3); }
.pc-cmd-main { display: flex; align-items: baseline; gap: var(--s-2); }
.pc-cmd-value { font-size: 44px; font-weight: 800; color: var(--accent); line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -0.03em; text-shadow: 0 0 24px rgba(240, 179, 74, 0.18); }
.pc-cmd-value.bump { animation: bump 0.4s var(--ease-pop); }
.pc-cmd-label { font-size: var(--fs-s); letter-spacing: var(--track); text-transform: uppercase; color: var(--text-2); font-weight: 700; }
.pc-pips { display: grid; grid-template-columns: repeat(10, 1fr); gap: 3px; margin-top: var(--s-3); }
.pip { height: 7px; border-radius: 2px; background: var(--bg-deep); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06); transition: background 0.2s, box-shadow 0.2s; }
.pip.filled { background: var(--accent); box-shadow: 0 0 6px -1px var(--accent-glow); }
.pip.pop { animation: pip-pop 0.4s ease-out; }
.pc-gains { position: absolute; right: 0; top: -2px; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; pointer-events: none; }
.gain {
  font-size: 20px;
  font-weight: 900;
  color: var(--accent-2);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  animation: gain 1.15s var(--ease) forwards;
  text-shadow: 0 0 12px var(--accent-glow);
}
.gain.note { font-size: var(--fs-xs); font-weight: 600; color: var(--muted); text-shadow: none; letter-spacing: 0.08em; text-transform: uppercase; }

.pc-rows { margin-top: var(--s-3); display: flex; flex-direction: column; gap: var(--s-2); }
.pc-row { display: flex; justify-content: space-between; align-items: center; gap: var(--s-2); font-size: var(--fs-s); color: var(--muted); min-height: 18px; }
.pc-res-value { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; }
.pc-captured { display: flex; flex-wrap: wrap; gap: 1px; justify-content: flex-end; min-height: 16px; }
.pc-captured .none { font-size: var(--fs-s); }

/* small piece icons (captured lists, shop, roster, stats) */
.pc-svg { display: inline-block; width: 1em; height: 1em; vertical-align: -0.15em; overflow: visible; }
.pc-svg.white { --pc-fill: url(#mat-ivory); --pc-rim: var(--ivory-rim); }
.pc-svg.black { --pc-fill: url(#mat-graphite); --pc-rim: var(--graphite-rim); }
.cap { display: inline-block; font-size: 17px; line-height: 1; }

/* ---------------------------------------------------------------- board */

/* The frame is as wide as --board-size and as tall as the map's aspect
   ratio needs. It has no surface of its own: the tiles are the board, so
   an irregular map's silhouette is the frame. */
.board-frame {
  position: relative;
  width: var(--board-size);
  height: calc(var(--board-size) * var(--rows) / var(--cols));
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.6)) drop-shadow(0 22px 36px rgba(0, 0, 0, 0.5));
  transform-origin: 50% 50%;
}
.board-stage.turning .board-frame { animation: board-turn 340ms var(--ease); }
.board-stage.turning .piece .glyph, .board-stage.turning .sq .coord { animation: stay-upright 340ms var(--ease); }

/* the incoming player's turn, announced over the board during the hand-off */
.turn-flash {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%) scale(0.92);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 9px 18px 9px 14px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: rgba(22, 26, 33, 0.94);
  box-shadow: var(--shadow-l), 0 0 0 1px rgba(0, 0, 0, 0.5);
  font-size: var(--fs-m);
  font-weight: 800;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--text);
  opacity: 0;
  pointer-events: none;
  z-index: 5;
  transition: opacity 160ms ease-out, transform 220ms var(--ease-pop);
}
.turn-flash.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.tf-swatch { width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25); }
.turn-flash.white .tf-swatch { background: linear-gradient(180deg, #f3ebd9, #c9b48d); }
.turn-flash.black .tf-swatch { background: linear-gradient(180deg, #46505f, #12161d); box-shadow: inset 0 0 0 1px var(--graphite-rim); }
.turn-flash.white { border-color: rgba(234, 223, 198, 0.55); }
.turn-flash.black { border-color: rgba(198, 211, 230, 0.5); }

.board {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  grid-template-rows: repeat(var(--rows), 1fr);
  gap: var(--tile-gap);
}

.sq {
  position: relative;
  border-radius: 4px;
  background: linear-gradient(180deg, var(--tile-b) 0%, color-mix(in srgb, var(--tile-b) 88%, black) 100%);
  box-shadow: var(--tile-shadow);
  user-select: none;
  transition: filter var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast);
}
.sq.light { background: linear-gradient(180deg, var(--tile-a) 0%, color-mix(in srgb, var(--tile-a) 88%, black) 100%); }

/* A missing square: nothing is drawn, the ground shows through. */
.sq.void { background: none; box-shadow: none; pointer-events: none; }

.sq .coord {
  position: absolute;
  font-size: calc(var(--board-size) / var(--cols) * 0.13);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: rgba(236, 240, 246, 0.38);
  pointer-events: none;
}
.sq .coord.file { right: 5px; bottom: 3px; }
.sq .coord.rank { left: 5px; top: 3px; }

/* deployment zone during setup / deploy mode */
.sq.zone::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--focus-soft);
  opacity: 0.55;
}

/* resource squares */
.sq.resource {
  background: linear-gradient(180deg, #5a5240 0%, #494334 100%);
  box-shadow: var(--tile-shadow), inset 0 0 0 1px rgba(240, 179, 74, 0.36);
}
.sq.resource.light { background: linear-gradient(180deg, #675e49 0%, #554e3c 100%); }
.res-mark {
  position: absolute;
  inset: 0;
  display: none;
  place-items: center;
  pointer-events: none;
}
.sq.resource .res-mark { display: grid; }
.res-mark::before {
  /* embedded diamond */
  content: "";
  width: 30%;
  height: 30%;
  border: 2px solid var(--accent);
  transform: rotate(45deg);
  border-radius: 2px;
  box-shadow: 0 0 12px var(--accent-glow), inset 0 0 6px rgba(240, 179, 74, 0.2);
  opacity: 0.9;
}
.res-mark::after {
  /* breathing ring */
  content: "";
  position: absolute;
  width: 62%;
  height: 62%;
  border: 1px solid var(--accent);
  border-radius: 50%;
  opacity: 0.25;
  animation: res-breathe 3.2s ease-in-out infinite;
}
.sq.resource.leaving .res-mark::before { border-style: dashed; opacity: 0.65; box-shadow: none; }
.sq.resource.leaving .res-mark::after { border-style: dashed; animation: res-breathe 1.4s ease-in-out infinite; }
.sq.resource.leaving-now .res-mark::before { opacity: 0.5; }
.sq.resource.leaving-now .res-mark::after { opacity: 0.5; animation: res-breathe 0.8s ease-in-out infinite; }
.sq.res-arrived .res-mark::before { animation: res-arrive 0.6s var(--ease-pop); }
.sq.res-arrived { animation: res-land 0.6s ease-out; }
.sq.res-left { animation: res-leave 0.8s ease-out; }
.sq.res-left::after {
  /* the old marker's ghost fading out */
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 30%; height: 30%;
  border: 2px dashed var(--accent);
  border-radius: 2px;
  transform: translate(-50%, -50%) rotate(45deg);
  animation: res-ghost 0.8s ease-out forwards;
  pointer-events: none;
}

/* King that an enemy piece could capture right now: a stronger ring than
   before (was a static, fairly subtle glow) that also breathes, since a
   King in danger is the single most important thing on the board to
   notice immediately. The player card banner (.pc-danger, above) already
   carries the same coral; its dot now pulses in step. */
.sq.king-danger { box-shadow: var(--tile-shadow), inset 0 0 0 3px var(--warn), 0 0 26px -2px var(--warn-glow); animation: king-alarm 1.1s ease-in-out infinite; }
.piece.danger .glyph { filter: drop-shadow(0 0 10px var(--warn-glow)); animation: king-piece-alarm 1.1s ease-in-out infinite; }
.pc-danger-dot { animation: king-alarm-dot 1.1s ease-in-out infinite; }
@keyframes king-alarm {
  0%, 100% { box-shadow: var(--tile-shadow), inset 0 0 0 3px var(--warn), 0 0 26px -2px var(--warn-glow); }
  50% { box-shadow: var(--tile-shadow), inset 0 0 0 4px var(--warn), 0 0 34px 2px var(--warn-glow); }
}
@keyframes king-piece-alarm { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }
@keyframes king-alarm-dot { 0%, 100% { box-shadow: 0 0 8px var(--warn-glow); } 50% { box-shadow: 0 0 14px 2px var(--warn-glow); } }

/* Selection and move feedback. The last action is marked on both of its
   squares for one turn (the origin faintly, the destination a shade
   stronger with a hairline edge) and cleared by the next action; the
   same in local, solo, online and review. */
.sq.last-from::before, .sq.last-to::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--focus-soft);
  opacity: 0.55;
}
.sq.last-to::before { opacity: 1; box-shadow: inset 0 0 0 1px rgba(236, 240, 246, 0.22); }
.sq.pulse-land { animation: land 0.45s ease-out 180ms; }
.sq.pulse-impact { animation: impact 0.5s ease-out 200ms; }

.sq.selected { box-shadow: var(--tile-shadow), inset 0 0 0 2px var(--focus); filter: brightness(1.12); }

.sq.hl-move::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 24%; height: 24%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--focus-dot);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}
.sq.hl-capture { box-shadow: var(--tile-shadow), inset 0 0 0 3px var(--warn); }
.sq.hl-capture::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--warn-soft);
}
.sq.hl-danger::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 24%; height: 24%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--warn);
  opacity: 0.75;
  box-shadow: 0 0 10px var(--warn-glow);
}
.sq.hl-danger.hl-capture::after { width: 34%; height: 34%; background: transparent; border: 2px solid var(--warn); opacity: 0.9; }
.sq.hl-deploy { box-shadow: var(--tile-shadow), inset 0 0 0 1px var(--focus-dot); }
.sq.hl-deploy::after {
  content: "";
  position: absolute;
  inset: 18%;
  border-radius: 4px;
  border: 1.5px dashed var(--focus-dot);
}
.sq.hl-deploy::before {
  content: "+";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--focus);
  font-size: calc(var(--board-size) / var(--cols) * 0.42);
  font-weight: 300;
  opacity: 0.55;
  z-index: 1;
  background: none;
}
.sq.clickable, .sq.hl-move, .sq.hl-capture, .sq.hl-deploy, .sq.hl-danger { cursor: pointer; }
.sq.clickable:hover, .sq.hl-move:hover, .sq.hl-deploy:hover, .sq.hl-capture:hover, .sq.hl-danger:hover { filter: brightness(1.14); }

/* Setup drag: the carried piece lifts and follows the pointer, its
   origin square stays marked as where it came from, and the square under
   the pointer says whether it would be taken (neutral) or refused
   (coral: the piece goes back). */
.board { touch-action: none; }
.sq.drag-origin { box-shadow: var(--tile-shadow), inset 0 0 0 2px var(--focus-soft); }
.sq.drop-ok { box-shadow: var(--tile-shadow), inset 0 0 0 2.5px var(--focus); filter: brightness(1.22); }
.sq.drop-bad { box-shadow: var(--tile-shadow), inset 0 0 0 2px rgba(255, 95, 95, 0.7); }
.sq.drop-bad::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--warn-soft); }

/* pieces layer */
.pieces { position: absolute; inset: 0; pointer-events: none; }
.pieces.carrying .piece { transition: none; }
.piece.dragging { z-index: 6; }
.piece.dragging .glyph { transform: translateY(-13%) scale(1.18); filter: drop-shadow(0 16px 16px rgba(0, 0, 0, 0.7)); }
.piece.black.dragging .glyph { filter: drop-shadow(0 0 0.6px rgba(214, 226, 242, 0.9)) drop-shadow(0 16px 16px rgba(0, 0, 0, 0.75)); }
.piece {
  position: absolute;
  left: 0; top: 0;
  width: calc(100% / var(--cols));
  height: calc(100% / var(--rows));
  display: grid;
  place-items: center;
  transition: left var(--t-move) var(--ease), top var(--t-move) var(--ease), opacity 0.25s;
  z-index: 2;
}
.pieces.still .piece { transition: none; }
.piece.moving { z-index: 3; }
.piece.moving .glyph { transform: translateY(-6%) scale(1.05); filter: drop-shadow(0 9px 8px rgba(0, 0, 0, 0.6)); }
.piece .glyph {
  width: 78%;
  height: 78%;
  display: block;
  transform: translateY(-2%);
  transition: transform 0.18s var(--ease), filter 0.2s;
  filter: drop-shadow(0 3px 2px rgba(0, 0, 0, 0.6));
}
/* Black pieces: a hairline of light around the silhouette so they separate
   from dark tiles without becoming a grey army. */
.piece.black { --pc-stroke: 2.1; }
.piece.black .glyph { filter: drop-shadow(0 0 0.6px rgba(214, 226, 242, 0.85)) drop-shadow(0 3px 2px rgba(0, 0, 0, 0.7)); }
.piece.black.king .glyph { filter: drop-shadow(0 0 0.6px rgba(214, 226, 242, 0.85)) drop-shadow(0 3px 2px rgba(0, 0, 0, 0.7)) drop-shadow(0 0 6px var(--accent-soft)); }
.piece.black.selected .glyph { filter: drop-shadow(0 0 0.6px rgba(214, 226, 242, 0.9)) drop-shadow(0 6px 6px rgba(0, 0, 0, 0.65)) drop-shadow(0 0 6px var(--focus-soft)); }
.piece.black.moving .glyph { filter: drop-shadow(0 0 0.6px rgba(214, 226, 242, 0.85)) drop-shadow(0 9px 8px rgba(0, 0, 0, 0.65)); }
.piece.black.danger .glyph { filter: drop-shadow(0 0 0.6px rgba(214, 226, 242, 0.85)) drop-shadow(0 0 8px var(--warn-glow)); }
.pc-svg.black { --pc-stroke: 2; }
.piece .glyph svg { width: 100%; height: 100%; overflow: visible; }
.piece.selected .glyph { transform: translateY(-9%) scale(1.06); filter: drop-shadow(0 6px 6px rgba(0, 0, 0, 0.6)) drop-shadow(0 0 6px var(--focus-soft)); }
.piece.king .glyph { filter: drop-shadow(0 3px 2px rgba(0, 0, 0, 0.55)) drop-shadow(0 0 6px var(--accent-soft)); }
.piece.spawn .glyph { animation: spawn 0.38s var(--ease-pop); }
.piece.captured { z-index: 1; }
.piece.captured .glyph { animation: captured 0.32s ease-in forwards; }
.piece.dimmed { opacity: 0.45; }

/* board foot: one-line legend */
.board-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-2) var(--s-4);
  max-width: min(calc(var(--board-size) * 1.3), 100%);
  font-size: var(--fs-xs);
  color: var(--muted);
  letter-spacing: 0.02em;
}
.foot-item { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; max-width: 100%; }
.foot-res, .foot-dot, .foot-void, .foot-king { display: inline-block; flex: 0 0 auto; }
.foot-res { width: 8px; height: 8px; border: 1.5px solid var(--accent); transform: rotate(45deg); border-radius: 1px; margin: 0 2px; }
.foot-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.foot-void { width: 10px; height: 10px; border-radius: 2px; box-shadow: inset 0 0 0 1px var(--line-2); background: var(--bg-deep); }
.foot-king { width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--warn); }

/* ----------------------------------------------------------- side panel */

.side-section {
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line);
  border-radius: var(--r-l);
  padding: var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  box-shadow: var(--shadow-m);
}
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-2); }
.section-title { margin: 0; font-size: var(--fs-s); letter-spacing: var(--track); text-transform: uppercase; color: var(--text); font-weight: 800; }
.section-sub { font-size: var(--fs-xs); color: var(--muted); letter-spacing: 0.04em; }
/* The setup clock repeated in the panel head, for layouts that put the
   player cards below the board (phones and narrow windows). */
.section-sub .sub-clock { font-weight: 800; letter-spacing: var(--track); text-transform: uppercase; color: var(--text-2); font-variant-numeric: tabular-nums; }
.section-sub .sub-clock.warn { color: var(--warn); }
@media (min-width: 1081px) { .section-sub .sub-clock { display: none; } }
@media (max-width: 1080px) { .section-sub .sub-clock:not([hidden]) + .sub-default { display: none; } }

.map-card { display: grid; grid-template-columns: 64px 1fr; gap: var(--s-3); align-items: center; padding-bottom: var(--s-3); border-bottom: 1px solid var(--line); }
.map-card-text { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-s); color: var(--muted); line-height: 1.4; }
.map-card .map-card-desc { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.map-card-name { font-size: var(--fs-m); font-weight: 800; color: var(--text); letter-spacing: 0.02em; }
.map-card-dim { display: block; font-weight: 500; color: var(--muted); font-size: var(--fs-xs); margin-top: 1px; }
.map-card-res b { color: var(--accent); font-weight: 700; }

.budget { display: flex; flex-direction: column; gap: var(--s-2); }
.budget-main { display: flex; align-items: baseline; gap: var(--s-2); }
.budget-value { font-size: 36px; font-weight: 800; color: var(--accent); line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -0.03em; }
.budget-total { font-size: var(--fs-m); color: var(--muted); font-weight: 600; margin-left: 4px; }
.budget-label { font-size: var(--fs-s); letter-spacing: var(--track); text-transform: uppercase; color: var(--text-2); font-weight: 700; }
.roster { display: flex; flex-wrap: wrap; gap: 6px; min-height: 22px; align-items: center; }
.roster-title { font-size: var(--fs-xs); letter-spacing: var(--track); text-transform: uppercase; color: var(--muted); margin-right: 2px; }
.roster-item {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--fs-s); font-weight: 600; color: var(--text-2);
  border: 1px solid var(--line-2); border-radius: 999px; padding: 2px 8px 2px 5px;
  background: var(--surface-3);
  animation: fade-in 180ms ease-out;
}
.roster-item .pc-svg { font-size: 15px; }
.roster-item .n { color: var(--muted); font-weight: 500; }
.roster-empty { font-size: var(--fs-s); color: var(--muted-2); }
.roster-bank { font-size: var(--fs-s); color: var(--muted); margin-left: auto; }
.roster-bank b { color: var(--accent); }

/* shop */
.shop { display: flex; flex-direction: column; gap: 6px; }
.shop-item {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 7px 10px 7px 9px;
  min-height: 46px;
  min-width: 0;
  border-radius: var(--r-s);
  border: 1px solid var(--line-2);
  background: var(--surface-3);
  cursor: pointer;
  text-align: left;
  transition: border-color var(--t-fast), background var(--t-fast), transform 80ms, opacity var(--t-fast);
}
.shop-item:hover:not(.disabled) { border-color: var(--line-2); background: #2a3140; }
.shop-item:active:not(.disabled) { transform: scale(0.985); }
.shop-item.active { border-color: var(--focus); background: #2a3140; box-shadow: inset 0 0 0 1px var(--focus-soft); }
.shop-item.disabled { opacity: 0.55; cursor: not-allowed; }
.shop-item.disabled .si-name { color: var(--text-2); }
.shop-item.disabled .si-cost { background: transparent; box-shadow: inset 0 0 0 1px var(--line-2); color: var(--muted); }
.shop-item.locked { opacity: 0.6; }
.si-icon { width: 30px; height: 30px; display: grid; place-items: center; }
.si-icon .pc-svg { font-size: 28px; }
.si-name { display: flex; align-items: baseline; gap: 8px; min-width: 0; font-weight: 800; font-size: 14px; line-height: 1.15; color: var(--text); letter-spacing: 0.01em; white-space: nowrap; overflow: hidden; }
.si-tag { font-size: var(--fs-xs); color: var(--muted-2); font-weight: 500; letter-spacing: 0; overflow: hidden; text-overflow: ellipsis; }
.si-cost {
  font-weight: 800;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  font-size: 17px;
  min-width: 40px;
  text-align: center;
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px rgba(240, 179, 74, 0.22);
  transition: background var(--t-fast), color var(--t-fast), box-shadow var(--t-fast);
}
.si-cost.free, .si-cost.locked, .si-cost.done { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 800; background: transparent; box-shadow: inset 0 0 0 1px var(--line-2); color: var(--text-2); white-space: nowrap; padding: 6px 9px; min-width: 0; }
.si-cost.locked { color: var(--muted); box-shadow: inset 0 0 0 1px var(--line-2); border: 0; }
.shop-item.locked .si-name { color: var(--text-2); }
.si-cost.raised { color: var(--accent-2); background: rgba(255, 210, 124, 0.22); box-shadow: inset 0 0 0 1px rgba(255, 210, 124, 0.45); }
.si-cost.raised::after { content: "↑"; font-size: 11px; margin-left: 2px; vertical-align: top; }
.si-cost.changed { animation: price-bump 0.5s var(--ease-pop); }

.hint { margin: 0; font-size: var(--fs-s); color: var(--text-2); line-height: 1.5; min-height: 2.8em; }
.hint strong { color: var(--text); font-weight: 700; }
.hint .warn { color: var(--warn); }

.btn {
  padding: 10px 14px;
  border-radius: var(--r-s);
  border: 1px solid var(--line-2);
  background: var(--surface-3);
  color: var(--text);
  cursor: pointer;
  font-weight: 700;
  font-size: var(--fs-m);
  letter-spacing: 0.03em;
  transition: background var(--t-fast), border-color var(--t-fast), transform 80ms, opacity var(--t-fast);
}
.btn:hover:not(:disabled) { border-color: var(--text-2); background: #2c3443; }
.btn:active:not(:disabled) { transform: scale(0.985); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.btn.primary { background: var(--text); color: var(--bg-deep); border-color: var(--text); }
.btn.primary:hover:not(:disabled) { background: #fff; border-color: #fff; }
/* Confirm Setup, once the force on the board is actually legal: a
   restrained neutral glow (the same --focus used for a selected square)
   so "ready" reads at a glance without reaching for amber (Command and
   resources only) or coral (danger and capture only). */
.btn.primary.ready { border-color: var(--focus); box-shadow: 0 0 0 1px var(--focus-soft), 0 0 14px rgba(236, 240, 246, 0.3); }
.btn.primary.ready:hover:not(:disabled) { border-color: var(--focus); }
.btn.accent { background: var(--accent); color: #1a1207; border-color: var(--accent); }
.btn.accent:hover:not(:disabled) { background: var(--accent-2); border-color: var(--accent-2); }
.btn.ghost { background: rgba(255, 255, 255, 0.02); }
/* the new-match screen's call to action: the ivory of White's material,
   strong against the dark panel without the glare of pure white */
.btn.cta { background: linear-gradient(180deg, #f3ead6, var(--ivory)); color: #1c160c; border-color: #d9cba9; box-shadow: 0 1px 0 rgba(255, 255, 255, 0.35) inset, var(--shadow-m); font-weight: 800; letter-spacing: 0.02em; }
.btn.cta:hover:not(:disabled) { background: linear-gradient(180deg, #faf3e3, #efe5cd); border-color: #e6d9b8; }
.btn.small { padding: 6px 10px; font-size: var(--fs-s); }
.btn.big { padding: 13px 20px; font-size: var(--fs-l); }
.btn-row { display: flex; gap: 6px; align-items: stretch; }
.btn-row .btn { flex: 1; min-width: 0; min-height: 38px; padding-left: 8px; padding-right: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.info { display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-s); padding-bottom: var(--s-3); border-bottom: 1px solid var(--line); }
.info-row { display: flex; justify-content: space-between; gap: var(--s-2); align-items: baseline; }
.info-label { color: var(--muted); letter-spacing: 0.12em; text-transform: uppercase; font-size: var(--fs-xs); flex: 0 0 auto; font-weight: 700; }
.info-value { color: var(--text-2); text-align: right; font-weight: 600; }
.info-top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-2); margin-bottom: 2px; }
.info-turn { font-size: var(--fs-s); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.info-turn b { font-size: 18px; color: var(--text); font-weight: 800; letter-spacing: 0; margin-left: 4px; font-variant-numeric: tabular-nums; }
.info-map { font-size: var(--fs-s); color: var(--text-2); font-weight: 600; text-align: right; }
.countdown {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-2);
  padding: 8px 10px 8px 12px;
  border-radius: var(--r-s);
  border: 1px solid var(--line-2);
  background: var(--bg-deep);
  transition: border-color 0.25s, background 0.25s, box-shadow 0.25s;
}
.cd-label { font-size: var(--fs-xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-2); font-weight: 800; line-height: 1.25; }
.cd-label small { display: block; font-size: var(--fs-xs); letter-spacing: 0.02em; text-transform: none; color: var(--muted); font-weight: 500; margin-top: 1px; }
.cd-value {
  font-size: 22px;
  font-weight: 800;
  line-height: 1;
  min-width: 36px;
  text-align: center;
  padding: 4px 8px;
  border-radius: 999px;
  color: var(--text);
  background: var(--surface-3);
  font-variant-numeric: tabular-nums;
  transition: background 0.25s, box-shadow 0.25s;
}
.countdown.level-2 { border-color: rgba(240, 179, 74, 0.45); }
.countdown.level-2 .cd-label { color: var(--accent); }
.countdown.level-2 .cd-value { color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px rgba(240, 179, 74, 0.35); }
.countdown.level-1 { border-color: var(--accent); background: rgba(240, 179, 74, 0.1); box-shadow: 0 0 22px -8px var(--accent-glow); }
.countdown.level-1 .cd-label { color: var(--accent-2); }
.countdown.level-1 .cd-value { color: #1a1207; background: var(--accent); box-shadow: 0 0 14px -2px var(--accent-glow); }
.countdown.level-1 .cd-value.tick, .countdown.level-2 .cd-value.tick { animation: bump 0.4s var(--ease-pop); }
.shift-row .info-value { color: var(--accent); }
.pass-row .info-value { color: var(--text-2); }

/* move list: a secondary, reference block (the board, the clocks, Command
   and the shop are what a turn is actually decided from), so its heading
   and rows read a size quieter than the other section headings sharing
   this same card. */
.moves-head { margin-top: var(--s-2); padding-top: var(--s-2); border-top: 1px solid var(--line); }
.moves-head .section-title { font-size: var(--fs-xs); color: var(--muted); font-weight: 700; }
.moves {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px 6px;
  max-height: 152px;
  overflow-y: auto;
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  scrollbar-width: thin;
  opacity: 0.9;
}
.moves:empty { display: none; }
.mv {
  display: grid;
  grid-template-columns: 26px 18px minmax(0, 1fr);
  align-items: center;
  gap: 4px;
  min-height: 22px;
  padding: 1px 6px 1px 4px;
  border-radius: var(--r-s);
  color: var(--muted);
  border: 1px solid transparent;
}
.mv.black { grid-template-columns: 0 18px minmax(0, 1fr); }
.mv-n { color: var(--muted-2); font-weight: 700; font-size: var(--fs-xs); }
.mv-glyph { width: 16px; height: 16px; display: inline-flex; opacity: 0.85; }
.mv-glyph .pc-svg { width: 100%; height: 100%; }
.mv-txt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; letter-spacing: 0.02em; }
.mv.capture .mv-txt { color: var(--text); font-weight: 700; }
.mv.pass .mv-txt { color: var(--muted); font-style: italic; }
.mv.pass { grid-template-columns: 26px minmax(0, 1fr); }
.mv.pass.black { grid-template-columns: 0 minmax(0, 1fr); }
.moves.clickable .mv { cursor: pointer; }
.moves.clickable .mv:hover { background: var(--surface-3); border-color: var(--line-2); }
.mv.cur { background: var(--surface-3); border-color: var(--focus); color: var(--text); box-shadow: inset 0 0 0 1px var(--focus-soft); }

/* review controls (replace the shop while stepping through a match) */
.review { display: flex; flex-direction: column; gap: var(--s-2); }
.review-nav { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.review-nav .btn { font-size: 16px; font-weight: 800; padding: 8px 0; letter-spacing: -0.04em; }
.review .hint { min-height: 2.8em; }

/* ------------------------------------------------------------- overlay */

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(10, 12, 16, 0.94);
  display: grid;
  place-items: center;
  z-index: 50;
  animation: fade-in 0.25s ease-out;
  overflow: auto;
  padding: var(--s-5);
}
.overlay.victory { background: rgba(10, 12, 16, 0.9); }
.overlay-card {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-6);
  max-width: 560px;
  width: 100%;
}
.ov-brand { display: flex; align-items: center; gap: 8px; color: var(--muted); }
.ov-brand .brand-mark { width: 14px; height: 14px; }
.ov-brand .brand-word { font-size: 12px; letter-spacing: 0.4em; margin-right: -0.4em; color: var(--text-2); }
.ov-kicker { font-size: var(--fs-s); letter-spacing: 0.3em; text-transform: uppercase; color: var(--muted); }
.ov-title { font-size: 56px; font-weight: 900; letter-spacing: 0.06em; margin: 0; line-height: 1; animation: title-in 0.5s var(--ease-pop); }
.ov-title.white { color: var(--ivory); }
.ov-title.black { color: #c9d3e0; }
.ov-title.brand { letter-spacing: 0.3em; margin-right: -0.3em; color: var(--text); }
.ov-title.victory { color: var(--accent); text-shadow: 0 0 50px var(--accent-glow); }
.ov-sub { color: var(--text-2); font-size: var(--fs-l); line-height: 1.5; margin: 0; }
.ov-line { color: var(--muted); font-size: var(--fs-m); margin: 0; }
.ov-glyph { width: 84px; height: 84px; animation: spawn 0.5s var(--ease-pop); filter: drop-shadow(0 8px 12px rgba(0, 0, 0, 0.7)); }
.ov-glyph .pc-svg { width: 100%; height: 100%; }
.ov-actions { display: flex; gap: var(--s-2); margin-top: var(--s-2); flex-wrap: wrap; justify-content: center; }

/* new-match screen: choose how to play first (four tabs), then only
   that way's options in one panel. Sized to sit inside a laptop
   viewport without scrolling; an opened map grid may extend it.
   Staged like a tabletop: an opaque ground with a soft warm light
   behind the centre, a faint irregular board drifting under it
   (.ov-backdrop), and the panel lifted off both. */
.overlay.modes {
  background:
    radial-gradient(ellipse 46% 40% at 50% 38%, rgba(240, 179, 74, 0.075), transparent 72%),
    radial-gradient(ellipse 70% 62% at 50% 45%, rgba(130, 150, 180, 0.09), transparent 74%),
    var(--bg-deep);
}
.ov-backdrop { display: none; }
.overlay.modes .ov-backdrop {
  display: block;
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  /* pointer parallax: a few pixels against the pointer */
  transform: translate(calc(var(--px, 0) * -14px), calc(var(--py, 0) * -10px));
  transition: transform 900ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
.overlay.modes .ov-backdrop::after {
  /* vignette: the board fades into the ground at the edges and dims
     under the centre so the panel reads first */
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 34% 40% at 50% 50%, rgba(10, 12, 16, 0.5), transparent 100%),
    radial-gradient(ellipse 58% 64% at 50% 50%, transparent 38%, var(--bg-deep) 92%);
}
.ov-bg-drift { position: absolute; inset: 0; display: grid; place-items: center; animation: bg-drift 46s ease-in-out infinite alternate; }
.ov-bg-board {
  --cell: clamp(40px, 4.6vw, 64px);
  display: grid;
  grid-template-columns: repeat(var(--cols, 26), var(--cell));
  grid-auto-rows: var(--cell);
  gap: 5px;
  transform: translateY(-2%);
}
.ov-bg-board .bgc { display: block; border-radius: 3px; background: var(--tile-b); opacity: 0.15; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06); }
.ov-bg-board .bgc.light { background: var(--tile-a); opacity: 0.19; }
.ov-bg-board .bgc.void { background: transparent; opacity: 0; box-shadow: none; }
.ov-bg-board .bgc.res { background: var(--accent); opacity: 0.2; box-shadow: 0 0 22px var(--accent-soft), inset 0 0 0 2px rgba(255, 255, 255, 0.08); animation: bg-res 7s ease-in-out infinite; }
.ov-bg-board .bgc.res:nth-child(odd) { animation-delay: -3.5s; }
@keyframes bg-drift { from { transform: translate(-0.6%, 0.4%); } to { transform: translate(0.6%, -0.4%); } }
@keyframes bg-res { 0%, 100% { opacity: 0.16; } 50% { opacity: 0.3; } }
.overlay.modes .overlay-card { position: relative; z-index: 1; max-width: 720px; padding: var(--s-4) var(--s-6) var(--s-5); gap: var(--s-3); }
.overlay.modes .ov-brand { margin-top: var(--s-2); }
.overlay.modes .ov-title.brand { font-size: 46px; margin-top: 2px; text-shadow: 0 2px 0 rgba(0, 0, 0, 0.5), 0 14px 40px rgba(0, 0, 0, 0.6); }
.overlay.modes .ov-sub { font-size: var(--fs-m); color: var(--muted); margin-bottom: var(--s-3); }
.ov-tabs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-2); width: 100%; margin-top: var(--s-1); }
.ov-tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 11px 8px 9px;
  border-radius: var(--r-m);
  border: 1px solid var(--line-2);
  background: linear-gradient(180deg, #202630, var(--surface-2));
  box-shadow: var(--shadow-s);
  color: var(--text-2);
  cursor: pointer;
  min-width: 0;
  transition: border-color var(--t-fast), background var(--t-fast), transform 80ms, box-shadow var(--t-fast), color var(--t-fast);
}
.ov-tab:hover { border-color: var(--line-2); color: var(--text); transform: translateY(-1px); }
.ov-tab.chosen { border-color: var(--focus); background: linear-gradient(180deg, #2a313c, var(--surface-3)); color: var(--text); box-shadow: 0 0 0 1px var(--focus-soft), var(--shadow-m); }
.ov-tab-name { font-size: var(--fs-m); font-weight: 800; letter-spacing: 0.04em; line-height: 1.15; white-space: nowrap; }
.ov-tab-tag { font-size: var(--fs-xs); letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.ov-tab.chosen .ov-tab-tag { color: var(--text-2); }
.ov-panel {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  text-align: left;
  border: 1px solid var(--line-2);
  border-radius: var(--r-l, 12px);
  background: linear-gradient(180deg, #1d222b, #181c24);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.045), var(--shadow-l), 0 0 0 1px rgba(0, 0, 0, 0.45);
  padding: var(--s-4) var(--s-5);
}
.ov-row { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: var(--s-4); align-items: end; }
.ov-row > .ov-field { align-self: end; }
.ov-opt { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ov-opt-label { font-size: var(--fs-xs); letter-spacing: 0.24em; text-transform: uppercase; color: var(--muted); font-weight: 800; }
.ov-seg { display: flex; gap: 4px; }
.ov-seg-btn { flex: 0 1 auto; padding: 8px 14px; }
.ov-seg-btn b { color: var(--text); font-weight: 800; }
.ov-go { width: 100%; margin-top: var(--s-1); }
.ov-go-row { margin-top: var(--s-1); }
.ov-go-row .btn { padding-left: 16px; padding-right: 16px; }
.ov-join-row { border-top: 1px solid var(--line); padding-top: var(--s-3); }
.ov-join-row .ov-join { max-width: 260px; }
.ov-foot { display: flex; gap: var(--s-2); justify-content: center; flex-wrap: wrap; }
.ov-maps { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--s-2); width: 100%; margin-top: 2px; }
.ov-map {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
  min-width: 0;
  gap: 6px;
  padding: 7px 7px 8px;
  border-radius: var(--r-m);
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--muted);
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast), transform 80ms, box-shadow var(--t-fast);
}
.ov-map:hover { border-color: var(--line-2); color: var(--text); transform: translateY(-1px); }
.ov-map.chosen { border-color: var(--focus); background: var(--surface-3); color: var(--text); box-shadow: 0 0 0 1px var(--focus-soft); }
.ov-map.random.chosen { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-soft); }
/* time control picker */
.ov-times { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); width: 100%; }
.ov-time {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 9px 6px 8px;
  min-width: 0;
  border-radius: var(--r-m);
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--muted);
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast), transform 80ms, box-shadow var(--t-fast);
}
.ov-time:hover { border-color: var(--line-2); color: var(--text); transform: translateY(-1px); }
.ov-time.chosen { border-color: var(--focus); background: var(--surface-3); color: var(--text); box-shadow: 0 0 0 1px var(--focus-soft); }
.ov-time-min { font-size: 20px; font-weight: 800; letter-spacing: 0.04em; line-height: 1; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ov-time-tag { font-size: var(--fs-xs); letter-spacing: 0.08em; text-transform: uppercase; }
.ov-map-name { font-size: var(--fs-xs); letter-spacing: 0.06em; font-weight: 800; text-align: center; line-height: 1.2; text-transform: uppercase; }
.ov-map-tag { font-size: var(--fs-xs); color: var(--muted); text-align: center; line-height: 1.2; margin-top: -3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ov-mode-note { font-size: var(--fs-xs); color: var(--muted); line-height: 1.45; }
.ov-mode-note b { color: var(--text-2); }
/* bot strength (and the Random / Choose map switch, the same control) */
.ov-levels { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.ov-level, .ov-seg-btn {
  padding: 6px 4px;
  border-radius: var(--r-s);
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}
.ov-level:hover, .ov-seg-btn:hover { border-color: var(--line-2); color: var(--text); }
.ov-level.chosen, .ov-seg-btn.chosen { border-color: var(--focus); background: var(--surface-3); color: var(--text); box-shadow: 0 0 0 1px var(--focus-soft); }
/* record (profile) on the menu */
.ov-recent { display: flex; flex-direction: column; gap: 4px; width: 100%; max-height: 220px; overflow-y: auto; scrollbar-width: thin; }
.ov-recent-row {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  gap: var(--s-2);
  align-items: center;
  padding: 5px 8px;
  border-radius: var(--r-s);
  border: 1px solid var(--line);
  background: var(--surface-2);
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: 1.4;
}
.ov-recent-row b { color: var(--text-2); }
.ov-recent-result { font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.ov-recent-row.won .ov-recent-result { color: var(--accent); }
.ov-recent-row.lost .ov-recent-result { color: var(--text-2); }
.ov-recent-txt { min-width: 0; }
/* account panel (sign up / log in / verify / reset) */
.ov-account { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-2) 2px; }
.ov-account-tabs { display: flex; gap: var(--s-2); }
.ov-account-tabs .ov-tab.small { padding: 6px 12px; }
.ov-tab.small { border-radius: var(--r-s); border: 1px solid var(--line); background: var(--surface-2); color: var(--muted); font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.06em; cursor: pointer; }
.ov-tab.small:hover { border-color: var(--line-2); color: var(--text); }
.ov-tab.small.chosen { border-color: var(--focus); background: var(--surface-3); color: var(--text); }
/* an inline, text-styled button (e.g. an opponent's name that opens their profile) */
.ov-link { background: none; border: none; padding: 0; margin: 0; font: inherit; color: var(--text-2); text-decoration: underline; text-decoration-color: var(--line-2); cursor: pointer; }
.ov-link:hover { color: var(--text); text-decoration-color: var(--text-2); }
/* a public player-profile card (view-profile) */
.ov-profile-card { display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-3); border-radius: var(--r-s); border: 1px solid var(--line); background: var(--surface-2); }
.ov-profile-name { font-size: var(--fs-m); font-weight: 800; color: var(--text); }
.ov-profile-stats { font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; }
@media (max-width: 760px) { .ov-maps { grid-template-columns: repeat(3, minmax(0, 1fr)); } .ov-map-tag { white-space: normal; } .ov-tabs { grid-template-columns: 1fr 1fr; } .ov-row { grid-template-columns: 1fr; } }

/* map previews */
.map-mini {
  display: grid;
  grid-template-columns: repeat(var(--cols, 8), 1fr);
  width: 100%;
  gap: 1px;
  padding: 3px;
  background: var(--bg-deep);
  border-radius: 5px;
  box-shadow: inset 0 0 0 1px var(--line);
}
.map-mini .mm { display: block; aspect-ratio: 1 / 1; background: var(--tile-b); border-radius: 1px; }
.map-mini .mm.light { background: var(--tile-a); }
.map-mini .mm.void { background: transparent; }
.map-mini .mm.zw { box-shadow: inset 0 0 0 20px var(--ivory-soft); }
.map-mini .mm.zb { box-shadow: inset 0 0 0 20px rgba(0, 0, 0, 0.32); }
.map-mini .mm.res { background: var(--accent); box-shadow: 0 0 6px var(--accent-glow); }
.map-mini.random { display: grid; place-items: center; aspect-ratio: 1 / 1; color: var(--accent); font-size: 26px; font-weight: 900; }

/* victory */
.overlay.victory .overlay-card { max-width: 780px; padding: var(--s-5) var(--s-6); gap: var(--s-2); }
.overlay.victory .ov-title { font-size: 60px; letter-spacing: 0.08em; margin-right: -0.08em; }
.overlay.victory .ov-title.white { color: var(--ivory); text-shadow: 0 0 50px rgba(234, 223, 198, 0.35); }
.overlay.victory .ov-title.black { color: #d5dde8; text-shadow: 0 0 50px rgba(198, 211, 230, 0.3); }
.overlay.victory .ov-kicker { color: var(--accent); font-weight: 800; }
.overlay.victory .ov-glyph { width: 72px; height: 72px; }
.ov-capture { display: flex; align-items: center; gap: 10px; color: var(--text-2); font-size: 17px; margin-top: var(--s-1); }
.ov-capture b { color: var(--text); font-weight: 700; }
.ov-capture.timeout b { letter-spacing: 0.08em; font-weight: 800; }
.ov-cap-glyph { width: 30px; height: 30px; display: grid; place-items: center; filter: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.6)); }
.ov-cap-glyph .pc-svg { width: 100%; height: 100%; }
.ov-meta { display: flex; gap: var(--s-3); align-items: center; color: var(--muted); font-size: var(--fs-m); }
.ov-meta b { color: var(--text); font-weight: 700; }
.ov-meta .sep { color: var(--muted-2); }
.overlay.victory .ov-actions { margin-top: var(--s-3); }
.overlay.victory .stats { margin-top: var(--s-4); }
.stats {
  width: 100%;
  text-align: left;
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: rgba(22, 26, 33, 0.85);
  padding: var(--s-3) var(--s-4);
  font-size: var(--fs-s);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px var(--s-5);
  margin-top: var(--s-2);
}
.stats h3 { grid-column: 1 / -1; margin: 0 0 4px; font-size: var(--fs-xs); letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted); font-weight: 800; }
.stats .col { display: flex; flex-direction: column; gap: 3px; }
.stats .col-head { font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; font-size: var(--fs-xs); margin-bottom: 2px; color: var(--text-2); }
.stats .col-head.win { color: var(--accent); }
.stats .row { display: flex; justify-content: space-between; gap: 10px; color: var(--text-2); }
.stats .row b { color: var(--text); font-weight: 600; text-align: right; }
.stats .row .g { font-size: 15px; line-height: 1; letter-spacing: 1px; }
.stats .full { grid-column: 1 / -1; }
.stats .agg { grid-column: 1 / -1; border-top: 1px dashed var(--line); padding-top: 8px; margin-top: 4px; color: var(--muted); line-height: 1.55; }
.stats .agg b { color: var(--text); }
.stats .agg .amber { color: var(--accent); }
.ov-tools { display: flex; gap: var(--s-2); justify-content: center; }
.ov-tools .btn { padding: 5px 10px; font-size: var(--fs-xs); }

/* -------------------------------------------------------------- online */

.pc-tag { font-size: var(--fs-xs); color: var(--muted); letter-spacing: 0.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.pc-tag.offline { color: var(--warn); }
.online-rows { display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-s); }
.online-rows .info-value .code { font-family: ui-monospace, Consolas, monospace; letter-spacing: 0.18em; color: var(--accent); font-size: var(--fs-m); }
.online-rows .warn { color: var(--warn); font-weight: 700; }
.ov-field { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); font-weight: 700; min-width: 0; }
.ov-join { display: flex; gap: 6px; }
.input {
  font: inherit; color: var(--text); background: var(--bg-deep); border: 1px solid var(--line-2); border-radius: var(--r-s);
  padding: 10px 12px; min-width: 0; width: 100%; letter-spacing: 0.02em;
}
.input:focus { outline: none; border-color: var(--text-2); }
.input.code { font-family: ui-monospace, Consolas, monospace; letter-spacing: 0.2em; text-transform: uppercase; }
.ov-rejoin { display: flex; flex-wrap: wrap; gap: 6px; }
.ov-code { font-family: ui-monospace, Consolas, monospace; font-size: 44px; font-weight: 800; letter-spacing: 0.3em; margin-right: -0.3em; color: var(--accent); text-shadow: 0 0 30px var(--accent-glow); animation: title-in 0.5s var(--ease-pop); }
.ov-title.searching { color: var(--text); animation: breathe 1.6s ease-in-out infinite; font-size: 40px; }

/* --------------------------------------------------------------- debug */

.debug {
  position: fixed;
  left: 12px;
  bottom: 12px;
  margin: 0;
  max-width: 420px;
  max-height: 40vh;
  overflow: auto;
  font: 11px/1.4 ui-monospace, Consolas, monospace;
  color: #b7c1d3;
  background: rgba(8, 10, 14, 0.92);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  z-index: 40;
}

/* Online diagnostics (?diag=1): dev only, top-right, plain text. */
.diag {
  position: fixed;
  right: 12px;
  top: 12px;
  margin: 0;
  max-width: 460px;
  max-height: 40vh;
  overflow: auto;
  font: 11px/1.45 ui-monospace, Consolas, monospace;
  color: #b7c1d3;
  background: rgba(8, 10, 14, 0.92);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 10px;
  z-index: 40;
  white-space: pre;
  pointer-events: none;
}

/* ---------------------------------------------------------- animations */

@keyframes spawn { 0% { transform: translateY(22%) scale(0.55); opacity: 0; } 60% { opacity: 1; } 100% { transform: translateY(-2%) scale(1); opacity: 1; } }
@keyframes captured { 0% { opacity: 1; transform: scale(1); } 25% { opacity: 1; transform: scale(1.12); } 100% { opacity: 0; transform: scale(0.7) translateY(4%); } }
@keyframes land { 0% { box-shadow: var(--tile-shadow), inset 0 0 0 3px var(--focus); } 100% { box-shadow: var(--tile-shadow), inset 0 0 0 0 transparent; } }
@keyframes impact { 0% { box-shadow: var(--tile-shadow), inset 0 0 0 4px var(--warn), 0 0 26px -2px var(--warn-glow); transform: scale(1.04); } 30% { transform: scale(1); } 100% { box-shadow: var(--tile-shadow), inset 0 0 0 0 transparent, 0 0 0 0 transparent; } }
@keyframes price-bump { 0% { transform: scale(1); } 35% { transform: scale(1.22); background: rgba(255, 210, 124, 0.5); } 100% { transform: scale(1); } }
@keyframes res-ghost { 0% { opacity: 0.9; } 100% { opacity: 0; transform: translate(-50%, -50%) rotate(45deg) scale(1.5); } }
@keyframes res-land { 0% { box-shadow: var(--tile-shadow), inset 0 0 0 1px rgba(240, 179, 74, 0.36), 0 0 28px -4px var(--accent-glow); } 100% { box-shadow: var(--tile-shadow), inset 0 0 0 1px rgba(240, 179, 74, 0.36), 0 0 0 0 transparent; } }
@keyframes breathe { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
@keyframes bump { 0% { transform: scale(1); } 40% { transform: scale(1.18); } 100% { transform: scale(1); } }
@keyframes pip-pop { 0% { transform: scaleY(1); } 50% { transform: scaleY(1.8); } 100% { transform: scaleY(1); } }
@keyframes gain { 0% { opacity: 0; transform: translateY(6px) scale(0.85); } 18% { opacity: 1; transform: translateY(0) scale(1.08); } 32% { transform: scale(1); } 72% { opacity: 1; } 100% { opacity: 0; transform: translateY(-12px); } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes res-arrive { 0% { transform: rotate(45deg) scale(0.2); opacity: 0; } 60% { transform: rotate(45deg) scale(1.25); opacity: 1; } 100% { transform: rotate(45deg) scale(1); } }
@keyframes res-leave { 0% { box-shadow: var(--tile-shadow), inset 0 0 0 3px var(--accent); } 100% { box-shadow: var(--tile-shadow), inset 0 0 0 0 transparent; } }
@keyframes res-breathe { 0%, 100% { transform: scale(0.9); opacity: 0.18; } 50% { transform: scale(1.05); opacity: 0.4; } }
@keyframes card-in { 0% { box-shadow: var(--shadow-m), 0 0 0 0 var(--focus-soft); } 40% { box-shadow: var(--shadow-m), 0 0 0 4px var(--focus-soft); } 100% { box-shadow: var(--shadow-m), 0 0 0 1px var(--focus-soft); } }
@keyframes title-in { from { transform: scale(0.8); opacity: 0; letter-spacing: 0.3em; } to { transform: scale(1); opacity: 1; } }
/* the board turns half round to face the next player, dipping slightly as it goes */
@keyframes board-turn { 0% { transform: rotate(180deg) scale(1); } 50% { transform: rotate(90deg) scale(0.94); } 100% { transform: rotate(0deg) scale(1); } }
@keyframes glow-swap { 0% { opacity: 0; } 60% { opacity: 0; } 100% { opacity: 1; } }
@keyframes stay-upright { 0% { transform: rotate(-180deg); } 50% { transform: rotate(-90deg); } 100% { transform: rotate(0deg); } }
@keyframes card-swap { 0% { opacity: 0; transform: translateY(6px); } 100% { opacity: 1; transform: none; } }
@keyframes turn-pill { 0% { opacity: 0; transform: translateY(-4px); } 100% { opacity: 1; transform: none; } }
@keyframes clock-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}

/* ------------------------------------------- short-viewport overrides */
/* Laptops around 768px tall: the setup panel (map, budget, six shop rows,
   hint, buttons) is taller than the viewport, so it tightens; the piece
   descriptions stay in the tooltips. */
@media (min-width: 1081px) and (max-height: 820px) {
  .setup .shop { gap: 4px; }
  .setup .shop-item { padding: 6px 10px 6px 9px; }
  .setup .map-card .map-card-desc { -webkit-line-clamp: 2; }
  .setup .hint { min-height: 0; line-height: 1.4; }
  .setup .budget-value { font-size: 30px; }
  .setup .map-card { padding-bottom: 8px; }
  .setup .btn { padding-top: 8px; padding-bottom: 8px; }
  .side-section.setup { gap: 8px; }
}

/* ---------------------------------------------- small-screen overrides */
/* Last so they win the cascade over the component rules above. */
@media (max-width: 640px) {
  /* Two rows: brand and actions, then the status line at full width. */
  .topbar { grid-template-columns: 1fr auto; grid-template-rows: auto auto; gap: var(--s-2) var(--s-2); }
  .brand { grid-row: 1; grid-column: 1; }
  .topbar-actions { grid-row: 1; grid-column: 2; display: flex; gap: 6px; }
  .status { grid-row: 2; grid-column: 1 / -1; justify-self: stretch; white-space: normal; flex-wrap: wrap; justify-content: center; gap: 4px var(--s-2); font-size: var(--fs-xs); letter-spacing: 0.1em; }
  .pc-head { flex-wrap: wrap; row-gap: 4px; }
  .status .map-tag, .status .sep { display: none; }
  .brand-word { font-size: 14px; }
  .board-foot { display: none; }
  .foot-item { white-space: normal; }
  .setup .btn-row { flex-wrap: wrap; }
  .setup .btn-row .btn { flex: 1 1 40%; }
  .side-section { padding: var(--s-3); }
  /* A phone's overlay sits right over the panel; near-opaque so the
     result and the rules read cleanly. */
  .overlay, .overlay.victory { padding: var(--s-3); background: rgba(10, 12, 16, 0.97); }
  .overlay-card, .overlay.modes .overlay-card, .overlay.victory .overlay-card, .overlay.help .overlay-card { padding: var(--s-4) var(--s-3); }
  .ov-title { font-size: 40px; }
  .overlay.victory .ov-title { font-size: 40px; }
}

/* ------------------------------------------------------- how to play */
.overlay.help .overlay-card { max-width: 860px; padding: var(--s-5) var(--s-6); gap: var(--s-3); }
.overlay.help .ov-sub { max-width: 640px; }
.ov-title.help-title, .ov-title.off-title { font-size: 34px; letter-spacing: 0.04em; color: var(--text); }
.help-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); width: 100%; text-align: left; }
.help-block { border: 1px solid var(--line); border-radius: var(--r-m); padding: var(--s-3) var(--s-4); background: rgba(22, 26, 33, 0.8); }
.help-block p { margin: 0; font-size: var(--fs-s); line-height: 1.6; color: var(--text-2); }
.help-block p b, .help-pieces b { color: var(--text); font-weight: 700; }
.help-h { margin: 0 0 6px; font-size: var(--fs-xs); letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); font-weight: 800; align-self: flex-start; }
.help-res { color: var(--accent); font-weight: 700; }
.help-pieces { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px var(--s-3); width: 100%; text-align: left; }
.help-piece { display: grid; grid-template-columns: 30px 1fr; grid-template-rows: auto auto; column-gap: 8px; align-items: center; padding: 6px 8px; border: 1px solid var(--line); border-radius: var(--r-s); background: var(--surface); }
.help-glyph { grid-row: 1 / 3; width: 30px; height: 30px; }
.help-glyph .pc-svg { width: 100%; height: 100%; }
.help-piece-name { display: flex; align-items: baseline; gap: 8px; font-size: var(--fs-m); font-weight: 800; color: var(--text); }
.help-piece-name b { color: var(--accent); font-weight: 800; }
.help-piece-name small { font-size: var(--fs-xs); color: var(--muted); font-weight: 500; letter-spacing: 0.02em; }
.help-piece-desc { font-size: var(--fs-xs); color: var(--muted); line-height: 1.4; }
.setup-left b.warn { color: var(--warn); }
.info-value.setup-left b { font-variant-numeric: tabular-nums; }
@media (max-width: 760px) { .help-grid, .help-pieces { grid-template-columns: 1fr; } }
