/* ==========================================================================
   FPC Atomic Web
   ========================================================================== */

:root {
  --bg: #100e0c;
  --bg-2: #17130f;
  --panel: #1e1915;
  --panel-2: #26201a;
  --line: #3a3028;
  --text: #f0e6d8;
  --muted: #a99986;
  --accent: #ffb347;
  --accent-2: #ff7a3d;
  --good: #6ee7a0;
  --bad: #ff6b6b;
  --radius: 14px;
  --shadow: 0 18px 50px rgba(0, 0, 0, .55);
  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  /* Mobile browsers size `100%` to the layout viewport, which includes the
     space behind the address bar. dvh tracks what is actually visible so the
     canvas and the on-screen controls always fit on screen. */
  height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  background:
    radial-gradient(1100px 700px at 15% -10%, rgba(255, 179, 71, .13), transparent 60%),
    radial-gradient(900px 600px at 100% 110%, rgba(120, 60, 20, .18), transparent 60%),
    linear-gradient(180deg, #141110, #0b0908);
  z-index: -1;
}

/* #app must be the containing block for the absolutely-positioned .screen
   elements. Without `position: relative` they resolve against the viewport
   and ignore the height cap, which let the game screen grow past the bottom
   of a phone screen and pushed the touch controls off-screen. */
#app { height: 100dvh; position: relative; overflow: hidden; }

.screen {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  overflow: hidden;
}
.screen.active { display: flex; }

/* The play screen must never exceed the visible area on a phone: the touch
   pads live inside it and would otherwise be pushed off the bottom. */
#game { overflow: hidden; }
#game .game-canvas-wrap { min-height: 0; overflow: hidden; }

/* ------------------------------------------------------------- title ---- */
/* The original main menu: the artwork fills the frame and the options run
   down the right-hand side in the game's yellow/gold display face. */
#title {
  background: #05040a;
  overflow: hidden;
}
/* Layer 1: the art itself, painted as a background image so it scales to any
   viewport without re-flowing the menu. A CSS fallback starfield sits beneath
   it in case /assets is unavailable. */
#title::before {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(1200px 800px at 20% 10%, #1b2a5e 0%, #0a0f24 45%, #05040a 100%),
    radial-gradient(2px 2px at 12% 22%, #fff, transparent),
    radial-gradient(2px 2px at 78% 12%, #cfe3ff, transparent),
    radial-gradient(1.5px 1.5px at 34% 68%, #fff, transparent),
    radial-gradient(2px 2px at 88% 74%, #ffe9b0, transparent),
    radial-gradient(1.5px 1.5px at 56% 34%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 22% 86%, #b9d4ff, transparent);
  background-size: cover;
}
/* Layer 2: the real artwork. mainmenu.png has the ORIGINAL menu text painted
   into its right half, and we draw our own working list there, so that whole
   side is covered by an opaque gradient — otherwise both texts would show. */
.title-art {
  position: absolute; inset: 0;
  background-image: url('/assets/res/mainmenu.png');
  background-size: cover;
  background-position: left center;
  background-repeat: no-repeat;
}
.title-art::after {
  content: "";
  position: absolute; inset: 0;
  /* Fully opaque from the middle rightward: the artwork's own menu text would
     otherwise ghost through behind our working buttons. */
  background: linear-gradient(90deg,
    rgba(5,4,10,0) 0%,
    rgba(5,4,10,0) 38%,
    rgba(5,4,10,.86) 47%,
    #07050f 55%,
    #07050f 100%);
}

/* The menu column: one line per option, top to bottom, exactly like the
   original's list. */
.title-menu {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: center;
  gap: clamp(0px, .35vh, 6px);
  padding: clamp(12px, 3vh, 40px) clamp(16px, 3vw, 48px);
  /* Sit the list in the right half, like the original. */
  margin-left: auto;
  width: min(700px, 56vw);
  min-width: 0;
  z-index: 1;
}
.title-item {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 1px;
  background: none; border: 0; cursor: pointer; text-align: left;
  padding: 2px 10px 2px 6px;
  border-left: 3px solid transparent;
  border-radius: 3px;
  font: inherit;
  transition: color .12s, background .12s, border-color .12s, transform .12s;
  min-width: 0;
}
/* The game's display face: a heavy, high-contrast serif in warm gold. The
   original menu art uses a Bookman/Cooper-style display serif, so that family
   is preferred and Georgia is the widely-available fallback. */
.title-item-key {
  font-family: "Bookman Old Style", "Bookman", "Cooper Black", Georgia,
    "Times New Roman", var(--font), serif;
  font-size: clamp(15px, min(3.1vh, 2.1vw), 32px);
  font-weight: 900;
  font-style: normal;
  letter-spacing: .01em;
  line-height: 1.12;
  color: #ffd23f;
  /* Soft dark outline so the text reads over the art, like the original. */
  text-shadow:
    0 1px 0 #5c3f00,
    0 2px 3px rgba(0,0,0,.9),
    0 0 10px rgba(255, 190, 60, .22);
  white-space: nowrap;
}
.title-item-sub {
  font-family: var(--font);
  font-size: clamp(9px, 1.05vh, 12.5px);
  letter-spacing: .02em;
  color: #b9a06a;
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity .12s, transform .12s;
  white-space: nowrap;
}
.title-item:hover, .title-item:focus-visible {
  outline: none;
  background: rgba(255, 210, 63, .07);
  border-left-color: #ffd23f;
  transform: translateX(3px);
}
.title-item:hover .title-item-key,
.title-item:focus-visible .title-item-key {
  color: #fff3b0;
  text-shadow:
    0 1px 0 #7a5600,
    0 2px 4px rgba(0,0,0,.9),
    0 0 18px rgba(255, 205, 70, .55);
}
.title-item:hover .title-item-sub,
.title-item:focus-visible .title-item-sub {
  opacity: 1;
  transform: none;
}
.title-item:active { transform: translateX(3px) translateY(1px); }

/* Portrait / narrow: the art sits above the list, centred, and the list fills
   the lower part of the screen so every option stays reachable. */
@media (max-width: 820px), (max-aspect-ratio: 1/1) {
  .title-menu {
    position: absolute; inset: auto 0 0 0;
    width: auto; margin-left: 0;
    justify-content: flex-end;
    gap: 1px;
    padding: 10px 12px calc(12px + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(180deg, rgba(5,4,10,0) 0%, rgba(5,4,10,.82) 26%, rgba(5,4,10,.96) 100%);
  }
  .title-art {
    /* The artwork is 640x480 with the character on the left ~46%. In portrait
       we only want the character, so scale the image up and anchor it to the
       top-left; the baked-in menu text (right half) is cropped away. */
    background-size: 220% auto;
    background-position: left top;
    background-color: transparent;
  }
  /* No baked-in text is visible once the art is cropped, so the scrim only
     needs to fade the bottom of the character into the list. */
  .title-art::after {
    background: linear-gradient(180deg,
      rgba(5,4,10,0) 0%,
      rgba(5,4,10,0) 34%,
      rgba(5,4,10,.45) 44%,
      rgba(5,4,10,.92) 52%,
      #07050f 60%,
      #07050f 100%);
  }
  /* Keep the list anchored to the bottom, never overlapping the character. */
  .title-menu { justify-content: flex-end; }
  .title-item { padding: 5px 8px; }
  .title-item-key { font-size: clamp(15px, 4.2vw, 26px); }
  .title-item-sub { display: none; }
}
/* Short landscape (phones): tighten the list so all eight fit without scroll. */
@media (max-height: 520px) {
  .title-menu { gap: 0; padding: 6px 16px; }
  .title-item { padding: 1px 8px; }
  .title-item-key { font-size: clamp(13px, 2.7vh, 20px); }
  .title-item-sub { display: none; }
}

/* ------------------------------------------------------------- boot ---- */
#boot { align-items: center; justify-content: center; }
.boot-inner { text-align: center; width: min(520px, 84vw); }
.logo { display: flex; flex-direction: column; gap: 2px; margin-bottom: 34px; }
.logo-a {
  font-size: clamp(30px, 7vw, 58px); font-weight: 900; letter-spacing: .18em;
  color: var(--text); line-height: .95;
}
.logo-b {
  font-size: clamp(20px, 4.6vw, 37px); font-weight: 800; letter-spacing: .2em;
  color: var(--accent);
}
.logo-c {
  font-size: 12px; letter-spacing: .55em; color: var(--muted); margin-top: 8px;
}
.boot-bar {
  height: 8px; border-radius: 999px; background: #241d18; overflow: hidden;
  border: 1px solid var(--line);
}
#bootFill {
  height: 100%; width: 0%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width .18s ease-out;
}
.boot-text { margin-top: 14px; color: var(--muted); font-size: 13px; }

/* --------------------------------------------------------- back button ---- */
/* The tab bar is gone: every page carries its own Back button that returns to
   the title screen. It sits above the page heading, left-aligned. */
.btn.back {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0 0 14px;
  padding: 7px 14px 7px 10px;
  font-size: 13px; font-weight: 600;
  border-radius: 9px;
  color: var(--muted);
}
.btn.back:hover { color: var(--text); border-color: #6a5238; }
.btn.back span { font-size: 17px; line-height: 1; }
@media (max-width: 720px) {
  .btn.back { margin-bottom: 10px; padding: 6px 12px 6px 8px; }
}

/* ---------------------------------------------------------- viewport ---- */
.viewport {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 26px 26px 60px; min-width: 0;
  -webkit-overflow-scrolling: touch;
}
@media (max-width: 720px) {
  .viewport { padding: 18px 12px 40px; }
  .view-sub { margin-bottom: 18px; }
}
.view { display: none; max-width: 1180px; margin: 0 auto; animation: fade .22s ease-out; }
.view.active { display: block; }
@keyframes fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.view-title { font-size: clamp(24px, 3.4vw, 36px); margin: 0 0 6px; font-weight: 800; letter-spacing: -.01em; }
.view-sub { color: var(--muted); margin: 0 0 26px; font-size: 14.5px; line-height: 1.6; max-width: 720px; }
.section-title { font-size: 15px; text-transform: uppercase; letter-spacing: .14em; color: var(--muted); margin: 34px 0 14px; font-weight: 700; }

/* ------------------------------------------------------------ cards ---- */
.card-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(min(215px, 100%), 1fr));
}
.big-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
  padding: 22px; text-align: left; cursor: pointer;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); font: inherit; transition: .18s; position: relative; overflow: hidden;
}
.big-card::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(400px 200px at 20% 0%, rgba(255, 179, 71, .14), transparent 70%);
  opacity: 0; transition: opacity .2s;
}
.big-card:hover { transform: translateY(-3px); border-color: #6a5238; box-shadow: var(--shadow); }
.big-card:hover::after { opacity: 1; }
.big-card .icon { font-size: 27px; line-height: 1; margin-bottom: 4px; }
.card-title { font-weight: 800; font-size: 16.5px; }
.card-sub { font-size: 12.8px; color: var(--muted); line-height: 1.5; }

/* ----------------------------------------------------------- panels ---- */
/* minmax(280px, 1fr) forced a 280px column even in a 258px viewport, which
   pushed every panel past the right edge on a 320px phone. `min(280px, 100%)`
   lets the column shrink to whatever room is actually available. */
.setup-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  align-items: start;
}
.panel {
  background: linear-gradient(165deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px; min-width: 0;
}
@media (max-width: 480px) {
  .panel { padding: 14px; }
}
.panel.tight { padding: 14px; margin-bottom: 12px; }
.panel h3 {
  margin: 0 0 14px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .13em; color: var(--accent); font-weight: 800;
}

.field { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 8px 12px; margin-bottom: 12px; font-size: 13.5px; }
.field > span { color: var(--muted); grid-column: 1 / -1; }
.field input[type=range] { grid-column: 1; width: 100%; accent-color: var(--accent); }
.field output { font-variant-numeric: tabular-nums; color: var(--accent); font-weight: 700; font-size: 13px; }
.field input[type=text], .field select, select.wide, input[type=file] {
  grid-column: 1 / -1;
  background: #14100d; color: var(--text); font: inherit; font-size: 13.5px;
  border: 1px solid var(--line); border-radius: 9px; padding: 9px 11px; width: 100%;
}
select.wide { width: 100%; margin-bottom: 10px; }
.check { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--muted); margin: 10px 0; cursor: pointer; }
.check input { accent-color: var(--accent); width: 16px; height: 16px; }

/* ------------------------------------------------------------- maps ---- */
/* The match-setup strip shows the real field artwork, so the chips are wider
   than the old 5x5 ASCII sketches (the canvases are 15:11, the arena aspect).
   The strip is capped and scrolls: eleven full-arena thumbnails would otherwise
   make the map panel taller than the whole setup grid. */
.map-strip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(86px, 100%), 1fr));
  gap: 8px; margin-bottom: 12px;
  max-height: 300px; overflow-y: auto; padding-right: 2px;
  scrollbar-width: thin;
}
.map-chip {
  aspect-ratio: 15 / 11; border-radius: 8px; border: 1px solid var(--line);
  background: #0e0c0a; cursor: pointer; padding: 0; overflow: hidden;
  display: block; transition: .15s; position: relative;
}
.map-chip canvas { display: block; width: 100%; height: 100%; }
.map-chip:hover { border-color: #7a5f40; transform: translateY(-1px); }
.map-chip.active { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(255, 179, 71, .28); }
.map-chip .tag { position: absolute; bottom: 2px; right: 3px; font-size: 8px; color: var(--accent); }
.map-detail { font-size: 13px; color: var(--muted); line-height: 1.55; }
.map-detail strong { color: var(--text); }

.scheme-preview {
  font-family: var(--mono); font-size: 9.5px; line-height: 1.15;
  background: #0d0b09; border: 1px solid var(--line); border-radius: 8px;
  padding: 9px 11px; color: #8fb98f; margin-bottom: 10px; white-space: pre;
  overflow: auto;
}

/* ----------------------------------------------------------- buttons ---- */
.btn {
  background: linear-gradient(180deg, #2e261f, #241d18);
  color: var(--text); border: 1px solid var(--line); border-radius: 10px;
  font: inherit; font-size: 14px; font-weight: 600; padding: 11px 20px;
  cursor: pointer; transition: .15s; white-space: nowrap;
}
.btn:hover { border-color: #6a5238; background: linear-gradient(180deg, #3a3027, #2b231c); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.btn.primary {
  background: linear-gradient(180deg, #ffc266, #ef9028);
  color: #201406; border-color: #ffcf85; font-weight: 800;
}
.btn.primary:hover { background: linear-gradient(180deg, #ffd08c, #ff9f36); }
.btn.ghost { background: transparent; }
.btn.small { padding: 8px 14px; font-size: 13px; }
.btn.tiny { padding: 5px 10px; font-size: 12px; border-radius: 7px; }
.actions { display: flex; gap: 10px; margin-top: 26px; flex-wrap: wrap; }

/* ------------------------------------------------------------ online ---- */
.online-actions { display: flex; gap: 10px; margin-bottom: 18px; flex-wrap: wrap; }
.room-list { display: grid; gap: 10px; }
.room {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 12px 16px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 14px 18px;
}
@media (max-width: 560px) {
  .room { grid-template-columns: minmax(0, 1fr) auto; padding: 12px 14px; }
  .room .room-count { grid-row: 2; grid-column: 1; font-size: 12px; }
  .room .btn { grid-row: 1 / span 2; grid-column: 2; }
  .room-meta { white-space: normal; }
}
.room:hover { border-color: #6a5238; }
.room-name { font-weight: 700; font-size: 15px; display: flex; align-items: center; gap: 9px; }
.room-code { font-family: var(--mono); font-size: 11px; color: var(--accent); border: 1px solid var(--line); border-radius: 5px; padding: 2px 6px; }
.room-meta { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.room-count { font-variant-numeric: tabular-nums; font-size: 13px; color: var(--muted); }
.empty { color: var(--muted); font-size: 14px; padding: 30px; text-align: center; border: 1px dashed var(--line); border-radius: 12px; }

/* ---------------------------------------------------------- campaign ---- */
.campaign-list { display: grid; gap: 16px; }
.campaign {
  background: linear-gradient(165deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
}
.campaign-head { padding: 20px 22px; border-bottom: 1px solid var(--line); }
.campaign-head h2 { margin: 0 0 6px; font-size: 20px; }
.campaign-head p { margin: 0; color: var(--muted); font-size: 13.5px; line-height: 1.6; }
.campaign-stages { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); gap: 1px; background: var(--line); }
.stage {
  background: var(--panel); border: 0; padding: 14px 16px; cursor: pointer;
  color: var(--text); font: inherit; text-align: left; transition: .15s; position: relative;
}
.stage:hover { background: var(--panel-2); }
.stage.locked { opacity: .42; cursor: not-allowed; }
.stage-num { font-size: 10.5px; letter-spacing: .13em; color: var(--accent); font-weight: 800; }
.stage-name { font-weight: 700; font-size: 14px; margin: 4px 0 3px; }
.stage-meta { font-size: 11.5px; color: var(--muted); }
.stage.done::after { content: "✓"; position: absolute; top: 10px; right: 12px; color: var(--good); font-weight: 900; }

/* ------------------------------------------------------------ editor ---- */
.editor-layout { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr); gap: 16px; align-items: start; }
@media (max-width: 900px) { .editor-layout { grid-template-columns: minmax(0, 1fr); } }
.editor-canvas-wrap { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; min-width: 0; }
.editor-side { min-width: 0; }
#editorCanvas {
  width: 100%; height: auto; display: block; border-radius: 8px;
  background: #0b0908; cursor: crosshair; touch-action: none;
}
.palette { display: flex; gap: 6px; margin-top: 12px; flex-wrap: wrap; }
.pal {
  background: #241d18; border: 1px solid var(--line); color: var(--muted);
  border-radius: 8px; padding: 7px 12px; font: inherit; font-size: 12.5px; cursor: pointer;
}
.pal:hover { color: var(--text); }
.pal.active { background: var(--accent); color: #1a140e; border-color: var(--accent); font-weight: 700; }
.editor-hint { font-size: 11.5px; color: var(--muted); margin-top: 9px; line-height: 1.6; }
.editor-legend {
  margin-top: 14px; padding: 14px 16px; border: 1px solid var(--line);
  border-radius: 12px; background: rgba(255,255,255,.02); font-size: 12.5px;
  line-height: 1.6; color: var(--muted);
}
.editor-legend h4 { margin: 0 0 8px; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
.editor-legend ul { margin: 0; padding-left: 18px; display: grid; gap: 6px; }
.editor-legend b { color: var(--text); }
.editor-legend em { color: var(--accent); font-style: normal; }
.powerup-rows { display: grid; gap: 6px; max-height: 300px; overflow-y: auto; }
.pu-header {
  display: grid; grid-template-columns: minmax(0, 1fr) 46px 62px 44px 24px;
  gap: 6px; font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--accent); margin: 10px 0 6px;
}
.pu-row { display: grid; grid-template-columns: minmax(0, 1fr) 46px 62px 44px 24px; gap: 6px; align-items: center; font-size: 12px; }
@media (max-width: 480px) {
  .pu-header, .pu-row { grid-template-columns: minmax(0, 1fr) 40px 52px 38px 22px; gap: 4px; }
  .pu-header { font-size: 9px; letter-spacing: 0; }
}
.pu-row label { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: help; }
.pu-row input[type=number] { width: 100%; background: #14100d; color: var(--text); border: 1px solid var(--line); border-radius: 6px; font: inherit; font-size: 12px; padding: 4px; }
.pu-row input[type=checkbox] { accent-color: var(--accent); }

/* Keybinding editor */
.keybind-list { display: grid; gap: 8px; margin-top: 10px; }
.keybind-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; }
.keybind-name { color: var(--muted); }
.keybind-keys { display: flex; gap: 6px; }
.keybind-keys kbd {
  cursor: pointer; min-width: 34px; text-align: center;
  transition: border-color .15s, color .15s;
}
.keybind-keys kbd:hover { border-color: var(--accent); color: var(--accent); }
/* An action with no key bound. It must stay visible and clickable, otherwise
   reassigning a key away from an action leaves that action unrecoverable. */
.keybind-keys kbd.keybind-empty {
  color: var(--muted); border-style: dashed; opacity: .8;
}
.keybind-keys kbd.keybind-empty:hover { color: var(--accent); opacity: 1; }

/* Lobby team picker */
.team-picker { margin-top: 14px; }
.team-buttons { display: flex; gap: 8px; flex-wrap: wrap; }
.team-buttons .btn { min-width: 96px; justify-content: center; }

/* Lobby scheme picker */
.scheme-pick { display: grid; gap: 10px; }
.lobby-scheme-note {
  margin-top: 12px; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 10px; font-size: 12.5px; color: var(--muted); line-height: 1.5;
}
.editor-buttons { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.problems { color: var(--bad); font-size: 12.5px; margin-top: 10px; line-height: 1.5; }

/* ------------------------------------------------------------- lobby ---- */
#lobby { background: #0c0a09; }
/* The lobby keeps its own header — it is a different screen from the tabbed
   menu and its header carries the room code, capacity and Leave button. */
.lobbybar {
  display: flex; align-items: center; gap: 12px 22px;
  padding: 14px 26px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(32, 26, 21, .92), rgba(24, 20, 16, .8));
  backdrop-filter: blur(10px);
  flex-shrink: 0; flex-wrap: wrap; min-width: 0;
  justify-content: space-between;
}
.lobbybar .brand {
  font-weight: 800; letter-spacing: .06em; font-size: 17px;
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
  flex-shrink: 0;
}
.lobbybar .brand span {
  color: var(--accent); font-weight: 700; font-size: 12px; letter-spacing: .18em;
  padding: 3px 7px; border: 1px solid var(--line); border-radius: 6px;
}
.dot { width: 9px; height: 9px; border-radius: 50%; background: #555; transition: .2s; flex-shrink: 0; }
.dot.on { background: var(--good); box-shadow: 0 0 10px var(--good); }
.dot.off { background: var(--bad); }
.dot.wait { background: var(--accent); }
.lobby-meta {
  display: flex; gap: 18px; font-size: 13px; color: var(--muted);
  min-width: 0; flex-wrap: wrap;
}
.lobby-meta > * { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 42vw; }
/* Inline nickname: the one lobby field a joining player is expected to edit. */
.lobby-name {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; color: var(--muted); flex-shrink: 0;
}
.lobby-name input {
  width: 132px; background: #14100d; color: var(--text);
  border: 1px solid var(--line); border-radius: 7px;
  font: inherit; font-size: 12.5px; padding: 5px 8px;
}
.lobby-name input:focus { outline: none; border-color: var(--accent); }
@media (max-width: 720px) {
  .lobby-name { order: 4; flex-basis: 100%; }
  .lobby-name input { flex: 1; width: auto; }
}
@media (max-width: 720px) {
  /* Keep the lobby title + Leave on one row and move the details below. */
  .lobbybar { gap: 8px; }
  .lobby-meta { order: 3; flex-basis: 100%; gap: 10px; font-size: 12px; }
  .lobby-meta > * { max-width: 100%; }
}
.lobby-body { flex: 1; display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 0; min-height: 0; overflow-y: auto; }
@media (max-width: 880px) { .lobby-body { grid-template-columns: minmax(0, 1fr); } }
.lobby-main { padding: 24px; overflow-y: auto; min-width: 0; }
@media (max-width: 480px) { .lobby-main { padding: 14px; } }

/* The lobby mirrors the original Match Setup screen: roster on the left,
   map preview + options on the right. */
.setup-columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}
@media (max-width: 900px) { .setup-columns { grid-template-columns: minmax(0, 1fr); } }
.setup-panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; padding: 18px; min-width: 0;
}
.panel-title {
  margin: 0 0 14px; font-size: 12px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--accent);
}

/* ------------------------------------------------------- player roster --- */
.roster { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.roster-row {
  display: flex; align-items: baseline; gap: 10px;
  padding: 7px 10px; border-radius: 8px;
  font-family: var(--mono); font-size: 13px; letter-spacing: .02em;
  min-width: 0;
}
.roster-row + .roster-row { border-top: 1px solid rgba(255,255,255,.045); }
.roster-num { font-weight: 700; white-space: nowrap; flex-shrink: 0; }
.roster-name {
  font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.roster-row.open .roster-name { color: var(--muted); font-weight: 500; opacity: .75; }
.roster-row.cpu .roster-name { color: #d8d2c4; }
.roster-row.open { background: rgba(255,255,255,.018); }
.roster-row.host { background: rgba(255,179,71,.08); }
/* Interactive slots. Clicking a colour claims it; the host can flip a slot
   between Open and CPU. */
.roster-row.clickable { cursor: pointer; transition: background .12s, border-color .12s; }
.roster-row.clickable:hover { background: rgba(255,179,71,.12); }
.roster-row.clickable:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.roster-row.current { box-shadow: inset 3px 0 0 var(--accent); }
.roster-chip {
  margin-left: 6px; flex-shrink: 0;
  font-size: 9.5px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase;
  padding: 1px 5px; border-radius: 4px;
  color: var(--muted); border: 1px solid var(--line);
}
.roster-chip.take { color: var(--accent); border-color: rgba(255,179,71,.4); }
.slot-picker { display: flex; flex-direction: column; gap: 8px; min-width: 280px; }
.slot-option {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; padding: 11px 14px; cursor: pointer;
  color: var(--text); font: inherit; transition: .15s;
}
.slot-option:hover { border-color: var(--accent); background: rgba(255,179,71,.08); }
.slot-option.active { border-color: var(--accent); background: rgba(255,179,71,.12); }
.slot-option strong { font-size: 13.5px; }
.slot-option span { font-size: 12px; color: var(--muted); }
.roster-hint {
  list-style: none; margin-top: 6px; padding: 6px 10px;
  font-size: 11.5px; color: var(--accent); opacity: .85;
}
.roster-sub {
  font-size: 11px; color: var(--muted); margin-left: auto;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45%;
}
/* Slot 2 is "black" in the original palette: unreadable on a dark panel, so
   the whole row gets a light plate (like the in-game HUD). The slot number
   keeps its black swatch, so the colour is still identifiable. */
.roster-row.light-plate { background: #f0f0f0; }
.roster-row.light-plate .roster-name,
.roster-row.light-plate .roster-sub { color: #14110e; }
.roster-row.light-plate .roster-sub { opacity: .8; }
.roster-row.light-plate.clickable:hover { background: #ffe9c2; }
.roster-row.light-plate .roster-chip { color: #4a423a; border-color: rgba(0,0,0,.25); }
/* Your own row: accent bar plus a tint, without crushing the label contrast. */
.roster-row.current { box-shadow: inset 3px 0 0 var(--accent); }
.roster-crown { font-size: 11px; margin-left: 4px; }

/* ------------------------------------------------------ map preview ------ */
/* Capped so the preview + all ten option rows + the buttons fit the lobby
   without the panel needing its own scrollbar on a 780px-tall window. */
.map-preview {
  border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
  background: #0e0c0a; margin-bottom: 8px; line-height: 0;
  max-width: 260px;
}
.map-preview canvas { display: block; width: 100%; height: auto; }
.map-caption {
  font-size: 12.5px; color: var(--text); margin-bottom: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.map-caption .muted { color: var(--muted); }

/* ------------------------------------------------------ setup rows ------- */
.lobby-settings {
  background: transparent; border: 0; border-radius: 0; padding: 0;
}
.lobby-settings h3 { margin: 0 0 8px; font-size: 12px; letter-spacing: .13em; text-transform: uppercase; color: var(--accent); }
.setup-row {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 0; border-bottom: 1px solid rgba(255,255,255,.045);
  font-size: 13px; min-width: 0;
}
.setup-row:last-of-type { border-bottom: 0; }
.setup-label { color: var(--muted); flex-shrink: 0; }
.setup-value {
  margin-left: auto; color: var(--text); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.setup-action {
  flex-shrink: 0; background: transparent; border: 1px solid var(--line);
  color: var(--accent); border-radius: 6px; cursor: pointer;
  font: inherit; font-size: 11px; font-weight: 700; padding: 2px 8px;
  transition: .15s;
}
.setup-action:hover { border-color: var(--accent); background: rgba(255,179,71,.1); }
.setup-stepper { display: inline-flex; gap: 3px; flex-shrink: 0; }
.setup-stepper .setup-action { min-width: 22px; padding: 2px 0; text-align: center; }
.lobby-side {
  border-left: 1px solid var(--line); display: flex; flex-direction: column;
  padding: 18px; background: var(--bg-2); min-height: 0;
}
.lobby-side h3 { margin: 0 0 10px; font-size: 12px; letter-spacing: .13em; text-transform: uppercase; color: var(--muted); }
.chat-log { flex: 1; overflow-y: auto; font-size: 13px; line-height: 1.5; margin-bottom: 10px; min-height: 120px; }
.chat-line { margin-bottom: 5px; word-break: break-word; }
.chat-line b { color: var(--accent); }
.chat-form { display: flex; gap: 6px; margin-bottom: 12px; }
.chat-form input {
  flex: 1; background: #14100d; border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font: inherit; font-size: 13px; padding: 8px 10px; min-width: 0;
}
.lobby-buttons { display: flex; flex-direction: column; gap: 8px; }

/* -------------------------------------------------------------- game ---- */
#game { background: #070605; }
.hud {
  display: flex; align-items: center; justify-content: space-between; gap: 10px 16px;
  padding: 10px 18px; border-bottom: 1px solid #241d18; flex-shrink: 0;
  background: rgba(14, 12, 10, .9);
  flex-wrap: wrap;
}
.hud-left, .hud-right { display: flex; align-items: center; gap: 14px; font-size: 13px; color: var(--muted); min-width: 0; }
@media (max-width: 560px) {
  .hud { padding: 8px 12px; gap: 8px; }
  .hud-left, .hud-right { gap: 9px; font-size: 12px; }
  .hud-center { order: 3; flex-basis: 100%; }
  .timer { font-size: 15px; }
}
.hud-state { font-family: var(--mono); font-size: 12px; font-weight: 800; letter-spacing: .12em; color: var(--bad); }
.hud-state.low { animation: pulse 1s infinite; }
.timer { font-family: var(--mono); font-size: 18px; font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
.timer.low { color: var(--bad); animation: pulse 1s infinite; }
@keyframes pulse { 50% { opacity: .45; } }
.hud-center { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; flex: 1; }
.score-chip {
  display: flex; align-items: center; gap: 6px; font-size: 12px;
  background: #1c1712; border: 1px solid var(--line); border-radius: 999px; padding: 4px 10px;
}
.score-chip .sq { width: 9px; height: 9px; border-radius: 2px; }
.score-chip.dead { opacity: .4; }
.game-canvas-wrap {
  flex: 1 1 auto; display: flex; align-items: center; justify-content: center;
  position: relative; min-height: 0; padding: 10px;
  overflow: hidden;
}
#gameCanvas {
  /* Width/height are set in JS (Renderer.fitToParent) so the 4:3 buffer fits
     whatever room the flex layout gives it. These are just safety rails. */
  max-width: 100%;
  max-height: 100%;
  display: block;
  border-radius: 10px;
  image-rendering: pixelated;
}
/* Touch devices: the D-pad and action buttons overlay the lower corners of
   the canvas, so the field keeps the full height instead of shrinking. */
body.touch-device #gameCanvas {
  max-height: 100%;
  max-width: calc(100% - 24px);
}
/* Fade the pads slightly while a match runs so they never hide the arena. */
body.touch-device .touch-controls { opacity: .92; }
body.touch-device .touch-controls:active { opacity: 1; }
#gameCanvas.smooth { image-rendering: auto; }
.game-overlay {
  position: absolute; inset: 0; display: none; align-items: center; justify-content: center;
  background: rgba(6, 5, 4, .82); backdrop-filter: blur(3px); z-index: 5;
  flex-direction: column; gap: 18px; text-align: center; padding: 24px;
}
.game-overlay.show { display: flex; }
.game-overlay h2 { font-size: clamp(26px, 5vw, 46px); margin: 0; letter-spacing: .04em; }
.game-overlay .sub { color: var(--muted); font-size: 14px; }
.hurry-banner {
  position: absolute; top: 14%; left: 50%; transform: translateX(-50%) scale(.7);
  font-size: clamp(24px, 5vw, 54px); font-weight: 900; letter-spacing: .1em;
  color: #ff4d3d; text-shadow: 0 0 30px rgba(255, 77, 61, .65);
  opacity: 0; pointer-events: none; transition: .3s;
}
.hurry-banner.show { opacity: 1; transform: translateX(-50%) scale(1); }
.hud-bottom {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 8px 18px 12px; font-size: 12px; color: var(--muted); flex-shrink: 0;
}
.hud-powerups { display: flex; gap: 8px; }
.hud-powerups img { width: 26px; height: 23px; image-rendering: pixelated; opacity: .9; }
.hud-hint { font-family: var(--mono); font-size: 11.5px; }

/* --------------------------------------------------- touch controls ---- */
/* While a match is on screen the page itself must not scroll, bounce or
   rubber-band: every touch belongs to the D-pad or the action buttons. */
body.touch-device,
body.touch-device #app {
  overscroll-behavior: none;
  -webkit-overflow-scrolling: auto;
}
body.touch-device #game.active {
  touch-action: none;
  user-select: none; -webkit-user-select: none;
}
body.touch-device #gameCanvas { pointer-events: none; }

/* Hidden by default; `body.touch-device` turns them on. */
.touch-controls {
  display: none; position: absolute; inset: auto 0 0 0;
  padding: 0 18px calc(14px + env(safe-area-inset-bottom, 0px));
  pointer-events: none; z-index: 4;
  align-items: flex-end; justify-content: space-between;
}
body.touch-device .touch-controls { display: flex; }
/* NOTE: #game must stay `position: absolute` (from `.screen`) so it fills
   #app. Setting `position: relative` here made it size to its content, which
   capped the play area at ~370px on a large window and left the arena tiny. */

/* ---------------------------------------------------------------- stick -- */
/* An analog stick rather than four arrow buttons: the thumb can rest anywhere
   in the base and drag in eight directions without letting go or travelling
   between separate buttons. It also makes multitouch natural — one thumb owns
   the stick while the other taps the action buttons. */
.touch-stick {
  position: relative; width: 168px; height: 168px;
  pointer-events: auto; touch-action: none;
  display: flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
  user-select: none; -webkit-user-select: none;
}
.touch-stick-base {
  position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.16);
  background:
    radial-gradient(circle at 50% 42%, rgba(255,255,255,.07), rgba(20,16,13,.5) 70%);
  backdrop-filter: blur(6px);
  box-shadow: inset 0 0 26px rgba(0,0,0,.45);
  transition: border-color .12s, box-shadow .12s;
}
/* Subtle compass marks so the neutral point is readable. */
.touch-stick-base::before,
.touch-stick-base::after {
  content: ""; position: absolute; background: rgba(255,255,255,.10);
  left: 50%; top: 50%; transform: translate(-50%, -50%);
}
.touch-stick-base::before { width: 2px; height: 58%; }
.touch-stick-base::after { width: 58%; height: 2px; }
.touch-stick-knob {
  position: absolute; width: 74px; height: 74px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.26);
  background: radial-gradient(circle at 42% 36%, rgba(255,255,255,.30), rgba(36,29,24,.92));
  box-shadow: 0 6px 16px rgba(0,0,0,.45);
  /* Only the knob's transform animates; it must track the finger exactly, so
     the transition is short and position-only. */
  transition: transform .05s linear, background .1s, border-color .1s;
  will-change: transform;
}
.touch-stick.active .touch-stick-base {
  border-color: rgba(240,178,70,.55);
  box-shadow: inset 0 0 30px rgba(240,178,70,.18);
}
.touch-stick.active .touch-stick-knob {
  background: radial-gradient(circle at 42% 36%, rgba(255,215,140,.95), rgba(224,146,40,.92));
  border-color: #f6c878;
}

.touch-key {
  border: 1px solid rgba(255,255,255,.22);
  background: rgba(24, 20, 16, .62);
  backdrop-filter: blur(6px);
  color: rgba(255,255,255,.85);
  border-radius: 12px; font-size: 20px; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  user-select: none; -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: none; cursor: pointer;
  transition: background .08s, transform .08s, border-color .08s;
}
.touch-key.held, .touch-key:active {
  background: rgba(240, 178, 70, .82);
  border-color: #f6c878; color: #1a1207;
  transform: scale(.94);
}
.touch-actions {
  display: flex; align-items: flex-end; gap: 14px;
  pointer-events: auto; touch-action: none;
}
.touch-actions .touch-key {
  width: 84px; height: 84px; border-radius: 50%; font-size: 30px;
}
.touch-actions .touch-key.second { width: 68px; height: 68px; font-size: 24px; }
/* Landscape is the intended orientation: keep the canvas clear of the pads. */
@media (max-height: 520px) {
  .touch-stick { width: 138px; height: 138px; }
  .touch-stick-knob { width: 62px; height: 62px; }
  .touch-actions .touch-key { width: 70px; height: 70px; }
  .touch-actions .touch-key.second { width: 58px; height: 58px; }
}
@media (max-width: 560px) {
  .touch-stick { width: 148px; height: 148px; }
  .touch-stick-knob { width: 66px; height: 66px; }
}
/* Portrait phones: stack the hint row above the pads. */
@media (max-width: 560px) {
  .hud-bottom { flex-wrap: wrap; gap: 6px; }
  .hud-hint { font-size: 10.5px; }
}

/* Ghost contact flash (6-player co-op). */
.hud.ghost-hit { animation: ghostHit .5s ease-out; }
@keyframes ghostHit {
  0% { box-shadow: inset 0 0 0 0 rgba(255, 60, 140, .0); }
  20% { box-shadow: inset 0 0 90px 20px rgba(255, 60, 140, .55); }
  100% { box-shadow: inset 0 0 0 0 rgba(255, 60, 140, 0); }
}

/* Create Lobby dialog */
.create-lobby .field { grid-template-columns: 1fr; }
.create-lobby .field > span { margin-bottom: 2px; }
.create-lobby .hint { margin: 10px 0 0; font-size: 12.5px; color: var(--accent); }

/* ------------------------------------------------------------ modal ---- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(5, 4, 3, .78); backdrop-filter: blur(4px);
  display: none; align-items: center; justify-content: center; z-index: 100; padding: 16px;
}
.modal-backdrop.show { display: flex; }
.modal {
  background: linear-gradient(165deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: 16px; padding: 24px;
  width: min(520px, 100%); box-shadow: var(--shadow);
  /* dvh (not vh) so the dialog still fits when mobile browser chrome is shown */
  max-height: min(86vh, 86dvh); overflow-y: auto; -webkit-overflow-scrolling: touch;
}
@media (max-width: 480px) {
  .modal { padding: 18px; border-radius: 12px; }
  .modal h2 { font-size: 17px; }
  .modal-actions .btn { flex: 1 1 auto; }
}
.modal h2 { margin: 0 0 14px; font-size: 19px; }
.modal-body { color: var(--muted); font-size: 13.8px; line-height: 1.62; }
.modal-body p { margin: 0 0 12px; }
.modal-body input {
  width: 100%; background: #14100d; border: 1px solid var(--line); border-radius: 9px;
  color: var(--text); font: inherit; font-size: 15px; padding: 10px 12px; margin-top: 8px;
  text-transform: uppercase; letter-spacing: .12em; text-align: center;
}
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px; flex-wrap: wrap; }

/* ----------------------------------------------------------- toasts ---- */
.toasts {
  position: fixed; bottom: calc(20px + env(safe-area-inset-bottom, 0px)); left: 50%;
  transform: translateX(-50%); display: flex; flex-direction: column; gap: 8px;
  z-index: 200; pointer-events: none; max-width: calc(100vw - 24px);
}
.toast {
  background: #241d18; border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 9px; padding: 10px 16px; font-size: 13px; box-shadow: var(--shadow);
  animation: toastIn .2s ease-out;
}
.toast.bad { border-left-color: var(--bad); }
.toast.good { border-left-color: var(--good); }
@keyframes toastIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ------------------------------------------------------------ misc ---- */
kbd {
  font-family: var(--mono); font-size: 11px; background: #241d18;
  border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 4px;
  padding: 1px 5px; margin-right: 3px; color: var(--text);
}
table.keys { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.keys th { text-align: left; color: var(--muted); font-weight: 600; padding: 6px 0; font-size: 11px; text-transform: uppercase; letter-spacing: .1em; }
table.keys td { padding: 6px 0; border-top: 1px solid #2a231d; color: var(--muted); }
table.keys td:last-child { text-align: right; }
code { font-family: var(--mono); font-size: .92em; background: #241d18; padding: 1px 5px; border-radius: 4px; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: #100d0b; }
::-webkit-scrollbar-thumb { background: #332a22; border-radius: 5px; }
::-webkit-scrollbar-thumb:hover { background: #463829; }
