/* UI overhaul 2026-10-01: PSX-era console menus (reference: the Bloodborne PSX demake's options screen).
   Black panels with a hard bone border, oxblood title bars (blue at first; Noah: cool but it did not mesh with the dusk maps), muted parchment-gold options that turn white when selected (bright green at first; Noah: Bloodborne PSX works because it is muted yellow + white).
   One terminal face (VT323) everywhere. No neon glow; the CRT overlay supplies the bleed.
   2026-10-06: gold is gone (Noah: "replace the gold with red"), then "too much red ... red should be a CTA color only": options
   and HUD numbers are the warm white #f4f1e8 (labels and hints stay grey), --accent red marks primary actions and the hover/focus row; --red is errors + logo.
   Legacy names kept so the HUD rules below keep working: --amber/--green are the option colour (--ok is the real "good" green),
   --cyan the grey-bone label colour. */
:root {
  --bg: #000; --panel: rgba(0, 0, 0, 0.86); --bone: #e9e4d4; --bar: #8e0f0a; --bar-hi: #cc1f16; --bar-lo: #3f0402;
  --amber: #f4f1e8; --amber-dim: #5a5548; --green: #f4f1e8; --green-row: rgba(230, 40, 30, 0.16); --ok: #6fbf7a;
  --accent: #e6281e; --accent-dim: #6e0f0a; /* red: brand (title bars, logo) and the hover/focus highlight; 2026-10-06 a purer red (Noah: "more primary") */
  --cyan: #a39d8c; --red: #ff4a3d; --text: #f4f1e8; --dim: #7c8478;
  --font: 'VT323', 'Courier New', monospace; --font2: 'VT323', 'Courier New', monospace;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text); font-family: var(--font); overflow: hidden; user-select: none; }
#app { position: fixed; inset: 0; }
#game { position: absolute; inset: 0; }
#game canvas { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.hidden { display: none !important; }
button, input, select { font-family: inherit; }

/* ---------- attract mode (menu backdrop) ---------- */
#attract { position: absolute; inset: 0; z-index: 1; }
#attract canvas { display: block; width: 100%; height: 100%; image-rendering: pixelated; filter: saturate(0.85) contrast(1.05); }

/* ---------- CRT overlay ---------- */
#crt { position: absolute; inset: 0; pointer-events: none; z-index: 100;
  background: repeating-linear-gradient(0deg, rgba(0,0,0,0.25) 0 1px, transparent 1px 3px);
  box-shadow: inset 0 0 180px rgba(0,0,0,0.8); mix-blend-mode: multiply; }
#crt::after { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse at center, transparent 50%, rgba(0,0,0,0.6) 100%); }
body.no-crt #crt { display: none; }
/* Feedback #19 (WHEATRIDER): over the HUD, the vignette and scanlines dimmed the readouts in the corners. In a match the
   overlay drops under the HUD (z 10), so it filters the 3D view only; menus keep the full effect. */
body:has(#hud:not(.hidden)) #crt { z-index: 9; }

/* ---------- screens ---------- */
#screens { position: absolute; inset: 0; z-index: 20; }
.screen { position: absolute; inset: 0; display: none; flex-direction: column; align-items: center; justify-content: safe center; gap: 22px; padding: 24px; overflow-y: auto;
  background: linear-gradient(rgba(0,0,0,0.35), rgba(0,0,0,0.55)); }
.screen.active { display: flex; }
.screen.transparent { background: rgba(0,0,0,0.7); }

/* Logo: bone-white terminal letters, hard drop shadow, a one-pixel red/blue split like a misconverged tube. */
.logo { font-size: clamp(64px, 13vw, 168px); letter-spacing: 0.04em; color: var(--bone); line-height: 0.85;
  text-shadow: -1px 0 rgba(255,60,40,0.7), 1px 0 rgba(60,90,255,0.7), 5px 6px 0 #000; }
.logo .alt { color: var(--accent); }
.logo.small { font-size: clamp(44px, 6vw, 72px); }
.tag { color: var(--bone); opacity: 0.75; font-size: 24px; letter-spacing: 3px; text-shadow: 2px 2px 0 #000; }
.blink { color: var(--text); font-size: 30px; letter-spacing: 2px; text-shadow: 2px 2px 0 #000; animation: blink 1.1s steps(2) infinite; }
@keyframes blink { 50% { opacity: 0; } }
.footer { position: absolute; bottom: 18px; color: var(--bone); opacity: 0.6; font-size: 20px; letter-spacing: 1px; text-align: center; text-shadow: 2px 2px 0 #000; }

/* Panel: black slab, bone frame, black gap, then the content; .title is the oxblood bar across the top. */
.panel { background: var(--panel); border: 3px solid var(--bone); outline: 3px solid #000; box-shadow: 0 0 0 6px var(--bone), 0 0 0 9px #000, 0 12px 40px rgba(0,0,0,0.7);
  padding: 0 18px 18px; min-width: 340px; }
.panel { max-width: calc(100vw - 32px); }
.quickrow { display: flex; gap: 6px; } .quickrow .btn { flex: 1; } .quickrow select, .quickrow .dd { background: #000; color: var(--green); border: 2px solid var(--dim); padding: 0 6px; font-size: 24px; font-family: var(--font); }
.panel.gate { width: 440px; display: flex; flex-direction: column; gap: 4px; padding-top: 18px; } /* no title bar, so pad the top like the sides */
.panel.gate .btnrow { margin-top: 6px; }
.gate-note { margin-top: 10px; text-align: center; }
/* guest is the fallback, not the main action: grey and a size down, the option colour only on hover/focus */
.gate-or { display: flex; align-items: center; gap: 10px; margin-top: 12px; color: var(--dim); font-size: 18px; letter-spacing: 2px; }
.gate-or::before, .gate-or::after { content: ''; flex: 1; border-top: 2px solid rgba(255,255,255,0.12); }
#btn-guest { text-align: center; color: var(--cyan); font-size: 24px; border-bottom-color: transparent; }
#btn-guest:hover, #btn-guest:focus-visible { color: #fff; border-color: var(--accent); } /* full box: the rest-state rule hides only the underline */
#btn-guest.solo { color: var(--green); font-size: inherit; } /* plain http: PLAY is the only choice */
#s-title .footer { position: static; margin-top: auto; } /* in the flow under the log-in panel, never on top of it */
/* menu lists read left-aligned, like the PSX console menus this follows; button rows (LOG IN / SIGN UP, READY ...) stay centred */
.panel.menu > .btn, .panel.menu .quickrow .btn { text-align: left; padding-left: 14px; }
.panel.menu { display: flex; flex-direction: column; gap: 4px; width: 440px; }
.panel.wide { width: min(880px, 94vw); flex-shrink: 0; }
.panel.supporter { width: min(780px, 94vw); }
.title, .panel.menu .field:first-child { margin: 0 -18px 12px; }
.title { background: linear-gradient(var(--bar-hi), var(--bar) 45%, var(--bar-lo)); color: #fff; font-size: 36px; line-height: 1; padding: 8px 18px 6px; text-align: center; letter-spacing: 1px;
  border-bottom: 3px solid #000; text-shadow: 2px 2px 0 #000; }
/* section headings (MATCH, RULES, PLAYERS, YOUR RECORD): smaller, spaced out, white with a rule under them, so they never
   read as one more setting label (those are grey and bigger). Noah, 2026-10-06. */
.sub { color: var(--text); font-size: 19px; margin: 16px 0 8px; padding-bottom: 3px; letter-spacing: 4px; text-shadow: 2px 2px 0 #000;
  border-bottom: 2px solid rgba(233,228,212,0.16); }
.dim { color: var(--dim); }
.title .dim { color: rgba(255,255,255,0.55); }

/* Options read like a console menu: green rows, a dark rule under each, the focused row boxed. */
.btn { display: block; width: 100%; background: transparent; color: var(--green); border: 2px solid transparent; border-bottom: 2px solid rgba(233,228,212,0.12);
  padding: 4px 12px 2px; font-size: 30px; line-height: 1.1; text-align: center; cursor: pointer; position: relative; transition: none; text-transform: uppercase; text-shadow: 2px 2px 0 #000; }
.btn:hover, .btn:focus-visible { background: var(--green-row); border-color: var(--accent); color: #fff; outline: none; }
/* primary actions are filled, not coloured (Noah, 2026-10-06: red, and blue, both wrong for a CTA): an off-white block
   with black text, like the inverted highlight bar of the PSX menus this UI follows. Red stays brand + hover only. */
.btn.primary { background: var(--text); color: #000; border-color: var(--text); text-shadow: none; }
.btn.primary:hover, .btn.primary:focus-visible { background: #fff; color: #000; border-color: #fff; box-shadow: 0 0 0 2px var(--accent); }
.btn.primary small { color: #4a463c; }
.btn.primary:disabled, .btn.primary:disabled:hover { background: transparent; color: var(--dim); border-color: #3a3a36; box-shadow: none; opacity: 0.8; }
.btn.danger { color: var(--red); }
.btn.danger:hover, .btn.danger:focus-visible { background: rgba(255,74,61,0.14); border-color: var(--red); }
.btn.sm { padding: 2px 10px; font-size: 22px; width: auto; display: inline-block; margin-right: 6px; border-color: rgba(233,228,212,0.3); }
.btn small { font-size: 20px; color: var(--dim); margin-left: 8px; text-transform: lowercase; text-shadow: none; }
.btn:disabled { opacity: 0.35; cursor: default; }
.btn:disabled:hover { background: transparent; border-color: transparent; border-bottom-color: rgba(233,228,212,0.12); }
.btnrow { display: flex; gap: 10px; margin-top: 14px; }
.btnrow .btn { width: auto; flex: 1; }
.field { display: flex; flex-direction: column; gap: 4px; font-size: 22px; color: var(--cyan); margin-bottom: 8px; }
.panel.menu .field:first-child { padding: 10px 18px 12px; background: linear-gradient(var(--bar-hi), var(--bar) 45%, var(--bar-lo)); color: #fff; border-bottom: 3px solid #000; }
.panel.menu .field:first-child .field-head { align-items: center; }
.panel.menu .field:first-child .link { color: #fff; font-size: 24px; padding: 0 12px; margin-left: 8px; border: 2px solid var(--bone); background: rgba(0,0,0,0.35); text-shadow: 2px 2px 0 #000; }
.panel.menu .field:first-child .link:hover, .panel.menu .field:first-child .link:focus-visible { background: var(--bone); color: #000; text-shadow: none; }
.guest-hint { color: rgba(255,255,255,0.75); font-size: 20px; letter-spacing: 1px; margin-top: 2px; text-shadow: 2px 2px 0 #000; }
.field input[type=text], .field input:not([type]), .field select, .field .dd { background: #000; color: var(--green); border: 2px solid var(--dim); padding: 4px 10px; font-size: 30px; letter-spacing: 2px; outline: none; text-transform: uppercase; }
.field input:not([type=checkbox]), .field select, .field .dd { width: 100%; min-width: 0; }
.field-note { color: var(--text); opacity: 0.7; font-size: 20px; line-height: 1.1; text-transform: uppercase; }
.field input:focus, .field select:focus, .field .dd:focus-visible, .field .dd.open { border-color: var(--accent); }
.field.range input { accent-color: var(--green); }
.field.check { flex-direction: row; align-items: center; color: var(--text); font-size: 24px; }
.field.check input { width: 20px; height: 20px; accent-color: var(--green); }
.status { color: var(--dim); font-size: 22px; margin-top: 8px; min-height: 22px; text-align: center; }
.status.ok { color: var(--ok); } .status.err { color: var(--red); }
table.list { width: 100%; border-collapse: collapse; font-size: 24px; }
table.list th { text-align: left; color: var(--cyan); padding: 4px 8px; border-bottom: 2px solid var(--bone); font-weight: normal; }
table.list td { padding: 4px 8px; border-bottom: 1px solid #222; color: var(--green); }
table.list tr:hover td { background: var(--green-row); }
.lobby-grid { display: grid; grid-template-columns: 1.15fr 1fr 1fr; gap: 28px; }
.panel.lobby { width: min(1240px, 96vw); flex-shrink: 0; }
/* under 1100 px: map above the people column on the left, settings on the right; phones: one column */
@media (max-width: 1100px) {
  .lobby-grid { grid-template-columns: 1fr 1fr; }
  .lobby-mapcol { grid-column: 1; grid-row: 1; } .lobby-people { grid-column: 1; grid-row: 2; } .lobby-right { grid-column: 2; grid-row: 1 / span 2; }
}
@media (max-width: 700px) { .lobby-grid { grid-template-columns: 1fr; } .lobby-mapcol, .lobby-people, .lobby-right { grid-column: 1; grid-row: auto; } }
/* the lobby fits the window: title and buttons stay put, the two columns scroll inside if a long rule list needs it */
.panel.lobby { display: flex; flex-direction: column; max-height: calc(100vh - 48px); }
.panel.lobby .lobby-grid { flex: 1; min-height: 0; }
.lobby-col { min-height: 0; overflow-y: auto; padding-right: 4px; }
.lobby-mapcol, .lobby-people, .lobby-right { display: flex; flex-direction: column; }
.lobby-col > .sub:first-child { margin-top: 4px; }
/* map card: the overhead preview with its description as a caption strip under it, in one frame, instead of a loose
   line of text between controls */
.map-card { flex-shrink: 0; margin: 2px 0 4px; border: 2px solid var(--dim); background: #000; }
.map-card .map-preview { margin: 0; height: 300px; border: 0; position: relative; overflow: hidden; }
/* screenshot fills the card; the overhead plan shrinks to an inset once the screenshot is in */
.map-shot { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; image-rendering: pixelated; display: none; }
.map-preview.has-shot .map-shot { display: block; }
.map-preview.has-shot .map-plan { position: absolute; right: 8px; bottom: 8px; width: 34%; height: 40%; background: rgba(0,0,0,0.75);
  border: 2px solid rgba(233,228,212,0.5); padding: 4px; box-sizing: border-box; }
@media (max-width: 1100px) { .map-card .map-preview { height: 150px; } }
.map-caption { padding: 5px 10px 6px; border-top: 2px solid #222; font-size: 18px; line-height: 1.1; letter-spacing: 1px; color: var(--cyan); text-transform: uppercase; }
.map-caption:empty { display: none; }
.bots-row { margin-top: 8px; } .bots-ctl { display: flex; align-items: center; gap: 6px; }
.lobby .kv.bots-row .dd { width: 120px; }
.host-tools.inline { display: flex; gap: 6px; letter-spacing: 1px; } .host-tools.inline .btn.sm { margin: 0; font-size: 20px; padding: 2px 8px; }
.host-tools.inline.hidden { display: none; }
.lobby-chat { flex-shrink: 0; margin-top: 12px; } /* a console strip under the columns, about three lines */
.lobby-chat .chatbox { height: 64px; margin-top: 0; font-size: 20px; }
.lobby-chat .chatline { margin-top: 4px; }
.lobby .kv { margin-bottom: 4px; }
/* one width for every lobby dropdown (fits CAPTURE THE FLAG), so the settings line up as a column */
.lobby .kv .dd { width: 216px; flex-shrink: 0; }
.dd-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#lobby-players { list-style: none; margin: 0; padding: 0; font-size: 26px; }
#lobby-players li { display: flex; align-items: center; gap: 10px; padding: 4px 6px; border-bottom: 1px solid #222; }
#lobby-players .swatch.pick { cursor: pointer; width: 16px; height: 16px; }
.swatch.pick:hover { outline: 2px solid var(--text); }
.swatch { width: 16px; height: 16px; border: 2px solid #000; box-shadow: 0 0 0 1px #fff3; }
#lobby-players .ready { margin-left: auto; color: var(--dim); font-size: 22px; }
#lobby-players .ready.on { color: var(--ok); }
#lobby-players .host { color: var(--bone); font-size: 20px; }
#lobby-players .bot { color: var(--dim); font-size: 20px; }
.kv { display: flex; justify-content: space-between; align-items: center; font-size: 24px; color: var(--cyan); margin-bottom: 6px; }
.kv select, .kv .dd { background: #000; color: var(--green); border: 2px solid var(--dim); padding: 2px 6px; font-size: 24px; font-family: var(--font); }
.kv select:disabled, .kv .dd:disabled { color: var(--text); opacity: 0.8; }
.map-preview { height: 150px; border: 2px solid var(--dim); background: #000; margin: 10px 0; display: flex; align-items: center; justify-content: center; }
.map-preview canvas { image-rendering: pixelated; width: 100%; height: 100%; object-fit: contain; } /* fits wide maps (DUEL, GULCH) too */
.chatbox { height: 100px; overflow-y: auto; border: 2px solid #333; background: #000; padding: 6px 8px; font-family: var(--font2); font-size: 22px; line-height: 1.1; margin-top: 12px; }
.chatline { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-family: var(--font2); font-size: 22px; }
.chatline input { flex: 1; background: #000; color: var(--text); border: 2px solid #333; font-family: var(--font2); font-size: 22px; padding: 2px 8px; outline: none; }
.prompt { color: var(--green); }
.winner { color: #fff; font-size: 40px; margin: 12px 0 18px; text-align: center; text-shadow: 3px 3px 0 #000; }
.loading { font-size: 40px; color: var(--bone); text-shadow: 3px 3px 0 #000; }
.dots::after { content: ''; animation: dots 1s steps(4) infinite; }
@keyframes dots { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } }
#update-banner { display: none; position: absolute; top: 14px; left: 50%; transform: translateX(-50%); z-index: 60; font-size: 26px; padding: 4px 16px; background: #000; border: 2px solid var(--green); color: var(--green); text-shadow: 2px 2px 0 #000; cursor: pointer; animation: blink 1.1s steps(2) infinite; }
#update-banner.show { display: block; }
#update-banner b { color: #fff; font-weight: normal; }
#toast { position: absolute; top: 16px; left: 50%; transform: translateX(-50%); z-index: 50; color: var(--red); font-size: 26px; pointer-events: none; text-shadow: 2px 2px 0 #000; }
#toast.ok { color: var(--ok); }

/* ---------- HUD ---------- */
#hud { position: absolute; inset: 0; z-index: 10; pointer-events: none; font-size: 23px; }
#hud .panel { padding: 10px 14px; min-width: 0; border-width: 2px; box-shadow: 0 0 0 4px var(--bone), 0 0 0 6px #000; outline-width: 2px; }
/* Always-on HUD readouts float over the game with no frame (Noah: the boxed version was too obtrusive).
   A hard 2px shadow keeps them legible on bright walls. Scoreboard and pause menu keep their panels. */
#match-info.panel, #vitals.panel, #weapon-panel.panel { background: none; border: 0; outline: 0; box-shadow: none; padding: 0; text-shadow: 2px 2px 0 #000; }
#crosshair { position: absolute; left: 50%; top: 50%; width: 0; height: 0; --gap: 6px; --xh: var(--cyan); --xh-scale: 1; transform: scale(var(--xh-scale)); }
#crosshair.nodot b { display: none; }
#crosshair i { position: absolute; background: var(--xh); box-shadow: 0 0 0 1px #000; }
#crosshair i:nth-child(1) { width: 2px; height: 7px; left: -1px; top: calc(-7px - var(--gap)); }
#crosshair i:nth-child(2) { width: 2px; height: 7px; left: -1px; top: var(--gap); }
#crosshair i:nth-child(3) { width: 7px; height: 2px; top: -1px; left: calc(-7px - var(--gap)); }
#crosshair i:nth-child(4) { width: 7px; height: 2px; top: -1px; left: var(--gap); }
#cd-ring { position: absolute; left: -20px; top: -20px; width: 40px; height: 40px; transform: rotate(-90deg); overflow: visible; }
#cd-ring circle { fill: none; stroke: var(--xh); stroke-width: 2.5; stroke-dasharray: 94.25; stroke-dashoffset: 94.25; opacity: 0.85; filter: drop-shadow(1px 1px 0 #000); }
#crosshair b { position: absolute; width: 2px; height: 2px; left: -1px; top: -1px; background: var(--xh); }
#scope { position: absolute; inset: 0; background: radial-gradient(circle at 50% 50%, transparent 0, transparent 34vmin, rgba(0,0,0,0.93) 36vmin); }
#scope::before { content: ''; position: absolute; left: 50%; top: 50%; width: 70vmin; height: 70vmin; transform: translate(-50%, -50%); border: 3px solid var(--cyan); border-radius: 50%; box-shadow: 0 0 0 2px #000, inset 0 0 0 2px #000, 0 0 24px rgba(53,240,255,0.35); }
#scope i { position: absolute; background: var(--cyan); opacity: 0.75; box-shadow: 0 0 0 1px #000; }
#scope i:nth-child(1) { left: 50%; top: calc(50% - 35vmin); width: 2px; height: 70vmin; margin-left: -1px; }
#scope i:nth-child(2) { top: 50%; left: calc(50% - 35vmin); height: 2px; width: 70vmin; margin-top: -1px; }
#scope span { position: absolute; left: 50%; top: calc(50% + 37vmin); transform: translateX(-50%); color: var(--cyan); font-size: 23px; letter-spacing: 3px; text-shadow: 2px 2px 0 #000; }
#shield-ind { position: absolute; left: 50%; top: 56%; transform: translateX(-50%); font-size: 19px; letter-spacing: 2px; color: var(--cyan); text-shadow: 2px 2px 0 #000, 0 0 12px rgba(53,240,255,0.7); animation: shieldblink 0.8s steps(2) infinite; }
@keyframes shieldblink { 50% { opacity: 0.35; } }
#hitmarker { position: absolute; left: 50%; top: 50%; opacity: 0; }
#hitmarker i { position: absolute; width: 2px; height: 9px; background: #fff; box-shadow: 0 0 0 1px #000; }
#hitmarker i:nth-child(1) { transform: translate(-9px,-14px) rotate(45deg); }
#hitmarker i:nth-child(2) { transform: translate(7px,-14px) rotate(-45deg); }
#hitmarker i:nth-child(3) { transform: translate(-9px,5px) rotate(-45deg); }
#hitmarker i:nth-child(4) { transform: translate(7px,5px) rotate(45deg); }
#hitmarker.show { animation: hm 0.25s ease-out; }
#hitmarker.kill i { background: var(--red); }
@keyframes hm { 0% { opacity: 1; transform: scale(1.4); } 100% { opacity: 0; transform: scale(1); } }
#damage-flash { position: absolute; inset: 0; background: radial-gradient(ellipse at center, transparent 40%, rgba(255,30,30,0.7)); opacity: 0; transition: opacity 0.4s; }
#pickup-flash { position: absolute; inset: 0; background: radial-gradient(ellipse at center, transparent 50%, rgba(53,240,255,0.35)); opacity: 0; transition: opacity 0.5s; }
#dmg-dir { position: absolute; left: 50%; top: 50%; width: 120px; height: 120px; margin: -60px; opacity: 0; border-radius: 50%; }
#dmg-dir.show { opacity: 1; transition: opacity 0.05s; }
#match-info { position: absolute; top: 18px; left: 18px; }
#match-info .row { display: flex; gap: 8px; align-items: baseline; margin: 3px 0; }
#match-info .lbl { color: var(--cyan); font-size: 17px; width: 52px; }
#match-info span:not(.lbl) { color: var(--amber); }
/* CTF flag markers: a diamond in the team colour over each flag, clamped to the screen edge, with the distance. */
#flag-markers i { position: absolute; transform: translate(-50%, -100%); font-style: normal; font-size: 18px; text-align: center; text-shadow: 2px 2px 0 #000; line-height: 1; }
#flag-markers i b { display: block; width: 14px; height: 14px; margin: 0 auto 2px; transform: rotate(45deg); border: 2px solid #000; }
#flag-markers i.dropped b { animation: blink 0.6s steps(2) infinite; }
#mi-teams b { font-weight: normal; }
#killfeed { position: absolute; top: 18px; right: 18px; display: flex; flex-direction: column; gap: 4px; align-items: flex-end; font-size: 19px; }
#killfeed .kf { background: rgba(0,0,0,0.7); padding: 6px 10px; border-left: 3px solid var(--amber); animation: kfin 0.2s ease-out; }
#killfeed .kf.me { border-left-color: var(--red); }
#killfeed .kf.mine { border-left-color: var(--ok); }
#killfeed .kf .w { color: var(--dim); margin: 0 6px; }
@keyframes kfin { from { transform: translateX(40px); opacity: 0; } }
#console { position: absolute; left: 18px; bottom: 150px; font-family: var(--font2); font-size: 22px; line-height: 1.05; max-width: 44vw; text-shadow: 2px 2px 0 #000; }
#console .line { opacity: 1; transition: opacity 1s; }
#console.open { background: rgba(0,0,0,0.6); padding: 6px 10px; border-left: 2px solid var(--amber); }
#console .line.fade { opacity: 0; }
#console .from { color: var(--amber); }
#chat-wrap { position: absolute; left: 18px; bottom: 120px; display: flex; gap: 8px; font-family: var(--font2); font-size: 24px; pointer-events: auto; }
#chat-wrap input { width: 420px; background: rgba(0,0,0,0.8); color: #fff; border: 2px solid var(--amber); font-family: var(--font2); font-size: 24px; padding: 2px 8px; outline: none; }
#announce { position: absolute; top: 22%; left: 0; right: 0; text-align: center; font-size: 49px; color: var(--amber); text-shadow: 3px 3px 0 #000, 0 0 20px rgba(255,176,0,0.6); opacity: 0; }
/* Feedback #18 (GRIMJET): who you just fragged, bottom centre between the vitals and the ammo, where the eye already is. */
#frag-notice { position: absolute; left: 50%; bottom: 120px; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 30px; color: var(--text); text-shadow: 2px 2px 0 #000; white-space: nowrap; }
#frag-notice div { animation: fragin 2.4s ease-out forwards; }
#frag-notice b { font-weight: normal; }
#frag-notice .dim { color: var(--dim); font-size: 22px; }
@keyframes fragin { 0% { opacity: 0; transform: translateY(8px) scale(1.15); } 8% { opacity: 1; transform: none; } 80% { opacity: 1; } 100% { opacity: 0; } }
#announce.show { animation: ann 1.8s ease-out; }
@keyframes ann { 0% { opacity: 0; transform: scale(2); } 12% { opacity: 1; transform: scale(1); } 80% { opacity: 1; } 100% { opacity: 0; } }
#pickup-prompt { position: absolute; left: 50%; top: 58%; transform: translateX(-50%); background: rgba(0,0,0,0.8); border: 2px solid var(--cyan); padding: 8px 14px; font-size: 21px; color: var(--cyan); }
#pickup-prompt kbd { background: var(--cyan); color: #000; padding: 2px 6px; margin-right: 6px; }
#vitals { position: absolute; left: 18px; bottom: 18px; display: flex; flex-direction: column; gap: 8px; }
.vital { display: flex; align-items: center; gap: 10px; }
.vital .lbl { color: var(--cyan); font-size: 17px; width: 22px; }
.vital .num { color: var(--amber); font-size: 49px; width: 84px; text-align: right; text-shadow: 2px 2px 0 #000; }
.vital .num.low { color: var(--red); animation: blink 0.6s steps(2) infinite; }
.segbar { display: flex; gap: 2px; width: 200px; height: 14px; }
.segbar i { flex: 1; background: rgba(0,0,0,0.45); border: 1px solid rgba(0,0,0,0.8); }
.segbar i.on { background: var(--ok); box-shadow: inset 0 -4px 0 rgba(0,0,0,0.3); }
.segbar i.over { background: var(--cyan); }
.segbar.armor i.on { background: var(--bone); }
#weapon-panel { position: absolute; right: 18px; bottom: 18px; text-align: right; min-width: 260px; }
#ammo-num { color: var(--amber); font-size: 76px; text-shadow: 3px 3px 0 #000; line-height: 1; }
#ammo-num.low { color: var(--red); }
#weapon-name { color: var(--cyan); font-size: 19px; margin: 6px 0 10px; letter-spacing: 1px; }
#slots { display: flex; flex-direction: column; gap: 4px; font-size: 17px; }
.slot { display: flex; gap: 10px; align-items: center; padding: 2px 0; background: none; border: 0; color: var(--dim); text-shadow: 2px 2px 0 #000; }
.slot .key { background: rgba(0,0,0,0.55); color: var(--text); padding: 0 6px; text-shadow: none; }
.slot .wn { flex: 1; text-align: left; }
.slot.active { color: var(--text); }
.slot.active .key { background: var(--amber); color: #000; }
.slot.empty { opacity: 0.5; }
#death-screen { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; background: rgba(60,0,0,0.35); }
#death-screen .big { font-size: 57px; color: var(--red); text-shadow: 3px 3px 0 #000; }
#death-by { font-size: 27px; color: var(--text); }
#death-timer { font-size: 21px; color: var(--dim); }
#scoreboard { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); min-width: 560px; }
#scoreboard table { width: 100%; border-collapse: collapse; font-size: 21px; }
#scoreboard th { text-align: left; color: var(--cyan); padding: 6px 8px; border-bottom: 2px solid var(--amber-dim); font-weight: normal; }
#scoreboard td { padding: 6px 8px; border-bottom: 1px solid #1a2333; }
#scoreboard tr.me td { color: var(--amber); }
#scoreboard tr.team td { color: inherit; border-bottom: 2px solid currentColor; padding-top: 12px; }
.chip.team-red, .chip.team-blue { text-decoration: none; }
.chip.team-red.on { background: #ff4b4b; color: #000; border-color: #ff4b4b; } .chip.team-blue.on { background: #3fa7ff; color: #000; border-color: #3fa7ff; }
#scoreboard tr.dead td { opacity: 0.6; }
.sb-title { color: var(--amber); font-size: 23px; margin-bottom: 10px; }
.sb-hint { color: var(--dim); font-size: 17px; margin-top: 10px; }
.swatch { display: inline-block; width: 12px; height: 12px; border: 2px solid #000; vertical-align: middle; }
#pause-menu { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); pointer-events: auto; display: flex; flex-direction: column; gap: 10px; width: 320px; }
/* #hud .panel's 10px 14px padding left the title bar 4px too wide and floating below the frame. */
#pause-menu.panel { padding: 0 18px 18px; gap: 4px; }
#pause-menu .title { margin-bottom: 8px; }
/* The pickup prompt and spawn-shield label sit under the pause menu and showed through its translucent panel. */
#hud:has(#pause-menu:not(.hidden)) :is(#pickup-prompt, #shield-ind) { display: none; }
kbd { font-family: inherit; }
::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-thumb { background: var(--amber-dim); }

/* accounts (2026-09-14): optional claimed callsign + stats */
.field-head { display: flex; justify-content: space-between; align-items: baseline; }
.link { background: none; border: 0; padding: 0; margin-left: 14px; color: var(--dim); font: inherit; font-size: 17px; letter-spacing: 1px; cursor: pointer; text-transform: uppercase; }
.link:hover, .link:focus-visible { color: var(--amber); outline: none; }
.field input:disabled { color: var(--green); border-color: var(--dim); opacity: 1; }
.field input[type=password] { background: #000; color: var(--amber); border: 2px solid var(--dim); padding: 10px; font-size: 27px; letter-spacing: 3px; outline: none; }
.stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px 18px; margin-bottom: 12px; }
.stats-grid .kv b { color: var(--amber); font-size: 25px; font-weight: normal; }
table.list tr.me td { color: var(--amber); }

/* ---------- supporter ---------- */
.sup { color: var(--amber); text-shadow: 0 0 6px var(--amber-dim); }
.support-row { margin: 14px 0 0; font-size: 17px; line-height: 1.7; color: var(--dim); text-align: center; }
.support-row b { color: var(--amber); }
#supporter-settings { margin-top: 14px; }
/* .field already lays out label-above-control in a left-aligned column; only the swatch row needs styling. */
#color-swatches { display: flex; gap: 6px; }
.color-pref .sw { width: 30px; height: 30px; border: 2px solid transparent; cursor: pointer; padding: 0; }
.color-pref .sw:hover { border-color: var(--text); }
.color-pref .sw.on { border-color: var(--amber); box-shadow: 0 0 8px var(--amber-dim); }
.return #contact a, .support-row a { color: var(--cyan); }

.perk { display: flex; gap: 10px; align-items: flex-start; font-family: var(--font2); font-size: 22px; line-height: 1.35; color: var(--text); margin: 8px 0; }
.perk b { color: var(--amber); font-family: var(--font); font-size: 21px; line-height: 1.6; }
.fineprint { font-family: var(--font2); font-size: 22px; line-height: 1.4; color: var(--dim); margin: 12px 0 4px; }
#sup-amounts .btn { text-align: center; }


/* ---------- lobby rules (2026-10-01) ---------- */
.chips { display: flex; gap: 4px; }
.chip { font: inherit; font-size: 20px; padding: 0 6px; background: #000; color: var(--dim); border: 2px solid #333; cursor: pointer; text-decoration: line-through; }
.chip.on { color: var(--green); border-color: var(--amber-dim); text-decoration: none; }
.chip:not(:disabled):hover { border-color: var(--green); color: #fff; }
.chip:disabled { cursor: default; }
.rules-lock { color: var(--amber); font-size: 18px; margin-left: 8px; }
.mode-tag { color: #000; background: var(--amber); font-size: 18px; padding: 0 5px; margin-left: 6px; }
#rule-gib-note { margin: 2px 0 6px; }
#sup-view-hint { color: var(--text); }

/* supporter preview (2026-10-01): a live crowned character beside the perks */
.sup-body { display: flex; gap: 18px; align-items: flex-start; }
.sup-main { flex: 1; min-width: 0; }
.sup-preview { flex: 0 0 200px; height: 260px; margin-top: 12px; border: 2px solid #333; background: radial-gradient(circle at 50% 45%, #4a110b 0, #170504 55%, #000 80%); }
.sup-preview canvas { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
@media (max-width: 640px) { .sup-body { flex-direction: column; align-items: center; } .sup-preview { flex-basis: auto; width: 180px; height: 220px; } }

/* Ad slots (dev accounts only for now): a 728x90 band under the panel, left out on narrower screens. */
.ad-slot { width: min(728px, 100%); min-height: 90px; display: flex; align-items: center; justify-content: center; border: 2px dashed var(--dim); color: var(--dim); font-size: 22px; letter-spacing: 2px; }
/* A live unit is transparent until Google sends an ad (during the site review it never does), so show the slot
   as a dashed AD box behind it until AdSense marks the unit filled. Outline, not border: the unit needs all 728 px. */
.ad-slot.live { border: 0; position: relative; outline: 2px dashed var(--dim); outline-offset: -2px; }
.ad-slot.live::before { content: 'AD'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 0; }
.ad-slot.live ins { position: relative; z-index: 1; }
.ad-slot.live:has(ins[data-ad-status="filled"]) { outline: 0; }
.ad-slot.live:has(ins[data-ad-status="filled"])::before { content: none; }
.ad-slot.narrow { display: none; }
/* About / privacy links under the title footer; they navigate rather than start the game (main.js). */
.footer .pagelinks { margin-top: 6px; } .footer .pagelinks a { color: var(--bone); }

/* Themed dropdowns (js/dropdown.js): the native <select> stays hidden as the source of truth; .dd is its trigger and
   .dd-list the open panel, built like the menus (black, bone border, option rows that go white on the red row). */
select.dd-native { display: none !important; }
.dd { display: inline-flex; align-items: center; justify-content: space-between; gap: 10px; cursor: pointer; text-align: left; text-transform: uppercase; line-height: 1.1; }
.dd:focus-visible, .dd.open { outline: none; border-color: var(--accent); }
.dd:disabled { cursor: default; }
.dd-arrow { font-size: 0.8em; opacity: 0.8; }
.dd:disabled .dd-arrow { display: none; }
.dd-list { position: fixed; z-index: 200; overflow-y: auto; background: #000; border: 2px solid var(--bone); outline: 2px solid #000; box-shadow: 0 8px 24px rgba(0,0,0,0.7);
  font-family: var(--font); font-size: 24px; letter-spacing: 1px; padding: 2px 0; }
.dd-item { padding: 3px 14px 3px 12px; color: var(--green); white-space: nowrap; cursor: pointer; border-left: 3px solid transparent; }
.dd-item.sel { color: #fff; border-left-color: var(--accent); }
.dd-item.hi { background: var(--green-row); color: #fff; }
.dd-item.off { opacity: 0.35; cursor: default; }

/* staging.fragbraten.com (the server sends staging: true): a fixed tag so nobody mistakes it for the live game,
   with the deployed commit and when it shipped (data-deploy, set in main.js; Noah 2026-10-07) */
body.staging::after { content: 'STAGING' attr(data-deploy); position: fixed; top: 10px; right: 12px; z-index: 100; pointer-events: none; font-family: var(--font);
  font-size: 22px; letter-spacing: 3px; color: #000; background: #ffd23f; padding: 2px 10px; box-shadow: 0 0 0 2px #000; }
