:root {
    --bg: #07070b;
    --panel: rgba(9, 9, 14, 0.74);
    --line: rgba(255, 255, 255, 0.09);
    --line-hi: rgba(255, 255, 255, 0.18);
    --txt: #e9e7f0;
    --dim: #6d6880;
    --accent: #ff2d55;
    --teal: #4ae2d0;
    --gold: #ffd23a;
    --mono: ui-monospace, SFMono-Regular, Consolas, monospace;
    --ui-scale: 1;
}

/* Each HUD block is anchored to an edge, so zooming them scales in place.
   Adjust with - and = in game (or the buttons in the Cosmetics panel). */
#wave-info, #leaderboard, #vitals, #menu-buttons, #chat, #perf, #notices, .panel {
    zoom: var(--ui-scale);
}

* { box-sizing: border-box; }

body, html {
    margin: 0;
    padding: 0;
    overflow: hidden;
    height: 100%;
    background: var(--bg);
    color: var(--txt);
    font: 400 13px/1.4 'Inter', 'Segoe UI', system-ui, sans-serif;
    user-select: none;
    -webkit-font-smoothing: antialiased;
}

canvas#bgCanvas, canvas#gameCanvas { position: absolute; top: 0; left: 0; display: block; }
canvas#bgCanvas { z-index: 1; }
canvas#gameCanvas { z-index: 2; cursor: crosshair; }

/* BACKGROUND DIM — settings > display, persisted as bd_dim.
   z-index 1 like #bgCanvas, and it comes after it in the markup, so equal-z source
   order puts it above the shader and below #gameCanvas (z-index 2). That is what
   makes it a BACKGROUND dim: the arena, the bodies and the HUD stay at full
   brightness and only the noise behind them goes down.
   pointer-events:none is not optional — game.js binds wheel and contextmenu to
   #gameCanvas, so an overlay that accepts hits would kill scroll-to-zoom and give
   you the browser right-click menu over the arena. */
#screen-dim {
    position: absolute; inset: 0; z-index: 1;
    background: #000; opacity: 0;
    pointer-events: none;
}

.set-wide.danger { color: #ff8fa3; border-color: rgba(255,45,85,0.35); }
.set-wide.danger:hover { background: rgba(255,45,85,0.12); border-color: rgba(255,45,85,0.6); }

.hidden { display: none !important; }

/* ============================================================== login == */

#login-screen {
    position: absolute; inset: 0; z-index: 50;
    display: flex; align-items: center; justify-content: center;
    background: var(--bg);   /* flat — no vignette. less "designed", more plain. */
}

.login-card { width: 268px; text-align: center; }

.login-card h1 {
    margin: 0 0 18px;
    font: 600 17px/1 'Inter', 'Segoe UI', sans-serif;
    letter-spacing: 5px;
    color: var(--txt);
}

.tagline { color: var(--dim); margin: 14px 0 22px; font-size: 11px; letter-spacing: .3px; }
.hint { color: #4d4960; margin: 14px 0 0; font-size: 10px; font-family: var(--mono); }

input[type="text"], input[type="password"] {
    display: block; width: 100%;
    padding: 9px 11px;
    font: 400 13px var(--mono);
    border: 1px solid var(--line); border-radius: 4px;
    outline: none; background: rgba(255,255,255,0.035); color: var(--txt);
    transition: border-color .15s, background .15s;
}
input[type="text"]:focus, input[type="password"]:focus { border-color: var(--line-hi); background: rgba(255,255,255,0.06); }
input[type="text"]::placeholder, input[type="password"]::placeholder { color: #4d4960; }

button {
    padding: 7px 13px;
    font: 600 11px/1 'Inter', 'Segoe UI', sans-serif;
    letter-spacing: .8px;
    cursor: pointer; border: 1px solid var(--line);
    border-radius: 4px; outline: none;
    background: rgba(255,255,255,0.05); color: var(--txt);
    transition: background .14s, border-color .14s, color .14s;
}
button:hover { background: rgba(255,255,255,0.1); border-color: var(--line-hi); }
button:disabled { background: none; color: #3f3b4e; border-color: rgba(255,255,255,0.05); cursor: default; }

#enter-game {
    padding: 11px;
    background: var(--accent); border-color: var(--accent); color: #fff;
    letter-spacing: 2.5px; font-size: 12px;
}
#enter-game:hover { background: #ff4767; border-color: #ff4767; }

/* ================================================================ HUD == */

/* Only things you can actually CLICK get pointer-events. Everything else is a
   read-only readout and must not swallow the mouse — hovering your own health bar
   used to stop you shooting. Aim and fire are bound to the window now (see
   setupInput), so even the clickable blocks don't break firing. */
#ui { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
#leaderboard, #menu-buttons, #chat, #perf { pointer-events: auto; }
#wave-info, #vitals, #notices, #downed-overlay { pointer-events: none; }

/* THE HUD IS OPAQUE. It goes transparent under YOUR CURSOR, and only there.
   This was backwards once: everything faded while you held fire and went solid when
   you pointed at it, which is exactly the wrong way round — the block you're aiming
   through is the one that needs to get out of the way.
   #chat is the exception — see the FADEABLE list in game.js. */
#wave-info, #leaderboard, #vitals, #menu-buttons, #chat, #perf, #skilltree {
    transition: opacity .13s ease-out;
}
#wave-info.see-through,
#leaderboard.see-through,
#vitals.see-through,
#menu-buttons.see-through,
#chat.see-through,
#perf.see-through { opacity: 0.15; }
/* The tree is huge, so it fades less far — enough to shoot through, not so far
   that you lose your place while dragging a node around. */
#skilltree.see-through { opacity: 0.3; }

/* Hidden for good from the settings panel. Separate from .hidden so a panel that
   toggles .hidden on the same element can't fight it. */
.hud-off { display: none !important; }

/* "(+4)" beside the wave number: waves you walked in carrying from a save. */
.wave-carry {
    font-size: 0.5em; color: var(--teal); margin-left: 4px;
    vertical-align: super; letter-spacing: 0;
}

#wave-info {
    position: absolute; top: 12px; left: 12px;
    background: var(--panel); border: 1px solid var(--line);
    border-radius: 5px; padding: 9px 11px; min-width: 158px;
    backdrop-filter: blur(7px);
}
.stat { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; }
.stat + .stat { margin-top: 5px; }
.stat .k {
    font-size: 9px; letter-spacing: 1.5px; text-transform: uppercase;
    color: var(--dim); white-space: nowrap;
}
.stat .v { font: 500 13px var(--mono); color: var(--txt); }
.stat.lead .v { font-size: 21px; font-weight: 600; line-height: 1; }
.stat .v.cash { color: var(--gold); }
.stat .v.essence { color: var(--accent); }
#wave-info .sub {
    font-size: 10px; color: var(--dim); font-family: var(--mono);
    margin: 3px 0 8px; padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
#wave-info.boss { border-color: rgba(255,45,85,0.55); }
#wave-info.boss .stat.lead .v { color: var(--accent); }

#leaderboard {
    position: absolute; top: 12px; right: 12px;
    background: var(--panel); border: 1px solid var(--line);
    border-radius: 5px; padding: 8px 10px; min-width: 156px;
    backdrop-filter: blur(7px);
}
#leaderboard h3 {
    margin: 0 0 6px; font-size: 9px; letter-spacing: 1.5px;
    color: var(--dim); text-transform: uppercase; font-weight: 500;
}
.lb-row {
    display: flex; justify-content: space-between; gap: 10px;
    padding: 1.5px 4px; margin: 0 -4px; font-size: 11px;
    border-radius: 3px; cursor: pointer;
    transition: background .1s;
}
.lb-row:hover { background: rgba(255,255,255,0.07); }
.lb-row.on { background: rgba(74,226,208,0.14); }
.lb-name { display: flex; align-items: center; gap: 6px; color: var(--txt); }
.lb-name small { color: var(--dim); font-family: var(--mono); font-size: 9px; }
.dot { width: 6px; height: 6px; border-radius: 50%; display: inline-block; flex: none; }
/* Deliberately NOT gold. This is a career score, not your spendable cash — gold
   made people think they were rich when they had nothing to spend. */
.lb-score { color: var(--txt); font-family: var(--mono); font-size: 11px; }

#notices {
    position: absolute; top: 78px; left: 50%; transform: translateX(-50%);
    text-align: center; pointer-events: none; width: 440px;
}
.notice {
    display: inline-block; padding: 3px 11px; margin-bottom: 4px;
    background: rgba(9,9,14,0.72); border: 1px solid var(--line);
    border-radius: 3px; font-size: 11px; color: #b9b4c8;
    animation: nIn .2s ease-out;
}
.notice.big {
    font-size: 15px; font-weight: 600; letter-spacing: 3.5px;
    color: var(--accent); border-color: rgba(255,45,85,0.4);
    padding: 5px 18px; text-transform: uppercase;
}
@keyframes nIn { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; } }

/* vitals: thin bars, number on the left */
#vitals { position: absolute; bottom: 46px; left: 50%; transform: translateX(-50%); width: 290px; }
.vrow { display: flex; align-items: center; gap: 9px; margin-bottom: 5px; }
.vlabel {
    font: 500 10px var(--mono); color: var(--dim);
    min-width: 62px; text-align: right; white-space: nowrap;
}
/* NO TRACK. A health bar is three layers — the fill in front, the hit chip behind
   it wearing your trim, and NOTHING behind that. The grey rail was a fourth thing
   that carried no information and sat there permanently. Same rule as the XP bar
   and the stamina arc in game.js. The XP bar keeps a faint one because it is a
   progress meter, not damage. */
.bar {
    position: relative;
    flex: 1; height: 5px; border-radius: 3px; overflow: hidden;
    background: none;
}
.bar.xp { background: rgba(255,255,255,0.06); }
.bar > div { position: absolute; left: 0; top: 0; height: 100%; width: 100%; }
/* the white "chip" sits behind the real fill and drains away a beat later */
#health-ghost { background: rgba(255,255,255,0.8); transition: width .1s linear; }
#health-fill { background: #4ae26a; transition: width .1s linear, background .25s linear; }
.bar.xp { height: 3px; }
#xp-fill { background: var(--teal); width: 0; transition: width .12s linear; }

/* stand-in for the shader on potato quality */
body.no-shader { background: radial-gradient(ellipse at 50% 45%, #180d29 0%, #07070b 72%); }

#perf {
    position: absolute; bottom: 44px; right: 12px;
    font: 500 10px var(--mono); color: var(--dim);
    background: var(--panel); border: 1px solid var(--line);
    border-radius: 4px; padding: 3px 7px; cursor: pointer;
    backdrop-filter: blur(7px);
}
#perf:hover { color: var(--txt); border-color: var(--line-hi); }
#perf.warn { color: var(--gold); border-color: rgba(255,210,58,0.35); }
#perf.bad { color: var(--accent); border-color: rgba(255,45,85,0.45); }

#menu-buttons { position: absolute; bottom: 12px; right: 12px; display: flex; gap: 5px; }
#menu-buttons button { background: var(--panel); backdrop-filter: blur(7px); }
.badge {
    display: inline-block; background: var(--accent); color: #fff;
    border-radius: 7px; padding: 0 5px; font: 700 9px var(--mono);
    font-style: normal; margin-left: 5px; vertical-align: 1px;
}

#downed-overlay {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    background: rgba(70, 0, 14, 0.26); pointer-events: none;
}
#downed-overlay h2 {
    margin: 0; font: 300 26px/1 'Inter', sans-serif;
    letter-spacing: 9px; text-indent: 9px; color: var(--accent);
}
#downed-overlay p { color: #a8909c; font-size: 11px; margin: 10px 0 0; }
.revive-bar { width: 190px; height: 3px; background: rgba(255,255,255,0.12); border-radius: 2px; overflow: hidden; margin-top: 10px; }
#revive-fill { height: 100%; width: 0; background: var(--teal); transition: width .1s linear; }

/* ========================================================= skill tree == */
/* Two states on #skilltree: .st-rail-only and .st-open. There is no "maximise" and no
   separate resize grip — #st-rail IS the handle. Click it to open/close, drag it to
   any width. .st-nosnap kills the transition mid-drag so it tracks the cursor.
   The UI chrome (#st-frame) and the tree surface (#st-viewport) are deliberately
   separate backgrounds — flat dark panel around a living one. */

/* The panel FLOATS — it deliberately doesn't touch the top or bottom of the screen.
   `left: 0` is load-bearing: without it this absolutely-positioned flex container
   shrink-to-fits to the width of the rail (36px) and crushes #st-frame to 2px no
   matter what --st-w says. pointer-events:none means the full-width container still
   lets clicks through to the game; the children re-enable it. */
#skilltree {
    position: absolute; inset: 0;
    z-index: 30;
    display: flex; align-items: center;
    justify-content: flex-end;
    pointer-events: none;
    --st-w: 520px;
}
#skilltree > * { pointer-events: auto; }
body.st-resizing { cursor: ew-resize; user-select: none; }
body.st-resizing #st-frame { transition: none; }

/* ---- the collapsed strip ---- */
#st-rail {
    width: 34px; flex: none;
    height: min(420px, 62vh);
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 14px;
    background: linear-gradient(180deg, rgba(14,14,23,0.9), rgba(7,7,12,0.9));
    border: 1px solid var(--line); border-right: none;
    border-radius: 6px 0 0 6px;
    backdrop-filter: blur(7px);
    cursor: ew-resize;
    user-select: none;
    transition: background .16s, border-color .16s;
}
#st-rail:hover { background: linear-gradient(180deg, rgba(24,24,38,0.94), rgba(11,11,19,0.94)); border-color: var(--line-hi); }

#st-rail-label {
    writing-mode: vertical-rl; rotate: 180deg;
    font: 600 9px 'Inter', sans-serif; letter-spacing: 4px;
    color: var(--dim); text-transform: uppercase;
}
#st-rail:hover #st-rail-label { color: var(--txt); }
/* three little bars, the universal "you can drag this" tell */
#st-rail-grip { display: flex; flex-direction: column; gap: 3px; }
#st-rail-grip i {
    display: block; width: 12px; height: 2px; border-radius: 1px;
    background: rgba(255,255,255,0.16);
    transition: background .14s, width .14s;
}
#st-rail:hover #st-rail-grip i { background: var(--teal); width: 16px; }

/* ---- the framed panel ---- */
#st-frame {
    position: relative;
    width: var(--st-w); flex: none;
    height: min(84vh, 900px);
    display: flex; flex-direction: column;
    overflow: hidden;
    background: linear-gradient(160deg, rgba(13,13,21,0.97), rgba(6,6,11,0.98));
    border: 1px solid var(--line-hi);
    border-radius: 7px 0 0 7px;
    box-shadow: -22px 0 70px rgba(0,0,0,0.7);
    transition: width .24s cubic-bezier(.22,.61,.36,1);
}
#skilltree.st-rail-only #st-frame { width: 0; border-width: 0; }
/* while you're dragging the bar the panel must follow the cursor exactly */
#skilltree.st-nosnap #st-frame { transition: none; }

#st-links { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
#st-tree { z-index: 2; }

#st-head {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 11px 9px 18px;
    border-bottom: 1px solid var(--line);
    background: rgba(255,255,255,0.022);
    flex: none;
}
#st-head h2 {
    margin: 0; font: 500 10px 'Inter', sans-serif;
    letter-spacing: 3px; text-transform: uppercase; color: var(--txt);
    white-space: nowrap;
}

/* the three currencies you spend in here — this panel replaced the Skills menu */
#st-wallet { display: flex; gap: 9px; margin-left: auto; }
.stw { display: flex; align-items: center; gap: 4px; font: 500 11px var(--mono); color: var(--dim); }
.stw i { width: 6px; height: 6px; border-radius: 50%; display: block; }
.stw.cash { color: var(--gold); } .stw.cash i { background: var(--gold); }
.stw.sp i { background: var(--teal); }
.stw.ess i { background: var(--accent); }
.stw.sp.has { color: var(--teal); }
.stw.ess.has { color: var(--accent); }

.st-actions { display: flex; gap: 4px; }
.st-actions button {
    min-width: 24px; padding: 3px 6px;
    font: 600 10px var(--mono); letter-spacing: 0;
    background: rgba(255,255,255,0.04);
}
#st-edit-toggle { letter-spacing: 1.5px; font-size: 9px; }
#st-edit-toggle.on { background: var(--gold); border-color: var(--gold); color: #17130a; }

/* ---- editor bar ---- */
#st-editbar { display: none; gap: 5px; padding: 7px 9px; border-bottom: 1px solid var(--line); flex: none; }
#skilltree.st-editing #st-editbar { display: flex; align-items: center; }
#st-editbar button { padding: 4px 9px; font: 500 10px var(--mono); }
#st-editbar .st-spacer { flex: 1; }
#st-snap { background: rgba(255,210,58,0.13); border-color: rgba(255,210,58,0.4); color: var(--gold); }
#st-save { background: rgba(74,226,106,0.14); border-color: rgba(74,226,106,0.42); color: #4ae26a; }
/* WIP toggle: dim while unwritten nodes are hidden (the shipping state), lit when
   they are being shown. Editor-only — the button lives in #st-editbar. */
#st-wip { color: #6f6a80; border-color: rgba(255,255,255,0.10); }
#st-wip.on { background: rgba(122,92,255,0.16); border-color: rgba(122,92,255,0.45); color: #b9a6ff; }

/* ---- the tree surface: its OWN background, not the panel's ---- */
#st-viewport {
    position: relative; flex: 1; min-height: 0;
    overflow: hidden;
    margin: 9px; border-radius: 5px;
    border: 1px solid rgba(255,255,255,0.14);
    background: #05050a;
    box-shadow: inset 0 0 44px rgba(0,0,0,0.85);
}
#st-bg, #st-tree { position: absolute; inset: 0; display: block; }
#st-bg { z-index: 0; }
#st-tree { z-index: 1; cursor: grab; }

#st-toast {
    position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%);
    z-index: 3; padding: 5px 12px;
    background: rgba(8,8,14,0.95); border: 1px solid var(--line-hi);
    border-radius: 4px; font: 500 11px var(--mono); color: var(--txt);
    white-space: nowrap;
}
#st-toast.bad { border-color: rgba(255,45,85,0.6); color: #ff8a9a; }

/* ---- inspector ---- */
#st-inspector {
    flex: none; max-height: 46%; overflow-y: auto;
    padding: 9px 11px 12px;
    border-top: 1px solid var(--line);
    background: rgba(255,255,255,0.022);
}
.sti-row { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.sti-k {
    flex: none; width: 66px;
    font: 500 9px var(--mono); letter-spacing: .8px;
    color: var(--dim); text-transform: uppercase;
}
#st-inspector input, #st-inspector select {
    flex: 1; min-width: 0;
    padding: 4px 7px; font: 400 11px var(--mono);
    background: rgba(255,255,255,0.045); color: var(--txt);
    border: 1px solid var(--line); border-radius: 3px; outline: none;
}
#st-inspector input:focus, #st-inspector select:focus { border-color: var(--line-hi); }
.sti-pair input, .sti-tri input { flex: 1; }
.sti-tri { padding-left: 74px; gap: 6px; }
.sti-sep {
    margin: 9px 0 5px; padding-top: 8px;
    border-top: 1px solid rgba(255,255,255,0.06);
    font: 500 9px var(--mono); letter-spacing: 1.4px;
    color: var(--dim); text-transform: uppercase;
}
.sti-id-row b { font: 500 10px var(--mono); color: var(--teal); word-break: break-all; }
.sti-help { margin: 9px 0 0; font: 400 9px var(--mono); color: #4d4960; line-height: 1.6; }

/* ======================================================= value editor == */
/* ---- the cheat spawner (C) ---- */
#cheat {
    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
    z-index: 58; width: 236px; max-height: 78vh;
    display: flex; flex-direction: column;
    background: rgba(7,7,12,0.97);
    border: 1px solid var(--line-hi); border-radius: 7px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.8);
}
#cheat header {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    padding: 8px 10px; border-bottom: 1px solid var(--line); flex: none;
}
#cheat h2 {
    margin: 0; font: 500 10px 'Inter', sans-serif;
    letter-spacing: 3px; text-transform: uppercase;
}
#cheat-hint { flex-basis: 100%; font: 400 9px var(--mono); color: var(--dim); }
#cheat header button { padding: 3px 7px; font: 500 9px var(--mono); }
#cheat-clear { color: #ff8a9a; border-color: rgba(255,45,85,0.35); margin-left: auto; }
#cheat-close { font-size: 14px; padding: 0 6px; }
#cheat-body { flex: 1; overflow-y: auto; padding: 8px 10px 12px; }
.cheat-group + .cheat-group { margin-top: 11px; }
.cheat-group h3 {
    margin: 0 0 5px; font: 500 8px var(--mono); letter-spacing: 2px;
    text-transform: uppercase; color: #4d4960;
}
.cheat-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.cheat-chip {
    padding: 3px 7px; font: 400 10px var(--mono);
    background: rgba(255,255,255,0.04); border: 1px solid var(--line);
    border-radius: 3px; color: #b9b3cf; cursor: pointer;
}
.cheat-chip:hover { border-color: var(--line-hi); color: #fff; }
.cheat-chip.elite { color: var(--gold); border-color: rgba(255,210,58,0.35); }
.cheat-chip.wip { opacity: 0.75; font-style: italic; }
.cheat-chip.on {
    background: var(--teal); border-color: var(--teal); color: #08080c; font-weight: 600;
}
.cheat-opts { display: flex; flex-direction: column; gap: 5px; }
.cheat-opts label { font: 400 10px var(--mono); color: var(--dim); display: flex; gap: 6px; align-items: center; }
.cheat-opts input {
    width: 56px; padding: 2px 5px; font: 400 10px var(--mono);
    background: rgba(0,0,0,0.4); border: 1px solid var(--line);
    border-radius: 3px; color: #fff;
}
/* something is armed: make it obvious the next click PLACES rather than shoots */
body.cheat-armed canvas#gameCanvas { cursor: cell; }

#spectate-game {
    width: 100%; margin-top: 8px; padding: 7px;
    font-size: 10px; letter-spacing: 2px; color: var(--dim);
}
#spectate-game:hover { color: var(--txt); }

/* ---- the wave editor (B). Shares the value editor's chrome. ---- */
#waveeditor {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    z-index: 60; width: min(820px, 94vw); height: min(80vh, 860px);
    display: flex; flex-direction: column;
    background: rgba(7,7,12,0.98);
    border: 1px solid var(--line-hi); border-radius: 7px;
    box-shadow: 0 30px 90px rgba(0,0,0,0.85);
}
#waveeditor header {
    display: flex; align-items: center; gap: 9px;
    padding: 10px 12px; border-bottom: 1px solid var(--line); flex: none;
}
#waveeditor h2 {
    margin: 0; font: 500 11px 'Inter', sans-serif;
    letter-spacing: 3px; text-transform: uppercase; white-space: nowrap;
}
#wave-count { flex: 1; font: 400 10px var(--mono); color: var(--dim); }
#waveeditor header button { padding: 4px 9px; font: 500 10px var(--mono); }
#wave-save { color: var(--teal); border-color: rgba(74,226,208,0.35); }
/* an unsaved table has to be obvious — losing authored work has happened before */
#wave-save.dirty {
    color: #0a0a0f; background: var(--teal); border-color: var(--teal);
    animation: waveDirty 1.4s ease-in-out infinite;
}
@keyframes waveDirty { 50% { opacity: 0.55; } }
#wave-reset { color: #ff8a9a; border-color: rgba(255,45,85,0.35); }
#wave-close { font-size: 15px; padding: 0 7px; }

#wave-list { flex: 1; overflow-y: auto; padding: 6px 10px 16px; }

.wave-row {
    border: 1px solid var(--line); border-radius: 5px;
    margin: 7px 0; padding: 7px 9px 9px;
    background: rgba(255,255,255,0.015);
}
.wave-head { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.wave-head b { font: 600 10px var(--mono); letter-spacing: 1.5px; color: #cfc9e4; }
.wave-boss {
    font: 600 9px var(--mono); letter-spacing: 1px; color: var(--accent);
    border: 1px solid rgba(255,45,85,0.4); border-radius: 3px; padding: 1px 5px;
}
.wave-total { flex: 1; font: 400 10px var(--mono); color: var(--dim); }
.wave-head button {
    padding: 2px 7px; font: 500 9px var(--mono);
    background: none; border: 1px solid var(--line); border-radius: 3px;
    color: var(--dim); cursor: pointer;
}
.wave-head button:hover { color: #fff; border-color: var(--line-hi); }

.wave-chips { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.wave-chip {
    display: inline-flex; align-items: center; gap: 3px;
    border: 1px solid var(--line); border-radius: 4px;
    padding: 2px 3px 2px 7px; background: rgba(255,255,255,0.03);
}
.wave-chip.elite { border-color: rgba(255,210,58,0.45); background: rgba(255,210,58,0.06); }
.wave-chip-name { font: 400 10px var(--mono); color: #b9b3cf; min-width: 74px; }
.wave-chip.elite .wave-chip-name { color: var(--gold); }
.wave-chip input {
    width: 40px; padding: 2px 4px; text-align: center;
    font: 400 10px var(--mono); background: rgba(0,0,0,0.4);
    border: 1px solid var(--line); border-radius: 3px; color: #fff;
}
.wave-dash { font: 400 10px var(--mono); color: var(--dim); }
.wave-chip-x {
    background: none; border: none; color: var(--dim);
    font-size: 13px; line-height: 1; padding: 0 3px; cursor: pointer;
}
.wave-chip-x:hover { color: var(--accent); }
.wave-add-type {
    padding: 3px 6px; font: 400 10px var(--mono);
    background: rgba(0,0,0,0.4); border: 1px dashed var(--line);
    border-radius: 4px; color: var(--dim); cursor: pointer;
}

#valeditor {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    z-index: 60; width: min(760px, 92vw); height: min(78vh, 820px);
    display: flex; flex-direction: column;
    background: rgba(7,7,12,0.98);
    border: 1px solid var(--line-hi); border-radius: 7px;
    box-shadow: 0 30px 90px rgba(0,0,0,0.85);
}
#valeditor header {
    display: flex; align-items: center; gap: 9px;
    padding: 10px 12px; border-bottom: 1px solid var(--line); flex: none;
}
#valeditor h2 {
    margin: 0; font: 500 11px 'Inter', sans-serif;
    letter-spacing: 3px; text-transform: uppercase; white-space: nowrap;
}
#val-search { flex: 1; padding: 5px 9px; font: 400 11px var(--mono); }
#val-count { font: 400 10px var(--mono); color: var(--dim); white-space: nowrap; }
#valeditor header button { padding: 4px 9px; font: 500 10px var(--mono); }
#val-reset { color: #ff8a9a; border-color: rgba(255,45,85,0.35); }
#val-close { font-size: 15px; padding: 0 7px; }

.val-help {
    margin: 0; padding: 8px 12px; flex: none;
    border-bottom: 1px solid var(--line);
    font: 400 10px/1.7 var(--mono); color: var(--dim);
}
.val-help code { color: var(--teal); }

#val-list { flex: 1; overflow-y: auto; padding: 6px 0 14px; }
#val-list::-webkit-scrollbar { width: 8px; }
#val-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); border-radius: 4px; }

.val-group {
    position: sticky; top: 0; z-index: 1;
    padding: 7px 12px 4px; margin-top: 4px;
    background: rgba(7,7,12,0.97);
    font: 600 9px var(--mono); letter-spacing: 1.6px;
    color: var(--teal); text-transform: uppercase;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
.val-row {
    display: flex; align-items: center; gap: 10px;
    padding: 3px 12px;
}
.val-row:hover { background: rgba(255,255,255,0.035); }
.val-row.changed .val-key { color: var(--gold); }
.val-row.flash { background: rgba(74,226,106,0.16); }
.val-key {
    flex: none; width: 190px;
    font: 400 11px var(--mono); color: var(--txt);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.val-row input, .val-row select {
    width: 150px; flex: none;
    padding: 3px 7px; font: 400 11px var(--mono);
    background: rgba(255,255,255,0.05); color: var(--txt);
    border: 1px solid var(--line); border-radius: 3px; outline: none;
}
.val-row input:focus, .val-row select:focus { border-color: var(--teal); }
.val-row input.bad { border-color: var(--accent); background: rgba(255,45,85,0.12); }
.val-tags { display: flex; gap: 4px; flex-wrap: wrap; }
.val-tag {
    font: 600 8px var(--mono); letter-spacing: .6px; text-transform: uppercase;
    padding: 1px 5px; border-radius: 2px;
}
.val-tag.changed { background: rgba(255,210,58,0.16); color: var(--gold); }
.val-tag.restart { background: rgba(255,45,85,0.14); color: #ff8a9a; }
.val-tag.spawn   { background: rgba(74,226,208,0.13); color: var(--teal); }
.val-empty { padding: 22px 12px; text-align: center; color: var(--dim); font: 400 11px var(--mono); }

/* =============================================================== chat == */

#chat { position: absolute; bottom: 12px; left: 12px; width: 268px; }
#chat-log {
    height: 108px; overflow-y: auto;
    padding: 5px 0; margin-bottom: 4px;
    font-size: 11px; line-height: 1.55;
    mask-image: linear-gradient(to bottom, transparent, #000 18px);
}
#chat-log::-webkit-scrollbar { width: 3px; }
#chat-log::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); }
#chat-log .sys { color: #575269; }
#chat-input { font: 400 11px var(--mono); padding: 6px 9px; background: var(--panel); }
/* Chat idles half-lit and gets OUT OF THE WAY when you fire through it. It used to
   brighten to FULL on hover, which meant pointing at an enemy underneath it made the
   chat harder to see past, not easier.
   The second rule needs the extra .dim to outrank #chat.dim above it — same
   specificity would lose on source order, and chat is almost always .dim. */
#chat.dim { opacity: .5; transition: opacity .2s; }
#chat.dim.see-through { opacity: 0.12; }

/* ---- BALLS CAGE: centred, floating chat + a stripped HUD ----
   #cage-chat is a zero-size anchor at the exact centre of the screen; every message
   is absolutely placed off it and driven by cagechat.js. It lives above #ui and eats
   no clicks. */
#cage-chat {
    position: absolute; left: 50%; top: 50%;
    width: 0; height: 0; z-index: 6;
    pointer-events: none;
}
.cage-msg {
    position: absolute; left: 0; top: 0;
    transform: translate(-50%, -50%);
    white-space: nowrap; text-align: center;
    font: 500 20px/1.2 'Inter', 'Segoe UI', sans-serif;
    color: var(--txt);
    text-shadow: 0 2px 18px rgba(0,0,0,0.85), 0 0 3px rgba(0,0,0,0.9);
    will-change: transform, opacity;
}
.cage-msg b { font-weight: 700; }
.cage-msg.sys { font-style: italic; color: var(--dim); font-size: 15px; }

/* In the cage the arena HUD has nothing to report, so it's hidden, and the input
   moves to the bottom centre — under the words rising off the middle. */
#ui.cage-mode #wave-info,
#ui.cage-mode #leaderboard,
#ui.cage-mode #vitals,
#ui.cage-mode #chat-log { display: none !important; }
#ui.cage-mode #chat {
    left: 50%; bottom: 26px; width: 320px;
    transform: translateX(-50%); text-align: center;
}
#ui.cage-mode #chat-input { width: 100%; text-align: center; background: rgba(9,9,14,0.6); }

/* ============================================================= panels == */

.panel {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    z-index: 20; width: 368px; max-height: 76vh; overflow-y: auto;
    background: rgba(8, 8, 12, 0.96);
    border: 1px solid var(--line); border-radius: 6px;
    padding: 14px 16px 16px;
    box-shadow: 0 24px 80px rgba(0,0,0,0.8);
}
.panel header { display: flex; justify-content: space-between; align-items: center; }
.panel h2 { margin: 0; font: 500 12px 'Inter', sans-serif; letter-spacing: 2.5px; text-transform: uppercase; }
.panel .close { background: none; border: none; color: var(--dim); font-size: 17px; padding: 0 4px; line-height: 1; }
.panel .close:hover { background: none; color: var(--txt); }
.panel-sub {
    color: var(--dim); font-size: 10px; margin: 5px 0 13px;
    padding-bottom: 10px; border-bottom: 1px solid var(--line);
}
.cash { color: var(--gold); }
.sp { color: var(--teal); }
.essence { color: var(--accent); }

.row {
    display: flex; justify-content: space-between; align-items: center;
    gap: 12px; padding: 7px 0;
    border-bottom: 1px solid rgba(255,255,255,0.045);
}
.row:last-child { border-bottom: none; }
.row-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.row-label { font-size: 12px; font-weight: 500; }
.row-meta { font: 400 10px var(--mono); color: var(--dim); }
.row-buy { min-width: 74px; text-align: center; font: 500 11px var(--mono); letter-spacing: 0; }
.pips { display: flex; gap: 3px; margin-top: 3px; }
.pip { width: 15px; height: 2px; border-radius: 1px; background: rgba(255,255,255,0.14); }
.pip.on { background: var(--teal); }

.cosmetic-stage { display: flex; align-items: center; justify-content: center; gap: 14px; margin: 6px 0 2px; }
#cosmetic-preview { background: rgba(255,255,255,0.03); border-radius: 5px; }
#cosmetic-label {
    text-align: center; font-size: 10px; letter-spacing: 2px;
    text-transform: uppercase; color: var(--txt);
    border: none; padding: 0; margin: 8px 0 0;
}
.color-picker-row { display: flex; gap: 6px; margin-top: 14px; }
.color-picker-row input { flex: 1; }

/* rare cosmetics / trims get a gold label in the picker */
#cosmetic-label.rare, #trim-label.rare { color: var(--gold); }
#trim-preview { background: rgba(255,255,255,0.03); border-radius: 4px; }
.hint code { color: var(--teal); }

/* The HUD health bar's shader layer sits under the coloured fill.
   Its CSS size is pinned to 100% of the bar and its BACKING STORE is sized
   separately in ui.js — otherwise the canvas lays itself out at its pixel width,
   which #vitals' `zoom` then scales a second time and the trim overhangs the bar. */
/* ON TOP of the fill, not under it. The trim paints over the health you still have
   (the more hurt you are, the more it takes over) and over the fading hit just past
   it. It never paints the empty end of the bar. */
#health-trim { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 3; }
#health-ghost { z-index: 1; }
#health-fill { z-index: 2; }

/* ---- settings ---- */
.set-row { display: flex; align-items: center; gap: 10px; margin-bottom: 9px; }
.set-row label { flex: none; width: 108px; font: 400 11px var(--mono); color: var(--dim); }
/* section break inside the settings panel */
.set-sep {
    margin: 14px 0 7px; padding-top: 11px;
    border-top: 1px solid var(--line);
    font: 500 9px var(--mono); letter-spacing: 2px;
    text-transform: uppercase; color: #4d4960;
}
.set-row input[type=range] { flex: 1; accent-color: var(--teal); }
.save-slots { display: flex; gap: 6px; flex: 1; }
.save-slot {
    flex: 1; padding: 5px 0; font: 600 11px var(--mono);
    color: var(--teal); border-color: rgba(74,226,208,0.3);
}
.save-slot:hover { background: rgba(74,226,208,0.14); }
.set-row select { flex: 1; padding: 4px 7px; font: 400 11px var(--mono);
    background: rgba(255,255,255,0.05); color: var(--txt);
    border: 1px solid var(--line); border-radius: 3px; }
.set-row > span { flex: none; width: 46px; text-align: right; font: 400 10px var(--mono); color: var(--txt); }
.set-wide { width: 100%; margin-top: 4px; }
#settings-btn { font-size: 15px; line-height: 1; padding: 5px 10px; }

/* ---- upgrade draft ---- */
#upgrade-draft {
    position: absolute; inset: 0; z-index: 45;
    display: flex; align-items: center; justify-content: center;
    background: rgba(4,4,9,0.72); backdrop-filter: blur(3px);
}
.ud-inner { text-align: center; max-width: 94vw; }
#ud-title { margin: 0; font: 300 22px/1 'Inter', sans-serif; letter-spacing: 8px; text-indent: 8px; color: var(--txt); }
#ud-sub { border: none; padding: 0; margin: 8px 0 20px; }
#ud-sub.lucky { color: var(--gold); }
#ud-cards { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
#ud-cards.many { gap: 10px; }
.ud-card {
    position: relative; width: 150px; padding: 0 0 10px;
    display: flex; flex-direction: column; align-items: center;
    background: rgba(10,10,17,0.9);
    border: 1px solid var(--line); border-radius: 6px;
    cursor: pointer; overflow: hidden;
    transition: transform .12s, border-color .12s, box-shadow .12s;
}
#ud-cards.many .ud-card { width: 112px; }
#ud-cards.many .ud-art { width: 112px; height: 112px; }
.ud-card:hover { transform: translateY(-5px); border-color: var(--c); box-shadow: 0 10px 30px -8px var(--c); }
.ud-card.big { border-color: var(--gold); }
.ud-art { display: block; width: 150px; height: 150px; }
.ud-name { font: 600 12px 'Inter', sans-serif; letter-spacing: 1px; color: var(--txt); margin-top: 4px; }
.ud-eff { font: 400 10px var(--mono); color: var(--c); margin-top: 2px; }
.ud-mult {
    position: absolute; top: 6px; right: 6px;
    font: 700 11px var(--mono); color: #17130a;
    background: var(--gold); border-radius: 3px; padding: 1px 5px;
}
.ud-key {
    position: absolute; top: 6px; left: 6px;
    font: 600 9px var(--mono); color: var(--dim);
    border: 1px solid var(--line); border-radius: 3px; padding: 0 4px;
}
#ud-skip-row { margin: 18px 0 0; }
#ud-skip { padding: 5px 16px; font: 500 10px var(--mono); color: var(--dim); }

/* ============================================================ accounts == */
/* The corner is deliberately understated — accounts are optional and must never
   look like a wall in front of the game. */
#account-corner {
    position: absolute; top: 14px; right: 16px;
    padding: 4px 10px; font: 500 9px var(--mono);
    letter-spacing: 1.6px; text-transform: uppercase;
    color: #4d4960; background: none; border: 1px solid rgba(255,255,255,0.07);
}
#account-corner:hover { color: var(--txt); border-color: var(--line-hi); background: none; }

.login-card.wide { width: 340px; }
.menu-row { display: flex; gap: 8px; margin-top: 14px; align-items: stretch; flex-wrap: wrap; }
.menu-row #enter-game, .menu-row #li-go, .menu-row #cr-go { flex: 1; margin-top: 0; }
/* smaller than PLAY, but still centre stage next to it */
#li-back, #cr-back, #slots-logout, #slots-guest, #slots-saveless, #slots-spectate {
    flex: 1; padding: 10px 8px;
    font: 600 9px 'Inter', sans-serif; letter-spacing: 1.4px;
    color: var(--dim); background: rgba(255,255,255,0.04);
}
#li-back:hover, #cr-back:hover, #slots-logout:hover, #slots-guest:hover,
#slots-saveless:hover, #slots-spectate:hover { color: var(--txt); }

/* ---- server list: the rows you pick a world from ---- */
.server-list { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 12px; }
.server-row {
    display: flex; align-items: center; justify-content: space-between;
    padding: 9px 12px; cursor: pointer; text-align: left;
    border: 1px solid var(--line); border-radius: 4px;
    background: rgba(255,255,255,0.03);
    transition: background .14s, border-color .14s;
}
.server-row:hover, .server-row.sel { background: rgba(255,255,255,0.08); border-color: var(--line-hi); }
.server-row .sv-name { font: 600 12px 'Inter', sans-serif; letter-spacing: .5px; color: var(--txt); }
.server-row .sv-count { font: 400 10px var(--mono); color: var(--dim); }
.server-row .sv-count b { color: var(--teal); font-weight: 600; }
.server-row.dead { opacity: .5; cursor: default; }

/* ---- the secret Balls Cage button. Dim and wordless until you hover it, then it
   opens to reveal what it is. Discoverable, not advertised. ---- */
#balls-cage.secret {
    flex: none; width: 42px; padding: 11px 0; position: relative; overflow: hidden;
    color: #34313f; border-color: rgba(255,255,255,0.05);
    background: rgba(255,255,255,0.02);
    transition: width .28s cubic-bezier(.2,.8,.2,1), color .2s, border-color .2s, background .2s;
}
#balls-cage.secret .secret-face { font-size: 13px; font-weight: 700; }
#balls-cage.secret .secret-text {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    opacity: 0; font-size: 10px; letter-spacing: 1.5px; color: var(--teal);
    transition: opacity .18s;
}
#balls-cage.secret:hover {
    width: 118px; border-color: rgba(74,226,208,0.5); background: rgba(74,226,208,0.08);
}
#balls-cage.secret:hover .secret-face { opacity: 0; }
#balls-cage.secret:hover .secret-text { opacity: 1; }

/* ---- quiet text links (log in / spectate / make an account) ---- */
.menu-links { display: flex; justify-content: center; gap: 18px; margin-top: 16px; }
.menu-links .link {
    padding: 2px 4px; border: none; background: none;
    color: var(--dim); font: 400 11px var(--mono); letter-spacing: .5px;
}
.menu-links .link:hover { color: var(--txt); background: none; border: none; }

#menu-login input, #menu-create input { margin-top: 8px; }
.acc-err {
    margin: 10px 0 0; font: 400 10px var(--mono);
    color: #ff8a9a; text-align: left;
}
.hint a { color: var(--teal); text-decoration: none; }
.hint a:hover { text-decoration: underline; }

/* ---- save slots ---- */
#slot-list { display: flex; flex-direction: column; gap: 7px; margin-top: 4px; }
.slot {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 10px; text-align: left;
    background: rgba(255,255,255,0.03);
    border: 1px solid var(--line); border-radius: 5px;
    transition: border-color .14s, background .14s;
}
.slot:hover { border-color: var(--line-hi); background: rgba(255,255,255,0.06); }
.slot.used { border-color: rgba(74,226,208,0.3); }
.slot-main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.slot-name { font: 600 11px 'Inter', sans-serif; letter-spacing: .6px; color: var(--txt); }
.slot-stats { font: 400 10px var(--mono); color: var(--teal); }
.slot-stats.empty { color: #4d4960; }
.slot-when { font: 400 9px var(--mono); color: #45415a; }
.slot-play { flex: none; padding: 6px 11px; font: 600 9px var(--mono); letter-spacing: 1px; }
.slot.used .slot-play { border-color: rgba(74,226,208,0.4); color: var(--teal); }
.slot-del {
    flex: none; padding: 4px 8px; font-size: 13px; line-height: 1;
    color: #5a4550; border-color: transparent; background: none;
}
.slot-del:hover { color: var(--accent); background: rgba(255,45,85,0.1); }
