/* ============================================================================
   FONTS — self-hosted, no network dependency.
   Staatliches (SIL OFL 1.1) and Special Elite (Apache 2.0) both permit
   redistribution; see assets/fonts/LICENSE.txt. Subsets are the unmodified
   Google Fonts latin / latin-ext slices.
   ========================================================================== */
@font-face {
  font-family: 'Staatliches';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/staatliches-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Staatliches';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/staatliches-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Special Elite';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/special-elite-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Special Elite';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/special-elite-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============================================================================
   DER KOLOSS — front-end design system
   One type scale, one spacing scale, one colour system.
   Palette: cold moonlight blue · warm sodium orange · red alert.
   All motion is transform/opacity only.
   ========================================================================== */

:root {
  /* ---- colour: cold moonlight ---- */
  --void:        #04060b;
  --ink:         #070a10;
  --steel-900:   #0a0e15;
  --steel-800:   #0e131c;
  --steel-700:   #141b26;
  --steel-600:   #1c2531;
  --moon:        #b9cbe0;
  --moon-dim:    #7d90a6;
  --moon-faint:  #4d5b6d;
  --moon-ghost:  #333e4c;

  /* ---- colour: warm sodium + bone ---- */
  --bone:        #ece6d6;
  --bone-dim:    #a9a292;
  --sodium:      #ffb454;
  --sodium-deep: #c47a2a;
  --sodium-soft: rgba(255, 180, 84, 0.16);

  /* ---- colour: alert / states ---- */
  --alert:       #e0453a;
  --alert-deep:  #8e1e1c;
  --alert-soft:  rgba(224, 69, 58, 0.16);
  --ready:       #5fd08a;
  --ready-soft:  rgba(95, 208, 138, 0.14);

  /* ---- surfaces & edges ---- */
  --surface-0:   rgba(7, 10, 16, 0.94);
  --surface-1:   rgba(13, 18, 26, 0.88);
  --surface-2:   rgba(20, 27, 38, 0.62);
  --surface-3:   rgba(28, 37, 50, 0.5);
  --edge:        rgba(150, 178, 210, 0.14);
  --edge-soft:   rgba(150, 178, 210, 0.07);
  --edge-strong: rgba(178, 206, 236, 0.3);

  /* legacy aliases still referenced by older rules */
  --red:   #b3242a;
  --dim:   var(--moon-dim);
  --panel: var(--surface-0);
  --line:  var(--edge);

  /* ---- type ---- */
  --f-display: 'Staatliches', 'Oswald', 'Haettenschweiler', 'Arial Narrow', Impact, sans-serif;
  --f-mono:    'Special Elite', 'Courier New', ui-monospace, SFMono-Regular, monospace;
  --f-ui:      'Arial Narrow', Arial, Helvetica, sans-serif;

  --t-3xs: 10px;
  --t-2xs: 11px;
  --t-xs:  12px;
  --t-sm:  13px;
  --t-md:  15px;
  --t-lg:  17px;
  --t-xl:  20px;
  --t-2xl: 26px;
  --t-3xl: 34px;
  --t-4xl: 46px;

  --track-tight: 1px;
  --track:       2px;
  --track-wide:  4px;
  --track-max:   8px;

  /* ---- space ---- */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px;

  /* ---- motion ---- */
  --ease-out:  cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft: cubic-bezier(0.33, 1, 0.68, 1);
  --ease-io:   cubic-bezier(0.65, 0, 0.35, 1);
  --dur-1: 110ms;
  --dur-2: 190ms;
  --dur-3: 320ms;
  --dur-4: 520ms;
  --dur-5: 780ms;

  /* ---- elevation ---- */
  --lift-1: 0 2px 10px rgba(0, 0, 0, 0.5);
  --lift-2: 0 14px 40px rgba(0, 0, 0, 0.55);
  --lift-3: 0 30px 90px rgba(0, 0, 0, 0.72);

  --radius: 3px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; background: var(--void); }
body {
  font-family: var(--f-ui);
  color: var(--bone);
  user-select: none;
  -webkit-user-select: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
#game-canvas { position: fixed; inset: 0; width: 100%; height: 100%; display: block; cursor: crosshair; }
.hidden { display: none !important; }

/* focus: invisible for the mouse, unmissable for the keyboard */
:focus { outline: none; }
:focus-visible { outline: none; }
body.kbd-nav :focus-visible {
  outline: 2px solid var(--sodium);
  outline-offset: 2px;
  border-radius: 2px;
}
body.kbd-nav .mbtn:focus-visible { outline-offset: 1px; }

/* shared kicker / label / section-head vocabulary ------------------------- */
.panel-kicker, .lbl, .brief-kicker, .section-head span,
.load-kicker, .char-section-head, .char-voice-head, .squad-kicker {
  font-family: var(--f-mono);
  font-size: var(--t-2xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--moon-faint);
}
.panel-kicker { display: block; margin-bottom: var(--s-2); color: var(--sodium-deep); }
.section-head {
  display: flex; align-items: center; gap: var(--s-3);
  margin: var(--s-5) 0 var(--s-3);
  text-align: left;
}
.section-head span { flex: 0 0 auto; color: var(--moon-dim); }
.section-head::after, .section-head .section-rule {
  content: ''; flex: 1 1 auto; height: 1px;
  background: linear-gradient(90deg, var(--edge), transparent);
}
.section-head .section-rule { display: none; }

/* ============================================================================
   SCREEN LAYER + TRANSITIONS
   ========================================================================== */
.screen {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  animation: screenIn var(--dur-3) var(--ease-out) both;
}
@keyframes screenIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* the content inside a screen arrives a beat after the wash */
.screen > .panel,
.screen > .pause-shell,
.screen > .menu-inner,
.screen > .load-inner {
  animation: contentIn var(--dur-4) var(--ease-out) both;
  animation-delay: 60ms;
}
@keyframes contentIn {
  from { opacity: 0; transform: translate3d(0, 14px, 0) scale(0.988); }
  to   { opacity: 1; transform: none; }
}

/* Static scrim only. The blur is computed once on the frozen frame — never
   animated — so a live match never pays for a per-frame full-screen filter.
   The alpha floor is set high enough that a blown-out daylight courtyard and
   an unlit interior both resolve to the same readable backdrop under
   the renderer's auto-exposure. */
/* Sub-screens keep the menu's atmosphere instead of dropping to flat black.
   Static gradients only — no per-frame work, no filters. */
#lobby, #options, #charselect, #charpage, #cheats, #join-modal, #solo-fs-modal {
  background:
    radial-gradient(ellipse at 50% 118%, rgba(140, 60, 16, 0.14), transparent 56%),
    radial-gradient(ellipse at 22% -12%, rgba(40, 62, 96, 0.2), transparent 60%),
    linear-gradient(180deg, #03050a 0%, #06090f 55%, #0a0907 100%);
}
#lobby::before, #options::before, #charselect::before, #charpage::before,
#cheats::before, #join-modal::before, #solo-fs-modal::before {
  content: '';
  position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(ellipse at 50% 46%, transparent 30%, rgba(0, 0, 0, 0.5) 76%, rgba(0, 0, 0, 0.88) 100%);
}
#lobby > *, #options > *, #charselect > *, #charpage > *,
#cheats > *, #join-modal > *, #solo-fs-modal > * { position: relative; z-index: 1; }
/* options can be opened over a frozen match — let a hint of it through */
#options { background-color: rgba(3, 5, 10, 0.92); }

.overlay-dark {
  background:
    linear-gradient(180deg, rgba(2, 3, 6, 0.6), rgba(2, 3, 6, 0.6)),
    radial-gradient(ellipse at 50% 45%, rgba(6, 9, 15, 0.55), rgba(2, 3, 6, 0.9) 80%);
  backdrop-filter: blur(10px) saturate(0.6) brightness(0.5);
  -webkit-backdrop-filter: blur(10px) saturate(0.6) brightness(0.5);
}

/* ============================================================================
   BUTTONS
   ========================================================================== */
.mbtn {
  position: relative;
  font-family: var(--f-mono);
  font-size: var(--t-md);
  font-weight: 400;
  letter-spacing: var(--track);
  text-transform: uppercase;
  text-align: center;
  padding: 13px 22px;
  min-height: 44px;
  color: var(--bone-dim);
  background: linear-gradient(180deg, var(--surface-2), var(--surface-1));
  border: 1px solid var(--edge);
  border-left: 2px solid var(--edge);
  border-radius: var(--radius);
  cursor: pointer;
  overflow: hidden;
  transform: translateZ(0);
  transition:
    color var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    background-color var(--dur-2) var(--ease-out),
    transform var(--dur-1) var(--ease-out),
    opacity var(--dur-2);
}
.mbtn::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(100deg, var(--sodium-soft), transparent 62%);
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease-out);
  pointer-events: none;
}
.mbtn:hover:not(:disabled) { color: var(--bone); border-color: var(--edge-strong); }
.mbtn:hover:not(:disabled)::after { opacity: 1; }
.mbtn.is-pressed:not(:disabled) { transform: scale(0.975); }
.mbtn:disabled { opacity: 0.32; cursor: not-allowed; }

.mbtn.primary {
  color: var(--bone);
  border-color: rgba(255, 180, 84, 0.34);
  border-left-color: var(--sodium);
  background: linear-gradient(180deg, rgba(255, 180, 84, 0.13), var(--surface-1));
}
.mbtn.primary:hover:not(:disabled) {
  color: #fff6e6;
  border-color: rgba(255, 180, 84, 0.6);
  border-left-color: var(--sodium);
}
.mbtn.danger { color: rgba(224, 140, 132, 0.82); border-left-color: rgba(224, 69, 58, 0.45); }
.mbtn.danger:hover:not(:disabled) { color: #ffd9d4; border-color: rgba(224, 69, 58, 0.6); }
.mbtn.danger::after { background: linear-gradient(100deg, var(--alert-soft), transparent 62%); }
.mbtn.ready { color: var(--ready); border-left-color: var(--ready); }
.mbtn.small { font-size: var(--t-xs); letter-spacing: var(--track-tight); padding: 9px 14px; min-height: 36px; }

.row-buttons { display: flex; gap: var(--s-3); justify-content: center; margin-top: var(--s-5); flex-wrap: wrap; }
.row-buttons.col { flex-direction: column; align-items: stretch; flex-wrap: nowrap; }

/* ============================================================================
   PANELS
   ========================================================================== */
.panel {
  position: relative;
  background:
    linear-gradient(180deg, rgba(30, 40, 55, 0.28), transparent 34%),
    var(--surface-0);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  padding: var(--s-6) var(--s-7) var(--s-6);
  min-width: 380px;
  max-width: min(96vw, 1180px);
  max-height: 92vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  text-align: center;
  box-shadow: var(--lift-3), inset 0 1px 0 rgba(180, 208, 236, 0.06);
}
.panel::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--sodium-deep) 22%, var(--sodium) 50%, var(--sodium-deep) 78%, transparent);
  opacity: 0.5;
  pointer-events: none;
}
.panel.wide { min-width: 560px; width: min(1080px, 94vw); }
.panel h2 {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--t-3xl);
  letter-spacing: var(--track-max);
  line-height: 1;
  color: var(--bone);
  margin-bottom: var(--s-4);
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.8);
}
.panel .dim { color: var(--moon-dim); font-size: var(--t-sm); line-height: 1.6; letter-spacing: 0.4px; }
.panel .panel-lead { max-width: 62ch; margin: 0 auto; }
.panel .small-note { font-size: var(--t-xs); margin-top: var(--s-4); }

/* panel scrollbars, so a tall options list still reads intentional */
.panel::-webkit-scrollbar, .wpn-list::-webkit-scrollbar { width: 8px; }
.panel::-webkit-scrollbar-track, .wpn-list::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.3); }
.panel::-webkit-scrollbar-thumb, .wpn-list::-webkit-scrollbar-thumb { background: var(--moon-ghost); border-radius: 4px; }
.panel::-webkit-scrollbar-thumb:hover, .wpn-list::-webkit-scrollbar-thumb:hover { background: var(--moon-faint); }

/* form controls, one look everywhere -------------------------------------- */
input[type='text'], input[type='number'], input:not([type]), select, textarea {
  font-family: var(--f-mono);
  font-size: var(--t-sm);
  letter-spacing: var(--track-tight);
  color: var(--bone);
  background: rgba(4, 6, 11, 0.7);
  border: 1px solid var(--edge);
  border-radius: 2px;
  padding: 9px 11px;
  transition: border-color var(--dur-2) var(--ease-out), background-color var(--dur-2);
}
input:hover:not(:disabled), select:hover:not(:disabled) { border-color: var(--edge-strong); }
input:focus, select:focus { border-color: var(--sodium); background: rgba(6, 9, 15, 0.85); }
select { cursor: pointer; }
input:disabled, select:disabled { opacity: 0.5; cursor: not-allowed; }

/* ============================================================================
   MAIN MENU
   ========================================================================== */
/* The menu is laid out from AVAILABLE HEIGHT first. Every vertical dimension is
   a clamp whose preferred term is min(vw-term, vh-term), so a wide-but-short
   window compresses exactly like a narrow one. The corner gutters are reserved
   as padding, so the title can never reach the file-number header. Overflow
   scrolls as a last resort rather than clipping. */
#menu {
  --gutter-y: clamp(38px, 5vh, 68px);
  --gutter-x: clamp(20px, 3.4vw, 72px);
  --menu-rhythm: clamp(8px, 1.8vh, 22px);
  background:
    radial-gradient(ellipse at 50% 118%, rgba(140, 60, 16, 0.2), transparent 58%),
    radial-gradient(ellipse at 18% -10%, rgba(40, 62, 96, 0.28), transparent 62%),
    linear-gradient(180deg, #03050a 0%, #060910 52%, #0b0a08 100%);
  align-items: center;
  justify-content: center;
  padding: var(--gutter-y) var(--gutter-x);
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* fixed, so the safety-net scroll never drags the scene with it */
.menu-scene { position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
.scene-sky {
  position: absolute; inset: 0;
  background:
    radial-gradient(circle at 74% 12%, rgba(176, 202, 232, 0.14), transparent 34%),
    radial-gradient(ellipse at 50% 96%, rgba(196, 122, 42, 0.16), transparent 55%);
  animation: skyBreathe 19s var(--ease-io) infinite alternate;
}
@keyframes skyBreathe { from { opacity: 0.72; } to { opacity: 1; } }

/* two slow searchlights raking the cloud deck */
.scene-beam {
  position: absolute; bottom: 18%; left: 62%;
  width: 30vw; height: 130vh;
  transform-origin: 50% 100%;
  background: linear-gradient(180deg, transparent, rgba(150, 180, 214, 0.05) 58%, rgba(180, 206, 236, 0.11));
  clip-path: polygon(47% 100%, 53% 100%, 92% 0, 8% 0);
  filter: blur(24px);
  opacity: 0.55;
  will-change: transform;
}
.scene-beam.b1 { animation: beamSweepA 34s var(--ease-io) infinite alternate; }
.scene-beam.b2 { left: 84%; width: 22vw; opacity: 0.3; animation: beamSweepB 47s var(--ease-io) infinite alternate; }
@keyframes beamSweepA { from { transform: translateX(-50%) rotate(-19deg); } to { transform: translateX(-50%) rotate(15deg); } }
@keyframes beamSweepB { from { transform: translateX(-50%) rotate(12deg); } to { transform: translateX(-50%) rotate(-14deg); } }

/* The ridge and skyline are EXTERIOR scene layers from when the menu backdrop
   was a painted night horizon. The backdrop is now a real video plate shot
   INSIDE the machine hall, so a hillside and a city silhouette on top of it
   read as unexplained black polygons and a stray wire across the lower third.
   Hidden rather than deleted: the markup and the rest of the parallax stack
   (beams, fog, grain, scratch, vignette) still layer over the plate correctly,
   and these two come straight back if the backdrop ever returns to an
   exterior. */
.scene-ridge, #skyline { display: none; }

.scene-ridge {
  position: absolute; left: -4%; right: -4%; bottom: 0; height: 26vh;
  background: linear-gradient(180deg, transparent, rgba(2, 3, 6, 0.9) 46%, #020306);
  clip-path: polygon(0 62%, 7% 48%, 14% 57%, 22% 34%, 31% 51%, 39% 40%, 48% 58%, 57% 37%, 66% 52%, 74% 43%, 83% 60%, 91% 46%, 100% 58%, 100% 100%, 0 100%);
  animation: ridgeDrift 60s var(--ease-io) infinite alternate;
  will-change: transform;
}
@keyframes ridgeDrift { from { transform: translate3d(-1.2%, 0, 0); } to { transform: translate3d(1.2%, 0, 0); } }

#skyline { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 38vh; opacity: 0.75; }
#skyline .win { animation: winFlicker 3.7s infinite steps(1); }
#skyline .win.d2 { animation-delay: 1.3s; }
#skyline .win.d3 { animation-delay: 2.4s; }
@keyframes winFlicker { 0%, 88% { opacity: 0.9; } 90%, 94% { opacity: 0.15; } 96%, 100% { opacity: 0.9; } }

.fog-layer {
  position: absolute; left: -20%; right: -20%; height: 44vh; bottom: -6vh; pointer-events: none;
  background:
    radial-gradient(ellipse at 30% 100%, rgba(96, 122, 158, 0.13), transparent 62%),
    radial-gradient(ellipse at 72% 100%, rgba(120, 108, 92, 0.1), transparent 60%);
  animation: fogDrift 26s linear infinite alternate;
  will-change: transform;
}
.fog-layer.f2 { animation-duration: 37s; animation-direction: alternate-reverse; opacity: 0.6; }
@keyframes fogDrift { from { transform: translate3d(-6%, 0, 0); } to { transform: translate3d(6%, 0, 0); } }

/* drifting ash — two parallax planes, one element each */
.scene-dust {
  position: absolute; inset: -30% -10%;
  background-image:
    radial-gradient(circle, rgba(226, 214, 190, 0.5) 0.6px, transparent 1.1px),
    radial-gradient(circle, rgba(184, 202, 224, 0.34) 0.5px, transparent 1px);
  background-size: 190px 190px, 117px 117px;
  background-position: 0 0, 60px 40px;
  opacity: 0.35;
  will-change: transform;
}
.scene-dust.d1 { animation: dustA 58s linear infinite; }
.scene-dust.d2 { opacity: 0.2; background-size: 260px 260px, 143px 143px; animation: dustB 92s linear infinite; }
@keyframes dustA { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-190px, 190px, 0); } }
@keyframes dustB { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(143px, 143px, 0); } }

#film-grain {
  position: absolute; inset: -120px; pointer-events: none; opacity: 0.075; z-index: 3;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grainJit 0.55s infinite steps(1);
  will-change: transform;
}
@keyframes grainJit {
  0% { transform: translate3d(0, 0, 0); } 20% { transform: translate3d(-38px, 22px, 0); }
  40% { transform: translate3d(24px, -41px, 0); } 60% { transform: translate3d(-19px, -28px, 0); }
  80% { transform: translate3d(41px, 14px, 0); } 100% { transform: translate3d(0, 0, 0); }
}
#film-scratch {
  position: absolute; inset: 0; pointer-events: none; z-index: 3; opacity: 0.4;
  background:
    linear-gradient(90deg, transparent 0, transparent calc(22% - 1px), rgba(220, 215, 200, 0.11) 22%, transparent calc(22% + 1px)),
    linear-gradient(90deg, transparent 0, transparent calc(71% - 1px), rgba(220, 215, 200, 0.08) 71%, transparent calc(71% + 1px));
  animation: scratchMove 9s infinite steps(1);
}
@keyframes scratchMove {
  0%, 100% { background-position: 0 0, 0 0; opacity: 0.4; }
  20% { background-position: 14px 0, -8px 0; opacity: 0.16; }
  38% { background-position: -10px 0, 12px 0; opacity: 0.45; }
  55% { background-position: 6px 0, -14px 0; opacity: 0.12; }
  76% { background-position: -16px 0, 6px 0; opacity: 0.4; }
}
#menu-vignette {
  position: absolute; inset: 0; pointer-events: none; z-index: 3;
  background:
    linear-gradient(90deg, rgba(2, 3, 6, 0.9) 0%, rgba(2, 3, 6, 0.72) 24%, rgba(2, 3, 6, 0.1) 52%, transparent 68%),
    linear-gradient(0deg, rgba(2, 3, 6, 0.78), transparent 34%),
    radial-gradient(ellipse at 46% 44%, transparent 32%, rgba(0, 0, 0, 0.42) 72%, rgba(0, 0, 0, 0.88) 100%);
}

.menu-corner {
  position: absolute; z-index: 6;
  font-family: var(--f-mono);
  color: rgba(150, 168, 192, 0.34);
  font-size: var(--t-xs);
  letter-spacing: var(--track-wide);
  pointer-events: none;
  animation: cornerIn var(--dur-5) var(--ease-out) both;
}
@keyframes cornerIn { from { opacity: 0; } to { opacity: 1; } }
.menu-corner.tl { top: 24px; left: 28px; animation-delay: 420ms; }
.menu-corner.tr { top: 24px; right: 28px; animation-delay: 500ms; }
.menu-corner.br { bottom: 22px; right: 28px; animation-delay: 580ms; }
.menu-corner.tl::before {
  content: ''; position: absolute; left: -10px; top: -9px; width: 14px; height: 14px;
  border-top: 1px solid rgba(255, 180, 84, 0.4); border-left: 1px solid rgba(255, 180, 84, 0.4);
}

.menu-inner {
  position: relative; z-index: 5;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 330px);
  align-items: center;
  gap: clamp(28px, 5vw, 88px);
  width: min(1320px, 100%);
  max-width: 100%;
  text-align: left;
}
/* The title is sized from ITS OWN COLUMN, not the viewport — that is the only
   way it can never outgrow the space beside the field manual and wrap. */
.menu-lead { min-width: 0; container-type: inline-size; }

/* ---- title block ---- */
.title-block { position: relative; display: block; max-width: 100%; padding-right: 56px; }
/* the eyebrow strikes like a cold fluorescent tube finding its arc — once,
   on entry, then it holds. Same rise as its siblings, different ignition. */
.title-top {
  font-family: var(--f-mono);
  font-size: clamp(9px, min(0.95vw, 1.5vh), 13px);
  letter-spacing: clamp(2px, 0.6vw, 6px);
  color: var(--moon-faint);
  text-shadow: 0 0 14px rgba(140, 178, 224, 0.16);
  margin-bottom: var(--menu-rhythm);
  animation: eyebrowStrike 900ms var(--ease-out) 80ms both;
}
@keyframes eyebrowStrike {
  0%   { opacity: 0;    transform: translate3d(0, 10px, 0); }
  18%  { opacity: 0.9;  transform: translate3d(0, 5px, 0); }
  24%  { opacity: 0.08; }
  32%  { opacity: 0.95; }
  38%  { opacity: 0.2; }
  52%  { opacity: 1;    transform: none; }
  100% { opacity: 1;    transform: none; }
}
@keyframes riseIn {
  from { opacity: 0; transform: translate3d(0, 10px, 0); }
  to   { opacity: 1; transform: none; }
}
/* THE HERO ------------------------------------------------------------------
   Read the wordmark as plate steel with the letters cut clean out of it and
   the hall's reactor burning behind the cut. That gives two things:

     · a continuous churn of light INSIDE the glyphs (the reactor, always on)
     · a surge every 11s — bloom swells, an arc strikes along the cut, the
       image misregisters for four frames, then the afterglow decays

   The surge is one authored event on one clock, so the tear always has a
   visible cause. Deliberately NOT a diagonal white band travelling across
   the text — that is a skeleton-loader, not a title.
   Everything is background-position / opacity / transform. No JS. */
#menu h1 {
  position: relative;
  isolation: isolate;
  font-family: var(--f-display);
  font-size: clamp(38px, min(7.6vw, 12vh), 132px);
  font-weight: 400;
  letter-spacing: 0.18em;
  text-indent: 0.18em;
  line-height: 0.92;
  white-space: nowrap;
  color: transparent;
  background:
    /* a broad, low-contrast reflection of the hall drifting down the plate.
       Wide and soft on purpose — a narrow band would read as a shine sweep. */
    linear-gradient(186deg,
      transparent 2%,
      rgba(206, 228, 255, 0.17) 30%,
      rgba(255, 238, 206, 0.12) 58%,
      transparent 92%),
    /* the plate itself */
    linear-gradient(178deg, #f6f2e8 2%, #96a3b4 21%, #e6e0d0 42%, #6f7a88 61%, #cfc5ae 80%, #5b6270 100%);
  background-size: 100% 230%, auto;
  background-position: 50% 16%, 0 0;
  background-repeat: no-repeat;
  -webkit-background-clip: text; background-clip: text;
  filter: drop-shadow(0 0 30px rgba(255, 150, 60, 0.24)) drop-shadow(0 6px 6px rgba(0, 0, 0, 0.9));
  animation:
    titleIn var(--dur-5) var(--ease-out) 120ms both,
    titleDrift 19s var(--ease-io) infinite,
    titleJitter 7.3s steps(1) 2s infinite;
}
/* the signal is never quite stable — sub-pixel at rest, ~1px at full size,
   two frames at a time. You register it without being able to point at it. */
@keyframes titleJitter {
  0%, 40%  { transform: none; }
  40.4%    { transform: translate3d(0.006em, 0, 0); }
  40.9%    { transform: translate3d(-0.004em, 0, 0); }
  41.3%    { transform: none; }
  100%     { transform: none; }
}
@keyframes titleIn {
  from { opacity: 0; transform: translate3d(0, 18px, 0) scale(0.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes titleDrift {
  0%   { background-position: 50% 16%, 0 0; }
  50%  { background-position: 50% 80%, 0 0; }
  100% { background-position: 50% 16%, 0 0; }
}
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  #menu h1 { color: var(--bone); background: none; animation: titleIn var(--dur-5) var(--ease-out) 120ms both; }
}

/* ---- the overlays ----------------------------------------------------------
   Three aria-hidden spans that re-draw the wordmark. inset:0 plus the
   inherited tracking / indent / nowrap makes them register exactly on top of
   the real glyphs, so nothing has to be kept in sync by hand.
   They blend with `screen` so the light ADDS to the steel instead of painting
   over it — that difference is most of why this reads as emission. */
.title-glow, .title-plasma, .title-tear { position: absolute; inset: 0; pointer-events: none; }
.title-glow::before,
.title-plasma::before,
.title-plasma::after,
.title-tear::before,
.title-tear::after {
  content: attr(data-text);
  position: absolute; inset: 0;
  display: block;
}

/* 1 · BLOOM — a blurred copy behind the plate so the wordmark throws light
   into the scene. One long eased breath, symmetric, zero-velocity at both
   turning points: it must never arrive anywhere, or it reads as a flash. */
.title-glow { z-index: -1; }
.title-glow::before {
  color: #6fd2ff;
  filter: blur(0.075em);
  mix-blend-mode: screen;
  opacity: 0.18;
  animation: titleBreath 8.6s var(--ease-io) infinite;
}
@keyframes titleBreath {
  0%, 100% { opacity: 0.14; transform: scale(1); }
  50%      { opacity: 0.33; transform: scale(1.007); }
}

/* 2 · THE REACTOR — fractal noise crushed to hot cores and composited inside
   the glyphs, morphing continuously. Noise rather than gradients because a
   soft gradient this size just averages into a flat tint on bright metal;
   noise keeps enough high-frequency detail to actually read as churn. */
.title-plasma::before {
  color: #fff;
  filter: url(#fx-title-plasma);
  mix-blend-mode: screen;
  opacity: 0.28;
  animation: plasmaBreath 13.4s var(--ease-io) infinite;
}
@keyframes plasmaBreath {
  0%, 100% { opacity: 0.2; }
  50%      { opacity: 0.36; }
}

/* 3 · CRACKLE — sparks worrying at the edges of the letters, always on. The
   seed steps discretely (~7/s) so it snaps between states like an arc rather
   than sliding like a gradient, and the swell keeps it from reading as static. */
.title-plasma::after {
  color: #eafaff;
  filter: url(#fx-title-crackle);
  mix-blend-mode: screen;
  opacity: 0.3;
  animation: crackleSwell 6.7s var(--ease-io) infinite;
}
@keyframes crackleSwell {
  0%, 100% { opacity: 0.1; }
  28%      { opacity: 0.4; }
  55%      { opacity: 0.16; }
  76%      { opacity: 0.34; }
}

/* 4 · MICRO-GLITCH — always on, never announced. Two chroma copies each flash
   a thin band for ~50ms, on coprime periods (3.7s / 5.3s) so the pattern never
   lands twice the same way. steps(1) keeps every band a hard cut; interpolating
   would make the slices slide like a wipe. Offsets are in em so the
   displacement stays proportional at every clamp step. */
.title-tear::before { color: rgba(150, 226, 255, 0.55); opacity: 0; animation: microTearA 3.7s steps(1) 1.4s infinite; }
.title-tear::after  { color: rgba(255, 176, 84, 0.45);  opacity: 0; animation: microTearB 5.3s steps(1) 2.9s infinite; }
@keyframes microTearA {
  0%, 22%     { opacity: 0;    transform: none;                     clip-path: inset(0 0 100% 0); }
  22.6%       { opacity: 0.5;  transform: translate3d(-0.022em,0,0); clip-path: inset(28% 0 60% 0); }
  24%         { opacity: 0;    transform: none;                     clip-path: inset(0 0 100% 0); }
  67%         { opacity: 0; }
  67.5%       { opacity: 0.42; transform: translate3d(0.016em,0,0);  clip-path: inset(58% 0 32% 0); }
  68.6%       { opacity: 0;    transform: none;                     clip-path: inset(0 0 100% 0); }
  100%        { opacity: 0; }
}
@keyframes microTearB {
  0%, 41%     { opacity: 0;    transform: none;                     clip-path: inset(0 0 100% 0); }
  41.5%       { opacity: 0.4;  transform: translate3d(0.019em,0,0);  clip-path: inset(12% 0 74% 0); }
  42.7%       { opacity: 0;    transform: none;                     clip-path: inset(0 0 100% 0); }
  84%         { opacity: 0; }
  84.4%       { opacity: 0.34; transform: translate3d(-0.014em,0,0); clip-path: inset(70% 0 18% 0); }
  85.3%       { opacity: 0;    transform: none;                     clip-path: inset(0 0 100% 0); }
  100%        { opacity: 0; }
}
/* "DER KOLOSS" measures ~6.4em wide at this tracking, so 13cqw leaves headroom
   for the fallback face too. The vh term still governs short windows. */
@supports (container-type: inline-size) {
  #menu h1 { font-size: clamp(38px, min(13cqw, 12vh), 168px); }
}
.title-rule {
  display: flex; align-items: center; gap: var(--s-3);
  margin: var(--menu-rhythm) 0 calc(var(--menu-rhythm) * 0.5);
  max-width: 460px;
  animation: riseIn var(--dur-4) var(--ease-out) both; animation-delay: 220ms;
}
.title-rule span { flex: 1; height: 1px; background: linear-gradient(90deg, rgba(190, 182, 158, 0.55), transparent); }
.title-rule span:last-of-type { background: linear-gradient(90deg, transparent, rgba(190, 182, 158, 0.28)); }
/* the ◆ shares the SOLO marker's heartbeat — one pulse rate across the screen */
.title-rule em {
  color: var(--sodium-deep); font-style: normal; font-size: var(--t-2xs);
  animation: idleBreath 4.6s var(--ease-io) infinite;
}
.title-sub {
  position: relative; z-index: 0; display: inline-block; padding: 4px 12px;
  letter-spacing: clamp(3px, 0.85vw, 9px); color: transparent;
  font-size: clamp(12px, min(1.35vw, 2.1vh), 20px); font-weight: 700; font-family: var(--f-mono);
  background: linear-gradient(180deg, #fffaf0 0%, #d8d0bf 34%, #f2ead8 53%, #aaa18f 72%, #ded3bc 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-stroke: .35px rgba(255, 248, 232, .7);
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, .98)) drop-shadow(0 0 7px rgba(240, 224, 192, .24));
  animation: riseIn var(--dur-4) var(--ease-out) 280ms both;
}
.title-sub::before {
  content: ''; position: absolute; z-index: -1; left: -8%; right: -8%; top: 50%; height: 34px;
  transform: translateY(-50%) rotate(-1deg);
  opacity: .7; filter: blur(.3px); pointer-events: none;
  background:
    radial-gradient(circle at 8% 62%, #7d1118 0 3px, transparent 4px),
    radial-gradient(circle at 91% 32%, #8f141b 0 2px, transparent 3px),
    radial-gradient(ellipse at 50% 52%, rgba(135, 18, 25, .9), rgba(96, 13, 18, .6) 45%, transparent 73%);
  clip-path: polygon(0 43%, 8% 33%, 16% 44%, 26% 25%, 39% 39%, 49% 18%, 61% 38%, 72% 29%, 84% 45%, 100% 34%, 97% 68%, 83% 58%, 69% 78%, 56% 61%, 42% 82%, 28% 63%, 12% 73%, 2% 62%);
}
.stamp {
  position: absolute; top: -8px; right: -14px; transform: rotate(11deg);
  font-family: var(--f-display); font-size: var(--t-2xl); letter-spacing: 5px;
  color: rgba(196, 58, 61, 0.5); border: 3px double rgba(196, 58, 61, 0.5); border-radius: 4px;
  padding: 4px 12px 2px; pointer-events: none;
  animation: stampIn 520ms var(--ease-out) both; animation-delay: 640ms;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='60'%3E%3Cfilter id='w'%3E%3CfeTurbulence baseFrequency='0.25' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.85 0.15'/%3E%3C/filter%3E%3Crect width='120' height='60' filter='url(%23w)'/%3E%3C/svg%3E");
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='60'%3E%3Cfilter id='w'%3E%3CfeTurbulence baseFrequency='0.25' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.85 0.15'/%3E%3C/filter%3E%3Crect width='120' height='60' filter='url(%23w)'/%3E%3C/svg%3E");
}
@keyframes stampIn {
  from { opacity: 0; transform: rotate(11deg) scale(1.6); }
  60%  { opacity: 1; transform: rotate(11deg) scale(0.96); }
  to   { opacity: 1; transform: rotate(11deg) scale(1); }
}

/* ---- menu list ---- */
.menu-buttons {
  display: flex; flex-direction: column; gap: clamp(0px, 0.25vh, 3px);
  margin-top: clamp(14px, 3.6vh, 46px);
  width: min(520px, 100%);
  border-left: 1px solid var(--edge-soft);
}
.menu-link { display: block; text-decoration: none; }
.menu-more-wrap { position: relative; }
.menu-more-wrap > .mbtn { width: 100%; }

#menu .menu-buttons .mbtn {
  display: flex; align-items: center;
  width: 100%;
  min-height: clamp(34px, 5.2vh, 48px);
  padding: clamp(5px, 0.9vh, 12px) 18px clamp(5px, 0.9vh, 12px) clamp(46px, 4.4vw, 62px);
  font-size: clamp(14px, min(1.5vw, 2.45vh), 21px);
  letter-spacing: clamp(2px, 0.4vw, 4px);
  text-align: left;
  color: #a3b1c2;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.9);
  /* the wash is always mounted at zero width, so hover floods it in from the
     selection rail instead of cross-fading a flat block of colour in place */
  background-color: transparent;
  background-image: linear-gradient(90deg, rgba(255, 180, 84, 0.15), rgba(255, 180, 84, 0.035) 44%, transparent 72%);
  background-repeat: no-repeat;
  background-size: 0% 100%;
  border: 0;
  border-radius: 0;
  box-shadow: inset 2px 0 0 transparent;
  transition:
    color var(--dur-2) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out),
    background-size var(--dur-3) var(--ease-out),
    transform var(--dur-2) var(--ease-out);
  animation: menuItemIn 460ms var(--ease-out) both;
}
@keyframes menuItemIn {
  from { opacity: 0; transform: translate3d(-14px, 0, 0); }
  to   { opacity: 1; transform: none; }
}
.menu-buttons > *:nth-child(1) .mbtn, .menu-buttons > .mbtn:nth-child(1) { animation-delay: 300ms; }
.menu-buttons > *:nth-child(2) .mbtn, .menu-buttons > .mbtn:nth-child(2) { animation-delay: 355ms; }
.menu-buttons > *:nth-child(3) .mbtn, .menu-buttons > .mbtn:nth-child(3) { animation-delay: 410ms; }
.menu-buttons > *:nth-child(4) .mbtn, .menu-buttons > .mbtn:nth-child(4) { animation-delay: 465ms; }
.menu-buttons > *:nth-child(5) .mbtn, .menu-buttons > .mbtn:nth-child(5) { animation-delay: 520ms; }
.menu-buttons > *:nth-child(6) .mbtn, .menu-buttons > .mbtn:nth-child(6) { animation-delay: 575ms; }
.menu-buttons > *:nth-child(7) .mbtn, .menu-buttons > .mbtn:nth-child(7) { animation-delay: 630ms; }

/* index number doubles as the selection marker */
#menu .menu-buttons .mbtn::before {
  content: attr(data-idx);
  position: absolute; left: clamp(14px, 1.5vw, 22px); top: 50%;
  transform: translateY(-50%);
  font-size: var(--t-2xs);
  letter-spacing: 1px;
  color: var(--moon-ghost);
  transition: color var(--dur-2) var(--ease-out), text-shadow var(--dur-2) var(--ease-out);
}
/* contextual hint, revealed only on intent */
#menu .menu-buttons .mbtn::after {
  content: attr(data-hint);
  position: absolute; inset: auto 20px auto auto; top: 50%;
  transform: translate3d(-10px, -50%, 0);
  font-size: var(--t-2xs);
  letter-spacing: var(--track);
  color: var(--sodium-deep);
  background: none;
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
#menu .menu-buttons .mbtn:hover:not(:disabled),
#menu .menu-buttons .mbtn:focus-visible {
  color: var(--bone);
  box-shadow: inset 2px 0 0 var(--sodium);
  transform: translate3d(6px, 0, 0);
  background-size: 100% 100%;
}
#menu .menu-buttons .mbtn:hover:not(:disabled)::before,
#menu .menu-buttons .mbtn:focus-visible::before {
  color: var(--sodium);
  text-shadow: 0 0 10px rgba(255, 180, 84, 0.65);
}
#menu .menu-buttons .mbtn:hover:not(:disabled)::after,
#menu .menu-buttons .mbtn:focus-visible::after { opacity: 1; transform: translate3d(0, -50%, 0); }
#menu .menu-buttons .mbtn.is-pressed { transform: translate3d(6px, 0, 0) scale(0.985); }
/* idle state: the default action keeps a resting selection rail and a
   slow ember glow on its index — nothing else in the list moves. */
#menu .menu-buttons .mbtn.primary {
  color: var(--bone);
  box-shadow: inset 2px 0 0 var(--sodium);
  /* layer 1 is the shared hover wash (still zero-width at rest), layer 2 is
     the resting glow that marks the default action */
  background-image:
    linear-gradient(90deg, rgba(255, 180, 84, 0.15), rgba(255, 180, 84, 0.035) 44%, transparent 72%),
    linear-gradient(90deg, rgba(255, 180, 84, 0.06), transparent 48%);
  background-size: 0% 100%, 100% 100%;
}
#menu .menu-buttons .mbtn.primary::before { color: var(--sodium); animation: idleBreath 4.6s var(--ease-io) infinite; }
@keyframes idleBreath { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }

.menu-more-links {
  position: absolute; z-index: 8; top: 0; left: calc(100% + 14px);
  display: grid; gap: 2px; width: 300px; padding: var(--s-2);
  border: 1px solid var(--edge);
  border-left: 2px solid var(--sodium-deep);
  background: var(--surface-0);
  box-shadow: var(--lift-2);
  animation: subIn 220ms var(--ease-out) both;
}
@keyframes subIn { from { opacity: 0; transform: translate3d(-8px, 0, 0); } to { opacity: 1; transform: none; } }
#menu .menu-buttons .menu-sub-link {
  min-height: 38px; font-size: var(--t-sm); letter-spacing: var(--track); padding: 8px 12px 8px 40px;
  animation: none;
}
#menu .menu-buttons .menu-sub-link::before { left: 14px; }
#menu .menu-buttons .menu-sub-link::after { content: none; }

/* ---- field manual / credits column ----------------------------------------
   Reference material, not primary content. It is height-capped and its own
   scroll container, so expanding the full legend can never change the height
   of the page — the menu actions are always the thing that fits first. */
.menu-brief {
  align-self: center;
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: min(68vh, 620px);
  padding: clamp(12px, 2vh, 24px) clamp(14px, 1.4vw, 24px);
  border: 1px solid var(--edge-soft);
  border-top: 1px solid var(--edge);
  background: linear-gradient(180deg, rgba(20, 27, 38, 0.5), rgba(7, 10, 16, 0.66));
  box-shadow: var(--lift-2);
  animation: riseIn var(--dur-5) var(--ease-out) both; animation-delay: 560ms;
}
.brief-head {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3); margin-bottom: clamp(8px, 1.4vh, 16px);
}
.brief-kicker { color: var(--sodium-deep); }
.brief-toggle {
  flex: 0 0 auto;
  padding: 4px 9px;
  font-family: var(--f-mono);
  font-size: var(--t-3xs);
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--moon-dim);
  background: rgba(120, 150, 186, 0.07);
  border: 1px solid var(--edge);
  border-radius: 2px;
  cursor: pointer;
  transition: color var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out);
}
.brief-toggle:hover { color: var(--bone); border-color: var(--edge-strong); }
.brief-toggle::after { content: ' +'; color: var(--sodium-deep); }
.menu-brief.open .brief-toggle::after { content: ' −'; }
.brief-rule { flex: 0 0 auto; height: 1px; margin: clamp(8px, 1.4vh, 16px) 0; background: linear-gradient(90deg, var(--edge), transparent); }
.menu-help {
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(4px, 0.7vh, 8px) var(--s-3);
  font-family: var(--f-mono);
  font-size: var(--t-2xs);
  letter-spacing: 0.5px;
  color: var(--moon-faint);
}
/* Collapsed: only the six essentials — one source of truth in the markup, no
   duplicated legend. The height queries below trim this further. */
.menu-brief:not(.open) .menu-help > .kp:nth-child(n + 7) { display: none; }
.menu-help .kp { display: flex; align-items: center; gap: 6px; min-width: 0; white-space: nowrap; }
.menu-help b {
  flex: 0 0 auto;
  display: inline-block;
  min-width: 22px;
  padding: 2px 6px;
  font-weight: 400;
  font-size: var(--t-3xs);
  color: var(--moon);
  background: rgba(120, 150, 186, 0.09);
  border: 1px solid var(--edge);
  border-bottom-width: 2px;
  border-radius: 3px;
  text-align: center;
}
.menu-foot {
  flex: 0 0 auto;
  font-family: var(--f-mono);
  font-size: var(--t-3xs);
  line-height: 1.75;
  letter-spacing: 0.4px;
  color: rgba(125, 144, 166, 0.6);
}
.menu-credit-link { color: var(--bone-dim); text-decoration-color: var(--sodium-deep); text-decoration-thickness: 1px; text-underline-offset: 3px; }
.menu-credit-link:hover { color: var(--sodium); }

/* ============================================================================
   LOADING
   ========================================================================== */
.load-inner { text-align: center; width: min(520px, 84vw); }
.load-kicker { display: block; margin-bottom: var(--s-3); color: var(--sodium-deep); animation: kickerBreath 2.8s var(--ease-io) infinite; }
@keyframes kickerBreath { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
.load-title {
  font-family: var(--f-display); font-size: var(--t-4xl); letter-spacing: 14px;
  color: var(--bone); text-shadow: 0 0 40px rgba(255, 150, 60, 0.3), 0 4px 4px #000;
  margin-bottom: var(--s-5);
}
.load-bar-wrap {
  position: relative; height: 3px; overflow: hidden;
  background: rgba(150, 178, 210, 0.12);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
}
#load-bar {
  height: 100%; width: 0;
  background: linear-gradient(90deg, var(--sodium-deep), var(--sodium));
  box-shadow: 0 0 12px rgba(255, 180, 84, 0.6);
  transition: width var(--dur-3) var(--ease-soft);
}
.load-bar-scan {
  position: absolute; inset: 0; width: 30%;
  background: linear-gradient(90deg, transparent, rgba(255, 220, 170, 0.5), transparent);
  transform: translate3d(-100%, 0, 0);
  animation: loadScan 1.6s var(--ease-io) infinite;
}
@keyframes loadScan { from { transform: translate3d(-120%, 0, 0); } to { transform: translate3d(440%, 0, 0); } }
.load-meta { display: flex; align-items: center; justify-content: center; gap: var(--s-2); margin-top: var(--s-4); }
.load-hint { color: var(--moon-faint); font-family: var(--f-mono); font-size: var(--t-sm); letter-spacing: var(--track); }
.load-dots { display: flex; gap: 4px; }
.load-dots i { width: 3px; height: 3px; background: var(--sodium-deep); border-radius: 50%; animation: loadDot 1.1s var(--ease-io) infinite; }
.load-dots i:nth-child(2) { animation-delay: 0.15s; }
.load-dots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes loadDot { 0%, 100% { opacity: 0.25; transform: translate3d(0, 0, 0); } 50% { opacity: 1; transform: translate3d(0, -3px, 0); } }

/* ============================================================================
   LOBBY
   ========================================================================== */
.lobby-panel { text-align: left; width: min(920px, 94vw); }
.lobby-head {
  display: flex; align-items: stretch; justify-content: space-between;
  gap: var(--s-7); flex-wrap: wrap;
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--edge-soft);
}
.lobby-head > div:first-child { align-self: flex-end; padding-bottom: 2px; }
.lobby-head h2 { margin-bottom: 0; }
.lobby-code-row {
  display: flex; align-items: center; gap: var(--s-5); flex-wrap: wrap;
  flex: 1 1 560px; justify-content: flex-end;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--edge-soft);
  border-left: 2px solid var(--sodium-deep);
  border-radius: 2px;
  background: linear-gradient(100deg, rgba(255, 180, 84, 0.05), transparent 60%);
}
.lobby-code-block { flex: 0 0 auto; }
.lobby-code-row .lbl { display: block; margin-bottom: 4px; text-align: left; }
#lobby-code {
  position: relative;
  font-family: var(--f-display);
  font-size: 44px; font-weight: 400; letter-spacing: 11px; line-height: 1;
  color: var(--sodium);
  text-shadow: 0 0 26px rgba(255, 180, 84, 0.32);
  text-align: left;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: color var(--dur-1), transform var(--dur-1) var(--ease-out);
}
#lobby-code::after {
  content: 'CLICK TO COPY';
  position: absolute; left: 2px; bottom: -13px;
  font-family: var(--f-mono); font-size: var(--t-3xs); letter-spacing: 1.5px;
  color: var(--moon-ghost);
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease-out);
}
#lobby-code:hover { color: #ffd6a0; }
#lobby-code:hover::after { opacity: 1; }
#lobby-code.copied { color: var(--ready); }
#lobby-code.copied::after { content: 'COPIED'; color: var(--ready); opacity: 1; }
.link-row { display: block; flex: 1 1 340px; min-width: 280px; }
.link-row .lbl { display: block; margin-bottom: 4px; }
.link-field { display: flex; gap: var(--s-2); }
#lobby-link {
  flex: 1 1 auto; min-width: 0;
  font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: 0.3px;
  color: var(--moon-dim);
  background: rgba(4, 6, 11, 0.72);
  border: 1px solid var(--edge);
  border-radius: 2px;
  padding: 10px 12px;
  cursor: text; user-select: all; -webkit-user-select: all;
  text-overflow: ellipsis;
}
#lobby-link:focus { color: var(--bone); }
#btn-copy-link { flex: 0 0 auto; white-space: nowrap; border-left-color: var(--sodium-deep); color: var(--bone); }

.lobby-you {
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-6);
  margin: var(--s-4) 0 0;
  padding: var(--s-4) 0 0;
}
.lobby-char-row { display: flex; align-items: center; gap: var(--s-3); }
.lobby-char-row .lbl { flex: 0 0 auto; }
.lobby-char-name { font-family: var(--f-display); letter-spacing: var(--track); color: var(--bone); font-size: var(--t-lg); }
.lobby-voice-note { color: var(--moon-faint); font-size: var(--t-2xs); letter-spacing: 0.4px; max-width: 30ch; line-height: 1.35; }
#lobby-name { width: 170px; }

/* ---- squad slots ---- */
#lobby-players { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); margin: 0 0 var(--s-4); }
.lobby-row {
  position: relative;
  display: grid;
  grid-template-columns: auto auto 1fr auto auto;
  align-items: center;
  gap: var(--s-3);
  min-height: 64px;
  padding: var(--s-2) var(--s-4) var(--s-2) var(--s-3);
  background: linear-gradient(100deg, var(--surface-3), var(--surface-2) 70%);
  border: 1px solid var(--edge);
  border-left: 3px solid var(--moon-ghost);
  border-radius: 2px;
  animation: slotIn 340ms var(--ease-out) both;
  transition: border-color var(--dur-2) var(--ease-out), background-color var(--dur-2);
}
@keyframes slotIn { from { opacity: 0; transform: translate3d(0, 8px, 0); } to { opacity: 1; transform: none; } }
.lobby-row[data-slot='2'] { animation-delay: 45ms; }
.lobby-row[data-slot='3'] { animation-delay: 90ms; }
.lobby-row[data-slot='4'] { animation-delay: 135ms; }
.lobby-row::before {
  content: attr(data-slot);
  position: absolute; top: 5px; left: 7px;
  font-family: var(--f-mono); font-size: var(--t-3xs); color: var(--moon-ghost);
}
.lobby-row.is-you { border-top-color: var(--edge-strong); border-right-color: var(--edge-strong); border-bottom-color: var(--edge-strong); }
.lobby-row.is-ready { border-left-color: var(--ready); background: linear-gradient(100deg, var(--ready-soft), var(--surface-2) 66%); }
.lobby-avatar {
  position: relative;
  grid-column: 1;
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--f-display); font-size: var(--t-lg); letter-spacing: 1px;
  color: var(--slot-color, var(--bone));
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.08), transparent),
    color-mix(in srgb, var(--slot-color, #8fa3ba) 18%, rgba(6, 9, 15, 0.9));
  border: 1px solid color-mix(in srgb, var(--slot-color, #8fa3ba) 45%, transparent);
  border-radius: 2px;
  text-shadow: 0 1px 3px #000;
}
.lobby-row.is-host .lobby-avatar::after {
  content: 'HOST';
  position: absolute; left: -1px; right: -1px; bottom: -9px;
  font-family: var(--f-mono); font-size: 7px; letter-spacing: 0.5px; line-height: 10px;
  text-align: center;
  color: #2a1c08; background: var(--sodium);
  border-radius: 1px;
}
.lobby-spk {
  grid-column: 2;
  width: 12px; height: 12px; border-radius: 50%;
  font-size: 0; color: transparent;
  background: var(--moon-ghost);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.6);
  transition: background-color var(--dur-1), box-shadow var(--dur-1);
}
.lobby-spk.on { background: var(--ready); box-shadow: 0 0 10px rgba(95, 208, 138, 0.8); animation: spkPulse 0.6s var(--ease-io) infinite alternate; }
@keyframes spkPulse { from { transform: scale(0.82); } to { transform: scale(1.12); } }
.lobby-name {
  grid-column: 3;
  min-width: 0;
  font-family: var(--f-display);
  font-size: var(--t-lg); font-weight: 400; letter-spacing: var(--track-tight);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lobby-mute {
  grid-column: 4;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  background: rgba(0, 0, 0, 0.3); border: 1px solid var(--edge-soft); border-radius: 2px;
  cursor: pointer; font-size: var(--t-sm);
  opacity: 0.6; filter: grayscale(0.6);
  transition: opacity var(--dur-1), border-color var(--dur-1), filter var(--dur-1);
}
.lobby-mute:hover { opacity: 1; border-color: var(--edge-strong); }
.lobby-mute.muted { opacity: 1; filter: none; border-color: rgba(224, 69, 58, 0.5); }
.lobby-ready {
  grid-column: 5;
  justify-self: end;
  font-family: var(--f-mono); font-size: var(--t-3xs); letter-spacing: var(--track);
  color: var(--moon-faint);
  padding: 4px 9px;
  border: 1px solid var(--edge-soft);
  border-radius: 999px;
  white-space: nowrap;
}
.lobby-ready.yes {
  color: var(--ready);
  border-color: rgba(95, 208, 138, 0.45);
  background: var(--ready-soft);
  text-shadow: 0 0 10px rgba(95, 208, 138, 0.4);
}
.lobby-slot-empty {
  display: flex; align-items: center; gap: var(--s-3);
  min-height: 64px;
  padding: var(--s-2) var(--s-4);
  border: 1px dashed rgba(150, 178, 210, 0.16);
  border-radius: 2px;
  background: rgba(4, 6, 11, 0.28);
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: var(--track);
  color: var(--moon-ghost);
}
.lobby-slot-empty .slot-num { font-size: var(--t-3xs); opacity: 0.7; }
.lobby-slot-empty .slot-text { color: var(--moon-faint); }
.lobby-slot-empty .slot-cta { margin-left: auto; font-size: var(--t-3xs); color: var(--sodium-deep); opacity: 0.65; }

#lobby-hint {
  color: var(--moon-dim); font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.6px; min-height: 20px; text-align: center;
}
.lobby-countdown {
  display: flex; align-items: center; justify-content: center; gap: var(--s-2);
  margin: 0 auto var(--s-2);
}
.lobby-countdown .cd-num {
  display: grid; place-items: center;
  width: 44px; height: 44px;
  font-family: var(--f-display); font-size: var(--t-2xl); line-height: 1;
  color: var(--sodium);
  border: 2px solid rgba(255, 180, 84, 0.45);
  border-radius: 50%;
  font-variant-numeric: tabular-nums;
}
.lobby-countdown .cd-lbl { font-family: var(--f-mono); font-size: var(--t-3xs); letter-spacing: var(--track-wide); color: var(--sodium-deep); }
.lobby-countdown.tick .cd-num { animation: cdTick 420ms var(--ease-out); }
@keyframes cdTick { from { transform: scale(1.28); } to { transform: scale(1); } }

#lobby .lobby-action-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  width: 100%;
  gap: 10px;
}
#lobby .lobby-action-row .mbtn { min-width: 0; }
#lobby .lobby-primary-action {
  color: #fff4e2;
  border-color: rgba(255, 180, 84, 0.5);
  border-left-width: 3px;
  border-left-color: var(--sodium);
  background: linear-gradient(100deg, rgba(255, 180, 84, 0.2), rgba(196, 122, 42, 0.06) 70%, var(--surface-1));
}
#lobby .lobby-primary-action:hover:not(:disabled) {
  border-color: rgba(255, 180, 84, 0.8);
  background: linear-gradient(100deg, rgba(255, 180, 84, 0.3), rgba(196, 122, 42, 0.1) 70%, var(--surface-1));
}
#lobby .lobby-primary-action.ready {
  color: #ccf3da;
  border-color: rgba(95, 208, 138, 0.55);
  border-left-color: var(--ready);
  background: linear-gradient(100deg, rgba(95, 208, 138, 0.2), rgba(40, 110, 70, 0.06) 70%, var(--surface-1));
}
#lobby .lobby-ghost-action {
  color: var(--moon-dim);
  border-color: var(--edge-soft);
  border-left-color: var(--edge-soft);
  background: rgba(9, 12, 18, 0.4);
  box-shadow: none;
}
#lobby .lobby-ghost-action:hover:not(:disabled) {
  color: var(--bone);
  border-color: var(--edge-strong);
}
/* an enabled START is the host's next move — findable without stealing
   primacy from READY UP (which stays the sole primary action). */
#lobby #btn-start-game:not(:disabled) {
  color: var(--bone);
  border-left-color: var(--sodium);
  border-left-width: 3px;
}
#lobby #btn-start-game:disabled { border-left-color: var(--edge-soft); }
.lobby-fullscreen-prompt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
}
.lobby-fullscreen-note {
  max-width: 640px;
  margin: 0;
  color: #fffdf4;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: 1.2px;
  text-align: center;
  text-shadow: 0 1px 9px rgba(0, 0, 0, 0.95);
}
#lobby .lobby-secondary-action {
  width: min(440px, 78%);
  min-height: 48px;
  color: #f2efe6;
  border: 1px solid rgba(178, 206, 236, 0.4);
  border-left-width: 2px;
  background: linear-gradient(180deg, rgba(200, 220, 240, 0.1), rgba(20, 27, 38, 0.8) 52%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 248, 0.09), 0 0 18px rgba(150, 180, 214, 0.07);
}
#lobby .lobby-secondary-action:hover:not(:disabled) {
  color: #fffdf4;
  border-color: rgba(212, 232, 252, 0.68);
  background: linear-gradient(180deg, rgba(210, 230, 250, 0.16), rgba(26, 34, 46, 0.84) 52%);
}
#btn-lobby-fs.fullscreen-callout,
#btn-solo-fs-toggle.fullscreen-callout { overflow: hidden; }
#btn-lobby-fs.fullscreen-callout::before,
#btn-solo-fs-toggle.fullscreen-callout::before {
  content: '';
  position: absolute;
  top: -55%; bottom: -55%; left: 0;
  width: 26%;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(238, 244, 252, 0.06) 20%, rgba(255, 255, 248, 0.34) 50%, rgba(184, 206, 232, 0.08) 78%, transparent);
  transform: translate3d(-260%, 0, 0) skewX(-18deg);
  animation: fullscreenMetalShimmer 4.8s var(--ease-io) infinite;
}
@keyframes fullscreenMetalShimmer {
  0%, 56% { transform: translate3d(-260%, 0, 0) skewX(-18deg); opacity: 0; }
  61% { opacity: 0.9; }
  79% { transform: translate3d(620%, 0, 0) skewX(-18deg); opacity: 0.6; }
  84%, 100% { transform: translate3d(620%, 0, 0) skewX(-18deg); opacity: 0; }
}
.lobby-note { margin-top: var(--s-4); color: rgba(125, 144, 166, 0.72); font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: 0.6px; text-align: center; }

/* ============================================================================
   JOIN + SOLO PREFLIGHT MODALS
   ========================================================================== */
.join-panel { width: min(460px, 92vw); }
#join-code {
  width: 260px; display: block; margin: var(--s-5) auto 0;
  font-family: var(--f-display); font-size: 38px; font-weight: 400;
  letter-spacing: 14px; text-indent: 14px; text-align: center; text-transform: uppercase;
  color: var(--sodium);
  background: rgba(4, 6, 11, 0.8);
  border: 1px solid var(--edge);
  border-bottom: 2px solid var(--sodium-deep);
  border-radius: 2px;
  padding: 12px 10px;
  outline: none;
}
#join-code::placeholder { color: var(--moon-ghost); letter-spacing: 10px; }
#join-code:focus { border-color: var(--sodium); box-shadow: 0 0 24px rgba(255, 180, 84, 0.14); }

.solo-fs-panel { max-width: 700px; text-align: center; }
.solo-fs-panel .dim { max-width: 520px; margin: var(--s-1) auto var(--s-5); line-height: 1.7; }
.solo-fs-actions { justify-content: center; flex-wrap: wrap; }
.solo-fs-actions .mbtn { flex: 0 1 auto; }

/* ============================================================================
   OPTIONS
   ========================================================================== */
.options-panel { text-align: left; width: min(960px, 94vw); }
.options-panel h2 { text-align: left; }
.options-panel > .panel-kicker { text-align: left; }
.opt-sections { column-count: 2; column-gap: var(--s-7); }
.opt-section { min-width: 0; break-inside: avoid; -webkit-column-break-inside: avoid; }
.opt-section + .opt-section { margin-top: var(--s-6); }
.opt-section .section-head { margin-top: 0; margin-bottom: var(--s-4); }
.options-panel h2 { margin-bottom: var(--s-6); }
.opt-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: var(--s-3) var(--s-5);
  align-items: center;
  text-align: left;
}
.opt-grid label {
  font-family: var(--f-mono);
  font-size: var(--t-sm);
  letter-spacing: 0.6px;
  color: var(--moon);
  display: flex; align-items: baseline; gap: var(--s-2);
}
.opt-grid .val {
  margin-left: auto;
  font-size: var(--t-xs);
  color: var(--sodium);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.5px;
}
.opt-grid select, .opt-grid input[type='text'], #opt-name { width: 100%; }

/* sliders: one custom look across engines */
.opt-grid input[type='range'] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 22px;
  background: transparent;
  cursor: pointer;
}
.opt-grid input[type='range'] { --fill: 50%; }
.opt-grid input[type='range']::-webkit-slider-runnable-track {
  height: 3px;
  background:
    linear-gradient(90deg, var(--sodium) 0 var(--fill), rgba(150, 178, 210, 0.18) var(--fill) 100%);
  border-radius: 2px;
}
.opt-grid input[type='range']::-moz-range-track {
  height: 3px;
  background:
    linear-gradient(90deg, var(--sodium) 0 var(--fill), rgba(150, 178, 210, 0.18) var(--fill) 100%);
  border-radius: 2px;
}
.opt-grid input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 12px; height: 20px; margin-top: -8.5px;
  background: linear-gradient(180deg, #f4efe3, #b9b0a0);
  border: 1px solid rgba(4, 6, 11, 0.9);
  border-radius: 2px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
  transition: transform var(--dur-1) var(--ease-out), box-shadow var(--dur-1);
}
.opt-grid input[type='range']::-moz-range-thumb {
  width: 12px; height: 20px;
  background: linear-gradient(180deg, #f4efe3, #b9b0a0);
  border: 1px solid rgba(4, 6, 11, 0.9);
  border-radius: 2px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
}
.opt-grid input[type='range']:hover::-webkit-slider-thumb { transform: scaleY(1.1); box-shadow: 0 0 14px rgba(255, 180, 84, 0.5); }
.opt-grid input[type='range']:active::-webkit-slider-thumb { background: linear-gradient(180deg, #ffd9a1, var(--sodium)); }

/* checkbox → switch */
.opt-toggle { position: relative; display: inline-flex; align-items: center; justify-self: start; }
.opt-toggle input[type='checkbox'] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer; z-index: 1;
}
.opt-switch {
  position: relative;
  width: 46px; height: 24px;
  background: rgba(4, 6, 11, 0.8);
  border: 1px solid var(--edge);
  border-radius: 999px;
  transition: background-color var(--dur-2) var(--ease-out), border-color var(--dur-2);
}
.opt-switch::after {
  content: '';
  position: absolute; top: 3px; left: 3px;
  width: 16px; height: 16px;
  background: var(--moon-faint);
  border-radius: 50%;
  transition: transform var(--dur-2) var(--ease-out), background-color var(--dur-2);
}
.opt-toggle input:checked + .opt-switch { background: rgba(255, 180, 84, 0.2); border-color: rgba(255, 180, 84, 0.55); }
.opt-toggle input:checked + .opt-switch::after { transform: translate3d(22px, 0, 0); background: var(--sodium); }
body.kbd-nav .opt-toggle input:focus-visible + .opt-switch { outline: 2px solid var(--sodium); outline-offset: 2px; }

/* ============================================================================
   CHEAT CODES
   ========================================================================== */
#cheats-panel { text-align: left; width: min(1020px, 95vw); }
#cheats-panel h2, #cheats-panel > .panel-kicker { text-align: left; }
#cheats-note { margin-bottom: var(--s-4); }
.cheats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--s-1) var(--s-6); text-align: left; }
.cheat {
  display: flex; align-items: flex-start; gap: var(--s-3);
  padding: 9px 11px;
  cursor: pointer; user-select: none;
  font-family: var(--f-mono); font-size: var(--t-sm); letter-spacing: 0.6px;
  color: var(--moon);
  border: 1px solid transparent;
  border-radius: 2px;
  transition: background-color var(--dur-1), border-color var(--dur-1), color var(--dur-1);
}
.cheat:hover { color: var(--bone); background: rgba(120, 150, 186, 0.06); border-color: var(--edge-soft); }
.cheat input { position: absolute; opacity: 0; width: 0; height: 0; }
.cheat .box {
  position: relative; top: 2px;
  width: 15px; height: 15px; flex: 0 0 15px;
  border: 1px solid rgba(150, 178, 210, 0.45);
  border-radius: 2px;
  transition: background-color var(--dur-1), border-color var(--dur-1);
}
.cheat .box::after {
  content: '';
  position: absolute; left: 4px; top: 1px;
  width: 4px; height: 8px;
  border: solid var(--sodium);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform var(--dur-2) var(--ease-out);
}
.cheat input:checked + .box { background: var(--sodium-soft); border-color: var(--sodium); }
.cheat input:checked + .box::after { transform: rotate(45deg) scale(1); }
.cheat input:checked ~ .txt { color: var(--bone); }
body.kbd-nav .cheat input:focus-visible + .box { outline: 2px solid var(--sodium); outline-offset: 3px; }
.cheat .txt { line-height: 1.45; }
.cheat .txt em { display: block; font-style: normal; color: var(--moon-faint); font-size: var(--t-2xs); letter-spacing: 0.3px; margin-top: 2px; }
.cheat-row { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.cheat-row .dim { font-family: var(--f-mono); font-size: var(--t-2xs); color: var(--moon-ghost); }
.cheat-lbl { font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: var(--track); color: var(--moon-dim); }

.mbtn.titan {
  display: block; width: 100%; margin: var(--s-3) 0 0; text-align: center;
  padding: 14px 18px;
  font-size: var(--t-sm); letter-spacing: var(--track-tight); line-height: 1.4;
  color: #ffe4a8;
  border-color: rgba(255, 180, 84, 0.4);
  border-left-color: var(--sodium);
  background: linear-gradient(100deg, rgba(255, 180, 84, 0.18), rgba(196, 122, 42, 0.05) 62%, var(--surface-1));
}
.mbtn.titan:hover:not(:disabled) { color: #fff3d6; border-color: rgba(255, 180, 84, 0.75); }

.loadout-row { margin-top: 0; text-align: left; }
.loadout-title { display: block; margin-bottom: var(--s-2); color: var(--moon-dim); }
.loadout-title em { font-style: normal; color: var(--moon-ghost); letter-spacing: 0.3px; }
.wpn-picks { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--s-4); }
.wpn-pick label { display: block; font-family: var(--f-mono); font-size: var(--t-3xs); letter-spacing: var(--track); color: var(--sodium-deep); }
.wpn-search { width: 100%; margin: var(--s-2) 0; }
.wpn-list {
  max-height: 180px; overflow-y: auto;
  border: 1px solid var(--edge-soft);
  border-radius: 2px;
  background: rgba(4, 6, 11, 0.5);
}
.wpn-group {
  position: sticky; top: 0; z-index: 1;
  font-family: var(--f-mono); font-size: var(--t-3xs); letter-spacing: var(--track);
  color: var(--moon-ghost);
  background: rgba(7, 10, 16, 0.96);
  padding: 6px 10px 4px;
}
.wpn-item {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-2);
  width: 100%; text-align: left;
  background: none; border: 0; border-left: 2px solid transparent; cursor: pointer;
  font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: 0.4px;
  color: var(--moon);
  padding: 6px 10px;
  transition: background-color var(--dur-1), color var(--dur-1), border-color var(--dur-1);
}
.wpn-item:hover:not(:disabled) { background: rgba(255, 180, 84, 0.09); color: var(--bone); }
.wpn-item.sel { background: var(--sodium-soft); color: #ffe6c2; border-left-color: var(--sodium); }
.wpn-item:disabled { cursor: default; opacity: 0.6; }
.wpn-item .cls { color: var(--moon-ghost); font-size: var(--t-3xs); flex: 0 0 auto; }
.read-only .cheat { cursor: default; }
.read-only .cheat:hover { color: var(--moon); background: none; border-color: transparent; }
#cheats-panel.read-only { border-left: 2px solid var(--sodium-deep); }
#cheat-round { width: 68px; text-align: center; }
#cheat-area { min-width: 220px; }

/* ============================================================================
   CHARACTER SELECT / CHARACTER PAGE
   ========================================================================== */
.chars-panel { max-width: 940px; }
#char-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--s-3); margin: var(--s-5) 0 0; }
.char-card {
  position: relative;
  padding: var(--s-4) var(--s-3) var(--s-3);
  text-align: center;
  cursor: pointer;
  background: linear-gradient(180deg, var(--surface-3), var(--surface-1));
  border: 1px solid var(--edge);
  border-bottom: 2px solid var(--edge);
  border-radius: 2px;
  overflow: hidden;
  transform: translateZ(0);
  transition: border-color var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out), background-color var(--dur-2);
  animation: slotIn 380ms var(--ease-out) both;
}
#char-cards > .char-card:nth-child(2) { animation-delay: 55ms; }
#char-cards > .char-card:nth-child(3) { animation-delay: 110ms; }
#char-cards > .char-card:nth-child(4) { animation-delay: 165ms; }
.char-card::after {
  content: '';
  position: absolute; inset: auto 0 0 0; height: 2px;
  background: var(--sodium);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-3) var(--ease-out);
}
.char-card:hover { border-color: var(--edge-strong); transform: translate3d(0, -3px, 0); }
.char-card:hover::after { transform: scaleX(1); }
.char-card.is-pressed { transform: translate3d(0, -1px, 0) scale(0.985); }
.char-card.taken { opacity: 0.3; pointer-events: none; filter: grayscale(1); }
.char-card.is-current { border-color: rgba(255, 180, 84, 0.45); background: linear-gradient(180deg, rgba(255, 180, 84, 0.09), var(--surface-1)); }
.char-card.is-current::after { transform: scaleX(1); }
.char-card.is-current::before {
  content: 'CURRENT';
  position: absolute; top: 0; right: 0;
  padding: 3px 7px;
  font-family: var(--f-mono); font-size: 8px; letter-spacing: 1.5px;
  color: #2a1c08; background: var(--sodium);
}
.char-card canvas {
  width: 78px; height: 78px; image-rendering: pixelated;
  margin-bottom: var(--s-2);
  background: rgba(4, 6, 11, 0.6);
  border: 1px solid var(--edge-soft);
  border-radius: 2px;
}
.char-card .cc-name { font-family: var(--f-display); font-size: var(--t-lg); letter-spacing: var(--track); color: var(--bone); }
.char-card .cc-role { font-family: var(--f-mono); font-size: var(--t-3xs); letter-spacing: 1px; color: var(--moon-faint); margin-top: 3px; }

.char-page { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: var(--s-6); max-width: 860px; text-align: left; }
.char-page-left { display: flex; flex-direction: column; gap: var(--s-3); }
.char-portrait-frame {
  position: relative; padding: var(--s-2);
  background: linear-gradient(180deg, var(--surface-3), rgba(4, 6, 11, 0.9));
  border: 1px solid var(--edge);
}
.char-portrait-frame::before, .char-portrait-frame::after {
  content: ''; position: absolute; width: 14px; height: 14px; border-color: var(--sodium-deep);
}
.char-portrait-frame::before { top: -1px; left: -1px; border-top: 2px solid; border-left: 2px solid; }
.char-portrait-frame::after { right: -1px; bottom: -1px; border-right: 2px solid; border-bottom: 2px solid; }
#char-portrait { display: block; width: 100%; height: auto; aspect-ratio: 1; image-rendering: pixelated; background: #05070c; }
.char-voice-head, .char-section-head { color: var(--sodium-deep); margin-top: var(--s-2); }
.char-section-head { display: block; margin: var(--s-5) 0 var(--s-2); }
.char-page-right .row-buttons { margin-top: var(--s-6); }
#char-voice-lines { display: grid; gap: 4px; }
.vline-btn {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: 0.8px;
  background: var(--surface-2); color: var(--moon);
  border: 1px solid var(--edge-soft); border-left: 2px solid var(--edge);
  border-radius: 2px;
  padding: 8px 10px; cursor: pointer; text-align: left;
  transition: color var(--dur-1), border-color var(--dur-1), background-color var(--dur-1), transform var(--dur-1);
}
.vline-btn:hover:not(:disabled) { color: var(--bone); border-left-color: var(--sodium); background: rgba(255, 180, 84, 0.08); }
.vline-btn.is-pressed { transform: scale(0.98); }
.vline-btn:disabled { opacity: 0.45; cursor: progress; }
.char-page-right h2 { text-align: left; margin-bottom: 2px; }
.char-role { font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: var(--track); color: var(--alert); margin: 0 0 var(--s-4); }
.char-bio { font-family: var(--f-mono); font-size: var(--t-sm); line-height: 1.75; color: var(--moon); }
.char-traits { margin: 0; padding-left: var(--s-4); font-family: var(--f-mono); font-size: var(--t-xs); color: var(--moon-dim); }
.char-traits li { margin: 4px 0; }
.char-traits li::marker { color: var(--sodium-deep); }
.char-quotes { font-family: var(--f-mono); font-size: var(--t-xs); font-style: italic; color: rgba(150, 190, 224, 0.72); }
.char-quotes div { margin: 5px 0; padding-left: var(--s-3); border-left: 1px solid var(--edge); }
.char-page-right .row-buttons { justify-content: flex-start; }

/* ============================================================================
   PAUSE
   ========================================================================== */
#pause { z-index: 60; }
.pause-shell {
  display: grid; gap: var(--s-4);
  width: min(460px, 92vw);
  animation: contentIn var(--dur-4) var(--ease-out) both; animation-delay: 40ms;
}
.pause-panel { min-width: 0; width: 100%; padding: var(--s-6) var(--s-6) var(--s-5); }
.pause-panel h2 { margin-bottom: var(--s-5); }
.pause-panel .row-buttons.col { gap: var(--s-2); }
.pause-panel .row-buttons.col .mbtn { text-align: left; padding-left: var(--s-5); }
.pause-panel .mbtn.primary { font-size: var(--t-lg); min-height: 52px; }
/* live match state stays readable while the world is frozen behind */
.pause-stats {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  margin: 0 0 var(--s-5);
  background: var(--edge-soft);
  border: 1px solid var(--edge-soft);
  border-radius: 2px;
  overflow: hidden;
}
.pstat { display: flex; flex-direction: column; gap: 3px; padding: var(--s-3) var(--s-4); background: rgba(6, 9, 15, 0.7); }
.pstat-lbl { font-family: var(--f-mono); font-size: var(--t-3xs); letter-spacing: var(--track-wide); color: var(--moon-faint); }
.pstat-val {
  font-family: var(--f-display); font-size: var(--t-2xl); line-height: 1;
  letter-spacing: var(--track); color: var(--bone);
  font-variant-numeric: tabular-nums;
}
.pause-stats .pstat:first-child .pstat-val { color: var(--alert); }

.pause-controls {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px var(--s-3);
  margin-top: var(--s-4); padding-top: var(--s-4);
  border-top: 1px solid var(--edge-soft);
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: 0.5px;
  color: var(--moon-faint);
  text-align: left;
}
.pause-controls .kp { display: flex; align-items: center; gap: 6px; min-width: 0; white-space: nowrap; }
.pause-controls b {
  flex: 0 0 auto;
  display: inline-block; min-width: 22px; padding: 2px 6px;
  font-weight: 400; font-size: var(--t-3xs); color: var(--moon);
  background: rgba(120, 150, 186, 0.09);
  border: 1px solid var(--edge); border-bottom-width: 2px; border-radius: 3px;
  text-align: center;
}

/* ============================================================================
   TOAST
   ========================================================================== */
#toast {
  position: fixed; bottom: 36px; left: 50%;
  transform: translateX(-50%);
  max-width: min(640px, 90vw);
  background: var(--surface-0);
  border: 1px solid var(--edge);
  border-left: 3px solid var(--sodium);
  border-radius: 2px;
  padding: 13px 22px;
  font-family: var(--f-mono);
  font-size: var(--t-sm); letter-spacing: 0.5px; line-height: 1.5;
  color: var(--bone);
  z-index: 90;
  box-shadow: var(--lift-2);
  animation: toastIn 340ms var(--ease-out);
}
@keyframes toastIn {
  from { opacity: 0; transform: translate3d(-50%, 14px, 0); }
  to   { opacity: 1; transform: translate3d(-50%, 0, 0); }
}

/* ============================================================================
   FULL-SCREEN FX OVERLAYS
   ========================================================================== */
#dmg-vignette, #health-pulse, #screen-flash {
  position: fixed; inset: 0; pointer-events: none; opacity: 0; z-index: 40;
}
#dmg-vignette {
  background:
    radial-gradient(ellipse at center, transparent 38%, rgba(190, 20, 12, 0.5) 88%, rgba(120, 6, 4, 0.75) 100%);
  transition: opacity 0.32s var(--ease-out);
}
#health-pulse {
  background: radial-gradient(ellipse at center, transparent 46%, rgba(150, 8, 2, 0.58) 100%);
  transition: opacity 0.5s var(--ease-soft);
}
#screen-flash { background: #fff; transition: opacity 0.45s; z-index: 41; }

/* ---- directional damage ---------------------------------------------------
   Contract with js/fx.js (see the markup comment in index.html):
     --dmg-angle : <number>deg — bearing of the attacker relative to where the
                   player is looking. 0 = dead ahead, 90 = right, 180 = behind,
                   270 = left. Any value; it is used raw in a rotate().
     data-hit    : any string that CHANGES per hit. The attribute change is what
                   replays the animation, so a monotonic counter is ideal.
   The arc is a rotated wedge pinned to the screen centre, so a single element
   covers every bearing. Compositor-only: rotate + opacity. */
#dmg-dir {
  --dmg-angle: 0deg;
  position: fixed; inset: 0; z-index: 40;
  pointer-events: none;
  display: grid; place-items: center;
}
#dmg-dir .dmg-arc {
  width: min(62vmin, 620px);
  aspect-ratio: 1;
  transform: rotate(var(--dmg-angle));
  opacity: 0;
  background:
    conic-gradient(from -30deg,
      rgba(236, 60, 44, 0) 0deg,
      rgba(255, 92, 74, 0.9) 14deg,
      rgba(255, 120, 96, 0.95) 30deg,
      rgba(255, 92, 74, 0.9) 46deg,
      rgba(236, 60, 44, 0) 60deg,
      rgba(236, 60, 44, 0) 360deg);
  /* hollow it out so it reads as a curved band at the edge of vision */
  /* closest-side keeps the ring radii relative to the half-width, so the mask
     lines up with the conic wedge instead of being pushed out to the corners */
  mask-image: radial-gradient(circle closest-side at center, transparent 62%, #000 76%, #000 94%, transparent 100%);
  -webkit-mask-image: radial-gradient(circle closest-side at center, transparent 62%, #000 76%, #000 94%, transparent 100%);
  filter: blur(2px) drop-shadow(0 0 12px rgba(236, 60, 44, 0.55));
}
/* A CSS animation does not replay when an attribute merely changes value, so
   consecutive hits alternate between two identical keyframe sets keyed on the
   counter's last digit. fx.js just increments; the restart is free. */
#dmg-dir[data-hit$="0"] .dmg-arc, #dmg-dir[data-hit$="2"] .dmg-arc,
#dmg-dir[data-hit$="4"] .dmg-arc, #dmg-dir[data-hit$="6"] .dmg-arc,
#dmg-dir[data-hit$="8"] .dmg-arc { animation: dmgArcA 900ms var(--ease-out); }
#dmg-dir[data-hit$="1"] .dmg-arc, #dmg-dir[data-hit$="3"] .dmg-arc,
#dmg-dir[data-hit$="5"] .dmg-arc, #dmg-dir[data-hit$="7"] .dmg-arc,
#dmg-dir[data-hit$="9"] .dmg-arc { animation: dmgArcB 900ms var(--ease-out); }
@keyframes dmgArcA {
  0% { opacity: 0; } 8% { opacity: 1; } 38% { opacity: 0.9; } 100% { opacity: 0; }
}
@keyframes dmgArcB {
  0% { opacity: 0; } 8% { opacity: 1; } 38% { opacity: 0.9; } 100% { opacity: 0; }
}

/* ============================================================================
   HUD  —  sparse, high contrast, animated only on change. No backdrop filters.
   ========================================================================== */
#hud {
  position: fixed; inset: 0; pointer-events: none; z-index: 30;
  font-family: var(--f-display);
  --hud-pad-x: clamp(24px, 2.4vw, 48px);
  --hud-pad-y: clamp(20px, 2.2vh, 40px);
  --map-size: 168px;
  --map-chrome: 40px; /* frame padding + caption */
}

#crosshair {
  --gap: 10px;
  position: absolute; left: 50%; top: 50%; width: 0; height: 0;
  transition: opacity 0.15s var(--ease-out);
}
#crosshair span { position: absolute; background: rgba(244, 248, 252, 0.92); box-shadow: 0 0 3px rgba(0, 0, 0, 0.9); }
.ch-l { width: 7px; height: 2px; left: calc(-7px - var(--gap)); top: -1px; }
.ch-r { width: 7px; height: 2px; left: var(--gap); top: -1px; }
.ch-t { width: 2px; height: 7px; left: -1px; top: calc(-7px - var(--gap)); }
.ch-b { width: 2px; height: 7px; left: -1px; top: var(--gap); }
.ch-dot { width: 2px; height: 2px; left: -1px; top: -1px; background: rgba(255, 255, 255, 0.65); }

#hitmarker { position: absolute; left: 50%; top: 50%; width: 0; height: 0; opacity: 0; }
#hitmarker span { position: absolute; width: 10px; height: 2px; background: #fff; box-shadow: 0 0 4px rgba(0, 0, 0, 0.9); }
#hitmarker span:nth-child(1) { transform: rotate(45deg); left: -13px; top: -9px; }
#hitmarker span:nth-child(2) { transform: rotate(-45deg); left: 3px; top: -9px; }
#hitmarker span:nth-child(3) { transform: rotate(-45deg); left: -13px; top: 7px; }
#hitmarker span:nth-child(4) { transform: rotate(45deg); left: 3px; top: 7px; }
#hitmarker.hm-show { opacity: 1; animation: hmPop 110ms var(--ease-out); }
@keyframes hmPop { from { transform: scale(1.5); } to { transform: scale(1); } }
#hitmarker.hm-kill span { background: var(--alert); width: 13px; box-shadow: 0 0 8px rgba(224, 69, 58, 0.9); }
#hitmarker.hm-head span { background: var(--sodium); box-shadow: 0 0 8px rgba(255, 180, 84, 0.9); }
#hitmarker.hm-kill.hm-head span { background: #ff8a2a; }

/* ---- bottom-left: round · vitals · points · perks ---- */
#bottom-left {
  position: absolute; left: var(--hud-pad-x); bottom: var(--hud-pad-y);
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.95);
}
.round-kicker, .points-kicker, .vitals-kicker {
  font-family: var(--f-mono);
  font-size: var(--t-3xs);
  letter-spacing: var(--track-wide);
  color: rgba(185, 203, 224, 0.5);
  transition: opacity var(--dur-2);
}
.round-block { position: relative; }
.round-block:has(#round:empty) .round-kicker { opacity: 0; }
#round {
  font-size: clamp(46px, 4.4vw, 66px);
  font-weight: 400; line-height: 0.88; letter-spacing: 3px;
  color: var(--alert);
  text-shadow: 0 0 26px rgba(224, 69, 58, 0.55), 0 2px 5px rgba(0, 0, 0, 0.95);
  min-height: 46px;
  font-variant-numeric: tabular-nums;
}
#round.round-anim { animation: roundIn 1.3s var(--ease-out); }
@keyframes roundIn {
  0%   { transform: scale(2.2); opacity: 0; }
  30%  { transform: scale(1); opacity: 1; }
  100% { transform: scale(1); }
}

.vitals-block { width: 190px; }
.vitals-kicker { display: block; margin-bottom: 3px; }
#health-track {
  position: relative;
  width: 100%; height: 6px;
  background: rgba(6, 9, 15, 0.72);
  box-shadow: inset 0 0 0 1px rgba(150, 178, 210, 0.22);
  overflow: hidden;
}
#health-fill {
  position: absolute; inset: 0;
  transform-origin: left center;
  transform: scaleX(1);
  background: linear-gradient(90deg, rgba(210, 228, 244, 0.75), rgba(236, 246, 255, 0.95));
  transition: transform 220ms var(--ease-soft), background-color 260ms;
  will-change: transform;
}
#health-track[data-state='warn'] #health-fill { background: linear-gradient(90deg, #ffd28a, var(--sodium)); }
#health-track[data-state='crit'] #health-fill { background: linear-gradient(90deg, #ff8a7a, var(--alert)); }
/* the critical-health edge pulses on opacity only — no box-shadow animation
   during live gameplay */
#health-track::after {
  content: '';
  position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px var(--alert);
  opacity: 0;
  pointer-events: none;
}
#health-track[data-state='crit']::after { animation: critEdge 0.85s var(--ease-io) infinite alternate; }
@keyframes critEdge { from { opacity: 0.35; } to { opacity: 1; } }
#health-tip {
  position: absolute; top: 0; bottom: 0; width: 2px;
  background: rgba(255, 255, 255, 0.75);
  transform: translate3d(0, 0, 0);
  transition: transform 220ms var(--ease-soft);
  will-change: transform;
}

.points-block { margin-top: 2px; }
.points-kicker { display: block; }
.points-row { position: relative; display: flex; align-items: baseline; gap: var(--s-2); }
#points {
  font-size: clamp(26px, 2.3vw, 34px); font-weight: 400; letter-spacing: 2px;
  color: var(--bone);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
#points.flash { animation: ptsFlash 0.4s var(--ease-out); }
@keyframes ptsFlash {
  0%   { color: var(--sodium); transform: scale(1.14); }
  100% { color: var(--bone); transform: scale(1); }
}
#points-delta {
  font-family: var(--f-mono);
  font-size: var(--t-sm); letter-spacing: 0.5px;
  color: var(--sodium);
  opacity: 0;
}
#points-delta.pop { animation: deltaPop 900ms var(--ease-out); }
@keyframes deltaPop {
  0%   { opacity: 0; transform: translate3d(0, 6px, 0); }
  18%  { opacity: 1; transform: translate3d(0, 0, 0); }
  70%  { opacity: 1; transform: translate3d(0, -3px, 0); }
  100% { opacity: 0; transform: translate3d(0, -10px, 0); }
}
#points-delta.neg { color: var(--alert); }

#perk-icons { display: flex; gap: 6px; margin-top: 4px; }
.perk-icon {
  --perk: var(--moon);
  width: 32px; height: 32px;
  border-radius: 3px;
  box-shadow: 0 0 12px -4px var(--perk);
  animation: perkIn 420ms var(--ease-out) both;
}
/* The perk art carries its own gold frame, so the chip contributes only the
   per-perk glow — a border here would read as a second frame. */
img.perk-icon { display: block; object-fit: contain; }
/* Fallback for a perk id with no shipped art: the original bordered glyph. */
.perk-icon-glyph {
  display: flex; align-items: center; justify-content: center;
  font-family: var(--f-display); font-size: var(--t-sm); font-weight: 400; letter-spacing: 0;
  color: var(--perk);
  border: 1px solid var(--perk);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--perk) 22%, transparent), rgba(4, 6, 11, 0.8));
}
@keyframes perkIn {
  from { opacity: 0; transform: scale(0.55) translate3d(0, 6px, 0); }
  to   { opacity: 1; transform: none; }
}

/* ---- bottom-right: weapon · ammo · grenades ---- */
#bottom-right {
  position: absolute; right: var(--hud-pad-x); bottom: var(--hud-pad-y);
  display: flex; flex-direction: column; align-items: flex-end; gap: 3px;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.95);
}
#weapon-name {
  font-family: var(--f-mono);
  font-size: var(--t-2xs); letter-spacing: var(--track-wide);
  color: rgba(185, 203, 224, 0.62);
  text-transform: uppercase;
}
#ammo {
  display: flex; align-items: baseline; gap: 4px;
  font-size: clamp(36px, 3.2vw, 48px); font-weight: 400; letter-spacing: 1px; line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--bone);
}
#ammo .mag { transition: color var(--dur-2); }
#ammo .sep { color: rgba(150, 178, 210, 0.35); font-size: 0.5em; margin: 0 2px; }
#ammo .reserve { color: rgba(185, 203, 224, 0.62); font-size: 0.52em; letter-spacing: 1px; }
#ammo.tick .mag { animation: ammoTick 200ms var(--ease-out); }
@keyframes ammoTick { from { transform: translate3d(0, -3px, 0); opacity: 0.55; } to { transform: none; opacity: 1; } }
#ammo.low .mag { color: var(--sodium); }
#ammo.empty .mag { color: var(--alert); animation: ammoEmpty 0.75s var(--ease-io) infinite alternate; }
@keyframes ammoEmpty { from { opacity: 0.45; } to { opacity: 1; } }
#ammo-track {
  width: 120px; height: 3px; margin-top: 3px;
  background: rgba(6, 9, 15, 0.7);
  box-shadow: inset 0 0 0 1px rgba(150, 178, 210, 0.18);
  overflow: hidden;
}
#ammo-fill {
  height: 100%; width: 100%;
  transform-origin: right center;
  background: rgba(220, 232, 244, 0.55);
  transition: transform 160ms var(--ease-soft), background-color var(--dur-2);
  will-change: transform;
}
#ammo.low ~ #ammo-track #ammo-fill { background: var(--sodium); }
#ammo.empty ~ #ammo-track #ammo-fill { background: var(--alert); }

#nade-row { display: flex; gap: var(--s-2); justify-content: flex-end; align-items: center; margin-top: 6px; }
#nade-count { font-family: var(--f-mono); font-size: var(--t-2xs); color: rgba(185, 203, 224, 0.62); letter-spacing: 1px; }
#grenades { display: flex; gap: 4px; justify-content: flex-end; }
.nade {
  width: 9px; height: 14px;
  background: linear-gradient(180deg, #8a9a72, #58664a);
  border-radius: 2px 2px 4px 4px;
  border: 1px solid rgba(4, 6, 11, 0.9);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
  animation: perkIn 260ms var(--ease-out) both;
}
.nade.monkey { background: linear-gradient(180deg, #cfa066, #8a6534); }
#monkey-count {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: 1px;
  color: var(--sodium); margin-bottom: 2px;
}
#monkey-count em { font-style: normal; color: rgba(255, 180, 84, 0.5); font-size: var(--t-3xs); }

/* ---- top strip ---- */
/* Top-right belongs to the co-op roster. When it is on screen the power-up
   timers drop below it; in solo they take the corner themselves. */
#drop-timers {
  position: absolute;
  top: var(--hud-pad-y);
  right: var(--hud-pad-x);
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
  text-align: right;
}
#multiplayer-roster:not(.hidden) ~ #drop-timers { top: calc(var(--hud-pad-y) + 216px); }
.drop-timer {
  font-family: var(--f-mono);
  font-size: var(--t-xs); letter-spacing: var(--track);
  padding: 4px 10px;
  border: 1px solid currentColor;
  border-radius: 999px;
  background: rgba(4, 6, 11, 0.55);
  text-shadow: 0 1px 3px #000;
  animation: pulse 0.9s var(--ease-io) infinite alternate;
}
@keyframes pulse { from { opacity: 0.68; } to { opacity: 1; } }

#wave-progress {
  position: absolute; top: var(--hud-pad-y); left: 50%;
  transform: translateX(-50%);
  font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: var(--track-wide);
  color: rgba(185, 203, 224, 0.62);
  text-shadow: 0 2px 6px #000;
}
#pap-notice {
  position: absolute; top: calc(var(--hud-pad-y) + 26px); left: 50%;
  transform: translateX(-50%);
  font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: var(--track);
  color: #cba2ff; text-shadow: 0 0 16px rgba(138, 92, 255, 0.8), 0 2px 5px #000;
}

/* ---- minimap ---- */
/* minimap takes the top-left corner; the top-right is reserved for squad +
   power-up state so the two never overlap in co-op */
#minimap-frame {
  position: absolute; left: var(--hud-pad-x); top: var(--hud-pad-y);
  padding: 5px;
  /* Near-opaque: the canvas inside is opaque, so a translucent surround left a
     bright halo of live 3D frame around a dark map whenever the camera faced
     the moon. Dark and desaturated keeps it inside the HUD's palette. */
  background: rgba(6, 9, 15, 0.9);
  border: 1px solid rgba(150, 178, 210, 0.16);
  border-radius: 2px;
}
#minimap { display: block; width: var(--map-size); height: var(--map-size); }
#minimap-frame .minimap-label {
  display: block; margin-top: 3px;
  font-family: var(--f-mono); font-size: var(--t-3xs); letter-spacing: var(--track);
  color: rgba(150, 178, 210, 0.42); text-align: center;
}
#minimap-frame .minimap-tick {
  position: absolute; top: 2px; left: 50%; width: 1px; height: 5px;
  background: rgba(255, 180, 84, 0.7);
}

/* ---- prompts + banners ---- */
#prompt-wrap { position: absolute; left: 50%; top: 58%; transform: translateX(-50%); text-align: center; }
#prompt {
  font-family: var(--f-mono);
  font-size: var(--t-md); color: var(--bone); letter-spacing: 0.4px;
  text-shadow: 0 2px 5px #000;
  background: rgba(4, 6, 11, 0.62);
  padding: 9px 20px;
  border: 1px solid var(--edge);
  border-radius: 2px;
  animation: promptIn 180ms var(--ease-out);
}
@keyframes promptIn { from { opacity: 0; transform: translate3d(0, 5px, 0); } to { opacity: 1; transform: none; } }
#prompt b { color: var(--sodium); }
#prompt .pts { color: var(--ready); font-weight: 700; }
#prompt .dim { color: var(--moon-faint); }
#prompt-bar { width: 200px; height: 4px; background: rgba(255, 255, 255, 0.14); margin: var(--s-2) auto 0; overflow: hidden; }
#prompt-bar-fill { height: 100%; background: var(--sodium); width: 0; box-shadow: 0 0 10px rgba(255, 180, 84, 0.7); }

#banner {
  position: absolute; left: 50%; top: 24%;
  transform: translateX(-50%);
  font-size: clamp(34px, 4.4vw, 60px); font-weight: 400; letter-spacing: 0.18em;
  color: var(--alert);
  opacity: 0; white-space: nowrap;
  text-shadow: 0 0 34px currentColor, 0 3px 8px rgba(0, 0, 0, 0.95);
}
#banner.banner-anim { animation: bannerIn 3.4s var(--ease-out) forwards; }
@keyframes bannerIn {
  0%   { opacity: 0; transform: translateX(-50%) scale(1.35); }
  10%  { opacity: 1; transform: translateX(-50%) scale(1); }
  82%  { opacity: 1; }
  100% { opacity: 0; }
}
#banner-sub {
  position: absolute; left: 50%; top: 24%; margin-top: 68px;
  transform: translateX(-50%);
  font-family: var(--f-mono);
  font-size: var(--t-sm); letter-spacing: var(--track-wide);
  color: rgba(185, 203, 224, 0.7);
  opacity: 0; white-space: nowrap;
  text-shadow: 0 2px 6px #000;
}
#banner-sub.banner-sub-anim { animation: bannerIn 3.4s var(--ease-out) forwards; }

/* ---- revive / down ---- */
#revive-wrap { position: absolute; left: 50%; top: 64%; transform: translateX(-50%); text-align: center; }
#revive-text {
  font-family: var(--f-mono); font-size: var(--t-sm); letter-spacing: var(--track-wide);
  color: #8fd4ea; text-shadow: 0 0 14px rgba(58, 122, 154, 0.9); margin-bottom: var(--s-2);
}
.bar { width: 260px; height: 5px; background: rgba(255, 255, 255, 0.12); overflow: hidden; }
#revive-fill { height: 100%; background: #8fd4ea; width: 0; box-shadow: 0 0 12px rgba(143, 212, 234, 0.7); }

#down-overlay {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at center, rgba(70, 0, 0, 0.2), rgba(28, 0, 0, 0.72));
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-3);
  animation: screenIn 260ms var(--ease-out);
}
#down-text {
  font-size: clamp(32px, 3.6vw, 48px); font-weight: 400; letter-spacing: 0.16em;
  color: #ff6a5a; text-shadow: 0 0 30px rgba(170, 0, 0, 0.9), 0 3px 6px #000;
}
.bar.bleed { width: 340px; height: 6px; }
#bleed-fill { height: 100%; background: linear-gradient(90deg, #ff5545, #a01a12); width: 100%; transition: width 0.3s linear; }
.down-note {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: var(--track);
  color: rgba(255, 170, 160, 0.6);
}

/* ---- scoreboard ---- */
#scoreboard {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  background: var(--surface-0);
  border: 1px solid var(--edge);
  border-top: 2px solid var(--sodium-deep);
  border-radius: 2px;
  padding: var(--s-5) var(--s-6);
  min-width: 540px;
  box-shadow: var(--lift-3);
  animation: contentIn 200ms var(--ease-out);
}
#scoreboard h3 {
  font-family: var(--f-mono); font-weight: 400;
  letter-spacing: var(--track-max); color: var(--sodium-deep);
  font-size: var(--t-2xs); margin-bottom: var(--s-4); text-align: center;
}
#scoreboard table { width: 100%; border-collapse: collapse; font-size: var(--t-lg); }
#scoreboard th {
  font-family: var(--f-mono); font-weight: 400;
  color: var(--moon-faint); font-size: var(--t-3xs); letter-spacing: var(--track);
  text-align: right; padding: 4px 12px 8px; border-bottom: 1px solid var(--edge);
}
#scoreboard th:first-child { text-align: left; }
#scoreboard td {
  padding: 8px 12px; letter-spacing: 1px; text-align: right;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 3px #000;
  border-bottom: 1px solid var(--edge-soft);
}
#scoreboard td:first-child { text-align: left; }
#scoreboard tr.is-down td { opacity: 0.75; }
#scoreboard tr.is-dead td { opacity: 0.45; }

/* ---- co-op roster (kept at contracted widths) ---- */
#multiplayer-roster {
  position: absolute;
  top: max(20px, env(safe-area-inset-top));
  right: max(22px, env(safe-area-inset-right));
  width: clamp(190px, 21vw, 248px);
  color: rgba(232, 228, 216, 0.9);
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.78));
}
.squad-kicker { margin: 0 0 4px 5px; color: rgba(150, 178, 210, 0.5); font-size: var(--t-3xs); letter-spacing: var(--track-wide); }
#multiplayer-roster-rows { display: flex; flex-direction: column; gap: 3px; }
.squad-row {
  --squad-color: var(--bone);
  min-height: 40px;
  display: flex; align-items: center; gap: var(--s-2);
  padding: 5px 7px 5px 6px;
  border-left: 3px solid var(--squad-color);
  background: linear-gradient(90deg, rgba(6, 9, 15, 0.78), rgba(6, 9, 15, 0.36) 78%, transparent);
  text-shadow: 0 1px 3px #000;
}
.squad-color { width: 5px; height: 18px; flex: 0 0 auto; background: var(--squad-color); box-shadow: 0 0 7px color-mix(in srgb, var(--squad-color) 45%, transparent); }
.squad-identity { min-width: 0; flex: 1 1 auto; }
.squad-name { overflow: hidden; color: rgba(244, 240, 226, 0.94); font-size: 14px; letter-spacing: 1.3px; line-height: 1.05; text-overflow: ellipsis; white-space: nowrap; }
.squad-persona { overflow: hidden; margin-top: 2px; color: rgba(150, 178, 210, 0.55); font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.45px; line-height: 1.1; text-overflow: ellipsis; text-transform: uppercase; white-space: nowrap; }
.squad-points { flex: 0 0 auto; min-width: 42px; color: rgba(232, 228, 216, 0.84); font-size: 15px; font-variant-numeric: tabular-nums; letter-spacing: 0.7px; text-align: right; }
.squad-voice {
  width: 25px; flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  color: rgba(150, 178, 210, 0.4);
  font-family: var(--f-mono); font-size: 7px; line-height: 1;
}
.squad-voice-glyph { position: relative; width: 7px; height: 10px; border: 1px solid currentColor; border-radius: 5px; }
.squad-voice-glyph::after {
  content: ''; position: absolute; left: 50%; bottom: -4px; width: 9px; height: 5px;
  transform: translateX(-50%); border-bottom: 1px solid currentColor; border-radius: 0 0 6px 6px;
}
.squad-voice[data-state="speaking"] { color: var(--ready); }
.squad-voice[data-state="speaking"] .squad-voice-glyph { animation: squadSpeak 0.72s var(--ease-io) infinite alternate; }
.squad-voice[data-state="muted"] { color: rgba(224, 69, 58, 0.62); }
@keyframes squadSpeak { from { opacity: 0.56; } to { opacity: 1; } }
#multiplayer-roster:not(.hidden) + #mic-indicator { display: none !important; }

#mic-indicator {
  position: fixed;
  top: calc(var(--hud-pad-y, 20px) + var(--map-size, 168px) + var(--map-chrome, 40px) + 10px);
  left: var(--hud-pad-x, 28px);
  display: flex; flex-direction: column; gap: 4px; align-items: flex-start;
  pointer-events: none; z-index: 34;
}
#mic-indicator .spk {
  font-family: var(--f-display); font-size: 14px; letter-spacing: var(--track);
  color: var(--ready); text-shadow: 0 2px 6px #000;
  background: rgba(6, 9, 15, 0.6); border: 1px solid rgba(95, 208, 138, 0.35);
  padding: 2px 10px; border-radius: 3px;
  animation: spkIn 0.15s var(--ease-out);
}
@keyframes spkIn { from { opacity: 0; transform: translate3d(-8px, 0, 0); } to { opacity: 1; transform: none; } }

#vox-sub {
  position: fixed; left: var(--hud-pad-x, 28px); bottom: 168px; max-width: 46ch;
  font-family: var(--f-mono); font-size: var(--t-sm); letter-spacing: 0.4px;
  color: #e8dfc8; text-shadow: 0 2px 6px #000; pointer-events: none; z-index: 34;
  opacity: 0.96;
}
#vox-sub::before { content: '📻 '; opacity: 0.7; }
.vox-anim { animation: voxIn 0.25s var(--ease-out); }
@keyframes voxIn { from { opacity: 0; transform: translate3d(0, 6px, 0); } to { opacity: 0.96; transform: none; } }

#lock-hint {
  position: fixed; left: 50%; top: 58%;
  transform: translateX(-50%);
  font-family: var(--f-display); font-size: var(--t-2xl); letter-spacing: var(--track-wide);
  color: var(--bone); text-shadow: 0 2px 10px #000; pointer-events: none; z-index: 35;
  animation: lockHintPulse 1.6s var(--ease-io) infinite;
}
@keyframes lockHintPulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }

/* ============================================================================
   MOBILE FPS CONTROLS
   ========================================================================== */
#touch-controls {
  position: fixed; inset: 0; z-index: 42;
  display: none;
  pointer-events: none;
  touch-action: none;
  overscroll-behavior: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
.touch-capable #touch-controls.is-active { display: block; }
#touch-look {
  position: absolute; z-index: 1;
  top: 0; right: 0; bottom: 0; left: 38%;
  pointer-events: auto;
  touch-action: none;
}
#touch-move {
  --stick-size: clamp(116px, 24vmin, 172px);
  position: absolute; z-index: 3;
  left: max(22px, env(safe-area-inset-left));
  bottom: max(22px, env(safe-area-inset-bottom));
  width: var(--stick-size); height: var(--stick-size);
  pointer-events: auto;
  touch-action: none;
}
.touch-stick-ring, #touch-move-knob {
  position: absolute; left: 50%; top: 50%;
  border-radius: 50%;
  transform: translate3d(-50%, -50%, 0);
  pointer-events: none;
}
.touch-stick-ring {
  width: 100%; height: 100%;
  border: 2px solid rgba(185, 203, 224, 0.28);
  background: radial-gradient(circle, rgba(7, 10, 16, 0.14) 0 34%, rgba(7, 10, 16, 0.48) 35% 100%);
  box-shadow: inset 0 0 22px rgba(0, 0, 0, 0.32), 0 3px 12px rgba(0, 0, 0, 0.35);
}
#touch-move-knob {
  width: 44%; height: 44%;
  margin-left: -22%; margin-top: -22%;
  transform: translate3d(0, 0, 0);
  border: 2px solid rgba(255, 180, 84, 0.54);
  background: rgba(24, 31, 42, 0.78);
  box-shadow: 0 0 16px rgba(255, 180, 84, 0.16);
}
.touch-actions { position: absolute; z-index: 4; pointer-events: none; }
.touch-actions-right {
  right: max(18px, env(safe-area-inset-right));
  bottom: max(18px, env(safe-area-inset-bottom));
  width: min(46vw, 380px); height: min(70vh, 390px);
}
.touch-actions-left {
  left: calc(max(22px, env(safe-area-inset-left)) + clamp(116px, 24vmin, 172px) + 12px);
  bottom: max(24px, env(safe-area-inset-bottom));
  display: flex; gap: 10px;
}
.touch-action {
  position: absolute;
  display: grid; place-items: center;
  width: clamp(50px, 9.2vmin, 68px); height: clamp(50px, 9.2vmin, 68px);
  min-width: 50px; min-height: 50px;
  padding: 0;
  border: 1px solid rgba(185, 203, 224, 0.38);
  border-radius: 50%;
  color: rgba(236, 230, 214, 0.9);
  background: rgba(7, 10, 16, 0.62);
  box-shadow: inset 0 0 16px rgba(150, 178, 210, 0.08), 0 3px 12px rgba(0, 0, 0, 0.38);
  font: 400 clamp(9px, 1.8vmin, 12px)/1 var(--f-display);
  letter-spacing: 0;
  pointer-events: auto;
  touch-action: none;
  transition: transform 80ms ease-out, border-color 80ms, background-color 80ms;
}
.touch-action.is-active, .touch-action.is-latched {
  transform: scale(0.9);
  color: #fff6e6;
  border-color: rgba(255, 180, 84, 0.84);
  background: rgba(121, 68, 21, 0.72);
}
.touch-fire {
  width: clamp(72px, 13vmin, 94px); height: clamp(72px, 13vmin, 94px);
  right: 0; bottom: 2%;
  border: 2px solid rgba(224, 69, 58, 0.68);
  background: rgba(72, 18, 18, 0.62);
  font-size: clamp(12px, 2.2vmin, 15px);
}
#touch-ads { right: 0; bottom: 37%; }
#touch-interact { right: 27%; bottom: 29%; border-color: rgba(255, 180, 84, 0.62); }
#touch-jump { right: 29%; bottom: 2%; }
#touch-reload { right: 55%; bottom: 20%; }
#touch-swap { right: 58%; bottom: 49%; }
#touch-crouch { right: 4%; bottom: 67%; }
.touch-actions-left .touch-action { position: relative; }
.touch-pause {
  z-index: 6;
  top: max(12px, env(safe-area-inset-top));
  right: max(12px, env(safe-area-inset-right));
  width: 48px; height: 48px; min-width: 48px; min-height: 48px;
  border-radius: 4px;
  font-size: 15px;
}
#touch-rotate-hint { display: none; }

.touch-capable #game-canvas { cursor: default; }
.touch-capable #hud { --hud-pad-x: max(14px, env(safe-area-inset-left)); --hud-pad-y: max(10px, env(safe-area-inset-top)); --map-size: 116px; }
.touch-capable #bottom-left { bottom: calc(max(10px, env(safe-area-inset-bottom)) + clamp(116px, 24vmin, 172px) + 8px); }
.touch-capable #bottom-right {
  right: max(76px, calc(env(safe-area-inset-right) + 64px));
  top: max(10px, env(safe-area-inset-top));
  bottom: auto;
  transform: scale(0.78);
  transform-origin: top right;
}
.touch-capable #multiplayer-roster { top: max(64px, env(safe-area-inset-top)); right: max(12px, env(safe-area-inset-right)); transform: scale(0.82); transform-origin: top right; }
.touch-capable #prompt-wrap { bottom: 22%; }

@media (orientation: portrait) and (pointer: coarse) {
  #touch-move { --stick-size: clamp(118px, 31vw, 154px); bottom: max(42px, env(safe-area-inset-bottom)); }
  .touch-actions-right { width: 62vw; height: 38vh; bottom: max(36px, env(safe-area-inset-bottom)); }
  #touch-jump { right: 36%; }
  .touch-actions-left { left: max(16px, env(safe-area-inset-left)); bottom: calc(max(42px, env(safe-area-inset-bottom)) + clamp(118px, 31vw, 154px) + 10px); }
  #touch-rotate-hint {
    position: absolute; left: auto; right: max(72px, env(safe-area-inset-right)); top: max(14px, env(safe-area-inset-top));
    display: block; transform: none;
    padding: 6px 10px; color: rgba(185, 203, 224, 0.66);
    background: rgba(7, 10, 16, 0.58); border: 1px solid rgba(150, 178, 210, 0.16);
    font: 9px/1 var(--f-mono); letter-spacing: 0.5px; white-space: nowrap;
  }
  .touch-capable #bottom-left {
    top: calc(max(10px, env(safe-area-inset-top)) + 126px);
    bottom: auto;
    transform: scale(0.78);
    transform-origin: top left;
  }
  .touch-capable #bottom-right { top: max(58px, env(safe-area-inset-top)); bottom: auto; }
  .touch-capable #toast { top: 46%; bottom: auto; }
  .touch-capable #minimap-frame, .touch-capable #multiplayer-roster { transform: scale(0.72); transform-origin: top right; }
}

/* ============================================================================
   SCOPES
   ========================================================================== */
#scope-overlay { position: fixed; inset: 0; pointer-events: none; z-index: 36; }
#scope-overlay.hidden { display: none; }
.scope-ring { position: absolute; inset: 0; background: radial-gradient(circle at center, transparent 33vmin, rgba(0,0,0,0.55) 33.8vmin, rgba(0,0,0,0.99) 34.4vmin); }
.scope-h { position: absolute; top: 50%; left: 50%; width: 64vmin; height: 2px; transform: translate(-50%, -1px); background: rgba(20, 20, 20, 0.85); box-shadow: 0 0 2px rgba(230, 230, 220, 0.7); }
.scope-v { position: absolute; top: 50%; left: 50%; width: 2px; height: 64vmin; transform: translate(-1px, -50%); background: rgba(20, 20, 20, 0.85); box-shadow: 0 0 2px rgba(230, 230, 220, 0.7); }
.scope-tick { position: absolute; left: 50%; width: 2px; height: 2vmin; transform: translateX(-1px); background: rgba(20, 20, 20, 0.85); box-shadow: 0 0 2px rgba(230, 230, 220, 0.7); }
.scope-tick.t1 { top: calc(50% + 6vmin); }
.scope-tick.t2 { top: calc(50% + 12vmin); }
.scope-tick.t3 { top: calc(50% + 18vmin); }
.scope-tick.t4 { top: calc(50% + 24vmin); }
#reddot-overlay { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); pointer-events: none; z-index: 36; }
#reddot-overlay.hidden { display: none; }
.rd-glass {
  width: 11vmin; height: 8.5vmin; border-radius: 12%;
  border: 2px solid rgba(30, 32, 36, 0.9);
  background: linear-gradient(135deg, rgba(160, 190, 210, 0.10), rgba(120, 150, 175, 0.05));
  box-shadow: inset 0 0 8px rgba(180, 200, 220, 0.15), 0 1px 3px rgba(0,0,0,0.6);
}
.rd-dot { position: absolute; left: 50%; top: 50%; width: 0.55vmin; height: 0.55vmin; transform: translate(-50%, -50%); border-radius: 50%; background: #ff2a1a; box-shadow: 0 0 6px 2px rgba(255, 40, 25, 0.75); }

/* ============================================================================
   TOUCH-DEVICE GATE
   ========================================================================== */
body.touch-device-gated > :not(#device-gate) { visibility: hidden; }
body.touch-device-gated #device-gate,
body.touch-device-gated #device-gate * { visibility: visible; }
#device-gate {
  z-index: 200; overflow: hidden; padding: 24px;
  background:
    radial-gradient(ellipse at 50% 110%, rgba(140, 60, 16, 0.22), transparent 58%),
    linear-gradient(180deg, #03050a 0%, #070a10 58%, #0d0b09 100%);
}
#device-gate .fog-layer { z-index: 0; }
.gate-grain {
  position: absolute; inset: -100px; pointer-events: none; opacity: 0.075; z-index: 1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.8'/%3E%3C/svg%3E");
  animation: grainJit 0.7s infinite steps(1);
}
.gate-vignette { position: absolute; inset: 0; z-index: 2; pointer-events: none; background: radial-gradient(ellipse at center, transparent 30%, rgba(0,0,0,.84) 100%); }
.gate-dossier, .gate-foot {
  position: absolute; z-index: 4;
  font: var(--t-2xs)/1.4 var(--f-mono);
  letter-spacing: 2.5px; color: rgba(150, 178, 210, 0.34); text-align: center;
}
.gate-dossier { top: 22px; left: 20px; right: 20px; }
.gate-foot { bottom: 18px; left: 20px; right: 20px; }
.device-gate-card {
  position: relative; z-index: 5; width: min(560px, 100%); padding: clamp(28px, 7vw, 58px);
  border: 1px solid var(--edge); background: var(--surface-0);
  box-shadow: var(--lift-3), inset 0 0 70px rgba(196, 122, 42, 0.05);
  text-align: center; animation: contentIn var(--dur-4) var(--ease-out) both;
}
.device-gate-card::before, .device-gate-card::after { content: ''; position: absolute; width: 28px; height: 28px; border-color: var(--sodium-deep); }
.device-gate-card::before { top: -1px; left: -1px; border-top: 2px solid; border-left: 2px solid; }
.device-gate-card::after { right: -1px; bottom: -1px; border-right: 2px solid; border-bottom: 2px solid; }
.gate-kicker { color: var(--sodium-deep); font: var(--t-xs)/1 var(--f-mono); letter-spacing: 5px; }
.gate-mark { width: 58px; height: 58px; margin: 26px auto 22px; border: 2px solid rgba(224, 69, 58, .6); border-radius: 50%; color: var(--alert); font: 46px/52px var(--f-display); transform: rotate(8deg); }
.device-gate-card h2 {
  font: 400 clamp(38px, 10vw, 64px)/.95 var(--f-display);
  letter-spacing: clamp(5px, 1.6vw, 11px); color: transparent;
  background: linear-gradient(178deg, #f6f2e8 2%, #96a3b4 21%, #e6e0d0 42%, #6f7a88 61%, #cfc5ae 80%, #5b6270 100%);
  -webkit-background-clip: text; background-clip: text;
  filter: drop-shadow(0 0 24px rgba(255, 150, 60, .3)) drop-shadow(0 5px 5px #000);
}
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .device-gate-card h2 { color: var(--bone); background: none; text-shadow: 0 0 28px rgba(255, 150, 60, .3), 0 5px 5px #000; }
}
.gate-lead { max-width: 26ch; margin: 20px auto 0; color: var(--moon); font: var(--t-lg)/1.55 var(--f-mono); }
.gate-copy { max-width: 48ch; margin: 16px auto 0; color: var(--moon-faint); font: var(--t-xs)/1.7 var(--f-mono); }
.gate-actions { display: grid; gap: 9px; margin-top: 28px; }
.gate-action, .gate-audio {
  min-height: 46px; display: flex; align-items: center; justify-content: center; padding: 11px 16px;
  border: 1px solid var(--edge); background: var(--surface-2); color: var(--bone-dim);
  font: var(--t-xs)/1.25 var(--f-mono); letter-spacing: 2px; text-decoration: none; cursor: pointer;
  transition: color var(--dur-2), border-color var(--dur-2), transform var(--dur-1);
}
.gate-action:hover { color: var(--bone); border-color: var(--edge-strong); }
.gate-action.is-pressed { transform: scale(0.98); }
.gate-action.primary { color: var(--bone); border-left: 3px solid var(--sodium); background: linear-gradient(90deg, rgba(255, 180, 84, .14), var(--surface-2)); }
.gate-audio { width: 100%; margin-top: 9px; border: 0; background: transparent; color: var(--moon-ghost); font-size: var(--t-3xs); }
.gate-audio[aria-pressed='true'] { color: var(--moon-dim); }

/* ============================================================================
   RESPONSIVE
   ========================================================================== */
/* ---- width-driven: below two-column viability, stack and shrink the brief -- */
@media (max-width: 1100px) {
  .menu-inner { grid-template-columns: minmax(0, 1fr); gap: clamp(16px, 2.4vh, 28px); width: min(720px, 100%); }
  .menu-brief { max-height: min(34vh, 300px); }
  .menu-help { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
}

/* ---- height-driven: shed the optional blocks, tightest last ---------------
   The control legend is reference material; the menu actions are the screen.
   Each step below removes legend first, then chrome, then decoration. */
@media (max-height: 900px) {
  #menu { --gutter-y: clamp(30px, 4.4vh, 48px); }
  .menu-brief { max-height: min(60vh, 460px); }
  .menu-brief:not(.open) .menu-help > .kp:nth-child(n + 5) { display: none; }
  .menu-foot { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
}
@media (max-height: 800px) {
  .menu-brief { max-height: min(56vh, 380px); }
  .menu-brief:not(.open) .menu-help > .kp:nth-child(n + 4) { display: none; }
  .brief-rule { margin: 8px 0; }
  .menu-foot { -webkit-line-clamp: 2; }
  .stamp { font-size: var(--t-xl); padding: 3px 9px 1px; }
}
@media (max-height: 700px) {
  #menu { --gutter-y: clamp(24px, 3.6vh, 36px); }
  .menu-brief:not(.open) .menu-help > .kp:nth-child(n + 3) { display: none; }
  .menu-foot { display: none; }
  .brief-rule { display: none; }
  .menu-corner.br { display: none; }
}
@media (max-height: 620px) {
  /* only the toggle survives — the legend opens as a scrolling overlay panel */
  .menu-brief { max-height: min(72vh, 340px); padding: 10px 12px; }
  .menu-brief:not(.open) .menu-help { display: none; }
  .title-rule { display: none; }
  .title-top { display: none; }
}
@media (max-height: 520px) {
  .menu-brief { display: none; }
  .title-sub { display: none; }
  .stamp { display: none; }
}
/* ---- panels: shed vertical padding before they start scrolling ---- */
@media (max-height: 820px) {
  .panel { padding: clamp(18px, 3vh, 32px) clamp(20px, 2.6vw, 40px); }
  .panel h2 { font-size: var(--t-2xl); margin-bottom: var(--s-3); }
  .options-panel h2 { margin-bottom: var(--s-4); }
  .opt-section + .opt-section { margin-top: var(--s-5); }
  .opt-grid { gap: var(--s-2) var(--s-5); }
  #lobby-code { font-size: 34px; letter-spacing: 8px; }
  .lobby-head { padding-bottom: var(--s-3); }
  .lobby-you { gap: var(--s-2) var(--s-5); margin-top: var(--s-3); padding-top: var(--s-3); }
  .lobby-row, .lobby-slot-empty { min-height: 52px; }
  .lobby-avatar { width: 32px; height: 32px; font-size: var(--t-md); }
  .section-head { margin: var(--s-3) 0 var(--s-2); }
  .row-buttons { margin-top: var(--s-4); }
  .lobby-fullscreen-prompt { margin-top: var(--s-3); gap: 6px; }
  .pause-panel .row-buttons.col .mbtn { min-height: 40px; padding-block: 8px; }
  .pause-panel .mbtn.primary { min-height: 46px; }
  .pause-stats { margin-bottom: var(--s-3); }
  .pstat { padding: var(--s-2) var(--s-3); }
  /* the legend is duplicated on the menu; the pause actions come first */
  .pause-controls { display: none; }
  .pause-panel .small-note { margin-top: var(--s-3); }
}
@media (max-height: 680px) {
  .panel h2 { font-size: var(--t-xl); letter-spacing: var(--track-wide); }
  .lobby-row, .lobby-slot-empty { min-height: 46px; }
  .lobby-note { display: none; }
  #char-cards { gap: var(--s-2); }
  .char-card canvas { width: 56px; height: 56px; }
}

/* ---- tall windows: there is room, so use it ---- */
@media (min-height: 1000px) and (min-width: 1101px) {
  #menu { --menu-rhythm: clamp(14px, 2vh, 30px); }
  .menu-brief { max-height: min(56vh, 720px); }
  .menu-buttons { gap: 4px; }
}
@media (max-width: 900px) {
  #lobby-players { grid-template-columns: minmax(0, 1fr); }
  .char-page { grid-template-columns: minmax(0, 1fr); }
  .char-page-left { max-width: 260px; }
}
@media (max-width: 700px) {
  #menu {
    align-items: flex-start;
    overflow-x: hidden;
    overflow-y: auto;
    padding-inline: max(20px, env(safe-area-inset-left), env(safe-area-inset-right));
  }
  .menu-inner {
    width: 100%;
    max-width: 560px;
    min-width: 0;
    margin: 0 auto;
    padding-block: max(56px, env(safe-area-inset-top)) max(48px, env(safe-area-inset-bottom));
  }
  .title-block { max-width: 100%; padding-right: 0; }
  #menu h1 { font-size: clamp(38px, 13vw, 54px); letter-spacing: 0.12em; text-indent: 0.12em; }
  .title-sub { letter-spacing: clamp(4px, 1.8vw, 7px); }
  .stamp { right: -6px; }
  .menu-buttons { width: min(100%, 380px); }
  #menu .menu-buttons .mbtn { min-height: 44px; }
  #menu .menu-buttons .mbtn::after { display: none; }
  .menu-more-links { position: static; width: 100%; margin-top: 4px; }
  .menu-brief { max-height: min(40vh, 300px); }
  .menu-help, .menu-foot { width: 100%; max-width: 48rem; overflow-wrap: anywhere; }
  .panel { padding: var(--s-5) var(--s-4); }
  .panel.wide { min-width: 0; width: 94vw; }
  .panel h2 { font-size: var(--t-2xl); letter-spacing: var(--track-wide); }
  .opt-sections { column-count: 1; }
  .lobby-head { flex-direction: column; align-items: stretch; }
  .lobby-code-row { justify-content: flex-start; }
  #lobby .lobby-action-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #lobby .lobby-secondary-action { width: min(440px, 88%); }
  #multiplayer-roster { width: min(226px, calc(100vw - 36px)); right: 18px; }
  .squad-row { min-height: 44px; }
  .squad-name { font-size: 16px; }
  .squad-persona { font-size: 10px; }
  .squad-points { font-size: 16px; }
  #banner { font-size: var(--t-3xl); }
  #scoreboard { min-width: 0; width: 94vw; padding: var(--s-4); }
}
@media (max-width: 440px) {
  #lobby .lobby-action-row { grid-template-columns: 1fr; }
  #lobby .lobby-secondary-action { width: 92%; }
  .lobby-fullscreen-note { font-size: 15px; }
}
@media (max-height: 540px) {
  #multiplayer-roster-rows { gap: 2px; }
  .squad-row { min-height: 34px; padding-block: 3px; }
  .squad-kicker { display: none; }
}
/* very large displays: hold the composition instead of letting it drift apart */
@media (min-width: 2200px) {
  :root { --t-md: 16px; --t-lg: 18px; --t-xl: 22px; --t-2xl: 30px; --t-3xl: 38px; --t-4xl: 54px; }
  .menu-inner { width: min(1560px, 100%); grid-template-columns: minmax(0, 1fr) minmax(320px, 400px); }
  .panel.wide { width: min(1240px, 88vw); }
  #hud { --map-size: 212px; }
}
/* short viewports: the HUD stays inside the frame before anything else gives */
@media (max-height: 780px) {
  #hud { --map-size: 146px; }
  #round { font-size: 44px; min-height: 40px; }
  .vitals-block { width: 168px; }
  #bottom-left { gap: 4px; }
  .perk-icon { width: 28px; height: 28px; }
}

/* ============================================================================
   REDUCED MOTION — keep every state change, drop the travel
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .screen, .panel, .menu-inner, .pause-shell, .load-inner,
  .menu-corner, .title-top, .title-sub, .title-rule, .stamp,
  #menu h1, .menu-brief, .lobby-row, .char-card, .perk-icon, .nade { animation: none !important; opacity: 1 !important; transform: none !important; }
  #menu .menu-buttons .mbtn { animation: none !important; opacity: 1; transform: none; }
  #menu .menu-buttons .mbtn:hover:not(:disabled),
  #menu .menu-buttons .mbtn:focus-visible { transform: none; }
  /* the hover wash still lands, it just arrives instead of travelling */
  #menu .menu-buttons .mbtn { background-size: 0% 100%; }
  #menu .menu-buttons .mbtn:hover:not(:disabled),
  #menu .menu-buttons .mbtn:focus-visible { background-size: 100% 100%; }
  /* the crackle and the glitch are motion by definition — drop them entirely
     rather than freeze them mid-tear (display:none also stops the SMIL inside
     the crackle filter). The bloom stays, held at its mid level, so the
     wordmark still reads as lit rather than flat. */
  .title-plasma::after, .title-tear { display: none !important; }
  .title-glow::before { animation: none !important; opacity: 0.22 !important; transform: none !important; }
  .title-plasma::before { animation: none !important; opacity: 0.26 !important; }
  #menu h1 { background-position: 50% 48%, 0 0 !important; }
  .title-rule em { animation: none !important; opacity: 1 !important; }
  .scene-beam, .scene-ridge, .scene-dust, .fog-layer, #film-grain, #film-scratch, .scene-sky,
  #skyline .win, .gate-grain { animation: none !important; }
  #btn-lobby-fs.fullscreen-callout::before,
  #btn-solo-fs-toggle.fullscreen-callout::before { animation: none !important; display: none; }
  .load-bar-scan { display: none; }
  .squad-voice[data-state="speaking"] .squad-voice-glyph { animation: none !important; }
  #lock-hint, .drop-timer, .load-kicker, #ammo.empty .mag { animation: none !important; opacity: 1 !important; }
  /* damage direction is information, not decoration — keep it, just don't move */
  #dmg-dir .dmg-arc { animation-duration: 700ms !important; }
  #banner.banner-anim, #banner-sub.banner-sub-anim { animation: bannerHold 3.4s steps(1) forwards !important; }
  @keyframes bannerHold { 0%, 88% { opacity: 1; } 100% { opacity: 0; } }
}

/* legacy HUD corner buttons (markup no longer shipped, kept for safety) */
#hud-btns { position: fixed; top: 14px; right: 14px; display: flex; gap: 8px; z-index: 40; }

