/*
 * Bixel UI kit: QUARANTINE ZONE.
 *
 * Shared by the menu (index.html), the game (game.html) and the leaderboard. The palette is
 * taken from things already painted in the game world: the amber QUARANTINE floor stencil and
 * hazard paint, the red barrels, the toxic-green sludge and zombies, and the warm flashlight
 * in heavy darkness. Surfaces are near-black grimy charcoal, neutral and slightly warm, so they
 * never tint the cool concrete.
 *
 * Construction (used the same way on every surface):
 *  - Notched frames drawn in whole UI pixels (--ui-px: 3 px desktop, 2 px phones, 4 px on 4K):
 *    four offset hard shadows leave the corner pixel cut, plus a black outer ring.
 *  - Two-tone bevelled faces, hard drops, no blur, no rounded corners.
 *  - Pixel-exact hazard tape (8x8 art-pixel SVG tiles, crispEdges, CSP-safe data: images).
 *  - In-game HUD panels use a 9-slice border image with the exact notch of the canvas status
 *    widgets (rendering/gameLayers.mjs drawStatusPanel).
 *
 * One job per accent:
 *  - Amber:  the action / attention colour. Primary CTA face, hover frames, active tabs, icons,
 *            eyebrows, and hazard tape on high-stakes surfaces (Choose Hero, Ranked, tier
 *            banner, loader, a NEW BEST end-of-run).
 *  - Toxic:  alive / online / positive / progress (online dots, Current, New best, tier labels,
 *            checked toggles, connected).
 *  - Red:    health, bosses, errors and destructive actions (GAME OVER tape, Exit, last heart).
 *  - Gold:   scores and points only.
 *  - Steel:  neutral chrome, and the hazard tape of routine windows and drawers.
 *  - White:  keyboard focus only (2 px white outside a black ring), never hover.
 *  - A hero's own accent: identity only (the selected Choose Hero card).
 */
:root {
  --ui-font: 'Retro Gaming', sans-serif;

  /* ---------------------------------------------------------------- palette */

  /* Surfaces */
  --ui-void: #070808;
  --ui-well: #0a0b0c;
  --ui-face: #16181a;
  --ui-face-hi: #1e2124;
  --ui-face-top: #272b2e;
  --ui-steel-lo: #2a2f32;
  --ui-steel: #3d4448;
  --ui-steel-hi: #5b656b;
  --ui-frame: #030303;

  /* Hazard amber */
  --ui-amber: #f2b134;
  --ui-amber-hi: #ffc54a;
  --ui-amber-lo: #dc9a20;
  --ui-amber-edge: #8c5a0b;
  --ui-amber-deep: #4a3108;
  --ui-amber-ink: #171004;
  --ui-amber-text: #f6c869;

  /* Toxic green */
  --ui-toxic: #7cf05a;
  --ui-toxic-lo: #4cb535;
  --ui-toxic-deep: #173a12;

  /* Alert red */
  --ui-red: #e5483b;
  --ui-red-text: #ff5a4a;
  --ui-red-face: #a3271b;
  --ui-red-face-hi: #bb3123;
  --ui-red-edge: #5a120b;
  --ui-red-dim: #7a2318;

  /* Text */
  --ui-text: #e8eef0;
  --ui-text-bright: #f3f6f7;
  --ui-text-muted: #a3acaf;
  --ui-text-dim: #7d8689;
  --ui-focus: #ffffff;
  --ui-gold: #ffcf4a;
  --ui-gold-deep: #6b4a0e;

  /* ---------------------------------------------------------------- roles */

  --ui-backdrop: rgba(5, 5, 6, 0.8);
  /* Even wash where there is no backdrop blur (touch devices, old browsers). */
  --ui-backdrop-solid: rgba(7, 8, 8, 0.9);
  --ui-panel: rgba(22, 24, 26, 0.96);
  --ui-panel-solid: #17191b;
  --ui-panel-muted: #1d2022;
  --ui-panel-raised: #25292c;
  --ui-border: var(--ui-steel);
  --ui-border-bright: var(--ui-amber);
  --ui-shadow: var(--ui-frame);
  --ui-accent: var(--ui-amber);
  --ui-accent-strong: var(--ui-amber-lo);
  --ui-accent-deep: var(--ui-amber-deep);
  --ui-warning: var(--ui-amber);
  --ui-danger: var(--ui-red);
  --ui-danger-deep: #7a1c14;
  --ui-success: var(--ui-toxic);
  --ui-radius: 0;
  --ui-control-height: 50px;

  /*
   * Pixel type scale. 'Retro Gaming' is drawn on an 11-unit em grid, so it is
   * only perfectly crisp at multiples of 11px.
   */
  --ui-type-label: 11px;
  --ui-type-value: 22px;
  --ui-type-title: 33px;

  /*
   * In-game HUD language: one translucent charcoal panel with a notched steel frame, shared by
   * the DOM HUD and the canvas status widgets (rendering/gameLayers.mjs mirrors these values in
   * STATUS_THEME: panelFill, panelFillStrong, panelBorder, panelEdge, panelHighlight).
   */
  --ui-hud-bg: rgba(14, 15, 16, 0.86);
  --ui-hud-bg-strong: rgba(14, 15, 16, 0.95);
  --ui-hud-border: #434a4f;
  --ui-hud-edge: rgba(0, 0, 0, 0.92);
  --ui-hud-highlight: rgba(255, 244, 222, 0.06);
  --ui-hud-shadow: rgba(0, 0, 0, 0.3);
  --ui-hud-radius: 0;
  --ui-hud-inset: 12px;
  --ui-hud-gap: 8px;
  --ui-hud-row: 52px;
  /* One HUD art pixel; the game world draws 1 art px as 3 screen px. */
  --ui-pixel: 3px;
  /* One UI "pixel": borders, notches, tape and drop edges are whole multiples of it. */
  --ui-px: var(--ui-pixel);

  /* ---------------------------------------------------------------- pixel textures */

  /* 1 SVG unit = 1 art pixel, scaled by --ui-px. */
  --ui-tile: calc(8 * var(--ui-px));
  --ui-grime-size: calc(32 * var(--ui-px));
  /* Hazard tape: amber (attention, stakes), red (game over, boss, errors), toxic (boss down),
     steel (routine windows and drawers). */
  --ui-stripe-amber: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Crect width='8' height='8' fill='%23141516'/%3E%3Cpath fill='%23f2b134' d='M0 0h4v1H0zM0 1h3v1H0zM7 1h1v1H7zM0 2h2v1H0zM6 2h2v1H6zM0 3h1v1H0zM5 3h3v1H5zM4 4h4v1H4zM3 5h4v1H3zM2 6h4v1H2zM1 7h4v1H1z'/%3E%3C/svg%3E");
  --ui-stripe-red: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Crect width='8' height='8' fill='%23141516'/%3E%3Cpath fill='%23d8392b' d='M0 0h4v1H0zM0 1h3v1H0zM7 1h1v1H7zM0 2h2v1H0zM6 2h2v1H6zM0 3h1v1H0zM5 3h3v1H5zM4 4h4v1H4zM3 5h4v1H3zM2 6h4v1H2zM1 7h4v1H1z'/%3E%3C/svg%3E");
  --ui-stripe-toxic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Crect width='8' height='8' fill='%23101410'/%3E%3Cpath fill='%235fc844' d='M0 0h4v1H0zM0 1h3v1H0zM7 1h1v1H7zM0 2h2v1H0zM6 2h2v1H6zM0 3h1v1H0zM5 3h3v1H5zM4 4h4v1H4zM3 5h4v1H3zM2 6h4v1H2zM1 7h4v1H1z'/%3E%3C/svg%3E");
  --ui-stripe-steel: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Crect width='8' height='8' fill='%23141516'/%3E%3Cpath fill='%233d4448' d='M0 0h4v1H0zM0 1h3v1H0zM7 1h1v1H7zM0 2h2v1H0zM6 2h2v1H6zM0 3h1v1H0zM5 3h3v1H5zM4 4h4v1H4zM3 5h4v1H3zM2 6h4v1H2zM1 7h4v1H1z'/%3E%3C/svg%3E");
  /* Faint art-pixel specks and scuffs on panel faces. */
  --ui-grime: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' shape-rendering='crispEdges'%3E%3Cpath fill='%23fff' fill-opacity='.035' d='M7 29h1v1h-1zM19 29h1v1h-1zM1 27h1v1h-1zM11 1h1v1h-1zM2 31h1v1h-1zM31 17h1v1h-1zM14 17h1v1h-1zM19 24h1v1h-1zM24 13h1v1h-1zM15 27h1v1h-1zM11 15h1v1h-1zM2 23h1v1h-1zM26 11h1v1h-1zM5 31h1v1h-1zM3 14h1v1h-1zM14 3h1v1h-1z'/%3E%3Cpath fill='%23000' fill-opacity='.22' d='M3 19h1v1h-1zM24 2h1v1h-1zM19 29h1v1h-1zM8 18h1v1h-1zM11 10h1v1h-1zM16 22h1v1h-1zM9 5h1v1h-1zM27 20h1v1h-1zM12 31h1v1h-1zM15 5h1v1h-1zM8 29h1v1h-1zM18 15h1v1h-1zM5 13h1v1h-1zM5 0h1v1h-1zM22 24h1v1h-1zM4 17h1v1h-1zM23 28h1v1h-1zM11 13h1v1h-1zM20 26h1v1h-1zM16 15h1v1h-1zM25 30h1v1h-1zM10 28h1v1h-1z'/%3E%3Cpath fill='%23fff' fill-opacity='.025' d='M5 8h5v1h-5zM18 6h2v1h-2zM7 26h5v1h-5zM5 16h5v1h-5z'/%3E%3C/svg%3E");

  /*
   * HUD frames: 9-slice border images, 3 px wide = the canvas widgets' 1 px black edge plus their
   * 2 px notched frame, drawn inside the box (border-image: var(--ui-hud-frame) 3 / 3px).
   */
  --ui-hud-frame: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9' viewBox='0 0 9 9' shape-rendering='crispEdges'%3E%3Cpath fill='%23000' fill-opacity='.92' d='M3 0h3v1H3zM3 8h3v1H3zM0 3h1v3H0zM8 3h1v3H8z'/%3E%3Cpath fill='%23434a4f' d='M3 1h3v2H3zM3 6h3v2H3zM1 3h2v3H1zM6 3h2v3H6zM2 2h1v1H2zM6 2h1v1H6zM2 6h1v1H2zM6 6h1v1H6z'/%3E%3C/svg%3E");
  --ui-hud-frame-amber: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9' viewBox='0 0 9 9' shape-rendering='crispEdges'%3E%3Cpath fill='%23000' fill-opacity='.92' d='M3 0h3v1H3zM3 8h3v1H3zM0 3h1v3H0zM8 3h1v3H8z'/%3E%3Cpath fill='%23f2b134' d='M3 1h3v2H3zM3 6h3v2H3zM1 3h2v3H1zM6 3h2v3H6zM2 2h1v1H2zM6 2h1v1H6zM2 6h1v1H2zM6 6h1v1H6z'/%3E%3C/svg%3E");
  --ui-hud-frame-amber-edge: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9' viewBox='0 0 9 9' shape-rendering='crispEdges'%3E%3Cpath fill='%23000' fill-opacity='.92' d='M3 0h3v1H3zM3 8h3v1H3zM0 3h1v3H0zM8 3h1v3H8z'/%3E%3Cpath fill='%238c5a0b' d='M3 1h3v2H3zM3 6h3v2H3zM1 3h2v3H1zM6 3h2v3H6zM2 2h1v1H2zM6 2h1v1H6zM2 6h1v1H2zM6 6h1v1H6z'/%3E%3C/svg%3E");
  --ui-hud-frame-red: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9' viewBox='0 0 9 9' shape-rendering='crispEdges'%3E%3Cpath fill='%23000' fill-opacity='.92' d='M3 0h3v1H3zM3 8h3v1H3zM0 3h1v3H0zM8 3h1v3H8z'/%3E%3Cpath fill='%23e5483b' d='M3 1h3v2H3zM3 6h3v2H3zM1 3h2v3H1zM6 3h2v3H6zM2 2h1v1H2zM6 2h1v1H6zM2 6h1v1H2zM6 6h1v1H6z'/%3E%3C/svg%3E");
  --ui-hud-frame-red-dim: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9' viewBox='0 0 9 9' shape-rendering='crispEdges'%3E%3Cpath fill='%23000' fill-opacity='.92' d='M3 0h3v1H3zM3 8h3v1H3zM0 3h1v3H0zM8 3h1v3H8z'/%3E%3Cpath fill='%237a2318' d='M3 1h3v2H3zM3 6h3v2H3zM1 3h2v3H1zM6 3h2v3H6zM2 2h1v1H2zM6 2h1v1H6zM2 6h1v1H2zM6 6h1v1H6z'/%3E%3C/svg%3E");
  --ui-hud-frame-toxic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9' viewBox='0 0 9 9' shape-rendering='crispEdges'%3E%3Cpath fill='%23000' fill-opacity='.92' d='M3 0h3v1H3zM3 8h3v1H3zM0 3h1v3H0zM8 3h1v3H8z'/%3E%3Cpath fill='%234cb535' d='M3 1h3v2H3zM3 6h3v2H3zM1 3h2v3H1zM6 3h2v3H6zM2 2h1v1H2zM6 2h1v1H6zM2 6h1v1H2zM6 6h1v1H6z'/%3E%3C/svg%3E");

  /*
   * Stepped hard-pixel glows (offset copies with falling alpha, no blur; the corners stay cut).
   * --ui-glow-amber sits outside a 1-UI-px frame ring; --ui-glow-toxic outside the box itself.
   */
  --ui-glow-amber:
    0 calc(-1 * var(--ui-px) - 2px) 0 0 rgba(242, 177, 52, 0.42),
    0 calc(var(--ui-px) + 2px) 0 0 rgba(242, 177, 52, 0.42),
    calc(-1 * var(--ui-px) - 2px) 0 0 0 rgba(242, 177, 52, 0.42),
    calc(var(--ui-px) + 2px) 0 0 0 rgba(242, 177, 52, 0.42),
    0 calc(-1 * var(--ui-px) - 4px) 0 0 rgba(242, 177, 52, 0.16),
    0 calc(var(--ui-px) + 4px) 0 0 rgba(242, 177, 52, 0.16),
    calc(-1 * var(--ui-px) - 4px) 0 0 0 rgba(242, 177, 52, 0.16),
    calc(var(--ui-px) + 4px) 0 0 0 rgba(242, 177, 52, 0.16);
  --ui-glow-toxic:
    0 -2px 0 0 rgba(124, 240, 90, 0.45),
    0 2px 0 0 rgba(124, 240, 90, 0.45),
    -2px 0 0 0 rgba(124, 240, 90, 0.45),
    2px 0 0 0 rgba(124, 240, 90, 0.45),
    0 -4px 0 0 rgba(124, 240, 90, 0.16),
    0 4px 0 0 rgba(124, 240, 90, 0.16),
    -4px 0 0 0 rgba(124, 240, 90, 0.16),
    4px 0 0 0 rgba(124, 240, 90, 0.16);
}

@media (max-width: 760px), (max-height: 520px) {
  :root {
    --ui-hud-inset: 8px;
    --ui-hud-gap: 6px;
    --ui-hud-row: 44px;
    --ui-pixel: 2px;
  }
}

@media (min-width: 2200px) and (min-height: 1200px) {
  :root {
    --ui-hud-inset: 18px;
    --ui-hud-gap: 10px;
    --ui-hud-row: 64px;
    --ui-pixel: 4px;
    --ui-type-value: 33px;
  }
}

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

button,
input,
a {
  font-family: var(--ui-font);
}

[hidden] {
  display: none !important;
}

/* ------------------------------------------------------------------ windows */

.overlay,
.ui-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  overflow: auto;
  background: radial-gradient(ellipse 80% 70% at 50% 45%, rgba(5, 5, 6, 0.55), rgba(3, 3, 4, 0.86));
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/* Without a backdrop blur the lighter vignette centre would show live gameplay: even wash. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .overlay,
  .ui-overlay {
    background: var(--ui-backdrop-solid);
  }
}

/*
 * Window plate: grimy charcoal face, a notched 1-UI-px steel frame, a 2-UI-px black ring and a
 * hard drop. Every dialog, drawer and result card is one of these.
 */
.ui-panel,
.popup,
.ui-dialog,
.game-over-content,
.duos-death-modal__panel,
.rotate-card__panel,
.asset-loader__panel {
  border: 0;
  border-radius: 0;
  background:
    var(--ui-grime) 0 0 / var(--ui-grime-size) repeat,
    linear-gradient(180deg, #1c1f21 0, #151719 calc(24 * var(--ui-px)), #121415 100%);
  box-shadow:
    inset 0 calc(4 * var(--ui-px)) 0 0 rgba(255, 244, 222, 0.03),
    0 calc(-1 * var(--ui-px)) 0 0 var(--ui-steel),
    0 var(--ui-px) 0 0 var(--ui-steel),
    calc(-1 * var(--ui-px)) 0 0 0 var(--ui-steel),
    var(--ui-px) 0 0 0 var(--ui-steel),
    0 0 0 calc(2 * var(--ui-px)) var(--ui-frame),
    0 calc(5 * var(--ui-px)) 0 calc(2 * var(--ui-px)) rgba(0, 0, 0, 0.55);
  color: var(--ui-text);
}

.popup,
.ui-dialog,
.game-over-content,
.duos-death-modal__panel,
.rotate-card__panel,
.asset-loader__panel {
  position: relative;
}

/*
 * Hazard-tape header trim. Tape hierarchy: steel for routine windows (settings, name, duos, log
 * in, leaderboard, pause), amber for attention and stakes (Choose Hero, loader, a NEW BEST
 * result), red for GAME OVER, the Duos death notice and errors.
 */
.popup::before,
.ui-dialog::before,
.game-over-content::before,
.duos-death-modal__panel::before,
.rotate-card__panel::before,
.asset-loader__panel::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: calc(3 * var(--ui-px));
  background: var(--ui-stripe-steel) 0 0 / var(--ui-tile) repeat;
  box-shadow: 0 var(--ui-px) 0 0 var(--ui-frame);
  pointer-events: none;
}

.popup,
.ui-dialog {
  width: min(500px, calc(100vw - 40px));
  max-height: calc(100dvh - 40px);
  padding: calc(24px + 3 * var(--ui-px)) 24px 24px;
  overflow-x: hidden;
  overflow-y: auto;
  text-align: center;
}

.popup h2,
.ui-dialog__title {
  margin: 0 0 20px;
  color: var(--ui-text-bright);
  font-size: var(--ui-type-title);
  line-height: 1.1;
  letter-spacing: 3px;
  text-shadow:
    0 var(--ui-px) 0 var(--ui-amber-edge),
    0 calc(2 * var(--ui-px)) 0 var(--ui-frame);
  text-transform: uppercase;
}

.ui-dialog__copy {
  margin: -6px auto 20px;
  max-width: 38ch;
  color: var(--ui-text-muted);
  font-size: 12px;
  line-height: 1.6;
}

.ui-actions {
  display: grid;
  justify-items: center;
  gap: 10px;
  width: min(100%, 340px);
  margin: 0 auto;
}

.ui-actions > .ui-button,
.ui-actions > .close-button {
  width: 100%;
  margin: 0;
}

/* ------------------------------------------------------------------ buttons */

/*
 * Steel button: two-tone face, notched 1-UI-px frame (--b-o), hard drop. Variants only swap
 * the --b-* variables. Primary = solid amber with hazard-stripe bumpers (the one call to
 * action), warning = amber outline (secondary), danger = alert red (destructive).
 */
.ui-button,
.close-button,
.popup-connect-btn {
  --b-face: var(--ui-face-hi);
  --b-face-hi: var(--ui-face-top);
  --b-edge: #101213;
  --b-o: var(--ui-steel);
  --b-text: var(--ui-text);
  --b-hl: rgba(255, 244, 222, 0.07);
  --b-drop: 0 calc(2 * var(--ui-px)) 0 0 rgba(0, 0, 0, 0.55);
  --b-glow: 0 0 0 0 transparent;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--ui-control-height);
  padding: 11px 18px;
  border: 0;
  border-radius: 0;
  background: linear-gradient(180deg, var(--b-face-hi) 0 50%, var(--b-face) 50% 100%);
  box-shadow:
    inset 0 var(--ui-px) 0 0 var(--b-hl),
    inset 0 calc(-1 * var(--ui-px)) 0 0 var(--b-edge),
    0 calc(-1 * var(--ui-px)) 0 0 var(--b-o),
    0 var(--ui-px) 0 0 var(--b-o),
    calc(-1 * var(--ui-px)) 0 0 0 var(--b-o),
    var(--ui-px) 0 0 0 var(--b-o),
    var(--b-drop),
    var(--b-glow);
  color: var(--b-text);
  cursor: pointer;
  font-size: 15px;
  font-weight: normal;
  letter-spacing: 1px;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.45);
  text-transform: uppercase;
  transition: transform 80ms steps(2), filter 80ms steps(2);
}

/* Hover only where a pointer can hover, so a tapped button does not stay lit on phones. */
@media (hover: hover) {
  .ui-button:hover,
  .close-button:hover,
  .popup-connect-btn:hover {
    --b-face: #25292c;
    --b-face-hi: #2f3438;
    --b-o: var(--ui-amber);
  }
}

.ui-button:active,
.close-button:active,
.popup-connect-btn:active {
  --b-hl: rgba(0, 0, 0, 0.35);
  --b-drop: 0 0 0 0 transparent;
  transform: translateY(var(--ui-px));
}

/* Keyboard focus: the frame turns black and a 2 px white frame sits right outside it. */
.ui-button:focus-visible,
.close-button:focus-visible,
.popup-connect-btn:focus-visible {
  --b-o: var(--ui-frame);
  outline: 2px solid var(--ui-focus);
  outline-offset: var(--ui-px);
}

.tab-button:focus-visible,
.ui-input:focus-visible,
.characterOption:focus-visible {
  outline: 2px solid var(--ui-focus);
  outline-offset: 1px;
}

.ui-button:disabled,
.ui-button[aria-disabled='true'],
.popup-connect-btn:disabled {
  cursor: not-allowed;
  opacity: 0.45;
  filter: grayscale(0.6);
  transform: none;
}

.ui-button--primary {
  --b-face: var(--ui-amber-lo);
  --b-face-hi: var(--ui-amber);
  --b-edge: var(--ui-amber-edge);
  --b-o: var(--ui-frame);
  --b-text: var(--ui-amber-ink);
  --b-hl: rgba(255, 236, 186, 0.55);
  text-shadow: none;
}

@media (hover: hover) {
  .ui-button--primary:hover {
    --b-face: var(--ui-amber);
    --b-face-hi: var(--ui-amber-hi);
    --b-o: var(--ui-frame);
    --b-glow: var(--ui-glow-amber);
  }
}

/* The key actions (Play, Resume, Continue, Restart) carry hazard-stripe bumpers at both ends. */
.ui-button--primary:not(.ui-button--compact) {
  padding-inline: calc(14px + 5 * var(--ui-px));
}

.ui-button--primary:not(.ui-button--compact)::before,
.ui-button--primary:not(.ui-button--compact)::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: calc(4 * var(--ui-px));
  background: var(--ui-stripe-amber) 0 0 / var(--ui-tile) repeat;
  pointer-events: none;
}

.ui-button--primary:not(.ui-button--compact)::before {
  left: 0;
  box-shadow: inset calc(-1 * var(--ui-px)) 0 0 0 var(--ui-frame);
}

.ui-button--primary:not(.ui-button--compact)::after {
  right: 0;
  box-shadow: inset var(--ui-px) 0 0 0 var(--ui-frame);
}

.ui-button--warning {
  --b-face: #211c12;
  --b-face-hi: #2a2416;
  --b-edge: #120f09;
  --b-o: var(--ui-amber-edge);
  --b-text: var(--ui-amber-text);
}

@media (hover: hover) {
  .ui-button--warning:hover {
    --b-face: #2c2415;
    --b-face-hi: #382d18;
    --b-o: var(--ui-amber);
    --b-text: var(--ui-amber-hi);
  }
}

.ui-button--danger {
  --b-face: var(--ui-red-face);
  --b-face-hi: var(--ui-red-face-hi);
  --b-edge: var(--ui-red-edge);
  --b-o: var(--ui-frame);
  --b-text: #fff3f0;
  --b-hl: rgba(255, 190, 170, 0.22);
}

@media (hover: hover) {
  .ui-button--danger:hover {
    --b-face: #b52e20;
    --b-face-hi: #cf3a29;
    --b-o: var(--ui-frame);
    --b-text: #ffffff;
  }
}

.ui-button--compact {
  min-height: 34px;
  padding: 7px 11px;
  font-size: 10px;
}

/* ------------------------------------------------------------------ inputs and tabs */

.ui-input {
  width: 100%;
  min-height: 46px;
  padding: 10px 12px;
  border: 0;
  border-radius: 0;
  background: var(--ui-well);
  box-shadow:
    inset 0 0 0 var(--ui-px) var(--ui-steel),
    inset 0 calc(2 * var(--ui-px)) 0 0 rgba(0, 0, 0, 0.55);
  color: var(--ui-text);
  caret-color: var(--ui-amber);
  font-size: 14px;
}

/* The frame brightens while typing; the white focus frame (above) still shows, because a
   focused text field always matches :focus-visible. */
.ui-input:focus {
  box-shadow:
    inset 0 0 0 var(--ui-px) var(--ui-steel-hi),
    inset 0 calc(2 * var(--ui-px)) 0 0 rgba(0, 0, 0, 0.55);
}

.ui-input::placeholder {
  color: var(--ui-text-dim);
}

.leaderboard-tabs,
.ui-tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: calc(2 * var(--ui-px));
  margin-bottom: 18px;
  padding: var(--ui-px);
  border: 0;
  border-radius: 0;
  background: var(--ui-well);
  box-shadow: inset 0 0 0 var(--ui-px) var(--ui-steel-lo);
}

.tab-button {
  min-width: 0;
  min-height: 38px;
  padding: 7px 8px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--ui-text-muted);
  cursor: pointer;
  font-size: 11px;
  letter-spacing: 1px;
  line-height: 1.2;
  text-transform: uppercase;
  transition: color 120ms steps(2), background-color 120ms steps(2);
}

@media (hover: hover) {
  .tab-button:hover {
    background: #1b1e20;
    color: var(--ui-text);
  }
}

.tab-button.active {
  background: linear-gradient(180deg, var(--ui-amber) 0 50%, var(--ui-amber-lo) 50% 100%);
  box-shadow: inset 0 calc(-1 * var(--ui-px)) 0 0 var(--ui-amber-edge);
  color: var(--ui-amber-ink);
}

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

/*
 * Compact translucent panel used by every in-game HUD readout: charcoal fill and the canvas
 * widgets' notched frame (1 px black edge + 2 px steel) as a 9-slice, inside the box.
 */
.hud-panel {
  border: 3px solid transparent;
  border-image: var(--ui-hud-frame) 3 / 3px stretch;
  border-radius: 0;
  background:
    var(--ui-grime) 0 0 / var(--ui-grime-size) repeat,
    var(--ui-hud-bg);
  background-clip: padding-box;
  box-shadow:
    inset 0 1px 0 var(--ui-hud-highlight),
    0 5px 0 -3px var(--ui-hud-shadow);
  color: var(--ui-text);
  font-family: var(--ui-font);
}

/* ------------------------------------------------------------------ loader */

/*
 * Full-screen loader shared by the home preloader (#assetLoader) and the game
 * boot overlay (#gameLoader). Its title is the menu wordmark.
 */
.asset-loader {
  position: fixed;
  inset: 0;
  z-index: 5000;
  display: grid;
  place-items: center;
  padding: 20px;
  background:
    radial-gradient(ellipse 46% 40% at 50% 46%, rgba(242, 177, 52, 0.1), transparent 70%),
    var(--ui-void);
  color: var(--ui-text);
  font-family: var(--ui-font);
  opacity: 1;
  transition: opacity 220ms ease, visibility 0s linear 0s;
}

.asset-loader[hidden] {
  display: none !important;
}

.asset-loader[data-state='ready'] {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 220ms ease, visibility 0s linear 220ms;
}

.asset-loader__panel {
  display: grid;
  justify-items: center;
  width: min(420px, 100%);
  gap: 12px;
  padding: calc(22px + 3 * var(--ui-px)) 22px 20px;
  text-align: center;
}

.asset-loader__panel::before {
  background-image: var(--ui-stripe-amber);
}

/* Same treatment as .menu-logo__word: mixed-case white face, amber extrusion. */
.asset-loader__title {
  margin-bottom: calc(3 * var(--ui-px));
  color: var(--ui-text-bright);
  font-size: 44px;
  line-height: 1;
  text-shadow:
    0 var(--ui-px) 0 var(--ui-amber),
    0 calc(2 * var(--ui-px)) 0 var(--ui-amber-edge),
    0 calc(3 * var(--ui-px)) 0 var(--ui-frame),
    0 calc(5 * var(--ui-px)) 0 rgba(0, 0, 0, 0.45);
}

.asset-loader__label {
  min-height: 1em;
  color: var(--ui-toxic);
  font-size: var(--ui-type-label);
  letter-spacing: 1px;
  line-height: 1.3;
  text-transform: uppercase;
}

.asset-loader__track {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: calc(18px + 2 * var(--ui-px));
  padding: var(--ui-px);
  border: 0;
  border-radius: 0;
  background: var(--ui-well);
  box-shadow:
    inset 0 0 0 var(--ui-px) var(--ui-steel-lo),
    0 0 0 var(--ui-px) var(--ui-frame);
}

.asset-loader__bar {
  width: 0%;
  height: 100%;
  background:
    repeating-linear-gradient(90deg, transparent 0 calc(4 * var(--ui-px)), rgba(23, 16, 4, 0.55) calc(4 * var(--ui-px)) calc(5 * var(--ui-px))),
    linear-gradient(180deg, var(--ui-amber-hi) 0 var(--ui-px), var(--ui-amber) var(--ui-px) 60%, var(--ui-amber-lo) 60%);
}

/* Waiting on something with no measurable progress (session handshake). */
.asset-loader[data-state='busy'] .asset-loader__bar {
  width: 34%;
  animation: asset-loader-scan 1.1s steps(12) infinite;
}

.asset-loader__percent {
  min-height: 1em;
  color: var(--ui-text);
  font-size: var(--ui-type-value);
  line-height: 1;
  text-shadow: 2px 2px 0 var(--ui-shadow);
}

.asset-loader__error {
  max-width: 34ch;
  margin: 0;
  color: var(--ui-red-text);
  font-size: var(--ui-type-label);
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.asset-loader__actions {
  width: 100%;
  margin-top: 4px;
}

.asset-loader[data-state='error'] {
  background:
    radial-gradient(ellipse 46% 40% at 50% 46%, rgba(229, 72, 59, 0.08), transparent 70%),
    var(--ui-void);
}

.asset-loader[data-state='error'] .asset-loader__panel::before {
  background-image: var(--ui-stripe-red);
}

.asset-loader[data-state='error'] .asset-loader__title {
  color: var(--ui-red-text);
  text-shadow:
    0 var(--ui-px) 0 var(--ui-red-edge),
    0 calc(2 * var(--ui-px)) 0 var(--ui-frame);
}

.asset-loader[data-state='error'] .asset-loader__label {
  color: var(--ui-warning);
}

.asset-loader[data-state='error'] .asset-loader__track,
.asset-loader[data-state='error'] .asset-loader__percent {
  display: none;
}

@keyframes asset-loader-scan {
  from { transform: translateX(-100%); }
  to { transform: translateX(300%); }
}

@media (max-width: 620px) {
  .overlay,
  .ui-overlay {
    align-items: flex-start;
    padding: max(12px, env(safe-area-inset-top)) 12px max(12px, env(safe-area-inset-bottom));
  }

  .popup,
  .ui-dialog {
    width: 100%;
    max-height: calc(100dvh - 24px);
    padding: calc(18px + 3 * var(--ui-px)) 14px 18px;
  }

  .popup h2,
  .ui-dialog__title {
    font-size: var(--ui-type-value);
    letter-spacing: 2px;
  }

  .ui-button,
  .close-button,
  .popup-connect-btn {
    min-height: 46px;
    padding-inline: 12px;
    font-size: 13px;
  }

  .ui-button--primary:not(.ui-button--compact) {
    padding-inline: calc(12px + 5 * var(--ui-px));
  }
}

/* ------------------------------------------------------------------ menu kit
 * Shared pixel-UI pieces for the front end (index.html, leaderboard).
 */

/* Generated pixel art (portraits, sprite canvases) scales by nearest neighbour. */
.pixel-art {
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}

@supports (image-rendering: pixelated) {
  .pixel-art {
    image-rendering: pixelated;
  }
}

/* Notched pixel plate: the window plate at a smaller scale (player card, stack, toasts). */
.px-box {
  --px-outline: var(--ui-steel);
  --px-face: rgba(20, 22, 24, 0.93);
  background: var(--ui-grime) 0 0 / var(--ui-grime-size) repeat, var(--px-face);
  border: 0;
  border-radius: 0;
  box-shadow:
    inset 0 var(--ui-px) 0 0 rgba(255, 244, 222, 0.05),
    0 calc(-1 * var(--ui-px)) 0 0 var(--px-outline),
    0 var(--ui-px) 0 0 var(--px-outline),
    calc(-1 * var(--ui-px)) 0 0 0 var(--px-outline),
    var(--ui-px) 0 0 0 var(--px-outline),
    0 0 0 calc(2 * var(--ui-px)) var(--ui-frame),
    0 calc(4 * var(--ui-px)) 0 calc(2 * var(--ui-px)) rgba(0, 0, 0, 0.45);
  color: var(--ui-text);
}

/* Stencil labels: uppercase pixel type with whole-pixel tracking. */
.ui-eyebrow {
  margin: 0;
  color: var(--ui-amber);
  font-size: var(--ui-type-label);
  letter-spacing: 1px;
  line-height: 1.2;
  text-transform: uppercase;
}

.ui-field-label {
  display: block;
  margin: 0 0 8px;
  color: var(--ui-amber-text);
  font-size: var(--ui-type-label);
  letter-spacing: 1px;
  line-height: 1.3;
  text-align: left;
  text-transform: uppercase;
}

.ui-field-error {
  margin: 8px 0 0;
  color: var(--ui-red-text);
  font-size: var(--ui-type-label);
  line-height: 1.5;
  text-align: left;
}

.ui-dialog__hint {
  margin: 14px auto 0;
  max-width: 40ch;
  color: var(--ui-text-muted);
  font-size: var(--ui-type-label);
  line-height: 1.6;
}

.ui-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 16px 0;
  color: var(--ui-text-dim);
  font-size: var(--ui-type-label);
  letter-spacing: 1px;
  text-transform: uppercase;
}

.ui-divider::before,
.ui-divider::after {
  content: "";
  flex: 1;
  height: var(--ui-px);
  background: repeating-linear-gradient(90deg, var(--ui-steel) 0 calc(2 * var(--ui-px)), transparent calc(2 * var(--ui-px)) calc(4 * var(--ui-px)));
}

.ui-actions--row {
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  width: min(100%, 420px);
}

@media (max-width: 420px) {
  .ui-actions--row {
    grid-auto-flow: row;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ui-button,
  .close-button,
  .popup-connect-btn,
  .tab-button,
  .asset-loader,
  .asset-loader[data-state='ready'] {
    transition: none;
  }

  .asset-loader[data-state='busy'] .asset-loader__bar {
    width: 100%;
    animation: none;
    opacity: 0.45;
  }
}

/*
 * Forced colours drop box shadows and border images, which draw every frame here. Give the
 * framed pieces a real outline, and use system colours for the call to action and focus.
 */
@media (forced-colors: active) {
  .ui-panel,
  .popup,
  .ui-dialog,
  .game-over-content,
  .duos-death-modal__panel,
  .rotate-card__panel,
  .asset-loader__panel,
  .px-box,
  .ui-input,
  .leaderboard-tabs,
  .ui-tabs,
  .asset-loader__track {
    outline: 2px solid CanvasText;
    outline-offset: -2px;
  }

  .ui-button,
  .close-button,
  .popup-connect-btn,
  .tab-button {
    outline: 2px solid ButtonText;
    outline-offset: -2px;
  }

  .hud-panel {
    border-image: none;
    border-color: CanvasText;
  }

  .ui-button--primary,
  .tab-button.active {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
  }

  .ui-button:focus-visible,
  .close-button:focus-visible,
  .popup-connect-btn:focus-visible,
  .tab-button:focus-visible,
  .ui-input:focus-visible {
    outline: 3px solid Highlight;
    outline-offset: 2px;
  }
}
