/* Local font bundling — desktop 0.2.0 / web parity.
   Previously these fonts were pulled from fonts.googleapis.com via
   <link> tags in index.html. The CDN dependency was removed so the
   desktop Electron build works offline and the web build avoids the
   FOIT/FOUT flash from a remote CSS round-trip. woff2 latin subsets
   only — game UI is English. Variable-font Pixelify Sans shares one
   binary across 400 and 700. */
@font-face {
    font-family: 'Press Start 2P';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/press-start-2p-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Silkscreen';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/silkscreen-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Fira Code';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/fira-code-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Pixelify Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/pixelify-sans-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Pixelify Sans';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('fonts/pixelify-sans-latin.woff2') format('woff2');
}
/* 6.158.0 — modern UI fonts for the font-switcher. Bundled locally (woff2
   latin subsets) to keep the build offline, matching the pixel fonts above.
   Each is a variable-font binary covering 400-700, so both weights share one
   file (same pattern as Pixelify Sans). */
@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/roboto-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/montserrat-latin.woff2') format('woff2');
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/inter-latin.woff2') format('woff2');
}

/* 6.158.0 — Font system. Two CSS variables drive every menu/overlay font:
   `--font-header` for titles + tabs, `--font-body` for everything else.
   Defaults are the retro pixel pairing (Press Start 2P / Silkscreen); the
   DISPLAY settings (pause menu + title SETTINGS button) rewrite these on
   :root via js/modules/ui/font-settings.js. Canvas-drawn text (title/HUD)
   is intentionally NOT switched — it stays Press Start 2P. */
:root {
    --font-header: 'Press Start 2P', monospace;
    --font-body: 'Silkscreen', monospace;
    /* 6.158.2 — font-size scales. Every UI font-size is `calc(px * scale)`,
       so these multipliers let the player shrink/enlarge menu text for
       readability. Body base px were bumped for a large, readable default;
       both scales default to 1.0 and are rewritten on :root by font-settings.js. */
    --font-header-scale: 1;
    --font-body-scale: 1;
}

body {
    margin: 0;
    padding: 0;
    background-color: #000;
    color: #fff;
    overflow: hidden;
    font-family: var(--font-body);
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    cursor: default;
    
    /* Multi-touch support */
    touch-action: none;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

/* Red cursor for hovering over enemies/asteroids */
body.cursor-red {
    cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><circle cx="8" cy="8" r="7" fill="none" stroke="red" stroke-width="2"/><circle cx="8" cy="8" r="2" fill="red"/></svg>') 8 8, auto;
}


h2 {
    margin-bottom: 0;
}

/* Both canvases occupy the full viewport at the same coordinates. The
   WebGL particle layer (glCanvas) renders behind the Canvas2D layer
   (gameCanvas) — gameCanvas keeps a transparent background so the
   WebGL particles show through. The black page background acts as the
   final clear color when neither canvas has drawn anything. */
canvas {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    cursor: none;
    touch-action: none;
    -webkit-touch-callout: none;
}

#glCanvas {
    background-color: #000;
    z-index: 0;
}

#gameCanvas {
    background-color: transparent;
    z-index: 1;
}

/* 5.79.2 — WebGL bullet layer. Above gameCanvas so bullets paint on top
   of asteroids / enemies / player; below HUD (.ui-element z-index: 10).
   pointer-events: none lets clicks fall through to gameCanvas for
   targeting. Standard alpha compositing — the bullet glow lives inside
   the canvas (procedural-SDF shader bakes body + core + halo). */
#bulletCanvas {
    background-color: transparent;
    z-index: 2;
    pointer-events: none;
}

canvas.asteroid-hover {
    cursor: url('data:image/svg+xml;utf8,<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M21 12C21 16.9706 16.9706 21 12 21M21 12C21 7.02944 16.9706 3 12 3M21 12H17M12 21C7.02944 21 3 16.9706 3 12M12 21V17M3 12C3 7.02944 7.02944 3 12 3M3 12H7M12 3V7M12 12H12.01" stroke="%23ff0000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>') 12 12, crosshair;
}

.ui-element {
    position: absolute;
    color: #fff;
    text-shadow: 0 0 5px rgba(255, 255, 255, 0.7);
    z-index: 10;
}

#lives-display {
    display: none; /* Lives are rendered on the game canvas */
}

/* Dim all HUD elements when the shop overlay is active. The shop overlay
   itself carries `.ui-element` (so it inherits the same z-index/font setup),
   so exclude it from the dimming via :not(#shop-overlay). */
body.shop-open .ui-element:not(#shop-overlay) {
    opacity: 0.25;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

#score {
    position: absolute;
    top: 30px;
    left: 350px; /* Moved right to make room for lives display */
    font-size: calc(13px * var(--font-body-scale, 1));
    color: #FFD700;
    z-index: 10;
    display: none; /* Hidden since money is now rendered on canvas */
}

#game-message-overlay {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    color: white;
    z-index: 50;
    pointer-events: none;
    text-align: center;
}

.message-title {
    font-size: calc(48px * var(--font-header-scale, 1));
    text-shadow: 0 0 15px #f0f;
    animation: pulse 1.5s ease-in-out infinite;
}

.message-subtitle {
    font-size: calc(20px * var(--font-body-scale, 1));
    margin-top: 20px;
    line-height: 1.5;
}

#pause-overlay {
    /* Backdrop is the see-through layer behind the menu so the player can
       still read the game state through it. Menu itself is fully opaque. */
    background-color: rgba(0, 0, 0, 0.25);
    display: none;
    pointer-events: all;
    z-index: 100;
}

/* ── 5.79.0 — Universal button click feedback ─────────────────────────
   Every in-game DOM button gets a subtle press animation: shrinks 1px
   on :active, deepens its background tint, and applies a small inset
   shadow. Rules use `:not([disabled])` so disabled buttons don't fake
   responsiveness. The `transform` is a 1-frame transition on transform
   only — no layout reflow. */
button:not([disabled]):active,
.btn:not([disabled]):active,
.shop-row:not([disabled]):active,
.pause-action-btn:not([disabled]):active,
.pause-tab:not([disabled]):active,
.powerups-subtab:not([disabled]):active,
.powerup-card-buy:not([disabled]):active {
    transform: translateY(1px) scale(0.985);
    filter: brightness(1.18) saturate(1.15);
    box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.45);
    transition: transform 60ms ease-out, filter 60ms ease-out;
}
button:not([disabled]),
.btn:not([disabled]),
.pause-action-btn:not([disabled]),
.pause-tab:not([disabled]),
.powerups-subtab:not([disabled]),
.powerup-card-buy:not([disabled]) {
    transition: transform 120ms ease-out, filter 120ms ease-out, background-color 120ms ease-out;
}

/* Card-style elements (powerup cards, shop rows) — same press feedback,
   slightly more pronounced because they're visually larger. */
.powerup-card.powerup-card--interactive:active {
    transform: translateY(1px) scale(0.99);
    filter: brightness(1.12);
    box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.5),
                0 0 14px rgba(0, 204, 255, 0.45);
    transition: transform 60ms ease-out, filter 60ms ease-out;
}
.powerup-card.powerup-card--interactive {
    transition: transform 120ms ease-out, filter 120ms ease-out, box-shadow 120ms ease-out;
}

/* ── 5.79.0 — Diablo-style stats screen ────────────────────────────── */
#stats-overlay {
    background-color: rgba(0, 0, 0, 0.45);
    z-index: 9000;
    font-family: var(--font-body);
    color: #e8e4d4;
}

#stats-panel {
    width: min(960px, 92vw);
    max-height: 88vh;
    background:
        linear-gradient(180deg, rgba(36, 26, 18, 0.97) 0%, rgba(20, 14, 10, 0.97) 100%);
    border: 2px solid #c2992f;
    border-radius: 10px;
    box-shadow: 0 0 24px rgba(255, 200, 64, 0.25), inset 0 0 60px rgba(80, 50, 0, 0.4);
    padding: 22px 26px 18px;
    display: flex;
    flex-direction: column;
    gap: 18px;
    position: relative;
    overflow: hidden;
}

#stats-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(194, 153, 47, 0.35);
}

#stats-panel-header h2 {
    margin: 0;
    font-size: calc(22px * var(--font-header-scale, 1));
    color: #ffd97a;
    letter-spacing: 2px;
    text-shadow: 0 0 12px rgba(255, 200, 64, 0.5);
}

#stats-panel-close {
    background: transparent;
    color: #ffd97a;
    border: 1px solid rgba(194, 153, 47, 0.55);
    width: 32px;
    height: 32px;
    cursor: pointer;
    font-size: calc(20px * var(--font-body-scale, 1));
    line-height: 1;
    font-family: inherit;
}
#stats-panel-close:hover { background: rgba(255, 200, 64, 0.15); }

#stats-panel-body {
    display: flex;
    flex-direction: column;
    gap: 20px;
    overflow-y: auto;
    padding-right: 8px;
    flex: 1;
}

#stats-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
    gap: 12px;
    background: rgba(0, 0, 0, 0.35);
    padding: 14px;
    border: 1px solid rgba(194, 153, 47, 0.25);
    border-radius: 8px;
}
#stats-summary .stats-summary-cell--hot {
    background: rgba(255, 200, 64, 0.12);
    border-radius: 4px;
    box-shadow: 0 0 10px rgba(255, 200, 64, 0.35);
    animation: sp-cell-pulse 1.4s ease-in-out infinite;
}
#stats-summary .stats-summary-cell--hot .stats-summary-value { color: #ffe27a; }
@keyframes sp-cell-pulse {
    0%, 100% { box-shadow: 0 0 8px rgba(255, 200, 64, 0.25); }
    50%      { box-shadow: 0 0 16px rgba(255, 200, 64, 0.6); }
}
#stats-summary .stats-summary-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    padding: 8px 6px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(194, 153, 47, 0.22);
    border-radius: 6px;
}
#stats-summary .stats-summary-label {
    font-size: calc(12px * var(--font-body-scale, 1));
    color: #b09464;
    letter-spacing: 1px;
}
#stats-summary .stats-summary-value {
    font-size: calc(17px * var(--font-body-scale, 1));
    color: #ffe5a0;
}

#stats-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}
.stats-section {
    background: rgba(0, 0, 0, 0.28);
    border: 1px solid rgba(194, 153, 47, 0.25);
    border-radius: 8px;
    padding: 14px 16px 8px;
}
.stats-section-title {
    font-size: calc(13px * var(--font-header-scale, 1));
    color: #ffd97a;
    letter-spacing: 1.5px;
    margin-bottom: 12px;
    border-bottom: 1px dashed rgba(194, 153, 47, 0.35);
    padding-bottom: 9px;
}
.stats-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 9px 6px;
    font-size: calc(13px * var(--font-body-scale, 1));
    line-height: 1.5;
    cursor: help;
    border-radius: 3px;
}
/* Faint separators give the rows breathing room without heavy lines. */
.stats-row:not(:last-child) {
    border-bottom: 1px solid rgba(194, 153, 47, 0.12);
}
.stats-row:hover {
    background: rgba(255, 200, 64, 0.08);
    outline: 1px solid rgba(194, 153, 47, 0.4);
}
.stats-row .stats-key   { color: #c8b986; }
.stats-row .stats-value { color: #fff4c4; font-weight: bold; }

/* 6.36.0 — SP allocation card. Spans both columns; one row per stat
   with a [−] points/cap [+] control. */
.stats-section--sp { grid-column: 1 / -1; }
.stats-section-title--hot {
    color: #fff0b0;
    text-shadow: 0 0 8px rgba(255, 210, 90, 0.7);
}
.sp-alloc-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 6px;
    font-size: calc(13px * var(--font-body-scale, 1));
    cursor: help;
    border-radius: 3px;
}
.sp-alloc-row:not(:last-child) {
    border-bottom: 1px solid rgba(194, 153, 47, 0.12);
}
.sp-alloc-row:hover { background: rgba(255, 200, 64, 0.07); }
.sp-alloc-icon {
    flex: 0 0 26px;
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #ffe5a0;
}
.sp-alloc-info {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}
.sp-alloc-name  { color: #e8d7a4; font-weight: bold; letter-spacing: 0.5px; }
.sp-alloc-value { color: #9fb4ff; font-size: calc(12px * var(--font-body-scale, 1)); line-height: 1.4; }
.sp-alloc-points {
    flex: 0 0 auto;
    min-width: 58px;
    text-align: center;
    color: #fff4c4;
    font-weight: bold;
    font-variant-numeric: tabular-nums;
}
.sp-alloc-points--max { color: #c79bff; font-size: calc(12px * var(--font-body-scale, 1)); }
.sp-alloc-btn {
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    font-size: calc(18px * var(--font-body-scale, 1));
    line-height: 1;
    font-weight: bold;
    color: #ffe5a0;
    background: rgba(255, 200, 64, 0.12);
    border: 1px solid rgba(194, 153, 47, 0.55);
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.12s, transform 0.06s;
    pointer-events: auto;
}
.sp-alloc-btn:hover:not(:disabled) {
    background: rgba(255, 200, 64, 0.28);
    box-shadow: 0 0 8px rgba(255, 200, 64, 0.4);
}
.sp-alloc-btn:active:not(:disabled) { transform: scale(0.9); }
.sp-alloc-plus:not(:disabled) {
    color: #b6ffb0;
    border-color: rgba(120, 220, 110, 0.6);
    background: rgba(120, 220, 110, 0.14);
}
.sp-alloc-minus:not(:disabled) {
    color: #ffb0b0;
    border-color: rgba(220, 120, 110, 0.55);
    background: rgba(220, 120, 110, 0.12);
}
.sp-alloc-btn:disabled {
    opacity: 0.3;
    cursor: default;
    pointer-events: none;
}

#stats-tooltip {
    position: absolute;
    pointer-events: none;
    background: rgba(0, 0, 0, 0.95);
    border: 1px solid #c2992f;
    color: #f5e8b0;
    padding: 10px 12px;
    font-size: calc(13px * var(--font-body-scale, 1));
    line-height: 1.55;
    max-width: 360px;
    box-shadow: 0 0 12px rgba(255, 200, 64, 0.25);
    display: none;
    z-index: 100;
    white-space: pre-line;
}

#stats-panel-footer {
    text-align: center;
    color: #8a7549;
    font-size: calc(12px * var(--font-body-scale, 1));
    padding-top: 6px;
    border-top: 1px solid rgba(194, 153, 47, 0.25);
}
#stats-panel-footer kbd {
    background: rgba(255, 200, 64, 0.18);
    color: #ffe5a0;
    border: 1px solid rgba(194, 153, 47, 0.5);
    padding: 1px 6px;
    font-family: inherit;
    font-size: calc(12px * var(--font-body-scale, 1));
}

/* ── Inventory overlay (6.x — 'I' key) ───────────────────────────── */
#inventory-overlay {
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 9000;
    font-family: var(--font-body);
    color: #d6def0;
}
#inventory-panel {
    width: min(1080px, 94vw);
    max-height: 88vh;
    background: linear-gradient(180deg, rgba(14, 20, 30, 0.98) 0%, rgba(8, 11, 18, 0.98) 100%);
    border: 2px solid #2f6fc2;
    box-shadow: 0 0 24px rgba(64, 150, 255, 0.25), inset 0 0 60px rgba(0, 30, 80, 0.4);
    padding: 18px 22px 14px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    position: relative;
    overflow: hidden;
}
#inventory-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(80, 140, 220, 0.35);
}
#inventory-title {
    margin: 0;
    font-size: calc(22px * var(--font-header-scale, 1));
    color: #8fd0ff;
    letter-spacing: 2px;
    text-shadow: 0 0 12px rgba(64, 150, 255, 0.5);
}
#inventory-close {
    background: transparent;
    color: #8fd0ff;
    border: 1px solid rgba(80, 140, 220, 0.55);
    width: 32px; height: 32px;
    cursor: pointer;
    font-size: calc(20px * var(--font-body-scale, 1));
    line-height: 1;
    font-family: inherit;
}
#inventory-close:hover { background: rgba(64, 150, 255, 0.15); }
#inventory-body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    overflow-y: auto;
    padding-right: 4px;
    flex: 1;
}
#inventory-footer {
    text-align: center;
    color: #5e7290;
    font-size: calc(12px * var(--font-body-scale, 1));
    padding-top: 6px;
    border-top: 1px solid rgba(80, 140, 220, 0.25);
}
.inv-section-title {
    font-size: calc(12px * var(--font-header-scale, 1));
    color: #9fd6ff;
    letter-spacing: 1.5px;
    border-bottom: 1px dashed rgba(80, 140, 220, 0.35);
    padding-bottom: 6px;
}
.inv-armory-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(260px, 320px);
    gap: 16px;
    min-height: 0;
}
.inv-armory-main,
.inv-armory-side {
    min-width: 0;
}
.inv-armory-main {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.inv-glyph { display: block; image-rendering: auto; }
.inv-equipped-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 10px;
}
.inv-slot {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--inv-rarity, #3a4254);
    border-left-width: 4px;
    border-radius: 4px;
}
.inv-slot--empty { opacity: 0.5; }
.inv-slot-info { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.inv-slot-label { font-size: calc(12px * var(--font-body-scale, 1)); color: #7e93b4; letter-spacing: 1px; }
.inv-item-name { font-size: calc(12px * var(--font-body-scale, 1)); font-weight: bold; }
.inv-item-affix { font-size: calc(11px * var(--font-body-scale, 1)); color: #aab6ce; line-height: 1.5; }
.inv-drop-list { display: flex; flex-direction: column; gap: 6px; }
.inv-drop-empty { font-size: calc(12px * var(--font-body-scale, 1)); color: #5e7290; padding: 8px 4px; }
.inv-drop-row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    text-align: left;
    padding: 7px 10px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(80, 140, 220, 0.25);
    border-left: 4px solid var(--inv-rarity, #3a4254);
    border-radius: 4px;
    color: inherit;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.12s;
}
.inv-drop-row:hover:not(:disabled) { background: rgba(64, 150, 255, 0.12); }
.inv-drop-row:disabled { cursor: default; }
.inv-drop-row--equipped { opacity: 0.7; }
.inv-drop-info { flex: 1 1 auto; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.inv-drop-name { font-size: calc(12px * var(--font-body-scale, 1)); font-weight: bold; }
.inv-drop-affix { font-size: calc(11px * var(--font-body-scale, 1)); color: #aab6ce; line-height: 1.5; }
.inv-drop-tag {
    flex: 0 0 auto;
    font-size: calc(11px * var(--font-body-scale, 1));
    letter-spacing: 1px;
    padding: 3px 7px;
    border-radius: 3px;
    color: #0c1018;
    background: #7fb6ff;
}
.inv-drop-row--equipped .inv-drop-tag { background: #7CFC9A; }

.item-card {
    --item-rarity: #7fb6ff;
    position: relative;
    display: grid;
    grid-template-columns: 58px minmax(0, 1fr);
    gap: 10px;
    align-items: center;
    min-height: 78px;
    padding: 10px;
    border: 1px solid color-mix(in srgb, var(--item-rarity) 78%, #1b2436);
    border-left-width: 4px;
    border-radius: 6px;
    background:
        linear-gradient(135deg, color-mix(in srgb, var(--item-rarity) 12%, transparent), transparent 48%),
        rgba(255, 255, 255, 0.035);
    box-shadow: inset 0 0 22px rgba(255, 255, 255, 0.025), 0 0 14px color-mix(in srgb, var(--item-rarity) 14%, transparent);
    color: #dbe7fb;
    transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
}
.item-card:hover,
.item-card:focus,
.item-card.is-gamepad-focused {
    outline: none;
    transform: translateY(-1px);
    background:
        linear-gradient(135deg, color-mix(in srgb, var(--item-rarity) 18%, transparent), transparent 54%),
        rgba(95, 150, 230, 0.08);
    border-color: var(--item-rarity);
}
.item-card--empty {
    opacity: 0.58;
    border-style: dashed;
}
.item-card--compact {
    grid-template-columns: 38px minmax(0, 1fr);
    min-height: 54px;
    padding: 7px 9px;
}
.item-card__icon {
    display: grid;
    place-items: center;
}
.item-card__glyph-canvas {
    display: block;
}
.item-card__body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.item-card__topline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-width: 0;
}
.item-card__name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--item-rarity);
    font-weight: 700;
    font-size: calc(12px * var(--font-body-scale, 1));
}
.item-card__meta,
.item-card__desc,
.item-card__affix {
    color: #aab8d3;
    font-size: calc(10px * var(--font-body-scale, 1));
    line-height: 1.35;
}
.item-card__affixes {
    display: grid;
    gap: 2px;
}
.item-card__affix::before {
    content: '▸ ';
    color: var(--item-rarity);
}
.item-card__deltas {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 2px;
}
.item-card__delta {
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 4px;
    padding: 2px 5px;
    font-size: calc(9px * var(--font-body-scale, 1));
}
.item-card__delta.is-up { color: #7cff9c; border-color: rgba(124, 255, 156, 0.35); }
.item-card__delta.is-down { color: #ff7f8f; border-color: rgba(255, 127, 143, 0.35); }
.item-card__badge,
.binding-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 22px;
    padding: 0 6px;
    border-radius: 4px;
    border: 1px solid color-mix(in srgb, var(--item-rarity) 60%, #ffffff);
    background: rgba(0, 0, 0, 0.22);
    color: #eef6ff;
    font-size: calc(9px * var(--font-body-scale, 1));
    white-space: nowrap;
}
.item-card__badge {
    position: absolute;
    right: 8px;
    bottom: 6px;
    color: #0c1018;
    background: var(--item-rarity);
}
.item-stats-panel {
    position: sticky;
    top: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    border: 1px solid rgba(120, 170, 235, 0.32);
    border-radius: 6px;
    background: rgba(8, 13, 22, 0.72);
}
.item-stats-panel__title {
    color: #9fd6ff;
    font-size: calc(12px * var(--font-header-scale, 1));
    letter-spacing: 1px;
}
.item-stat-row {
    display: grid;
    grid-template-columns: 72px minmax(0, 1fr) 42px;
    align-items: center;
    gap: 7px;
}
.item-stat-row__label,
.item-stat-row__value,
.item-resist-wheel__spoke {
    font-size: calc(10px * var(--font-body-scale, 1));
    color: #b9c8e5;
}
.item-stat-row__value { text-align: right; color: #e5efff; }
.item-stat-row__bar {
    height: 7px;
    border-radius: 2px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.08);
}
.item-stat-row__bar span {
    display: block;
    height: 100%;
    background: linear-gradient(90deg, #49d6ff, #7cff9c);
}
.item-resist-wheel {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 5px;
    padding-top: 6px;
    border-top: 1px dashed rgba(120, 170, 235, 0.22);
}
.item-resist-wheel__spoke {
    min-width: 0;
    padding: 4px 5px;
    border-radius: 4px;
    background: linear-gradient(90deg, rgba(120, 170, 235, 0.2) var(--resist-fill), rgba(255,255,255,0.04) var(--resist-fill));
}

@media (max-width: 820px) {
    .inv-armory-shell {
        grid-template-columns: 1fr;
    }
    .inv-armory-side {
        order: -1;
    }
    .item-stats-panel {
        position: static;
    }
}

#pause-menu {
    /* Fullscreen pause panel — fills the entire viewport with a 75%-opaque
       backdrop so the underlying game world is faintly visible. */
    background-color: rgba(0, 0, 0, 0.78);
    padding: 40px;
    border-radius: 0;
    text-align: center;
    width: 100vw;
    height: 100vh;
    max-width: none;
    border: none;
    box-shadow: none;
    box-sizing: border-box;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 18px;
}

/* Center the tab content vertically inside the fullscreen menu. */
#pause-menu .pause-tab-content.active {
    width: min(900px, 100%);
    margin: 0 auto;
}

/* Kill the inherited .ui-element text-shadow inside the pause menu — it
   makes body text look blurred (visible on the ABILITIES tab instructions in
   particular). Empty ability slots opt back into a faint dim look via their
   own classes; they don't need this glow. */
#pause-menu,
#pause-menu * {
    text-shadow: none;
}

/* Center the controls list as a block while keeping each row left-justified. */
#controls-tab {
    text-align: center;
}
/* 5.79.40 — Controls page rewritten as a programmatic table.
   Two columns: action on the left, key bindings (SimpleKeys
   sprites) on the right. Section header rows span both columns
   with a glowing accent bullet + SVG icon. Press Start 2P is
   reserved for the page header — section titles + action labels
   use Inter for readability. The gold-gradient title style is
   shared across ALL pause-menu tabs (5.79.40) so the menu feels
   visually cohesive. */

.pause-tab-content > h2 {
    /* 6.225.2 — pause-tab page titles use the HEADER font (Press Start 2P by
       default), not the body font. They were inheriting --font-body, so a
       modern body-font pick (e.g. Helvetica Neue) leaked into the headers. */
    font-family: var(--font-header);
    font-size: calc(24px * var(--font-header-scale, 1));
    letter-spacing: 5px;
    margin: 0 auto 22px;
    text-align: center;
    /* 5.79.41 — Animated gold sheen sweeps across the title once
       per several seconds for a subtle "polished metal" feel.
       background-size 200% so the linear-gradient slides 100% of
       its width per cycle. */
    background: linear-gradient(110deg,
        #cf8b00 0%,
        #FFC107 25%,
        #fff7d6 45%,
        #FFC107 65%,
        #cf8b00 100%) 0 0 / 200% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    text-shadow: 0 0 22px rgba(255, 193, 7, 0.28);
    position: relative;
    padding-bottom: 14px;
    animation: title-sheen 7s ease-in-out infinite;
}
@keyframes title-sheen {
    0%, 100% { background-position: 0% 0%; }
    50%      { background-position: 100% 0%; }
}
.pause-tab-content > h2::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: 4px;
    transform: translateX(-50%);
    width: min(220px, 60%);
    height: 1px;
    background: linear-gradient(90deg, transparent 0%, rgba(255, 193, 7, 0.6) 30%, rgba(255, 247, 214, 0.9) 50%, rgba(255, 193, 7, 0.6) 70%, transparent 100%);
    box-shadow: 0 0 10px rgba(255, 193, 7, 0.35);
}

.controls-table {
    width: calc(100% - 16px);
    max-width: 720px;
    margin: 8px auto 0;
    border-collapse: separate;
    border-spacing: 0 4px;
    background:
        radial-gradient(ellipse at top, rgba(255, 193, 7, 0.06) 0%, transparent 60%),
        linear-gradient(180deg, rgba(255, 255, 255, 0.04) 0%, rgba(255, 255, 255, 0) 50%),
        rgba(8, 12, 22, 0.65);
    backdrop-filter: blur(12px) saturate(130%);
    -webkit-backdrop-filter: blur(12px) saturate(130%);
    border: 1px solid rgba(255, 193, 7, 0.22);
    border-radius: 16px;
    padding: 10px 22px 18px;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.06),
        inset 0 -1px 0 rgba(0, 0, 0, 0.4),
        inset 0 0 40px rgba(255, 193, 7, 0.04),
        0 6px 28px rgba(0, 0, 0, 0.55),
        0 0 0 1px rgba(0, 0, 0, 0.4);
    text-align: left;
    position: relative;
    overflow: hidden;
}
/* Dapper accent — diagonal sheen ribbon across the corner. */
.controls-table::before {
    content: '';
    position: absolute;
    top: -40%;
    right: -20%;
    width: 140%;
    height: 200%;
    background: linear-gradient(115deg, transparent 45%, rgba(255, 193, 7, 0.04) 50%, transparent 55%);
    pointer-events: none;
    transform: rotate(-2deg);
}

/* Section header row — full-width bar with accent icon + bullet
   + uppercase title. Per-section accent set via `[data-accent]`. */
.controls-section-row {
    --accent: #FFC107;
    --accent-faint: rgba(255, 193, 7, 0.22);
    --accent-glow: rgba(255, 193, 7, 0.45);
}
.controls-section-row[data-accent="cyan"]   { --accent: #66e6ff; --accent-faint: rgba(102, 230, 255, 0.22); --accent-glow: rgba(102, 230, 255, 0.45); }
.controls-section-row[data-accent="orange"] { --accent: #ffb366; --accent-faint: rgba(255, 179, 102, 0.22); --accent-glow: rgba(255, 179, 102, 0.45); }
.controls-section-row[data-accent="pink"]   { --accent: #ff88dd; --accent-faint: rgba(255, 136, 221, 0.22); --accent-glow: rgba(255, 136, 221, 0.45); }
.controls-section-row[data-accent="gold"]   { --accent: #FFC107; --accent-faint: rgba(255, 193, 7, 0.22); --accent-glow: rgba(255, 193, 7, 0.45); }

.controls-section-cell {
    padding: 14px 4px 10px;
    border-bottom: 1px solid var(--accent-faint);
}
.controls-table tr:first-child .controls-section-cell {
    padding-top: 6px;
}

.controls-section-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    color: var(--accent);
    margin-right: 10px;
    vertical-align: middle;
    filter: drop-shadow(0 0 6px var(--accent-glow));
}

/* 5.79.43 — Animated bullet dot removed; the SVG icon alone serves
   as the section indicator. `.controls-section-bullet` and the
   `control-bullet-pulse` keyframes were dropped along with the
   render path in ui-manager. */

.controls-section-title {
    font-family: var(--font-body);
    /*font-family: 'Silkscreen', monospace;*/
    font-size: calc(18px * var(--font-header-scale, 1));
    font-weight: 700;
    letter-spacing: 2px;
    color: var(--accent);
    text-transform: uppercase;
    vertical-align: middle;
    /* 5.79.46 — Outline replaced with a pure glow stack. The 1-px
       black 4-corner outline that lived here was visually
       "containing" the glow: opaque black renders on top of the
       blur layers underneath, so the halo never escaped the glyph
       outline. New approach: stack six layers of
       `0 0 Nx var(--accent)` at full opacity with increasing blur.
       Each layer is the silhouette in accent color spread out by
       its blur radius — they sum to a luminous halo radiating
       outward. Crisp legibility comes from the 1-px and 2-px
       layers; readable lift against the glass backdrop comes from
       the cumulative bloom. A `filter: drop-shadow` pair on top
       gives a shape-based halo that follows pixel-art glyph
       contours rather than the bounding box. */
    text-shadow:
        /* Tight inner halo — keeps the glyph edge crisp */
        0 0  1px var(--accent),
        0 0  2px var(--accent),
        /* Mid glow — primary luminous band */
        0 0  4px var(--accent),
        0 0  8px var(--accent),
        /* Outer bloom — halo that reaches into the row backdrop */
        0 0 16px var(--accent),
        0 0 28px var(--accent);
    filter:
        drop-shadow(0 0  6px var(--accent-glow))
        drop-shadow(0 0 14px var(--accent-glow));
}

/* Body row — action text (left) + key cluster (right). */
.controls-row {
    --accent: #FFC107;
    --accent-glow: rgba(255, 193, 7, 0.30);
    transition: background-color 160ms ease, box-shadow 160ms ease;
    position: relative;
}
.controls-row[data-accent="cyan"]   { --accent: #66e6ff; --accent-glow: rgba(102, 230, 255, 0.30); }
.controls-row[data-accent="orange"] { --accent: #ffb366; --accent-glow: rgba(255, 179, 102, 0.30); }
.controls-row[data-accent="pink"]   { --accent: #ff88dd; --accent-glow: rgba(255, 136, 221, 0.30); }
.controls-row[data-accent="gold"]   { --accent: #FFC107; --accent-glow: rgba(255, 193, 7, 0.30); }

/* 5.79.42 — Hover gradient was resetting at each <td> boundary
   because the previous fix transitioned `background` directly on
   each cell, which produced a visible flash mid-transition (cells
   repaint slightly out of sync, and CSS `background-image` doesn't
   smoothly transition between "none" and a gradient).
   New approach: each cell's gradient lives on a `::after` pseudo
   that's pre-rendered at full opacity from page load. The pseudo
   is hidden via `opacity: 0` at rest; on row hover, both pseudos
   transition opacity 0 → 1 in lockstep. Opacity is GPU-accelerated
   and synchronized, so there's no flash. The 200%-background-size
   slice technique still aligns the two halves across the column
   boundary into a continuous sweep. */
.controls-action::after,
.controls-keys::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(90deg,
        var(--accent-glow) 0%,
        rgba(255, 255, 255, 0.06) 50%,
        rgba(255, 255, 255, 0.02) 100%);
    background-size: 200% 100%;
    background-repeat: no-repeat;
    opacity: 0;
    transition: opacity 200ms ease;
    pointer-events: none;
    z-index: 0;
}
.controls-action::after { background-position: 0 0; }
.controls-keys::after   { background-position: 100% 0; }
.controls-row:hover .controls-action::after,
.controls-row:hover .controls-keys::after {
    opacity: 1;
}
.controls-row:hover .controls-action {
    box-shadow: inset 3px 0 0 var(--accent);
    color: #ffffff;
    padding-left: 38px;
}
.controls-row:hover .controls-action::before {
    left: 22px;
    transform: translateY(-50%) scale(1.5);
    box-shadow: 0 0 8px var(--accent);
}

/* 5.79.47 — Action cell — left column. The accent dot lives in
   its own absolutely-positioned column so the action text gets a
   true hanging indent: when the label wraps to a second line,
   the bullet stays put on its own and the second line is left-
   aligned with the first (both at `padding-left: 34px`). Font
   bumped 15 → 17 px for legibility. */
.controls-action {
    text-align: center;
    padding: 14px 18px 14px 34px;
    width: 50%;
    font-family: 'Silkscreen', monospace;
    /*font-family: 'Inter', 'Helvetica Neue', system-ui, -apple-system, sans-serif;*/
    font-size: calc(18px * var(--font-body-scale, 1));
    font-weight: 500;
    line-height: 1.35;
    letter-spacing: 0.2px;
    color: #d8e0ec;
    border-radius: 10px 0 0 10px;
    transition:
        background 200ms ease,
        color 200ms ease,
        box-shadow 200ms ease,
        padding-left 200ms ease;
    position: relative;
}
/*.controls-action::before {
    content: '';
    position: absolute;
    left: 18px;
    /* Anchor the bullet to the first text line:
         padding-top (12px) + half line-height ≈ centers on the
         first line's baseline. The translateY(-50%) flips its
         own height, keeping it vertically centered on that
         line regardless of how many lines wrap below. */
    /*
    top: calc(12px + 1.5em);
    transform: translateY(50%);
    width: 5px;
    height: 5px;
    background: var(--accent);
    border-radius: 50%;
    transition: transform 200ms ease, box-shadow 200ms ease, left 200ms ease;
}*/

/* Keys cell — right column. Right-aligned to lean the cluster
   toward the page edge; the row reads as a tabbed line of
   bindings. */
/* 5.79.48 — Centered so the binding cluster sits as a balanced
   visual unit inside its column regardless of cluster width
   (1 sprite vs. 5). Padding equalized on both sides since
   there's no lean toward one edge anymore. */
.controls-keys {
    padding: 10px 16px;
    border-radius: 0 10px 10px 0;
    transition: background 200ms ease;
    text-align: left;
    white-space: nowrap;
}
.controls-keys > * {
    margin-right: 6px;
    vertical-align: middle;
}
.controls-keys > *:last-child {
    margin-right: 0;
}

/* 5.79.42 — Cells need position:relative so the absolute hover-
   gradient ::after pseudo (defined further down) anchors to the
   cell box. The previous fade-edge divider that lived on this
   pseudo was removed because the gradient now owns ::after; row
   separation is handled by `border-spacing: 0 4px` on the table
   plus a soft border-top on body rows below. */
.controls-action,
.controls-keys {
    position: relative;
}
.controls-row + .controls-row .controls-action,
.controls-row + .controls-row .controls-keys {
    border-top: 1px solid rgba(255, 255, 255, 0.04);
}
.controls-row + .controls-section-row .controls-section-cell {
    margin-top: 6px;
}

/* WASD diamond — W on top centered, A/S/D row below. */
.kbd-cluster.kbd-wasd {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    vertical-align: middle;
}
.kbd-cluster.kbd-wasd > .kbd { margin-left: 36px; }
.kbd-row-bottom {
    display: inline-flex;
    gap: 2px;
}

/* WASD diamond — W on top centered, A/S/D row below. */
.kbd-cluster.kbd-wasd {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
}
.kbd-cluster.kbd-wasd > .kbd { margin-left: 36px; }
.kbd-row-bottom {
    display: inline-flex;
    gap: 2px;
}

/* 5.79.42 — Pixel-art key sprite. Switched from Classic SimpleKeys
   (16 px tall) to Jumbo SimpleKeys (21 px tall) per user request.
   Render at 3× with crisp sampling — Jumbo at 3× is 63 px tall vs
   Classic's 48 px, so keys are slightly chunkier and easier to read. */
.kbd {
    height: 63px;
    width: auto;
    image-rendering: pixelated;
    image-rendering: crisp-edges;
    -ms-interpolation-mode: nearest-neighbor;
    filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.6));
    user-select: none;
    transition: transform 120ms ease, filter 120ms ease;
}
.control-row:hover .kbd {
    transform: translateY(-1px);
    filter: drop-shadow(0 3px 0 rgba(0, 0, 0, 0.7)) drop-shadow(0 0 6px rgba(255, 255, 255, 0.15));
}

/* Sprite-backed text key. Uses EMPTY1/EMPTY2.png Jumbo backgrounds
   and overlays a readable Inter label on top so ESC reads as the
   same visual family as the actual sprite keys. */
.kbd-sprite-text {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 63px;
    min-width: 57px;            /* Jumbo EMPTY1.png at 3× (19×3) */
    padding: 0 8px 4px;
    background: url('../sprites/keys/EMPTY1.png') center/contain no-repeat;
    image-rendering: pixelated;
    font-family: 'Silkscreen', monospace;
    /*font-family: 'Inter', 'Helvetica Neue', system-ui, -apple-system, sans-serif;*/
    font-size: calc(24px * var(--font-body-scale, 1));
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: #f4f0e0;
    text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7);
    filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.6));
    user-select: none;
    transition: transform 120ms ease, filter 120ms ease;
}
.kbd-sprite-text.kbd-sprite-wide {
    min-width: 123px;            /* Jumbo EMPTY2.png at 3× (41×3) */
    background-image: url('../sprites/keys/EMPTY2.png');
    font-size: calc(14px * var(--font-body-scale, 1));
}
.kbd-sprite-text.kbd-sprite-small {
    height: 48px;
    min-width: 48px;
    font-size: calc(13px * var(--font-body-scale, 1));
}
.kbd-tone-cyan   { color: #66e6ff; text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7), 0 0 8px rgba(102, 230, 255, 0.45); }
.kbd-tone-orange { color: #ffb366; text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7), 0 0 8px rgba(255, 179, 102, 0.45); }
.control-row:hover .kbd-sprite-text {
    transform: translateY(-1px);
    filter: drop-shadow(0 3px 0 rgba(0, 0, 0, 0.7)) drop-shadow(0 0 6px rgba(255, 255, 255, 0.15));
}

/* 5.79.50 — Multi-letter key cluster (e.g. ESC = E + S + C built
   from individual Jumbo letter sprites). Sets the inner letter
   sprites flush together (zero gap) so the silhouette reads as a
   single tactile multi-letter key. The drop-shadow that lives on
   `.kbd` already gives each letter its own subtle lift; the
   cluster wrapper just lines them up. */
.kbd-sprite-cluster {
    display: inline-flex;
    align-items: center;
    gap: 0;
    vertical-align: middle;
    user-select: none;
}
.kbd-sprite-cluster > .kbd {
    /* Reset transition timing to fire in lockstep across all three
       letters so the cluster lifts as one unit on hover. */
    transition: transform 120ms ease, filter 120ms ease;
}
.kbd-sprite-cluster.kbd-sprite-cluster-small > .kbd {
    height: 48px;
}
.control-row:hover .kbd-sprite-cluster > .kbd {
    transform: translateY(-1px);
    filter: drop-shadow(0 3px 0 rgba(0, 0, 0, 0.7)) drop-shadow(0 0 6px rgba(255, 255, 255, 0.15));
}

/* 5.79.42 — Mouse-button SVG tile. Rendered inline by ui-manager
   (see _buildMouseSvgKey). Slight glow + drop shadow matches the
   key sprites so it reads as part of the same family. */
.kbd-mouse-svg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 63px;
    width: 56px;
    user-select: none;
    transition: transform 120ms ease, filter 120ms ease;
    filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.6));
}
.kbd-mouse-svg svg {
    width: 100%;
    height: 100%;
    color: #d8e0ec;
}
.kbd-mouse-svg.kbd-mouse-l { color: #66e6ff; }
.kbd-mouse-svg.kbd-mouse-r { color: #ffb366; }
.kbd-mouse-svg.kbd-mouse-l svg { color: #66e6ff; }
.kbd-mouse-svg.kbd-mouse-r svg { color: #ffb366; }
.kbd-mouse-svg .mouse-body {
    fill: rgba(255, 255, 255, 0.04);
    stroke: #d8e0ec;
    stroke-width: 1.4;
}
.kbd-mouse-svg .mouse-divider {
    stroke: #d8e0ec;
    stroke-width: 1.2;
    fill: none;
}
.kbd-mouse-svg .mouse-wheel {
    fill: #d8e0ec;
}
/* 5.79.45 — Motion arcs flank the neutral aim-reticle mouse to
   convey movement. Stroke only (no fill); slightly dimmer than
   the body outline so they read as ambient motion lines rather
   than structural detail. */
.kbd-mouse-svg .mouse-motion {
    fill: none;
    stroke: #d8e0ec;
    stroke-width: 1.1;
    stroke-linecap: round;
    opacity: 0.6;
}
.control-row:hover .kbd-mouse-svg .mouse-motion {
    opacity: 0.9;
}
.kbd-mouse-svg .mouse-button-active {
    fill: currentColor;
    opacity: 0.95;
}
.control-row:hover .kbd-mouse-svg {
    transform: translateY(-1px);
    filter: drop-shadow(0 3px 0 rgba(0, 0, 0, 0.7)) drop-shadow(0 0 8px currentColor);
}

/* Legacy classes kept as aliases of the sprite-backed key so any
   page still using `.kbd-mouse` / `.kbd-text` doesn't regress. */
.kbd-mouse,
.kbd-text {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 48px;
    min-width: 60px;
    padding: 0 12px;
    font-family: 'Silkscreen', monospace;
    /*font-family: 'Inter', 'Helvetica Neue', system-ui, -apple-system, sans-serif;*/
    font-size: calc(14px * var(--font-body-scale, 1));
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: #ffe9a3;
    background: linear-gradient(180deg, #3a3a3a 0%, #222 50%, #1a1a1a 100%);
    border: 2px solid #0a0a0a;
    border-top-color: #4a4a4a;
    border-left-color: #3a3a3a;
    border-radius: 4px;
    box-shadow:
        inset 0 -2px 0 rgba(0, 0, 0, 0.5),
        0 2px 0 rgba(0, 0, 0, 0.6);
    user-select: none;
}
.kbd-mouse-l { color: #66e6ff; }
.kbd-mouse-r { color: #ffb366; }

.kbd-or {
    color: #8090a0;
    font-family: 'Silkscreen', monospace;
    text-transform: uppercase;
    /*font-family: 'Inter', 'Helvetica Neue', system-ui, -apple-system, sans-serif;*/
    font-size: calc(13px * var(--font-body-scale, 1));
    font-style: italic;
    padding: 0 2px;
}

/* Action label — readable Inter copy. Pixel font reserved for the
   page header per user's 5.79.39 directive. */
.kbd-action {
    color: #f0f4fa;
    font-family: 'Silkscreen', monospace;
    /*font-family: 'Inter', 'Helvetica Neue', system-ui, -apple-system, sans-serif;*/
    font-size: calc(15px * var(--font-body-scale, 1));
    font-weight: 500;
    line-height: 1.45;
    letter-spacing: 0.3px;
    flex: 1 1 auto;
}

.controls-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 22px auto 0;
    padding-top: 14px;
    border-top: 1px dashed rgba(255, 255, 255, 0.10);
    color: #a8b0bc;
    font-family: 'Silkscreen', monospace;
    /*font-family: 'Inter', 'Helvetica Neue', system-ui, -apple-system, sans-serif;*/
    font-size: calc(20px * var(--font-body-scale, 1));
    font-weight: 400;
    letter-spacing: 0.3px;
}
.controls-footer-text {
    opacity: 0.85;
}

/* Goldenrod scrollbars throughout the pause menu.
   Dark yellow-goldenrod track + bright goldenrod thumb.
   Two notes on why this is split between Firefox and WebKit and uses no
   `scrollbar-width: thin`:
     - Firefox only honors `scrollbar-color` (no ::-webkit-scrollbar support).
     - Chromium / Safari respect ::-webkit-scrollbar pseudo-elements ONLY
       when the legacy scrollbar is in use; setting `scrollbar-width: thin`
       opts into the native thin scrollbar which ignores those pseudos and
       leaves the bar gray. So we omit `scrollbar-width`. */
#pause-menu,
#pause-menu * {
    scrollbar-color: #FFC107 #5a4509; /* thumb, track — Firefox */
}
#pause-menu::-webkit-scrollbar,
#pause-menu *::-webkit-scrollbar {
    width: 12px;
    height: 12px;
}
#pause-menu::-webkit-scrollbar-track,
#pause-menu *::-webkit-scrollbar-track {
    background: #5a4509; /* dark yellow-goldenrod */
    border-radius: 6px;
}
#pause-menu::-webkit-scrollbar-thumb,
#pause-menu *::-webkit-scrollbar-thumb {
    background: #FFC107; /* bright goldenrod */
    border-radius: 6px;
    border: 2px solid #5a4509; /* keeps thumb visually inset against the track */
}
#pause-menu::-webkit-scrollbar-thumb:hover,
#pause-menu *::-webkit-scrollbar-thumb:hover {
    background: #FFD740; /* even brighter on hover */
}
#pause-menu::-webkit-scrollbar-corner,
#pause-menu *::-webkit-scrollbar-corner {
    background: #5a4509;
}

.pause-tabs {
    /* 3-col grid keeps the 9 tabs in a clean 3×3 layout. */
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 20px;
    width: min(720px, 100%);
    margin-left: auto;
    margin-right: auto;
    justify-items: stretch;
}

.pause-tab {
    /* Per-tab color is supplied by the data-tab[…] selectors below. */
    --tab-color: #cccccc;
    --tab-glow: rgba(204, 204, 204, 0.35);
    padding: 14px 18px;
    background: rgba(255, 255, 255, 0.06);
    border: 2px solid color-mix(in srgb, var(--tab-color) 55%, transparent);
    color: white;
    cursor: pointer;
    /* 6.225.2 — tabs are header-class chrome (they already size off
       --font-header-scale, and the DISPLAY tab promises "headers + tabs use one
       font"), so they take the HEADER font, not --font-body. */
    font-family: var(--font-header);
    font-size: calc(18px * var(--font-header-scale, 1));
    border-radius: 5px;
    transition: all 0.2s;
    text-align: center;
    white-space: nowrap;
}

.pause-tab:hover:not(.active) {
    background: color-mix(in srgb, var(--tab-color) 18%, transparent);
    border-color: var(--tab-color);
    box-shadow: 0 0 15px var(--tab-glow);
    transform: translateY(-2px);
}

.pause-tab.active {
    background: color-mix(in srgb, var(--tab-color) 32%, transparent);
    border-color: var(--tab-color);
    box-shadow: 0 0 12px var(--tab-glow);
}

/* Per-tab colors — palette mirrors the shop tabs where applicable. */
.pause-tab[data-tab="controls"] { --tab-color: #cccccc; --tab-glow: rgba(204, 204, 204, 0.35); }
.pause-tab[data-tab="primary"]  { --tab-color: #00ccff; --tab-glow: rgba(0,   204, 255, 0.40); }
.pause-tab[data-tab="power"]    { --tab-color: #ff4444; --tab-glow: rgba(255,  68,  68, 0.40); }
.pause-tab[data-tab="abilities"]   { --tab-color: #aa66ff; --tab-glow: rgba(170, 102, 255, 0.40); }
.pause-tab[data-tab="powerups"] { --tab-color: #ffd700; --tab-glow: rgba(255, 215,   0, 0.40); }
.pause-tab[data-tab="assists"]  { --tab-color: #66ddcc; --tab-glow: rgba(102, 221, 204, 0.40); }
.pause-tab[data-tab="music"]    { --tab-color: #44dd88; --tab-glow: rgba( 68, 221, 136, 0.40); }
.pause-tab[data-tab="sfx"]      { --tab-color: #ffa500; --tab-glow: rgba(255, 165,   0, 0.40); }

/* ── ASSISTS pause-tab — toggle rows for accessibility helpers. ─── */
.assists-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 16px;
}
.assist-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(102, 221, 204, 0.30);
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
    line-height: 1.5;
}
.assist-row:hover {
    background: rgba(102, 221, 204, 0.10);
    border-color: rgba(102, 221, 204, 0.55);
}
.assist-row input[type="checkbox"] {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    margin: 0;
    accent-color: #66ddcc;
    cursor: pointer;
    align-self: center;
}
.assist-row-text { flex: 1 1 auto; }
.assist-row-title {
    font-family: var(--font-body);
    font-size: calc(14px * var(--font-header-scale, 1));
    color: #66ddcc;
    margin-bottom: 6px;
}
.assist-row-desc {
    font-size: calc(14px * var(--font-body-scale, 1));
    color: #cccccc;
}

.pause-tab-content {
    display: none;
    font-size: calc(16px * var(--font-body-scale, 1));
    line-height: 2.5;
    text-align: left;
}

.pause-tab-content.active {
    display: block;
}

/* 5.79.40 — Detailed pause-tab h2 styling moved up to the
   `.pause-tab-content > h2` rule (gold-gradient + tapered
   underline). This stub stays only to preserve the
   `margin-top: 0` reset for any rare tab content that wraps
   the h2 in another element. */
.pause-tab-content h2 {
    margin-top: 0;
}

/* 5.79.41 — Shared subtitle below tab headers (PRIMARY / POWER /
   etc.). Centered dim caption used for "Click a weapon to equip it"
   style intros. Was inline `style="..."` attributes; lifted to a
   class so the styling stays declarative. */
.pause-tab-subtitle {
    margin: -8px auto 16px;
    color: #9aa3b3;
    font-family: 'Silkscreen', monospace;
    /*font-family: 'Inter', 'Helvetica Neue', system-ui, -apple-system, sans-serif;*/
    font-size: calc(13px * var(--font-body-scale, 1));
    font-style: italic;
    letter-spacing: 0.4px;
    text-align: center;
    opacity: 0.85;
}
.pause-tab-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 8px;
}
.pause-tab-list--scroll {
    overflow-y: auto;
    max-height: 60vh;
    padding-right: 4px;
}

/* P5b — in-run PASSIVES swap rows (pause menu). */
.pause-equip-row {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas: "name status" "desc desc";
    gap: 2px 12px;
    text-align: left;
    padding: 10px 14px;
    border: 1px solid rgba(160, 130, 220, 0.35);
    border-radius: 8px;
    background: rgba(40, 30, 60, 0.5);
    color: #cfc4e8;
    cursor: pointer;
    font-family: var(--font-body);
    transition: border-color 0.15s, background 0.15s;
}
.pause-equip-row:hover { border-color: rgba(190, 160, 255, 0.7); background: rgba(60, 45, 90, 0.6); }
.pause-equip-row.equipped { border-color: #11bb88; background: rgba(20, 70, 55, 0.55); color: #d6ffe9; }
.pause-equip-name   { grid-area: name; font-size: calc(13px * var(--font-body-scale, 1)); }
.pause-equip-status { grid-area: status; font-size: calc(12px * var(--font-body-scale, 1)); color: #8effc0; align-self: center; }
.pause-equip-desc   { grid-area: desc; font-size: calc(12px * var(--font-body-scale, 1)); color: #9a90b8; line-height: 1.4; }

/* ── SHOP OVERLAY ──────────────────────────────────────────────────────────
   Mirrors the pause-menu layout: full-viewport backdrop, centered column,
   header (title + currency), tab strip, scrollable item list. Reuses
   pause-tab styling patterns where possible. */
#shop-overlay {
    background-color: rgba(0, 0, 0, 0.25);
    display: none;
    pointer-events: all;
    z-index: 100;
}

#shop-menu {
    position: relative;
    background-color: rgba(0, 0, 0, 0.78);
    padding: 40px;
    text-align: center;
    width: 100vw;
    height: 100vh;
    box-sizing: border-box;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 16px;
}

#shop-menu, #shop-menu * { text-shadow: none; }

.shop-close {
    position: absolute;
    top: 18px;
    left: 18px;
    width: 40px;
    height: 40px;
    background: rgba(150, 25, 25, 0.9);
    border: 2px solid #993333;
    color: white;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: calc(20px * var(--font-body-scale, 1));
    line-height: 1;
    border-radius: 5px;
    transition: all 0.2s;
    z-index: 1;
}
.shop-close:hover {
    background: rgba(220, 50, 50, 1.0);
    border-color: #ff9999;
    box-shadow: 0 0 14px rgba(255, 80, 80, 0.6);
}

.shop-title {
    color: #00ccff;
    font-size: calc(32px * var(--font-header-scale, 1));
    margin: 0;
    font-family: var(--font-body);
}

.shop-currency-row {
    display: flex;
    gap: 36px;
    justify-content: center;
    align-items: center;
    font-family: var(--font-body);
    font-size: calc(16px * var(--font-body-scale, 1));
    line-height: 1;
}
.shop-currency { display: inline-flex; align-items: center; gap: 8px; }
.shop-currency--coins { color: #ffd700; }
.shop-currency--sp    { color: #6ab7ff; }
.shop-currency--picks { color: #ff66cc; }
.shop-currency-icon   { font-size: calc(18px * var(--font-body-scale, 1)); }
.shop-currency-label  { color: #4a90e2; font-size: calc(14px * var(--font-body-scale, 1)); }
.shop-currency--picks .shop-currency-label { color: #ff66cc; }
/* 5.71.0 — big bold + sigil for the PICKS counter. Slightly oversized
   vs. other currency icons so the resource reads clearly as a "free
   pick" rather than a numeric cost. */
.shop-picks-icon {
    font-size: calc(28px * var(--font-body-scale, 1));
    font-weight: 900;
    line-height: 1;
    color: #ff66cc;
    text-shadow: 0 0 8px rgba(255, 102, 204, 0.6);
    margin-right: 2px;
}

.shop-tabs {
    /* 7 tabs: HELP + 6 category tabs. 4-column grid lays them out as
       4 + 3 (HELP / OFFENSE / PRIMARY / POWER on row 1; DEFENSE /
       DROPS / ABILITIES on row 2). Width capped to keep tab cells from
       getting too wide on ultrawide screens. */
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    margin: 8px 0 12px 0;
    width: min(960px, 100%);
    margin-left: auto;
    margin-right: auto;
}

.shop-tab {
    --tab-color: #cccccc;
    --tab-glow: rgba(204, 204, 204, 0.35);
    padding: 14px 18px;
    background: rgba(255, 255, 255, 0.06);
    border: 2px solid color-mix(in srgb, var(--tab-color) 55%, transparent);
    color: white;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: calc(18px * var(--font-header-scale, 1));
    border-radius: 5px;
    transition: all 0.2s;
    text-align: center;
    white-space: nowrap;
}
.shop-tab:hover:not(.active) {
    background: color-mix(in srgb, var(--tab-color) 18%, transparent);
    border-color: var(--tab-color);
    box-shadow: 0 0 15px var(--tab-glow);
    transform: translateY(-2px);
}
.shop-tab.active {
    background: color-mix(in srgb, var(--tab-color) 32%, transparent);
    border-color: var(--tab-color);
    box-shadow: 0 0 12px var(--tab-glow);
}

/* Per-tab category colors — matches the canvas palette. */
.shop-tab[data-tab="HELP"]    { --tab-color: #cccccc; --tab-glow: rgba(204, 204, 204, 0.35); }
.shop-tab[data-tab="OFFENSE"] { --tab-color: #ffd700; --tab-glow: rgba(255, 215,   0, 0.40); }
.shop-tab[data-tab="DEFENSE"] { --tab-color: #4a90e2; --tab-glow: rgba( 74, 144, 226, 0.40); }
.shop-tab[data-tab="DROPS"]   { --tab-color: #44dd88; --tab-glow: rgba( 68, 221, 136, 0.40); }
.shop-tab[data-tab="PRIMARY"] { --tab-color: #00ccff; --tab-glow: rgba(  0, 204, 255, 0.40); }
.shop-tab[data-tab="POWER"]   { --tab-color: #ff4444; --tab-glow: rgba(255,  68,  68, 0.40); }
.shop-tab[data-tab="ABILITIES"]  { --tab-color: #aa66ff; --tab-glow: rgba(170, 102, 255, 0.40); }

/* 5.99.0 — Per-WEAPON shop tab colors. The 5.79.57 per-weapon tab strip
   (PULSE / NEEDLES / SCATTER / RAIL / CHARGE / MINES / NOVA / MISSILES /
   LANCE / ARC) inherited the default `--tab-color: #cccccc` which made
   the whole strip read as grey. Now every weapon tab is tinted with its
   weapon's canonical color (same hex value as `PRIMARY_WEAPONS[id].color`
   / `POWER_WEAPONS[id].color` in weapon-data.js). */
.shop-tab[data-tab="PULSE_CANNON"]   { --tab-color: #00ccff; --tab-glow: rgba(  0, 204, 255, 0.40); }
.shop-tab[data-tab="STORM_NEEDLES"]  { --tab-color: #b3ff44; --tab-glow: rgba(179, 255,  68, 0.40); }
.shop-tab[data-tab="SCATTER_GUN"]    { --tab-color: #ff8844; --tab-glow: rgba(255, 136,  68, 0.40); }
.shop-tab[data-tab="RAIL_DRIVER"]    { --tab-color: #ff44ff; --tab-glow: rgba(255,  68, 255, 0.40); }
.shop-tab[data-tab="CHARGE_SHOT"]    { --tab-color: #00e6aa; --tab-glow: rgba(  0, 230, 170, 0.40); }
.shop-tab[data-tab="MINE_LAYER"]     { --tab-color: #ff3300; --tab-glow: rgba(255,  51,   0, 0.40); }
.shop-tab[data-tab="NOVA_BLAST"]     { --tab-color: #ffaa00; --tab-glow: rgba(255, 170,   0, 0.40); }
.shop-tab[data-tab="MISSILE_SALVO"]  { --tab-color: #ff4444; --tab-glow: rgba(255,  68,  68, 0.40); }
.shop-tab[data-tab="LANCE_BEAM"]     { --tab-color: #44ff44; --tab-glow: rgba( 68, 255,  68, 0.40); }
.shop-tab[data-tab="LIGHTNING_ARC"]  { --tab-color: #a855ff; --tab-glow: rgba(168,  85, 255, 0.40); }

.shop-content {
    width: min(900px, 100%);
    flex: 1;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
    text-align: left;
}

.shop-item {
    display: grid;
    grid-template-columns: 56px 1fr auto;
    align-items: center;
    gap: 16px;
    padding: 14px 18px;
    background: rgba(0, 255, 0, 0.10);
    border: 2px solid #00ff00;
    border-radius: 8px;
    color: white;
    font-family: var(--font-body);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.1s;
    text-align: left;
}
.shop-item:hover:not(.shop-item--maxed) {
    background: rgba(0, 255, 0, 0.20);
    box-shadow: 0 0 14px rgba(0, 255, 136, 0.45);
    transform: translateY(-2px);
}
.shop-item--cant-afford { background: rgba(255, 0, 0, 0.10); border-color: #ff4444; }
.shop-item--cant-afford:hover { background: rgba(255, 0, 0, 0.18); box-shadow: 0 0 14px rgba(255, 68, 68, 0.45); }
.shop-item--maxed { background: rgba(100, 100, 100, 0.20); border-color: #666; cursor: not-allowed; opacity: 0.7; }
.shop-item--owned { background: rgba(0, 150, 80, 0.20); border-color: #44ff88; }
.shop-item--owned:hover { background: rgba(0, 200, 100, 0.30); box-shadow: 0 0 14px rgba(68, 255, 136, 0.45); }
.shop-item--equipped { background: rgba(0, 140, 200, 0.30); border-color: #44ddff; }
.shop-item--equipped:hover { background: rgba(0, 180, 255, 0.40); box-shadow: 0 0 14px rgba(68, 221, 255, 0.50); }

/* 5.99.0 — Weapon-tinted shop items. Every row inside a per-weapon tab
   (PULSE / NEEDLES / SCATTER / RAIL / CHARGE / MINES / NOVA / MISSILES /
   LANCE / ARC) carries `.shop-item--weaponed` plus `--item-color` set in
   shop-dom.js. The accent color borders the row, tints the icon, and
   colors the hover glow so the upgrade list reads as belonging to that
   weapon. Owned / equipped / cant-afford state classes still take
   precedence (their selectors are later in the cascade). */
.shop-item--weaponed {
    background: color-mix(in srgb, var(--item-color) 12%, transparent);
    border-color: color-mix(in srgb, var(--item-color) 65%, transparent);
}
.shop-item--weaponed:hover:not(.shop-item--maxed) {
    background: color-mix(in srgb, var(--item-color) 22%, transparent);
    box-shadow: 0 0 14px color-mix(in srgb, var(--item-color) 50%, transparent);
    border-color: var(--item-color);
}
.shop-item--weaponed .shop-item-icon { color: var(--item-color); }
.shop-item--weaponed .shop-item-name { color: var(--item-color); }

.shop-item-icon { font-size: calc(32px * var(--font-body-scale, 1)); text-align: center; }
.shop-item-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.shop-item-name { font-size: calc(16px * var(--font-body-scale, 1)); font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.shop-item-desc { font-size: calc(13px * var(--font-body-scale, 1)); color: #cccccc; line-height: 1.4; }

.shop-item-cost {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    min-width: 110px;
}
.shop-item-price { font-size: calc(16px * var(--font-body-scale, 1)); font-weight: bold; color: #ffd700; display: inline-flex; align-items: center; gap: 6px; }
.shop-item-price--coin .shop-coin-icon { vertical-align: middle; }
.shop-item-price--sp { color: #4a90e2; }
.shop-item-price--picks { color: #ff66cc; }
.shop-item-price--picks-row { display: inline-flex; align-items: center; gap: 4px; }
.shop-item-price-pick-sigil {
    font-size: calc(24px * var(--font-body-scale, 1));
    font-weight: 900;
    line-height: 1;
    color: inherit;
    text-shadow: 0 0 6px rgba(255, 102, 204, 0.55);
}
.shop-item-price--cant { color: #ff6666; }
.shop-item-price--equipped { color: #44ddff; }
.shop-item-price--owned { color: #44ff88; }
.shop-item-status { font-size: calc(12px * var(--font-body-scale, 1)); color: #00ffff; }
.shop-item-status--maxed { color: #666; }
.shop-item-status--owned { color: #44ff88; }
/* Level 0 — item not yet purchased. Red so the player can tell at a
 * glance which upgrades they haven't put any stacks into yet. */
.shop-item-status--zero { color: #ff6666; }

/* Right-side cell of each shop item: holds costCol and (optional) sell
 * button as siblings inside a single grid track. Without this wrapper
 * the sell button overflows the grid and gets reflowed to a phantom
 * second row, clipping its background. */
.shop-item-right {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 12px;
    /* Important: this needs to live in the rightmost (auto) grid column,
     * which is implicit since it's the third child of `.shop-item`. */
}

.shop-item-sell {
    padding: 9px 14px;
    background: rgba(170, 45, 45, 0.92);
    border: 1px solid #cc6666;
    color: #ffffff;
    font-family: var(--font-body);
    font-size: calc(12px * var(--font-body-scale, 1));
    border-radius: 5px;
    cursor: pointer;
    align-self: center;
    transition: background 0.15s, border-color 0.15s, transform 0.1s;
    /* Force the SELL +### label onto a single line — Press Start 2P at
     * 9px is wide enough that the default flex shrink would clip-wrap
     * "SELL +1500SP" into two lines on narrower rows. The fuller padding
     * makes the red background pad evenly around the entire label so
     * the text reads as "inside a button" instead of "next to a small
     * tag". */
    white-space: nowrap;
    flex-shrink: 0;
    text-align: center;
    line-height: 1.3;
    letter-spacing: 0.5px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.shop-item-sell:hover {
    background: rgba(225, 85, 85, 0.96);
    border-color: #ffaaaa;
    transform: translateY(-1px);
}
.shop-item-sell:active {
    transform: translateY(0);
    background: rgba(140, 35, 35, 0.95);
}

/* HELP panel — instructional content shown on the HELP shop tab. */
.shop-help {
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 18px 22px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 10px;
    color: #e6e6e6;
    font-family: var(--font-body);
}
.shop-help-intro,
.shop-help-footer {
    font-size: calc(14px * var(--font-body-scale, 1));
    line-height: 1.7;
    color: #cccccc;
}
.shop-help-footer { color: #aaaaaa; font-style: normal; }
.shop-help-entry {
    display: grid;
    grid-template-columns: 70px 1fr;
    align-items: center;
    gap: 18px;
    padding: 14px 18px;
    background: rgba(0, 0, 0, 0.35);
    border: 2px solid rgba(255, 255, 255, 0.18);
    border-radius: 8px;
}
.shop-help-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    font-size: calc(22px * var(--font-body-scale, 1));
    font-weight: bold;
    background: rgba(0, 0, 0, 0.6);
    border: 2px solid rgba(255, 255, 255, 0.2);
}
.shop-help-icon--sp { color: #6ab7ff; border-color: rgba(74, 144, 226, 0.7); }
.shop-help-icon--xp { color: #ff6e6e; border-color: rgba(220, 60, 60, 0.7); }
.shop-help-icon--picks { color: #ff66cc; border-color: rgba(255, 102, 204, 0.7); font-size: calc(13px * var(--font-body-scale, 1)); }

.shop-help-text { display: flex; flex-direction: column; gap: 6px; }
.shop-help-title { font-size: calc(16px * var(--font-header-scale, 1)); font-weight: bold; letter-spacing: 1px; }
.shop-help-title--gold { color: #ffd700; }
.shop-help-title--sp   { color: #6ab7ff; }
.shop-help-title--picks { color: #ff66cc; }
.shop-help-title--xp   { color: #ff6e6e; }
.shop-help-body { font-size: calc(13px * var(--font-body-scale, 1)); color: #d8d8d8; line-height: 1.7; }

.pause-menu-actions {
    /* SHOP/RESUME row sits at the very top of the pause menu. The divider
       (border-bottom) sits inside this container, so the button→divider gap
       is `padding-bottom`. The divider→tabs gap below is the flex `gap` of
       #pause-menu (18px). Match `padding-bottom` to that gap so the divider
       is visually equidistant from the buttons and the tab row beneath it. */
    display: flex;
    gap: 20px;
    justify-content: center;
    margin: 0;
    padding-top: 0;
    padding-bottom: 18px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.3);
    border-top: none;
}

.pause-action-btn {
    padding: 12px 24px;
    background: rgba(0, 200, 255, 0.2);
    border: 2px solid rgba(0, 200, 255, 0.6);
    color: white;
    cursor: pointer;
    /* 6.158.2 — RESUME (and other pause action buttons) use the pixel header
       font, not the body font, so the CTA reads as a chunky retro button. */
    font-family: var(--font-header);
    font-size: calc(14px * var(--font-body-scale, 1));
    border-radius: 5px;
    transition: all 0.3s;
    text-transform: uppercase;
    letter-spacing: 1px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    line-height: 1;
}

.pause-action-btn:hover {
    background: rgba(0, 200, 255, 0.4);
    border-color: #00ccff;
    box-shadow: 0 0 15px rgba(0, 200, 255, 0.5);
    transform: translateY(-2px);
}

.pause-btn-icon {
    font-size: calc(26px * var(--font-body-scale, 1));
    line-height: 1;
    position: relative;
    top: -3px; /* icon sits low in em square — nudge up */
}

.pause-btn-label {
    line-height: 1;
    position: relative;
    top: 2px; /* Press Start 2P has large ascender, text renders high — nudge down */
}

#pause-shop-button {
    background: rgba(255, 165, 0, 0.2);
    border-color: rgba(255, 165, 0, 0.6);
}

#pause-shop-button:hover {
    background: rgba(255, 165, 0, 0.4);
    border-color: #ffaa00;
    box-shadow: 0 0 15px rgba(255, 165, 0, 0.5);
}

/* No-powerups placeholder text — suppress inherited text-shadow from .ui-element parent */
#no-powerups {
    text-shadow: none;
}

/* HUD shop button — top-right, sits to the LEFT of the pause button so
   the player can pop into the shop at any time without first pausing.
   Same visual language as the pause button (goldenrod, dim until hover). */
#hud-shop-btn {
    /* 5.79.2 — DOM hud-shop-btn replaced by canvas-rendered bottom-center
       buttons in hud-buttons.js. Permanently hidden so the canvas
       layer owns the click region; the reticule cursor now floats
       over the button visuals like any in-world entity. */
    display: none !important;
}
#hud-shop-btn:hover {
    opacity: 1;
    background: rgba(218, 165, 32, 0.28);
    border-color: goldenrod;
    box-shadow: 0 0 14px rgba(218, 165, 32, 0.8), 0 0 28px rgba(218, 165, 32, 0.35);
}
body.shop-open #hud-shop-btn {
    opacity: 0;
    pointer-events: none;
}

/* HUD pause button (5.79.14 — moved to canvas; DOM hidden permanently)
   Replaced by the canvas-rendered PAUSE button in hud-buttons.js so
   the reticule cursor floats over it like any in-world entity. */
#hud-pause-btn {
    display: none !important;
}

#hud-pause-btn:hover {
    opacity: 1;
    background: rgba(218, 165, 32, 0.28);
    border-color: goldenrod;
    box-shadow: 0 0 14px rgba(218, 165, 32, 0.8), 0 0 28px rgba(218, 165, 32, 0.35);
}

.hud-pause-bar {
    display: block;
    width: 5px;
    height: 22px;
    background: goldenrod;
    border-radius: 2px;
}

/* Hide HUD pause button when shop canvas is active */
body.shop-open #hud-pause-btn {
    opacity: 0;
    pointer-events: none;
}

#customize-button {
    display: block;
    margin: 20px auto 0;
    padding: 10px;
    font-family: var(--font-body);
    font-size: calc(16px * var(--font-body-scale, 1));
    color: white;
    background: #333;
    border: 2px solid white;
    cursor: pointer;
}

#customize-button:hover {
    background: #555;
}

.control-symbol {
    font-size: 1.75rem;
}

#touch-fire {
    position: absolute;
    right: 18%;
    bottom: 18%;
    width: 20vmin; /* was 16vmin */
    height: 20vmin; /* was 16vmin */
    background-color: rgba(255, 255, 255, 0.15);
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 10vmin; /* was 8vmin */
    color: rgba(255, 255, 255, 0.6);
    user-select: none;
    -webkit-user-select: none;
    pointer-events: all;
    box-sizing: border-box;
    transition: transform 0.05s ease-out;
    z-index: 201;
}
#touch-thrust {
    position: absolute;
    right: 5%;
    bottom: 5%;
    width: 16vmin;
    height: 16vmin;
    background-color: rgba(255, 255, 255, 0.15);
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 8vmin;
    color: rgba(255, 255, 255, 0.8);
    user-select: none;
    -webkit-user-select: none;
    pointer-events: all;
    box-sizing: border-box;
    transition: transform 0.05s ease-out;
    z-index: 201;
}
#touch-fire:active {
    background-color: rgba(255, 255, 255, 0.3);
    transform: scale(0.95);
}
#touch-thrust:active {
    background-color: rgba(255, 255, 255, 0.3);
    transform: scale(0.95);
}

#touch-tractor {
    position: absolute;
    right: 5%;
    bottom: 28%;
    width: 16vmin;
    height: 16vmin;
    background-color: rgba(255, 255, 255, 0.15);
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 8vmin;
    color: rgba(255, 255, 255, 0.8);
    user-select: none;
    -webkit-user-select: none;
    pointer-events: all;
    box-sizing: border-box;
    transition: transform 0.05s ease-out;
    z-index: 201;
}
#touch-tractor:active,
#touch-tractor.pressed {
    background-color: #eee !important;
    color: #333 !important;
    border-color: #bbb !important;
}



#customization-overlay {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background-color: rgba(0, 0, 0, 0.85);
    z-index: 300;
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    pointer-events: all;
}

#customization-overlay h2 { 
    font-size: calc(24px * var(--font-header-scale, 1)); 
    margin-bottom: 15px; 
}

#customization-overlay p { 
    font-size: calc(16px * var(--font-body-scale, 1)); 
    max-width: 80%; 
    margin-bottom: 30px; 
    line-height: 1.5; 
}

#customization-overlay .draggable {
    border: 2px dashed #f0f;
    animation: pulse-border 2s infinite;
}

@keyframes pulse-border {
    0% { border-color: #f0f; }
    50% { border-color: #0ff; }
    100% { border-color: #f0f; }
}

#save-layout-button {
     margin-top: 30px;
     padding: 15px 30px;
     font-family: var(--font-body);
     font-size: calc(18px * var(--font-body-scale, 1));
     color: black;
     background: white;
     border: 2px solid white;
     cursor: pointer;
}

/* #loading-screen {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background-color: #000;
    z-index: 500;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    color: white;
    font-family: var(--font-body);
} */

/* #loading-screen h1 {
    font-size: 8vmin;
    margin-bottom: 60px;
    text-align: center;
    animation: color-cycle 10s linear infinite;
}

#loading-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
}

#loading-bar {
    width: 300px;
    height: 20px;
    background-color: rgba(255, 255, 255, 0.1);
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 10px;
    overflow: hidden;
}

#loading-progress {
    height: 100%;
    background: linear-gradient(90deg, #00F, #4B0082, #8A2BE2, #FF00FF, #FF4500, #F00);
    width: 0%;
    transition: width 0.3s ease-out;
    border-radius: 8px;
}

#loading-text {
    font-size: calc(16px * var(--font-body-scale, 1));
    color: rgba(255, 255, 255, 0.8);
    margin: 0;
} */

/* #title-screen {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    z-index: 400;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    cursor: pointer;
} */

#game-title {
    font-size: 10vmin;
    text-align: center;
}

.title-char {
    display: inline-block;
    position: relative;
    animation: color-cycle 10s linear infinite, wave 2s ease-in-out infinite;
}

#start-prompt {
    font-size: 2.5vmin;
    animation: pulse-opacity 2s ease-in-out infinite;
    margin-top: 40px;
}

#high-score-display {
    margin-top: 20px;
    font-size: 2vmin;
    color: #ffd700;
    text-shadow: 0 0 8px #ffd700;
}

/* Mobile / tablet block — replaces the old orientation overlay. Shown via
   inline style by main.js when isMobileOrTabletDevice() is true. When this
   is visible, no game code runs at all. */
#desktop-only-block {
    position: fixed;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: #000;
    color: #fff;
    z-index: 9999;
    display: none; /* flipped to flex by main.js when blocking */
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    font-family: var(--font-body);
    padding: 24px;
    box-sizing: border-box;
}

#desktop-only-block .desktop-only-icon {
    font-size: calc(96px * var(--font-body-scale, 1));
    margin-bottom: 24px;
}

#desktop-only-block h1 {
    font-size: calc(28px * var(--font-header-scale, 1));
    margin: 0 0 24px 0;
    color: goldenrod;
    letter-spacing: 2px;
}

#desktop-only-block p {
    max-width: 520px;
    line-height: 1.7;
    font-size: calc(14px * var(--font-body-scale, 1));
    margin: 0 0 16px 0;
}

#desktop-only-block .desktop-only-sub {
    font-size: calc(13px * var(--font-body-scale, 1));
    color: #aaa;
}

/* When the desktop-only block is up, hide everything else so leftover DOM
   never peeks through. */
body.desktop-only-blocked > *:not(#desktop-only-block) {
    display: none !important;
}

#energy-bar-row {
    position: absolute;
    top: 18px;
    left: 24px;
    display: flex;
    align-items: center;
    z-index: 90;
}

#energy-bar-container {
    position: relative;
    width: 220px;
    height: 16px;
    background: rgba(64,64,64,0.5);
    border-radius: 3px;
    margin-left: 45px;
}

#energy-bar {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border-radius: 3px;
    overflow: hidden;
}
#energy-value {
    position: absolute;
    top: 0;
    left: 0;
    font-family: var(--font-body);
    font-size: 1.1em;
    font-weight: bold;
    color: #00ff00;
    text-shadow: none;
    width: 36px;
    display: block;
    text-align: right;
    transition: color 0.2s;
}
/* Critical/flashing effects removed */

/* Music Info Display */
#music-info {
    position: absolute;
    top: 20px;
    right: 20px;
    width: 250px;
    cursor: pointer;
    background: rgba(0, 0, 0, 0.8);
    border: 2px solid rgba(255, 255, 255, 0.3);
    padding: 12px;
    border-radius: 10px;
    z-index: 90;
    box-shadow: 0 0 20px rgba(255, 255, 255, 0.1);
}

#track-name {
    height: 30px;
    margin-bottom: 8px;
    overflow: hidden;
    position: relative;
}

#track-name-text {
    display: inline-block;
    white-space: nowrap;
    font-family: var(--font-body);
    font-size: calc(18px * var(--font-body-scale, 1));
    color: #00ff00;
    line-height: 30px;
}

#current-track-name {
    font-family: var(--font-body);
    font-size: calc(18px * var(--font-body-scale, 1));
    color: #00ff00;
    line-height: 30px;
    white-space: nowrap;
    text-overflow: ellipsis;
}

#music-info-progress-container {
    display: flex;
    align-items: center;
    gap: 8px;
}

#music-info-current-time,
#music-info-duration {
    font-size: calc(12px * var(--font-body-scale, 1));
    color: rgba(255, 255, 255, 0.8);
    min-width: 35px;
}

#music-progress-bar {
    flex: 1;
    height: 8px;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 4px;
    overflow: hidden;
}

#music-progress {
    height: 100%;
    background: #0088ff;
    width: 0%;
    transition: width 0.1s;
}

#shop-button {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%); /* Center horizontally */
    padding: 12px 24px;
    background: rgba(0, 0, 0, 0.7);
    border: 2px solid #FFD700;
    color: #FFD700;
    cursor: pointer;
    font-size: calc(18px * var(--font-body-scale, 1));
    font-weight: bold;
    transition: all 0.2s;
    z-index: 2; /* Above canvas (z-index 1) but behind shop overlay */
    border-radius: 8px;
    text-shadow: 0 0 8px rgba(255, 215, 0, 0.8);
}

#shop-button:hover {
    background: rgba(255, 215, 0, 0.2);
    border-color: #FFFF00;
    color: #FFFF00;
    text-shadow: 0 0 12px rgba(255, 255, 0, 1);
    transform: translateX(-50%) scale(1.05);
}

/* Music Player Styles */
#music-player {
    margin-top: 0;
}

#current-track-name {
    margin-bottom: 20px;
    padding: 0 20px;
    overflow: hidden;
    position: relative;
    width: 100%;
    height: 30px;
    text-align: center;
    box-sizing: border-box;
}

#music-progress-container {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 20px;
}

#music-player-progress-bar {
    flex: 1;
    height: 8px;
    /* Unbuffered (not-yet-downloaded) region — near-black so it reads
       as "empty" against the buffered ghost fill on top. */
    background: rgba(0, 0, 0, 0.75);
    border-radius: 4px;
    cursor: pointer;
    overflow: hidden;
    position: relative; /* Anchor for layered fills */
}

/* Buffered (downloaded) range — sits behind the playback fill so the
   user sees a darker indicator of how much is loaded ahead. */
#music-player-buffered {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 0%;
    background: rgba(255, 255, 255, 0.15);
    transition: width 0.2s ease-out;
    pointer-events: none;
}

#music-player-progress {
    position: relative; /* Sits above the buffered fill */
    height: 100%;
    background: #0088ff;
    width: 0%;
    transition: width 0.1s;
}

#music-current-time,
#music-duration {
    font-size: calc(13px * var(--font-body-scale, 1));
    color: rgba(255, 255, 255, 0.8);
    min-width: 45px;
}

#music-controls {
    /* 3-column grid: side groups expand into the side fr units while the
       center column stays auto-width — this guarantees the play/prev/next
       cluster is centered regardless of how many buttons each side has. */
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    margin-top: 20px;
    gap: 15px;
}

.music-side-controls {
    display: flex;
    gap: 10px;
    align-items: center;
}

.music-side-left  { justify-self: start; }
.music-side-right { justify-self: end; }

.music-main-controls {
    display: flex;
    gap: 15px;
    align-items: center;
}

.music-control-btn {
    background: rgba(255, 255, 255, 0.1);
    border: 2px solid rgba(255, 255, 255, 0.3);
    color: white;
    padding: 10px;
    cursor: pointer;
    font-size: calc(20px * var(--font-body-scale, 1));
    border-radius: 50%;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
}

.music-control-btn.large {
    width: 60px;
    height: 60px;
    font-size: calc(24px * var(--font-body-scale, 1));
}

.music-control-btn:hover {
    background: rgba(255, 255, 255, 0.2);
    border-color: rgba(255, 255, 255, 0.5);
}

.music-control-btn.active {
    background: rgba(0, 255, 0, 0.2);
    border-color: #00ff00;
}

/* Instant custom tooltip via data-tooltip attribute. The native `title`
   attribute has a ~700ms browser delay; a CSS :hover pseudo-element
   fires the moment the cursor enters the button. */
.music-control-btn[data-tooltip] {
    position: relative;
}
.music-control-btn[data-tooltip]:hover::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, 0.92);
    color: #fff;
    padding: 5px 10px;
    border-radius: 4px;
    border: 1px solid rgba(0, 204, 255, 0.6);
    font-size: calc(13px * var(--font-body-scale, 1));
    font-family: inherit;
    white-space: nowrap;
    pointer-events: none;
    z-index: 10000;
}
/* Little arrow under the tooltip pointing at the button */
.music-control-btn[data-tooltip]:hover::before {
    content: '';
    position: absolute;
    bottom: calc(100% + 2px);
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: rgba(0, 204, 255, 0.6);
    pointer-events: none;
    z-index: 10000;
}

/* Playlist Styles */
#playlist-container {
    margin-top: 20px;
}

#playlist-container h3 {
    font-size: calc(16px * var(--font-header-scale, 1));
    margin-bottom: 15px;
    color: #00ff00;
    text-align: center;
}

#playlist-tracks {
    max-height: 300px;
    overflow-y: auto;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 4px;
    background: rgba(0, 0, 0, 0.3);
}

#playlist-tracks::-webkit-scrollbar {
    width: 8px;
}

#playlist-tracks::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 4px;
}

#playlist-tracks::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.3);
    border-radius: 4px;
}

#playlist-tracks::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.5);
}

.playlist-track {
    padding: 0 15px;
    cursor: pointer;
    font-family: 'Silkscreen', monospace;
    font-size: calc(18px * var(--font-body-scale, 1));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: all 0.2s;
    position: relative;
}

.playlist-track-content {
    display: inline-block;
    white-space: nowrap;
}

.playlist-track:nth-child(odd) {
    background: rgba(255, 255, 255, 0.05);
}

.playlist-track:nth-child(even) {
    background: rgba(255, 255, 255, 0.02);
}

.playlist-track:hover {
    background: rgba(0, 136, 255, 0.3);
    color: #fff;
}

.playlist-track.playing {
    background: rgba(0, 255, 0, 0.2);
    color: #00ff00;
    font-weight: bold;
}

.playlist-track.playing::before {
    content: "♪ ";
    margin-right: 5px;
}

#shield-tanks {
    position: absolute;
    top: 40px;
    left: 24px;
    margin-left: 45px;
    display: flex;
    gap: 2px;
    z-index: 90;
}

.shield-tank {
    width: 14px;
    height: 14px;
    border-radius: 3px;
    background: rgba(0,255,0,0.8);
    transition: background 0.2s;
}

@keyframes pulse {
    0% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.05); opacity: 0.8; }
    100% { transform: scale(1); opacity: 1; }
}

@keyframes wave {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-15px); }
}

@keyframes color-cycle {
    0%   { color: #00F; text-shadow: 0 0 15px #00F; }
    16%  { color: #4B0082; text-shadow: 0 0 15px #4B0082; }
    32%  { color: #8A2BE2; text-shadow: 0 0 15px #8A2BE2; }
    48%  { color: #FF00FF; text-shadow: 0 0 15px #FF00FF; }
    64%  { color: #FF4500; text-shadow: 0 0 15px #FF4500; }
    80%  { color: #F00; text-shadow: 0 0 15px #F00; }
    100% { color: #00F; text-shadow: 0 0 15px #00F; }
}

@keyframes pulse-opacity {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.4; }
}

/* SFX Volume Slider */
#sfx-volume-slider {
    -webkit-appearance: none;
    appearance: none;
    height: 8px;
    background: rgba(255, 255, 255, 0.2);
    outline: none;
    border-radius: 4px;
    cursor: pointer;
}

#sfx-volume-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 20px;
    height: 20px;
    background: #00ff00;
    cursor: pointer;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.8);
}

#sfx-volume-slider::-moz-range-thumb {
    width: 20px;
    height: 20px;
    background: #00ff00;
    cursor: pointer;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.8);
}

#sfx-volume-value {
    color: #00ff00;
    font-size: calc(14px * var(--font-body-scale, 1));
}

/* Music Volume Slider */
#music-volume-slider {
    -webkit-appearance: none;
    appearance: none;
    height: 8px;
    background: rgba(255, 255, 255, 0.2);
    outline: none;
    border-radius: 4px;
    cursor: pointer;
}

#music-volume-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 20px;
    height: 20px;
    background: #0088ff;
    cursor: pointer;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.8);
}

#music-volume-slider::-moz-range-thumb {
    width: 20px;
    height: 20px;
    background: #0088ff;
    cursor: pointer;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.8);
}

#music-volume-value {
    color: #0088ff;
    font-size: calc(14px * var(--font-body-scale, 1));
}

/* Sound Effect Toggles */
#sfx-toggles {
    max-height: 300px;
    overflow-y: auto;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 4px;
    background: rgba(0, 0, 0, 0.3);
}

#sfx-toggles::-webkit-scrollbar {
    width: 8px;
}

#sfx-toggles::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 4px;
}

#sfx-toggles::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.3);
    border-radius: 4px;
}

#sfx-toggles::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.5);
}

.sfx-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 15px;
    transition: background 0.2s;
}

.sfx-toggle:nth-child(odd) {
    background: rgba(255, 255, 255, 0.05);
}

.sfx-toggle:nth-child(even) {
    background: rgba(255, 255, 255, 0.02);
}

.sfx-toggle:hover {
    background: rgba(255, 255, 255, 0.15);
}

.sfx-toggle-label {
    font-family: 'Silkscreen', monospace;
    font-size: calc(18px * var(--font-body-scale, 1));
    text-transform: capitalize;
}

.sfx-toggle-switch {
    position: relative;
    width: 40px;
    height: 20px;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 10px;
    cursor: pointer;
    transition: background 0.3s;
}

.sfx-toggle-switch.active {
    background: #00ff00;
}

.sfx-toggle-switch::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    background: white;
    border-radius: 50%;
    transition: transform 0.3s;
}

.sfx-toggle-switch.active::after {
    transform: translateX(20px);
}

.sfx-controls {
    display: flex;
    align-items: center;
    gap: 8px;
}

.sfx-test-button {
    width: 30px;
    height: 30px;
    border: 1px solid rgba(0, 200, 255, 0.5);
    border-radius: 6px;
    background: rgba(0, 200, 255, 0.2);
    color: white;
    font-size: calc(16px * var(--font-body-scale, 1));
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    font-family: inherit;
}

.sfx-test-button:hover {
    background: rgba(0, 200, 255, 0.3);
    border-color: rgba(0, 200, 255, 0.7);
    transform: scale(1.05);
}

.sfx-test-button:active {
    transform: scale(0.95);
    background: rgba(0, 200, 255, 0.3);
}

/* 5.74.17 — Powerup HUD moved from bottom-left to a vertical column
   anchored to the top-RIGHT corner. First column starts at the top-
   right and fills downward; when it overflows the available height,
   `flex-wrap: wrap-reverse` opens additional columns to the LEFT of
   the previous one (the rightmost column is always the "newest" one).
   `bottom: 110px` reserves clearance for the bottom-right gold readout
   (canvas y = height-76) and survival timer (canvas y = height-40)
   plus a small buffer, so icons never collide with either readout. */
#powerup-hud {
    top: 20px;
    right: 20px;
    bottom: 110px;
    display: flex;
    flex-direction: column;
    flex-wrap: wrap-reverse;
    align-content: flex-start;
    align-items: center;
    gap: 10px;
    pointer-events: none;
}

.powerup-hud-item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: auto;
    min-width: 40px;
}

.powerup-hud-countdown {
    font-family: 'Silkscreen', monospace;
    font-size: calc(14px * var(--font-body-scale, 1));
    color: #ffffff;
    text-align: center;
    white-space: nowrap;
    margin-bottom: 6px;
    line-height: 1.2;
    text-shadow: 0 0 4px rgba(0,0,0,0.9);
}

.powerup-hud-circle {
    position: relative; /* anchor for stacks badge */
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.7);
    border: 3px solid;
    box-sizing: border-box; /* keeps total width exactly 40px so timer aligns */
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: calc(20px * var(--font-body-scale, 1));
    line-height: 1;
}

.powerup-hud-stacks {
    position: absolute;
    bottom: -4px;
    right: -7px;
    background: rgba(0, 0, 0, 0.85);
    color: #ffffff;
    border-radius: 5px;
    padding: 1px 3px;
    font-size: calc(14px * var(--font-body-scale, 1));
    font-family: 'Silkscreen', monospace;
    line-height: 1.3;
    white-space: nowrap;
}

.powerup-hud-timer {
    margin: 8px 2px 0; /* 8px gap above, 2px side insets — wider bar, centered under circle */
    align-self: stretch; /* fill full width of flex column parent */
    height: 4px;
    background: rgba(255, 255, 255, 0.25);
    border-radius: 2px;
    overflow: hidden;
}

.powerup-hud-timer-bar {
    height: 100%;
    border-radius: 2px;
    width: 100%;
    transition: width 0.15s linear;
}

.powerup-hud-name {
    font-family: 'Silkscreen', monospace;
    font-size: calc(14px * var(--font-body-scale, 1));
    color: #aaddff;
    text-align: center;
    margin-top: 5px;
    white-space: nowrap;
    text-shadow: 0 0 4px rgba(0,0,0,0.9);
    line-height: 1.2;
}

#music-repeat {
    position: relative;
}

#music-repeat.repeat-one::after {
    content: '1';
    position: absolute;
    bottom: 0;
    right: 0;
    width: 14px;
    height: 14px;
    background: white;
    color: #00ccff;
    border-radius: 50%;
    font-size: calc(13px * var(--font-body-scale, 1));
    font-family: var(--font-body);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 1px 4px rgba(0,0,0,0.15);
    z-index: 2;
    border: 2px solid #00ccff;
    pointer-events: none;
} 
/* ── Contextual hint overlay ─────────────────────────────────────────── */
/* Driven by js/modules/ui/hint-system.js. One-at-a-time tooltip pinned
   above the HUD, fades in/out for soft entry/exit. */
#hint-overlay {
    position: fixed;
    bottom: 110px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, 0.88);
    border: 1px solid rgba(0, 204, 255, 0.7);
    border-radius: 8px;
    padding: 14px 26px;
    color: #ffffff;
    font-size: calc(14px * var(--font-body-scale, 1));
    font-family: 'Silkscreen', monospace;
    line-height: 1.5;
    pointer-events: none;
    z-index: 9999;
    opacity: 0;
    transition: opacity 0.3s ease, transform 0.3s ease;
    max-width: min(520px, 80vw);
    text-align: center;
    box-shadow: 0 0 24px rgba(0, 204, 255, 0.18);
    display: none;
    align-items: center;
    justify-content: center;
}
#hint-overlay.visible {
    opacity: 1;
    transform: translateX(-50%) translateY(-6px);
}
/* 5.68.2 — fade the overlay way down when the player ship is under it
   or the mouse cursor is hovering over it. Driven by hint-system.js
   updateHintDimming() each frame; the overlay still has
   pointer-events: none so the cursor passes through, but the dimming
   keeps the tooltip out of the player's way during action. */
#hint-overlay.visible.dimmed {
    opacity: 0.18;
}
#hint-overlay .hint-text strong {
    color: #00ccff;
    background: rgba(0, 204, 255, 0.12);
    padding: 1px 6px;
    border-radius: 3px;
    margin: 0 2px;
}

/* Shop banner that names the equipped weapon when on PRIMARY / POWER tabs.
   Sits at the top of the items list, makes it unambiguous which weapon
   the upgrades you're browsing apply to. */
.shop-equipped-banner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 14px 20px;
    margin: 0 0 18px 0;
    border: 2px solid rgba(0, 204, 255, 0.6);
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.45);
    text-align: center;
}
.shop-equipped-label {
    font-family: var(--font-body);
    font-size: calc(13px * var(--font-body-scale, 1));
    letter-spacing: 1.5px;
    color: rgba(255, 255, 255, 0.65);
    text-transform: uppercase;
}
.shop-equipped-weapon {
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-body);
    font-size: calc(20px * var(--font-body-scale, 1));
    font-weight: bold;
}
.shop-equipped-icon {
    font-size: calc(24px * var(--font-body-scale, 1));
}

/* ── Powerups pause-tab — Offense / Drops sub-tabs + card list ───── */
/* Two-button sub-tab strip inside the Powerups pause-tab. */
.powerups-subtab-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    width: min(720px, 100%);
    margin: 8px auto 12px auto;
}
.powerups-subtab {
    padding: 12px 20px;
    background: rgba(255, 255, 255, 0.06);
    border: 2px solid rgba(0, 204, 255, 0.4);
    color: #ffffff;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: calc(14px * var(--font-header-scale, 1));
    border-radius: 5px;
    transition: all 0.18s;
    flex: 1;
}
.powerups-subtab:hover:not(.active) {
    background: rgba(0, 204, 255, 0.12);
    border-color: #00ccff;
}
.powerups-subtab.active {
    background: rgba(0, 204, 255, 0.28);
    border-color: #00ccff;
    box-shadow: 0 0 12px rgba(0, 204, 255, 0.4);
}
.powerup-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.04);
    font-family: 'Silkscreen', monospace;
    transition: transform 0.15s ease, background 0.15s ease,
                border-color 0.15s ease, box-shadow 0.15s ease;
}
/* Hover lift — only applies when the row is interactive (cursor:pointer set
   in JS when picks > 0). The :hover selector still matches without it, so
   gate the lift on the cursor being pointer to avoid hovering disabled
   cards into a misleading "I can buy this" feedback. */
.powerup-card--interactive { cursor: pointer; }
.powerup-card--interactive:hover {
    transform: translateY(-2px);
    background: rgba(255, 215, 0, 0.10);
    border-color: rgba(255, 215, 0, 0.55);
    box-shadow: 0 4px 16px rgba(255, 215, 0, 0.18);
}
.powerup-card--interactive:hover .powerup-card-buy:not(:disabled) {
    background: #ff66cc;
    color: #1a0a14;
    transform: scale(1.06);
}
/* 5.74.15 — owned cards: lighter gray background + thicker accent border.
   The vibrant accent color is applied INLINE in renderPowerupsOverlay
   from cfg.color (mirrors the POWER pause-tab weapon-row treatment), so
   each owned powerup gets a frame in its own identity color. The base
   --owned class just lifts the background opacity from 0.06 → 0.18 so
   purchased cards visually stand off the unowned ones. */
.powerup-card--owned {
    background: rgba(255, 255, 255, 0.18);
    border-width: 2px;
    border-style: solid;
    border-color: rgba(255, 255, 255, 0.55);
}
.powerup-card--owned.powerup-card--interactive:hover {
    background: rgba(255, 255, 255, 0.26);
    /* Brightness lift on hover; the inline border-color stays vivid. */
    filter: brightness(1.15);
}
.powerup-card--locked {
    opacity: 0.55;
}
.powerup-card--locked.powerup-card--interactive:hover {
    opacity: 1;
}
.powerup-card-icon {
    font-size: calc(26px * var(--font-body-scale, 1));
    width: 36px;
    text-align: center;
    flex-shrink: 0;
}
.powerup-card-body {
    flex: 1;
    min-width: 0;
}
.powerup-card-name {
    font-family: var(--font-body);
    font-size: calc(14px * var(--font-body-scale, 1));
    margin-bottom: 4px;
}
.powerup-card-desc {
    font-size: calc(13px * var(--font-body-scale, 1));
    color: #ccc;
    line-height: 1.35;
}
.powerup-card-stacks {
    font-family: var(--font-body);
    font-size: calc(16px * var(--font-body-scale, 1));
    min-width: 50px;
    text-align: right;
    color: #00ccff;
}
.powerup-card--locked .powerup-card-stacks {
    color: #666;
}

/* 5.73.0 — pause-menu POWERUPS tab buy controls. */
.powerups-pick-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 14px 18px;
    margin-bottom: 14px;
    background: rgba(255, 102, 204, 0.08);
    border: 1px solid rgba(255, 102, 204, 0.4);
    border-radius: 8px;
}
.powerups-pick-sigil {
    font-size: calc(28px * var(--font-body-scale, 1));
    font-weight: 900;
    line-height: 1;
    color: #ff66cc;
    text-shadow: 0 0 8px rgba(255, 102, 204, 0.6);
}
.powerups-pick-count {
    font-family: var(--font-body);
    font-size: calc(22px * var(--font-body-scale, 1));
    color: #ff66cc;
}
.powerups-pick-label {
    font-family: var(--font-body);
    font-size: calc(13px * var(--font-body-scale, 1));
    letter-spacing: 2px;
    color: #ff99dd;
}
.powerup-card-buy {
    margin-left: 12px;
    padding: 8px 14px;
    font-family: var(--font-body);
    font-size: calc(14px * var(--font-body-scale, 1));
    font-weight: bold;
    color: #ff66cc;
    background: rgba(255, 102, 204, 0.12);
    border: 2px solid rgba(255, 102, 204, 0.6);
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, transform 0.1s;
}
.powerup-card-buy:hover:not(:disabled) {
    background: #ff66cc;
    color: #1a0a14;
    transform: scale(1.06);
}
.powerup-card-buy:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

/* Hover-tooltip on HUD powerup badges. Same instant-fire pattern as
   the music-button tooltips: data-tooltip attribute + ::after
   pseudo-element. Tooltip pops UP (above the badge) since the badges
   sit at the bottom of the screen. */
.powerup-hud-item[data-tooltip] {
    position: relative;
}
.powerup-hud-item[data-tooltip]:hover::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 10px);
    left: 50%;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, 0.92);
    color: #fff;
    padding: 6px 12px;
    border-radius: 4px;
    border: 1px solid rgba(0, 204, 255, 0.6);
    font-size: calc(13px * var(--font-body-scale, 1));
    font-family: 'Silkscreen', monospace;
    white-space: nowrap;
    pointer-events: none;
    z-index: 10000;
    max-width: 360px;
    text-align: center;
    line-height: 1.35;
}
.powerup-hud-item[data-tooltip]:hover::before {
    content: '';
    position: absolute;
    bottom: calc(100% + 4px);
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: rgba(0, 204, 255, 0.6);
    pointer-events: none;
    z-index: 10000;
}

/* ─── 5.91.0 — Mobile-mode HUD adjustments ─────────────────────────────
   `body.mobile-mode` is set on every mobile session; the additional
   `body.mobile-portrait` class is toggled when the viewport is taller
   than it is wide (re-evaluated on resize / orientationchange). All
   rules here are gated by those classes so the desktop layout is
   untouched.

   Portrait rules: hide the contextual hint overlay (it overlaps
   gameplay too much on a tall screen) and the DOM lives display
   (energy tanks now render on canvas; the DOM mirror is redundant in
   limited screen real estate). The on-canvas wave-info and timer
   widgets are conditionally suppressed in `js/modules/hud/status.js`
   for the same reason.
*/
body.mobile-mode {
    /* Disable user-select + tap highlight so long-press doesn't pop the
       system text-selection magnifier on iOS. */
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    /* Prevent rubber-band scrolling on touchmove. */
    overscroll-behavior: none;
    touch-action: none;
}

body.mobile-mode #gameCanvas,
body.mobile-mode #glCanvas,
body.mobile-mode #bulletCanvas {
    touch-action: none;
}

body.mobile-portrait #hint-overlay {
    display: none !important;
}

body.mobile-portrait #lives-display {
    display: none !important;
}

/* Keyboard-control hint cluster in the pause menu — irrelevant on
   touch. Hidden in mobile-mode regardless of orientation. */
body.mobile-mode .kbd,
body.mobile-mode .kbd-cluster,
body.mobile-mode .kbd-sprite-text,
body.mobile-mode .kbd-sprite-cluster,
body.mobile-mode .kbd-mouse-svg {
    display: none !important;
}

/* Shrink the top-right pause/shop chrome a notch so it doesn't crowd
   the wave-info zone in portrait. */
body.mobile-portrait #hud-pause-btn,
body.mobile-portrait #hud-shop-btn {
    transform: scale(0.85);
    transform-origin: top right;
}

/* ─── 5.92.0 — Mobile UX overhaul v2 ───────────────────────────────────
   The 5.91 pass introduced auto-pilot + tap-to-shoot. 5.92 finishes the
   visual half: collapse non-essential HUD chrome (powerup meters,
   loadout squares, gold readout, survival timer — all canvas-drawn and
   gated by isMobile() in hud/status.js) and make the title screen + game
   layout responsive. Desktop CSS is untouched; everything below sits
   under `body.mobile-mode` / `body.mobile-portrait` selectors.

   The canvas itself is sized to the viewport by the resize listener in
   js/modules/ui/event-setup.js, so no `width: 100vw` is needed here —
   the rules below mostly tame DOM overlays + tap targets. */

/* Top-right DOM powerup readout (loadout/meter — hidden per spec).
   The 5.78+ pass left this as the only DOM-rendered loadout chrome;
   everything else (PRM / PWR / SKL squares) is canvas. */
body.mobile-mode #powerup-hud {
    display: none !important;
}

/* Tap-target floor for the top-right HUD buttons. 44×44 px is the
   Apple HIG / Material Design baseline for "comfortable thumb tap";
   we go slightly larger so the visual button matches the hit rect.
   The 5.91 portrait scale-down lives in the rule above this one;
   this rule applies to both orientations. */
body.mobile-mode #hud-shop-btn,
body.mobile-mode #hud-pause-btn {
    min-width: 48px;
    min-height: 48px;
    /* Ensure tap target is comfortably above the chin / safe-area
       and clear of the bottom action button bar. */
    z-index: 1000;
}

/* Suppress horizontal scroll on narrow viewports. iOS Safari will
   sometimes overshoot the viewport on rotate; touch-action: none on
   body.mobile-mode already locks the gesture surface, but a
   defensive overflow-x rule keeps the layout pinned. */
body.mobile-mode {
    overflow-x: hidden;
}

/* Game canvases scale to viewport — the resize handler already sets
   the backing-store dimensions on each canvas, so we just want CSS
   to fill the viewport rect without leaving margins. The 5.91 rule
   set touch-action: none; we add object-fit-style sizing here. */
body.mobile-mode #gameCanvas,
body.mobile-mode #glCanvas,
body.mobile-mode #bulletCanvas {
    width: 100vw;
    height: 100vh;
    /* iOS Safari's address-bar collapse can cause a transient
       100vh > viewport-height gap; using dvh where available avoids
       the jump. The browsers that don't understand dvh fall back to
       the vh line above. */
    height: 100dvh;
}

/* Pause overlay + shop overlay use position:fixed at full-screen.
   In portrait orientation on a phone the pause-menu's tabbed UI can
   overflow; scale the inner panels down a notch so they fit. We
   stop short of a full responsive rebuild here — pause / shop still
   work as scrollable lists, just with a smaller anchor. */
body.mobile-portrait #pause-menu,
body.mobile-portrait #shop-menu {
    /* 5.97.0 — Tighter scale (0.92 → 0.82) so the pause / shop panels
       sit comfortably inside a typical phone viewport instead of
       pressing against the top + bottom edges. */
    transform: scale(0.82);
    transform-origin: center center;
}

/* 5.94.0 — Pause menu portrait text fit.
   In narrow portrait viewports (phones held vertically) the 9 pause-tab
   labels (CONTROLS / PRIMARY / POWER / ABILITIES / POWERUPS / ASSISTS /
   TIMER / MUSIC / SFX) overflow their 3-column grid cells at the default
   18-px Press Start 2P. The SHOP / RESUME action buttons also clip with
   their 14-px label + 26-px icon. Shrink both font sizes and tighten the
   button padding so the text fits inside its box in portrait. The
   pause-tab cells use `white-space: nowrap` (already set) so without this
   the labels would otherwise be clipped to ellipsis-or-overflow. */
body.mobile-portrait .pause-tab {
    font-size: calc(11px * var(--font-header-scale, 1));
    padding: 10px 6px;
    letter-spacing: 0.5px;
}

body.mobile-portrait .pause-tabs {
    gap: 6px;
    width: 100%;
}

body.mobile-portrait .pause-action-btn {
    font-size: calc(13px * var(--font-body-scale, 1));
    padding: 8px 12px;
    letter-spacing: 0.5px;
    gap: 6px;
}

body.mobile-portrait .pause-btn-icon {
    font-size: calc(20px * var(--font-body-scale, 1));
}

body.mobile-portrait .pause-menu-actions {
    gap: 10px;
}

/* 5.95.0 — Controls tab portrait fit.
   The Controls page (CONTROLS tab in the pause menu) uses a two-column
   table (action label | key bindings) with 18-px Press Start 2P headers
   and 18-px Silkscreen body. On narrow portrait viewports the long
   action strings ("Aim Reticle", "Fire Primary Weapon", "Cycle Power
   Weapon", etc.) overflow the cell horizontally — they push the keys
   column off-screen and the right-edge sprite cluster gets clipped.

   Fix: shrink the section-header font, the body-row font, the cell
   padding, the section icon size, the kbd tile size, and the footer
   font. Each row stays a single visual line (label + key cluster on
   the same row, with the keys allowed to wrap to a second line if a
   row has many sprites — that's a fine fallback at this size).

   Apply only on `body.mobile-portrait` so desktop and landscape mobile
   keep the original spacious treatment. */
body.mobile-portrait .controls-table {
    padding: 6px 10px 10px;
    width: calc(100% - 4px);
    margin: 4px auto 0;
}
body.mobile-portrait .controls-section-title {
    font-size: calc(12px * var(--font-header-scale, 1));
    letter-spacing: 1px;
}
body.mobile-portrait .controls-section-icon {
    width: 14px;
    height: 14px;
    margin-right: 6px;
}
body.mobile-portrait .controls-section-cell {
    padding: 8px 2px 6px;
}
body.mobile-portrait .controls-action {
    font-size: calc(13px * var(--font-body-scale, 1));
    letter-spacing: 0;
    padding: 8px 4px 8px 14px;
    line-height: 1.3;
}
body.mobile-portrait .controls-keys {
    padding: 6px 4px;
    white-space: normal; /* allow keys to wrap if a row has many */
}
body.mobile-portrait .controls-keys .kbd {
    height: 44px; /* scale down from 63 px so 2-3 key clusters fit on one row */
}
body.mobile-portrait .controls-keys .kbd-cluster.kbd-wasd > .kbd {
    margin-left: 24px; /* WASD diamond was margin-left: 36px at 63px */
}
body.mobile-portrait .controls-keys > * {
    margin-right: 3px;
}
body.mobile-portrait .controls-footer {
    font-size: calc(13px * var(--font-body-scale, 1));
    margin-top: 12px;
    padding-top: 8px;
    gap: 6px;
}
body.mobile-portrait #controls-tab h2 {
    font-size: calc(14px * var(--font-header-scale, 1));
    margin: 4px 0 4px;
}

/* ─── 5.98.0 — Wave-clear powerup pick overlay (mobile only) ─────────
   Full-screen modal shown after a wave clear. Three cards stacked
   vertically on portrait, side-by-side on landscape. Tap a card to
   claim that powerup and resume into the next wave. */
#wave-pick-overlay {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.88);
    z-index: 2000;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 16px;
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
    touch-action: none;
}

#wave-pick-panel {
    width: 100%;
    max-width: 520px;
    text-align: center;
}

.wave-pick-title {
    font-family: var(--font-body);
    font-size: calc(24px * var(--font-header-scale, 1));
    color: #ffd700;
    text-shadow: 0 0 8px rgba(255, 215, 0, 0.45);
    margin: 0 0 6px 0;
    letter-spacing: 2px;
}

.wave-pick-subtitle {
    font-family: var(--font-body);
    font-size: calc(13px * var(--font-body-scale, 1));
    color: #cfeaff;
    margin: 0 0 18px 0;
    letter-spacing: 1.5px;
}

#wave-pick-cards {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.wave-pick-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    background: rgba(10, 20, 40, 0.7);
    border: 2px solid rgba(140, 220, 255, 0.7);
    border-radius: 10px;
    color: #ffffff;
    font-family: monospace;
    cursor: pointer;
    text-align: left;
    transition: transform 0.08s ease, background 0.12s ease, border-color 0.12s ease;
}

.wave-pick-card:active {
    transform: scale(0.97);
    background: rgba(0, 80, 130, 0.75);
    border-color: #ffe5a0;
}

.wave-pick-card-icon {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 36px;
    color: var(--wp-color, #cccccc);
}

.wave-pick-card-icon svg {
    width: 100%;
    height: 100%;
}

.wave-pick-card-body {
    flex: 1;
    min-width: 0;
}

.wave-pick-card-name {
    font-family: var(--font-body);
    font-size: calc(13px * var(--font-body-scale, 1));
    color: var(--wp-color, #ffffff);
    margin-bottom: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wave-pick-card-desc {
    font-family: 'Silkscreen', monospace;
    font-size: calc(13px * var(--font-body-scale, 1));
    color: #b8c8e0;
    line-height: 1.25;
}

.wave-pick-card-stacks {
    flex: 0 0 auto;
    font-family: var(--font-body);
    font-size: calc(12px * var(--font-body-scale, 1));
    color: #88a8d4;
    white-space: nowrap;
}

/* R4 — in-run gold-sink actions (reroll / repair) under the cards. */
#wave-pick-actions {
    display: flex;
    gap: 12px;
    justify-content: center;
    margin-top: 14px;
}
.wave-pick-action-btn {
    font-family: var(--font-body);
    font-size: calc(12px * var(--font-body-scale, 1));
    padding: 9px 14px;
    cursor: pointer;
    color: #ffd75c;
    background: transparent;
    border: 1px solid rgba(255, 200, 60, 0.5);
}
.wave-pick-action-btn:hover:not(:disabled) { background: rgba(255, 200, 60, 0.15); }
.wave-pick-action-btn:disabled { color: #5e6680; border-color: rgba(94, 102, 128, 0.4); cursor: not-allowed; }

/* Portrait phone tightening — smaller card padding + icon so 3 cards
   plus title fit in a 640-px-tall viewport. */
body.mobile-portrait #wave-pick-panel {
    max-width: 100%;
}
body.mobile-portrait .wave-pick-title {
    font-size: calc(18px * var(--font-header-scale, 1));
}
body.mobile-portrait .wave-pick-subtitle {
    font-size: calc(12px * var(--font-body-scale, 1));
    margin-bottom: 12px;
}
body.mobile-portrait .wave-pick-card {
    padding: 10px 12px;
    gap: 10px;
}
body.mobile-portrait .wave-pick-card-icon {
    width: 28px;
    height: 28px;
    flex-basis: 28px;
}
body.mobile-portrait .wave-pick-card-name {
    font-size: calc(12px * var(--font-body-scale, 1));
}
body.mobile-portrait .wave-pick-card-desc {
    font-size: calc(13px * var(--font-body-scale, 1));
}
body.mobile-portrait .wave-pick-card-stacks {
    font-size: calc(12px * var(--font-body-scale, 1));
}

/* ─── 5.101.0 — Shop-suggest overlay ────────────────────────────────
   Fires after the survivor card claim. Three weapon-relevant upgrade
   buttons + a CONTINUE button to skip into the next wave. Visual
   language matches the wave-pick overlay (same fonts + card chrome)
   so the two screens read as a single ceremony. */
#shop-suggest-overlay {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.88);
    z-index: 2001;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 16px;
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
    touch-action: none;
}

#shop-suggest-panel {
    width: 100%;
    max-width: 520px;
    text-align: center;
}

#shop-suggest-gold-row {
    margin: 0 0 14px 0;
    font-family: var(--font-body);
    font-size: calc(14px * var(--font-body-scale, 1));
    color: #ffe27a;
    letter-spacing: 1.5px;
    text-shadow: 0 0 8px rgba(255, 226, 122, 0.55);
}

#shop-suggest-cards {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 16px;
}

.shop-suggest-skip {
    display: inline-block;
    padding: 12px 28px;
    background: rgba(10, 20, 40, 0.7);
    border: 2px solid rgba(140, 220, 255, 0.7);
    border-radius: 10px;
    color: #ffffff;
    font-family: var(--font-body);
    font-size: calc(13px * var(--font-body-scale, 1));
    letter-spacing: 2px;
    cursor: pointer;
    transition: transform 0.08s ease, background 0.12s ease, border-color 0.12s ease;
}
.shop-suggest-skip:active {
    transform: scale(0.97);
    background: rgba(0, 80, 130, 0.75);
    border-color: #ffe5a0;
}
.shop-suggest-skip:hover {
    background: rgba(20, 50, 90, 0.85);
    border-color: #ffe5a0;
}

body.mobile-portrait #shop-suggest-panel {
    max-width: 100%;
}
body.mobile-portrait #shop-suggest-gold-row {
    font-size: calc(13px * var(--font-body-scale, 1));
    margin-bottom: 10px;
}
body.mobile-portrait .shop-suggest-skip {
    font-size: calc(12px * var(--font-body-scale, 1));
    padding: 10px 22px;
}

/* ─── 5.99.0 — Mobile shop text scaling ────────────────────────────────
   The 5.79.57 per-weapon tab strip (10 tabs at 18-px Press Start 2P)
   overflows narrow phone viewports. Shrink the tab font + padding on
   mobile so all 10 fit, and tighten the SHOP title + currency badge so
   the shop header doesn't dominate the screen. Same intent as the
   pause-menu / Game Over scale-downs from 5.97. */
body.mobile-mode .shop-title {
    font-size: calc(22px * var(--font-header-scale, 1));
    margin: 8px 0 6px;
}
body.mobile-mode .shop-tab {
    font-size: calc(10px * var(--font-header-scale, 1));
    padding: 8px 8px;
    letter-spacing: 0.5px;
}
body.mobile-mode .shop-tabs {
    gap: 6px;
}
body.mobile-mode .shop-currency-row {
    font-size: calc(14px * var(--font-body-scale, 1));
}
body.mobile-mode .shop-item {
    padding: 10px 12px;
    gap: 10px;
    grid-template-columns: 40px 1fr auto;
}
body.mobile-mode .shop-item-icon {
    font-size: calc(22px * var(--font-body-scale, 1));
}
body.mobile-mode .shop-item-name {
    font-size: calc(13px * var(--font-body-scale, 1));
}
body.mobile-mode .shop-item-desc {
    font-size: calc(13px * var(--font-body-scale, 1));
    line-height: 1.3;
}
body.mobile-mode .shop-item-price {
    font-size: calc(13px * var(--font-body-scale, 1));
}
body.mobile-mode .shop-item-cost {
    min-width: 76px;
}

/* Portrait gets a further squeeze — 360-wide phones in portrait can't
   fit all 10 tabs at 10px without a horizontal scroll. The tab strip is
   already `flex-wrap` so we just tighten the font and let it wrap. */
body.mobile-portrait .shop-tab {
    font-size: calc(9px * var(--font-header-scale, 1));
    padding: 6px 6px;
}
body.mobile-portrait .shop-title {
    font-size: calc(18px * var(--font-header-scale, 1));
}
body.mobile-portrait .shop-item-name {
    font-size: calc(12px * var(--font-body-scale, 1));
}
body.mobile-portrait .shop-item-desc {
    font-size: calc(12px * var(--font-body-scale, 1));
}

/* ─── 5.100.1 — Mobile Controls tab chips ─────────────────────────
   The mobile renderer in ui-manager._renderMobileControlsTab uses a
   `.controls-mobile-chip` for each binding (rather than the WASD /
   mouse key tiles the desktop view uses). Chip = small icon + short
   description. Keep it readable on a narrow portrait phone. */
.controls-mobile-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    background: rgba(10, 22, 40, 0.55);
    border: 1px solid rgba(140, 200, 255, 0.45);
    border-radius: 6px;
    color: #cfeaff;
    font-family: var(--font-body);
    font-size: calc(13px * var(--font-body-scale, 1));
    line-height: 1.25;
    max-width: 100%;
}
.controls-mobile-chip-icon {
    font-size: calc(16px * var(--font-body-scale, 1));
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
}
.controls-mobile-chip-text {
    flex: 1 1 auto;
    word-break: break-word;
}
body.mobile-portrait .controls-mobile-chip {
    font-size: calc(12px * var(--font-body-scale, 1));
    padding: 5px 8px;
    gap: 6px;
}
body.mobile-portrait .controls-mobile-chip-icon {
    font-size: calc(14px * var(--font-body-scale, 1));
}

/* ─── 5.100.3 — Shop HELP panel mobile scale-down ─────────────────
   The HELP tab's long text blurbs (gold / SP / XP explanations) used
   Press Start 2P at 13-16 px, which overflowed phone viewports and
   produced ugly mid-word breaks. Cut roughly a third on mobile so
   the same content stays readable without a horizontal scroll. */
body.mobile-mode .shop-help {
    gap: 12px;
    padding: 12px 14px;
}
body.mobile-mode .shop-help-intro,
body.mobile-mode .shop-help-footer {
    font-size: calc(12px * var(--font-body-scale, 1));
    line-height: 1.6;
}
body.mobile-mode .shop-help-title {
    font-size: calc(12px * var(--font-header-scale, 1));
    letter-spacing: 0.5px;
}
body.mobile-mode .shop-help-body {
    font-size: calc(12px * var(--font-body-scale, 1));
    line-height: 1.6;
}
body.mobile-mode .shop-help-icon {
    /* Smaller currency badge so the gap to the text column tightens. */
    width: 32px;
    height: 32px;
    font-size: calc(13px * var(--font-body-scale, 1));
}
body.mobile-mode .shop-help-icon--picks {
    font-size: calc(12px * var(--font-body-scale, 1));
}

body.mobile-portrait .shop-help {
    gap: 10px;
    padding: 10px 12px;
}
body.mobile-portrait .shop-help-intro,
body.mobile-portrait .shop-help-footer {
    font-size: calc(12px * var(--font-body-scale, 1));
    line-height: 1.5;
}
body.mobile-portrait .shop-help-title {
    font-size: calc(10px * var(--font-header-scale, 1));
}
body.mobile-portrait .shop-help-body {
    font-size: calc(12px * var(--font-body-scale, 1));
    line-height: 1.5;
}
body.mobile-portrait .shop-help-icon {
    width: 26px;
    height: 26px;
    font-size: calc(12px * var(--font-body-scale, 1));
}

/* ──────────────────────────────────────────────────────────────────────
 * SHOP ABILITY TREE (Phase 7 — 2026-05-19)
 *
 * Diablo-style visual replacing the legacy tab + list layout. Four
 * cluster regions stacked vertically; within each cluster, weapon/ability
 * "parent" nodes have their upgrade nodes orbiting them in a ring. The
 * PASSIVES cluster uses a flat hex-style grid instead. No dependency
 * lines between nodes — every node is independently available.
 * ────────────────────────────────────────────────────────────────────── */

/* Base overlay swap — the ability-tree shop replaces the legacy list-
 * style layout, so override the old shop-menu sizing rules. */
.shop-menu--tree {
    position: relative;
    width: 100vw;
    height: 100vh;
    background:
        radial-gradient(ellipse at center top, rgba(40, 28, 60, 0.55) 0%, rgba(8, 8, 16, 0.92) 60%, rgba(0, 0, 0, 0.96) 100%),
        repeating-linear-gradient(
            45deg,
            rgba(255, 255, 255, 0.012) 0 2px,
            transparent 2px 6px
        );
    padding: 28px 36px;
    box-sizing: border-box;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 18px;
    font-family: var(--font-body);
    color: #e6e6e6;
}

/* Hide the legacy test-only stubs (kept in DOM for QA selector
 * back-compat). */
.shop-tree-legacy-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}

/* ── Header ───────────────────────────────────────────────────────── */
.shop-tree-header {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 24px;
    padding: 12px 24px 12px 80px; /* left padding leaves room for #shop-close-button */
    border-bottom: 1px solid rgba(200, 170, 100, 0.22);
}

.shop-tree-title {
    margin: 0;
    font-size: calc(22px * var(--font-header-scale, 1));
    color: #f0d090;
    letter-spacing: 4px;
    text-align: center;
    text-shadow: 0 0 12px rgba(240, 208, 144, 0.35);
}

.shop-tree-currency,
.shop-tree-wave {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-size: calc(16px * var(--font-body-scale, 1));
    line-height: 1;
}

.shop-tree-currency { justify-self: start; color: #ffd700; }
.shop-tree-wave     { justify-self: end;   color: #88ccff; }

.shop-tree-wave-label,
.shop-tree-currency-label {
    color: #888;
    font-size: calc(13px * var(--font-body-scale, 1));
    letter-spacing: 2px;
}

.shop-tree-currency-amount,
.shop-tree-wave-amount {
    font-size: calc(22px * var(--font-body-scale, 1));
    font-weight: bold;
    text-shadow: 0 0 8px currentColor;
}

/* Cores readout (right column, BUILD-only) — mirrors the gold currency. */
.shop-tree-cores {
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: calc(16px * var(--font-body-scale, 1));
    line-height: 1;
    color: #6fe9d0;
}
.shop-tree-cores-icon { font-size: calc(18px * var(--font-body-scale, 1)); text-shadow: 0 0 8px currentColor; }
.shop-tree-cores-amount {
    font-size: calc(22px * var(--font-body-scale, 1));
    font-weight: bold;
    text-shadow: 0 0 8px currentColor;
}

/* ── Tab strip (6.27.0) ───────────────────────────────────────────── */
.shop-tree-tabs {
    display: flex;
    justify-content: center;
    gap: 8px;
    padding: 4px 16px 0;
}

.shop-tree-tab {
    font-family: var(--font-body);
    font-size: calc(11px * var(--font-header-scale, 1));
    letter-spacing: 2px;
    color: #b0a070;
    background: rgba(20, 16, 30, 0.55);
    border: 1px solid rgba(200, 170, 100, 0.25);
    border-radius: 8px;
    padding: 12px 22px;
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.shop-tree-tab:hover {
    color: #f0d090;
    background: rgba(40, 30, 50, 0.7);
}

.shop-tree-tab.active {
    color: #ffe6a0;
    background: rgba(50, 38, 22, 0.9);
    border-color: #f0d090;
    box-shadow: 0 0 14px rgba(240, 208, 144, 0.3), inset 0 0 8px rgba(240, 208, 144, 0.15);
}

/* ── Tree body ────────────────────────────────────────────────────── */
/* 6.27.0 — Single active cluster (tab-gated). The tree is a flex column
 * that the active cluster fills; the other three clusters are hidden. */
.shop-tree {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    border: 1px solid rgba(200, 170, 100, 0.18);
    border-radius: 10px;
    background:
        linear-gradient(180deg, rgba(40, 30, 20, 0.45) 0%, rgba(20, 14, 10, 0.55) 100%);
    box-shadow:
        inset 0 0 24px rgba(0, 0, 0, 0.4),
        0 0 12px rgba(80, 60, 30, 0.25);
    overflow: hidden;
}

/* Only the cluster matching the tree's active tab is shown. */
.shop-tree-cluster { display: none; }
.shop-tree[data-active-tab="primary"] .shop-tree-cluster[data-tab="primary"],
.shop-tree[data-active-tab="power"]   .shop-tree-cluster[data-tab="power"],
.shop-tree[data-active-tab="defense"] .shop-tree-cluster[data-tab="defense"],
.shop-tree[data-active-tab="gear"]    .shop-tree-cluster[data-tab="gear"],
.shop-tree[data-active-tab="passive"] .shop-tree-cluster[data-tab="passive"],
.shop-tree[data-active-tab="passiveskills"] .shop-tree-cluster[data-tab="passiveskills"] {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

/* 6.158.3 — Weapon/ability rings laid out in a SINGLE column (one row per
   weapon/ability with its attunement/upgrade bubbles around it). The old
   2-column grid overlapped badly once a node had many orbiting bubbles. */
.shop-tree-cluster-body {
    display: grid;
    grid-template-columns: 1fr;
    justify-items: center;
    align-items: start;
    gap: 44px 0;
    flex: 1;
    min-height: 0;
    padding: 28px 16px;
    overflow-y: auto;
}

/* GEAR tab (pre-run BUILD only) — a single-column gear panel, not a ring grid. */
#shop-tree-gear {
    display: block;
    grid-template-columns: none;
    max-width: 820px;
    margin: 0 auto;
    text-align: left;
}
/* ── Pre-run BUILD footer (6.225.5) ─────────────────────────────────── */
/* Two tiers: a centered RUN SETUP card, then a BACK · status · START action
   bar. _applyPreRunChrome flips display to flex; the column direction + the
   rest of the layout live here. */
.shop-prerun-footer {
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
    width: 100%;
    box-sizing: border-box;
    padding: 16px 24px 6px;
    border-top: 1px solid rgba(120, 170, 230, 0.18);
}

/* Action bar — BACK left, readiness status centered, START right. */
.shop-prerun-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    width: 100%;
}

/* BUILD footer status line + equipped/locked node affordances. */
.shop-prerun-status {
    flex: 1;
    text-align: center;
    color: #bfe9ff;
    font-size: 0.85em;
    letter-spacing: 0.04em;
    transition: color 0.2s ease;
}
/* Readiness cues on the BUILD footer status line. */
.shop-prerun-status--warn  { color: #ffb454; text-shadow: 0 0 8px rgba(255, 180, 84, 0.4); }
.shop-prerun-status--ready { color: #8effa8; text-shadow: 0 0 8px rgba(142, 255, 168, 0.4); }

/* ── RUN SETUP control card (RUN-06) ────────────────────────────────── */
/* The run-shape picker: a labeled card with three vertical control groups
   (waves-per-stage · stages · difficulty) over a live readout. Reuses the
   menu-font var system + the armory blue. */
.shop-runsetup {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 11px;
    align-self: center;
    max-width: 100%;
    padding: 12px 22px 14px;
    border: 1px solid rgba(80, 140, 220, 0.28);
    border-radius: 10px;
    background: rgba(22, 38, 64, 0.32);
    font-family: inherit;
}
.shop-runsetup-title {
    color: #9cc4ec;
    font-family: var(--font-header);
    font-size: calc(11px * var(--font-header-scale, 1));
    letter-spacing: 0.2em;
    opacity: 0.9;
}
.shop-runsetup-groups {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    flex-wrap: wrap;
    gap: 16px;
}
.shop-runsetup-group {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
}
/* The row of buttons / stepper beneath a group's label. */
.shop-runsetup-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 6px;
}
/* Thin vertical rule between control groups. */
.shop-runsetup-divider {
    align-self: stretch;
    width: 1px;
    margin: 0 2px;
    background: linear-gradient(180deg, transparent, rgba(120, 170, 230, 0.35), transparent);
}
.shop-runsetup-label {
    display: flex;
    align-items: center;
    justify-content: center;
    /* Reserve two lines for every label so "WAVES PER STAGE" can wrap without
       knocking the button rows out of alignment with the single-line groups. */
    min-height: 2.4em;
    max-width: 9em;
    text-align: center;
    line-height: 1.2;
    color: #7fb6e6;
    font-size: calc(10px * var(--font-body-scale, 1));
    letter-spacing: 0.08em;
    opacity: 0.85;
}
.shop-runsetup-btn,
.shop-runsetup-step {
    padding: 5px 11px;
    cursor: pointer;
    font-family: inherit;
    font-size: calc(12px * var(--font-body-scale, 1));
    letter-spacing: 0.04em;
    border: 1px solid rgba(80, 140, 220, 0.5);
    border-radius: 4px;
    background: transparent;
    color: #8fd0ff;
    line-height: 1;
}
.shop-runsetup-step { padding: 5px 9px; min-width: 28px; }
.shop-runsetup-btn:hover:not(:disabled),
.shop-runsetup-step:hover:not(:disabled) { background: rgba(64, 150, 255, 0.15); }
.shop-runsetup-btn.active {
    color: #9affb0;
    border-color: rgba(120, 255, 150, 0.65);
    background: rgba(120, 255, 150, 0.12);
    text-shadow: 0 0 6px rgba(120, 255, 150, 0.4);
}
.shop-runsetup-step:disabled,
.shop-runsetup-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}
.shop-runsetup-value {
    min-width: 2.4em;
    text-align: center;
    color: #d8eeff;
    font-size: calc(13px * var(--font-body-scale, 1));
    letter-spacing: 0.04em;
}
.shop-runsetup-readout {
    color: #ffd98a;
    font-size: calc(12px * var(--font-body-scale, 1));
    letter-spacing: 0.05em;
    text-shadow: 0 0 6px rgba(255, 200, 100, 0.3);
    white-space: nowrap;
}
/* Disabled START (no primary equipped). */
.armory-btn--disabled,
.armory-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    filter: grayscale(0.5);
}
.shop-node--parent.shop-node--owned .shop-node-badge {
    background: #11bb88;
    color: #002211;
}
.shop-node--locked { opacity: 0.45; filter: grayscale(0.6); }

/* ── Weapon/ability subgroup (parent + orbiting upgrades) ──────────── */
.shop-tree-subgroup {
    --node-accent: #888;
    flex: 0 0 auto;
}

/* The ring container is the layout box for one parent + its orbiting
 * upgrade nodes. Children are absolute-positioned (transforms in JS)
 * relative to the ring's centre. */
.shop-tree-ring {
    position: relative;
    /* Width contains the widest orbit (radius 178 + a 56px bubble). */
    width: 400px;
    /* 6.225.3 — height tracks THIS ring's orbit radius (set inline as
       `--orbit-radius` by shop-dom) plus a constant 100px of padding for the
       bubble diameter + its label. Sizing the box to its content keeps the
       empty space around every cluster identical, so the vertical gap between
       consecutive weapons/abilities is uniform instead of varying with the
       bubble count. Falls back to the widest ring when unset. */
    height: calc(var(--orbit-radius, 178px) * 2 + 100px);
}

.shop-tree-ring > * {
    position: absolute;
    top: 50%;
    left: 50%;
}

/* The parent (weapon/ability) sits at the centre. JS doesn't translate
 * it, so a default centre transform applies. */
.shop-tree-ring > .shop-node--parent {
    transform: translate(-50%, -50%);
}

/* Decorative ring — purely visual, no dependency semantics. 6.225.3 — threads
   the orbiting bubbles (diameter == this ring's orbit) so it scales with the
   now content-sized box instead of sitting at a fixed 240px. */
.shop-tree-ring::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: calc(var(--orbit-radius, 120px) * 2);
    height: calc(var(--orbit-radius, 120px) * 2);
    transform: translate(-50%, -50%);
    border-radius: 50%;
    border: 1px dashed rgba(200, 170, 100, 0.18);
    pointer-events: none;
}

/* ── Passive cluster grid (no orbit) ─────────────────────────────── */
/* 6.27.0 — Span both columns of the cluster body so the passive hex
 * grid uses the full width instead of squeezing into one column. */
.shop-tree-passive-grid {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
    gap: 30px 22px;
    padding: 8px 20px;
    width: 100%;
}

.shop-tree-passive-grid > .shop-node {
    position: relative;
    margin: 0 auto;
}

/* 6.30.0 — Passive nodes are read-only (reward-only, not buyable). */
.shop-node--passive {
    cursor: default;
}

/* ── Node base ─────────────────────────────────────────────────────
 * A node is a 56px circle with an icon + cost label + name label
 * underneath. The border color drives the affordability state. */
.shop-node {
    --node-color: #999;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background:
        radial-gradient(circle at 30% 25%, rgba(255, 255, 255, 0.12) 0%, rgba(0, 0, 0, 0.35) 70%),
        rgba(20, 16, 30, 0.85);
    border: 3px solid var(--node-color);
    color: white;
    cursor: pointer;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    font-family: var(--font-body);
    transition: transform 0.15s ease, box-shadow 0.2s ease, border-color 0.2s ease, filter 0.2s ease;
    box-shadow:
        0 0 0 2px rgba(0, 0, 0, 0.6),
        0 0 14px color-mix(in srgb, var(--node-color) 35%, transparent);
    outline: none;
}

/* Icon centered inside the circle. */
.shop-node .shop-node-icon {
    line-height: 0;
    color: var(--node-color);
    filter: drop-shadow(0 0 4px color-mix(in srgb, var(--node-color) 60%, transparent));
}

/* Cost text — small label below the icon, inside the circle. */
.shop-node-cost {
    font-size: calc(11px * var(--font-body-scale, 1));
    color: #f8d670;
    margin-top: 2px;
    line-height: 1;
    letter-spacing: 0.5px;
}

/* Short name underneath the circle — wraps under, doesn't affect the
 * circle's hit area but is centered with it. */
.shop-node-label {
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    transform: translate(-50%, 0);
    font-size: calc(12px * var(--font-body-scale, 1));
    color: #c8c8c8;
    white-space: nowrap;
    max-width: 110px;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    letter-spacing: 1px;
}

/* Stack badge — small pill in the top-right corner. */
.shop-node-badge {
    position: absolute;
    top: -6px;
    right: -10px;
    background: #5cc8ff;
    color: #001020;
    font-size: calc(12px * var(--font-body-scale, 1));
    font-weight: bold;
    padding: 3px 6px;
    border-radius: 10px;
    line-height: 1;
    border: 1px solid rgba(0, 0, 0, 0.4);
    box-shadow: 0 0 6px rgba(92, 200, 255, 0.5);
    pointer-events: none;
}

/* Parent node — bigger, no buy state, weapon-tinted. Renders the
 * weapon icon at a larger size; sits at the cluster center. */
.shop-node--parent {
    width: 84px;
    height: 84px;
    border-width: 4px;
    cursor: default;
    background:
        radial-gradient(circle at 30% 25%, rgba(255, 255, 255, 0.15) 0%, rgba(0, 0, 0, 0.5) 75%),
        rgba(10, 8, 20, 0.95);
    box-shadow:
        0 0 0 2px rgba(0, 0, 0, 0.6),
        0 0 20px color-mix(in srgb, var(--node-color) 50%, transparent),
        inset 0 0 12px color-mix(in srgb, var(--node-color) 25%, transparent);
}

.shop-node--parent .shop-node-label {
    font-size: calc(12px * var(--font-body-scale, 1));
    color: var(--node-color);
    text-shadow: 0 0 8px color-mix(in srgb, var(--node-color) 50%, transparent);
    letter-spacing: 1.5px;
}

/* ── State variants ──────────────────────────────────────────────── */
.shop-node--unaffordable {
    --node-color: #555;
    filter: grayscale(0.6) brightness(0.7);
    /* 6.158.3 — locked (not-yet-unlocked) bubbles read as non-interactive:
       a not-allowed cursor instead of the clickable pointer they inherited. */
    cursor: not-allowed;
}
.shop-node--unaffordable .shop-node-cost { color: #ff8080; }
.shop-node--unaffordable .shop-node-icon { color: #888; filter: none; }

.shop-node--affordable {
    --node-color: #e0c060;
}
.shop-node--affordable .shop-node-cost { color: #ffe080; }

.shop-node--owned {
    --node-color: #5cc8ff;
}
.shop-node--owned .shop-node-cost { color: #aef0ff; }

.shop-node--maxed {
    --node-color: #a060e0;
    cursor: default;
}
.shop-node--maxed .shop-node-cost { color: #d8b8ff; font-weight: bold; }
.shop-node--maxed .shop-node-badge { background: #a060e0; color: white; box-shadow: 0 0 8px rgba(160, 96, 224, 0.55); }

.shop-node--locked {
    --node-color: #444;
    cursor: not-allowed;
    filter: grayscale(0.9) brightness(0.55);
}
.shop-node--locked .shop-node-cost { color: #555; font-size: calc(11px * var(--font-body-scale, 1)); }

/* Capstone (tier-2) rosette — adds an extra gold ring around the
 * node so mastery upgrades stand out before the player hovers. */
.shop-node--capstone {
    box-shadow:
        0 0 0 2px rgba(0, 0, 0, 0.6),
        0 0 0 4px rgba(240, 208, 144, 0.5),
        0 0 18px color-mix(in srgb, var(--node-color) 50%, transparent);
}

/* ── Interactions ────────────────────────────────────────────────── */
.shop-node--upgrade:not(:disabled):hover {
    transform: translate(-50%, -50%) scale(1.12);
    box-shadow:
        0 0 0 2px rgba(0, 0, 0, 0.6),
        0 0 22px color-mix(in srgb, var(--node-color) 75%, transparent);
    z-index: 2;
}

/* Passive grid nodes use a different transform origin (no orbit
 * translate) so the hover scale doesn't fight a half-translate. */
.shop-tree-passive-grid .shop-node--upgrade:not(:disabled):hover {
    transform: scale(1.12);
}

.shop-node--upgrade:not(:disabled):active {
    transform: translate(-50%, -50%) scale(1.04);
}
.shop-tree-passive-grid .shop-node--upgrade:not(:disabled):active {
    transform: scale(1.04);
}

.shop-node--upgrade:disabled {
    cursor: not-allowed;
}

/* ── Purchase flash animation ────────────────────────────────────── */
@keyframes shop-node-flash {
    0%   { box-shadow: 0 0 0 2px #fff8c0, 0 0 30px #ffd700; filter: brightness(1.8); }
    50%  { box-shadow: 0 0 0 2px #5cc8ff, 0 0 26px #5cc8ff; filter: brightness(1.3); }
    100% { box-shadow: 0 0 0 2px rgba(0,0,0,0.6), 0 0 14px color-mix(in srgb, var(--node-color) 35%, transparent); filter: brightness(1); }
}
.shop-node--flash {
    animation: shop-node-flash 0.55s ease-out 1;
}

/* ── Legend (6.27.0 — moved to top, reads as a key above the tabs) ── */
.shop-tree-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 24px;
    padding: 10px 16px 14px;
    border-bottom: 1px solid rgba(200, 170, 100, 0.18);
    font-size: calc(12px * var(--font-body-scale, 1));
    color: #aaa;
}

/* Pre-run BUILD instructions (one-line hint under the tab strip). */
.shop-prerun-hint {
    text-align: center;
    padding: 6px 16px 8px;
    font-size: calc(13px * var(--font-body-scale, 1));
    letter-spacing: 0.03em;
    color: #9fb3c8;
    opacity: 0.85;
}

.shop-tree-legend-entry {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.shop-tree-legend-swatch {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid #555;
    background: rgba(20, 16, 30, 0.85);
}

.shop-tree-legend-swatch--unaffordable { border-color: #555; }
.shop-tree-legend-swatch--affordable   { border-color: #e0c060; box-shadow: 0 0 6px rgba(224, 192, 96, 0.5); }
.shop-tree-legend-swatch--owned        { border-color: #5cc8ff; box-shadow: 0 0 6px rgba(92, 200, 255, 0.5); }
.shop-tree-legend-swatch--maxed        { border-color: #a060e0; box-shadow: 0 0 6px rgba(160, 96, 224, 0.5); }

.shop-tree-legend-label {
    letter-spacing: 1px;
}

/* ── Tooltip ─────────────────────────────────────────────────────── */
.shop-tree-tooltip {
    position: fixed;
    z-index: 1000;
    max-width: 280px;
    padding: 12px 14px;
    background: rgba(8, 8, 14, 0.96);
    border: 1px solid rgba(200, 170, 100, 0.55);
    border-radius: 8px;
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, 0.6),
        0 6px 24px rgba(0, 0, 0, 0.7),
        0 0 18px rgba(200, 170, 100, 0.18);
    pointer-events: none;
    font-family: var(--font-body);
    color: #e6e6e6;
}

.shop-tree-tooltip-name {
    font-size: calc(14px * var(--font-body-scale, 1));
    color: #f0d090;
    margin-bottom: 8px;
    letter-spacing: 1px;
}

.shop-tree-tooltip-desc {
    font-size: calc(12px * var(--font-body-scale, 1));
    color: #cccccc;
    line-height: 1.6;
    margin-bottom: 10px;
}

.shop-tree-tooltip-lock {
    font-size: calc(12px * var(--font-body-scale, 1));
    color: #ff9070;
    margin-bottom: 8px;
    line-height: 1.4;
}

.shop-tree-tooltip-meta {
    display: flex;
    gap: 16px;
    padding-top: 8px;
    border-top: 1px solid rgba(200, 170, 100, 0.2);
}

.shop-tree-tooltip-meta-cell {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.shop-tree-tooltip-meta-label {
    font-size: calc(11px * var(--font-body-scale, 1));
    color: #888;
    letter-spacing: 1.5px;
}

.shop-tree-tooltip-meta-value {
    font-size: calc(13px * var(--font-body-scale, 1));
    color: #ffd700;
    font-weight: bold;
}

.shop-tree-tooltip-sellhint {
    font-size: calc(11px * var(--font-body-scale, 1));
    color: #888;
    letter-spacing: 1px;
    margin-top: 8px;
    text-transform: uppercase;
}

/* ── Responsive — narrow viewports ───────────────────────────────── */
@media (max-width: 1100px) {
    /* 6.158.3 — single column is now the base; narrower viewports just get a
       slightly smaller ring so it fits the panel width. Height stays
       content-driven (see the base rule's --orbit-radius calc). */
    .shop-tree-ring {
        width: 340px;
    }
}

@media (max-width: 720px) {
    .shop-menu--tree {
        padding: 16px;
    }
    .shop-tree-header {
        padding-left: 60px;
        gap: 12px;
    }
    .shop-tree-title { font-size: 16px; letter-spacing: 2px; }
    .shop-tree-currency-amount { font-size: 16px; }
    /* 6.27.0 — single column + compact tabs on phones. */
    .shop-tree-tab { font-size: 9px; padding: 9px 12px; letter-spacing: 1px; }
    .shop-tree-cluster-body { grid-template-columns: 1fr; gap: 22px 30px; padding: 12px 4px; }
    .shop-tree-ring {
        width: 260px;
    }
    .shop-node {
        width: 48px;
        height: 48px;
        border-width: 2px;
    }
    .shop-node--parent {
        width: 64px;
        height: 64px;
    }
    .shop-node-label {
        font-size: 8px;
        max-width: 90px;
    }
}

/* ─── 6.28.0 — TUTORIAL OVERLAY ──────────────────────────────────────── */
#tutorial-overlay {
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.85);
    z-index: 2000;
    display: none;
    justify-content: center;
    align-items: center;
    padding: 16px;
    box-sizing: border-box;
}

.tutorial-panel {
    position: relative;
    width: 100%;
    max-width: 720px;
    max-height: 86vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background:
        radial-gradient(ellipse at center top, rgba(40, 28, 60, 0.6) 0%, rgba(8, 8, 16, 0.95) 60%, rgba(0, 0, 0, 0.97) 100%);
    border: 1px solid rgba(200, 170, 100, 0.3);
    border-radius: 12px;
    padding: 28px 32px 32px;
    box-sizing: border-box;
    font-family: var(--font-body);
    color: #e6e6e6;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6), 0 8px 40px rgba(0, 0, 0, 0.7);
}

.tutorial-title {
    margin: 0 0 20px;
    font-size: calc(20px * var(--font-header-scale, 1));
    letter-spacing: 4px;
    color: #f0d090;
    text-align: center;
    text-shadow: 0 0 12px rgba(240, 208, 144, 0.35);
}

.tutorial-section { margin-bottom: 22px; }

.tutorial-section-title {
    margin: 0 0 10px;
    font-size: calc(13px * var(--font-header-scale, 1));
    letter-spacing: 2px;
    color: #88ccff;
    border-bottom: 1px solid rgba(120, 180, 220, 0.25);
    padding-bottom: 6px;
}

.tutorial-line {
    font-size: calc(13px * var(--font-body-scale, 1));
    line-height: 1.7;
    color: #cfcfcf;
    margin-bottom: 4px;
}

@media (max-width: 720px) {
    .tutorial-panel { padding: 18px 16px 22px; max-height: 90vh; }
    .tutorial-title { font-size: 15px; letter-spacing: 2px; }
    .tutorial-section-title { font-size: 11px; }
    .tutorial-line { font-size: 9px; line-height: 1.6; }
}

/* ─── ARMORY (Phase R2 — pre-run unlock store) ───────────────────────── */
.armory-overlay {
    position: fixed;
    inset: 0;
    display: none;            /* toggled to flex by ArmoryOverlay.open() */
    align-items: center;
    justify-content: center;
    background: radial-gradient(circle at 50% 40%, rgba(10, 16, 28, 0.97) 0%, rgba(4, 6, 12, 0.99) 100%);
    z-index: 9500;
    font-family: var(--font-body);
    color: #d6def0;
}
.armory-panel {
    width: min(820px, 94vw);
    max-height: 90vh;
    background: linear-gradient(180deg, rgba(14, 20, 30, 0.98) 0%, rgba(8, 11, 18, 0.98) 100%);
    border: 2px solid #2f6fc2;
    box-shadow: 0 0 28px rgba(64, 150, 255, 0.28), inset 0 0 70px rgba(0, 30, 80, 0.4);
    padding: 20px 24px 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.armory-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(80, 140, 220, 0.35);
}
.armory-title {
    font-size: calc(24px * var(--font-header-scale, 1));
    letter-spacing: 3px;
    color: #8fd0ff;
    text-shadow: 0 0 12px rgba(64, 150, 255, 0.5);
}
.armory-header > .armory-cores { margin-left: auto; }
.armory-gold {
    font-size: calc(16px * var(--font-body-scale, 1));
    color: #ffd75c;
    text-shadow: 0 0 10px rgba(255, 200, 60, 0.5);
    margin-left: 14px;
}
.armory-cores {
    font-size: calc(16px * var(--font-body-scale, 1));
    color: #7fe0ff;
    text-shadow: 0 0 10px rgba(90, 200, 255, 0.5);
}
.armory-sub { font-size: calc(12px * var(--font-body-scale, 1)); line-height: 1.7; color: #7d8aa6; }
.armory-body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    overflow-y: auto;
    padding-right: 4px;
    flex: 1;
}
.armory-section-title {
    font-size: calc(11px * var(--font-header-scale, 1));
    color: #8fd0ff;
    letter-spacing: 1px;
    margin-bottom: 6px;
}
.armory-list { display: flex; flex-direction: column; gap: 5px; }
.armory-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 7px 10px;
    background: rgba(20, 30, 48, 0.6);
    border: 1px solid rgba(80, 140, 220, 0.25);
}
.armory-row--owned { opacity: 0.55; }
.armory-row-name { font-size: calc(12px * var(--font-body-scale, 1)); color: #d6def0; }
.armory-row-tag { font-size: calc(11px * var(--font-body-scale, 1)); color: #6fae6f; letter-spacing: 1px; }
.armory-buy {
    background: transparent;
    color: #ffd75c;
    border: 1px solid rgba(255, 200, 60, 0.5);
    padding: 6px 10px;
    cursor: pointer;
    font-size: calc(12px * var(--font-body-scale, 1));
    font-family: inherit;
    white-space: nowrap;
}
.armory-buy:hover:not(:disabled) { background: rgba(255, 200, 60, 0.15); }
.armory-buy:disabled { color: #5e6680; border-color: rgba(94, 102, 128, 0.4); cursor: not-allowed; }
.armory-row-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
/* R5 — selected loadout pick (green like the START button). */
.loadout-pick--on {
    color: #9affb0;
    border-color: rgba(120, 255, 150, 0.7);
    background: rgba(120, 255, 150, 0.12);
}
.loadout-pick--on:hover:not(:disabled) { background: rgba(120, 255, 150, 0.2); }
.armory-footer {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding-top: 10px;
    border-top: 1px solid rgba(80, 140, 220, 0.3);
}
.armory-btn {
    padding: 10px 20px;
    cursor: pointer;
    font-size: calc(13px * var(--font-body-scale, 1));
    font-family: inherit;
    letter-spacing: 1px;
    border: 1px solid rgba(80, 140, 220, 0.55);
    background: transparent;
    color: #8fd0ff;
}
.armory-btn--back:hover { background: rgba(64, 150, 255, 0.15); }
.armory-btn--start {
    color: #9affb0;
    border-color: rgba(120, 255, 150, 0.6);
    text-shadow: 0 0 8px rgba(120, 255, 150, 0.4);
}
.armory-btn--start:hover { background: rgba(120, 255, 150, 0.15); }

/* ── HANGAR — cosmetic ship-skin selector (6.157.0) ────────────────── */
.hangar-overlay {
    position: fixed;
    inset: 0;
    display: none;            /* toggled to flex by HangarOverlay.open() */
    align-items: center;
    justify-content: center;
    background: radial-gradient(circle at 50% 40%, rgba(10, 16, 28, 0.97) 0%, rgba(4, 6, 12, 0.99) 100%);
    z-index: 9500;
    font-family: var(--font-body);
    color: #d6def0;
}
.hangar-panel {
    width: min(900px, 95vw);
    max-height: 92vh;
    background: linear-gradient(180deg, rgba(14, 20, 30, 0.98) 0%, rgba(8, 11, 18, 0.98) 100%);
    border: 2px solid #2f6fc2;
    box-shadow: 0 0 28px rgba(64, 150, 255, 0.28), inset 0 0 70px rgba(0, 30, 80, 0.4);
    padding: 20px 24px 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.hangar-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(80, 140, 220, 0.35);
}
.hangar-title {
    font-size: calc(24px * var(--font-header-scale, 1));
    letter-spacing: 3px;
    color: #8fd0ff;
    text-shadow: 0 0 12px rgba(64, 150, 255, 0.5);
}
.hangar-skin-name {
    font-size: calc(14px * var(--font-body-scale, 1));
    color: #ffd75c;
    text-shadow: 0 0 10px rgba(255, 200, 60, 0.4);
    letter-spacing: 1px;
}
.hangar-sub { font-size: calc(12px * var(--font-body-scale, 1)); line-height: 1.7; color: #7d8aa6; }
.hangar-body {
    display: flex;
    gap: 18px;
    overflow: hidden;
    flex: 1;
    min-height: 0;
}
.hangar-preview {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
}
.hangar-preview-canvas {
    border: 1px solid rgba(80, 140, 220, 0.4);
    background: #05070e;
    box-shadow: inset 0 0 30px rgba(0, 30, 80, 0.5);
}
.hangar-desc {
    font-size: calc(12px * var(--font-body-scale, 1));
    line-height: 1.6;
    color: #9fb0cc;
    width: 300px;
    text-align: center;
}
.hangar-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 10px;
    overflow-y: auto;
    align-content: start;
    flex: 1;
    padding-right: 4px;
}
.hangar-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 8px 4px;
    background: rgba(20, 30, 48, 0.6);
    border: 1px solid rgba(80, 140, 220, 0.25);
    cursor: pointer;
    font-family: inherit;
    color: #c6d2e8;
    transition: border-color 0.12s, background 0.12s;
}
.hangar-card:hover { border-color: rgba(140, 220, 255, 0.7); background: rgba(30, 50, 80, 0.6); }
.hangar-card--selected {
    border-color: rgba(120, 255, 150, 0.8);
    background: rgba(40, 80, 60, 0.45);
    box-shadow: 0 0 12px rgba(120, 255, 150, 0.25);
}
.hangar-thumb { background: #05070e; }
.hangar-card-name { font-size: calc(11px * var(--font-body-scale, 1)); letter-spacing: 0.5px; text-align: center; }
.hangar-card--selected .hangar-card-name { color: #9affb0; }
.hangar-footer {
    display: flex;
    justify-content: flex-start;
    padding-top: 10px;
    border-top: 1px solid rgba(80, 140, 220, 0.3);
}
.hangar-btn {
    padding: 10px 20px;
    cursor: pointer;
    font-size: calc(13px * var(--font-body-scale, 1));
    font-family: inherit;
    letter-spacing: 1px;
    border: 1px solid rgba(80, 140, 220, 0.55);
    background: transparent;
    color: #8fd0ff;
}
.hangar-btn--back:hover { background: rgba(64, 150, 255, 0.15); }
@media (max-width: 720px) {
    .hangar-body { flex-direction: column; overflow-y: auto; }
    .hangar-desc { width: auto; }
}

/* ── Font system (6.158.0) ─────────────────────────────────────────────
   Header override: titles + tabs use --font-header; everything else
   inherits --font-body from <body>. Placed last so it wins source-order
   ties against the per-component rules above. */
h1, h2, h3,
.pause-tab, .shop-tab, .shop-tree-tab, .powerups-subtab,
.controls-section-title,
.shop-title, .wave-pick-title,
.armory-title, .armory-section-title,
.hangar-title,
.settings-title, .settings-section-title {
    font-family: var(--font-header);
}

/* ── SETTINGS overlay + DISPLAY (font) controls ───────────────────────── */
.settings-overlay {
    position: fixed;
    inset: 0;
    display: none;            /* toggled to flex by SettingsOverlay.open() */
    align-items: center;
    justify-content: center;
    background: radial-gradient(circle at 50% 40%, rgba(10, 16, 28, 0.97) 0%, rgba(4, 6, 12, 0.99) 100%);
    z-index: 9500;
    font-family: var(--font-body);
    color: #d6def0;
}
.settings-panel {
    width: min(560px, 94vw);
    max-height: 90vh;
    overflow-y: auto;
    background: linear-gradient(180deg, rgba(14, 20, 30, 0.98) 0%, rgba(8, 11, 18, 0.98) 100%);
    border: 2px solid #2f6fc2;
    box-shadow: 0 0 28px rgba(64, 150, 255, 0.28), inset 0 0 70px rgba(0, 30, 80, 0.4);
    padding: 22px 26px 18px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.settings-title {
    font-size: calc(22px * var(--font-header-scale, 1));
    letter-spacing: 3px;
    color: #8fd0ff;
    text-shadow: 0 0 12px rgba(64, 150, 255, 0.5);
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(80, 140, 220, 0.35);
}
/* Reused both as a standalone overlay body and inside the pause DISPLAY tab. */
.font-controls { display: flex; flex-direction: column; gap: 16px; }
.font-field { display: flex; flex-direction: column; gap: 6px; }
.font-field-label { font-size: calc(12px * var(--font-body-scale, 1)); letter-spacing: 1px; color: #8fd0ff; }
.font-select {
    font-family: var(--font-body);
    font-size: calc(14px * var(--font-body-scale, 1));
    color: #e6eefc;
    background: rgba(20, 30, 48, 0.85);
    border: 1px solid rgba(80, 140, 220, 0.45);
    padding: 9px 10px;
    cursor: pointer;
    width: 100%;
}
.font-select:focus { outline: none; border-color: rgba(140, 220, 255, 0.8); }
.font-preview {
    margin-top: 2px;
    padding: 14px 16px;
    background: #05070e;
    border: 1px solid rgba(80, 140, 220, 0.35);
    line-height: 1.5;
}
.font-preview-header { font-family: var(--font-header); font-size: calc(16px * var(--font-header-scale, 1)); color: #ffd75c; margin-bottom: 8px; }
.font-preview-body   { font-family: var(--font-body);   font-size: calc(14px * var(--font-body-scale, 1)); color: #c6d2e8; }
.font-settings-footer {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding-top: 6px;
}
.font-btn {
    padding: 9px 18px;
    cursor: pointer;
    font-size: calc(13px * var(--font-body-scale, 1));
    font-family: var(--font-body);
    letter-spacing: 1px;
    border: 1px solid rgba(80, 140, 220, 0.55);
    background: transparent;
    color: #8fd0ff;
}
.font-btn:hover { background: rgba(64, 150, 255, 0.15); }
.font-btn--reset { color: #c6a0ff; border-color: rgba(170, 120, 255, 0.5); }
/* 6.158.2 — header/body font-size sliders */
.font-size-row { display: flex; justify-content: space-between; align-items: baseline; }
.font-size-pct { color: #ffd75c; }
.font-size-slider { width: 100%; margin-top: 2px; accent-color: #8fd0ff; cursor: pointer; }
