/* ============================================================
   SmartAdmin. RustApp-style theme v2
   palette sampled from RustApp screenshots:
   bg #141414 · surfaces #1e1e1e · pills/buttons #272727-#2d2d2d
   interactive BLUE #2f9df5 · online LIME #8bc94e · danger #e0342b
   ============================================================ */

/* ---- local fonts (served from /fonts, no external requests) ---- */
@font-face{font-family:'Inter';src:url('fonts/inter-latin.woff2') format('woff2');font-weight:100 900;font-display:swap;font-style:normal}
@font-face{font-family:'Space Grotesk';src:url('fonts/spacegrotesk-latin.woff2') format('woff2');font-weight:300 700;font-display:swap;font-style:normal}
@font-face{font-family:'Sora';src:url('fonts/sora-latin.woff2') format('woff2');font-weight:100 800;font-display:swap;font-style:normal}
@font-face{font-family:'JetBrains Mono';src:url('fonts/jetbrainsmono-latin.woff2') format('woff2');font-weight:100 800;font-display:swap;font-style:normal}
@font-face{font-family:'Vazirmatn';src:url('fonts/vazirmatn-arabic.woff2') format('woff2');font-weight:100 900;font-display:swap;font-style:normal}

:root{
  --bg:#141414;
  --surface-1:#1e1e1e;
  --surface-2:#272727;
  --surface-3:#2d2d2d;
  --input:#141414;
  --line:#262626;
  --line-bright:#363636;
  --topbar:#191919;

  --blue:#2f9df5;
  --blue-strong:#0d8de9;
  --blue-deep:rgba(47,157,245,.13);

  /* --green is the ONLINE lime; kept under the old name so every
     status rule (dots, map pips, pills) picks it up unchanged */
  --green:#8bc94e;
  --green-dim:#6ea83e;
  --green-deep:rgba(139,201,78,.10);
  --green-glow:rgba(139,201,78,.28);

  --amber:#d9a13c;
  --yellow:#e9c34a;
  --red:#e0342b;
  --red-soft:rgba(224,52,43,.12);
  --blue-old:#5a9cf2;
  --purple:#a87bf0;

  --text:#f2f2f2;
  --text-dim:#8d8d8d;
  --text-faint:#5c5c5c;

  /* semantic tokens so hovers/borders/map adapt per theme */
  --hover:#222222;
  --hover-strong:#2a2a2a;
  --pill-bg:rgba(20,20,20,.85);
  --pill-line:#333333;
  --map-bg:#0e0e0e;
  --border-hard:#101010;
  --track:#2e2e2e;
  --danger-text:#ff7d76;
  --chat-blue:#7ab5ff;
  --chat-green:#a9d97f;
  --lyr-on-bg:#e8e8e8;
  --lyr-on-text:#111111;
  /* terminal + code syntax stay dark in every theme (like a real console) */
  --term-bg:#0e0e0e;
  --term-text:#d4d4d4;
  --syn-blue:#569cd6;
  --syn-orange:#ce9178;
  --syn-green:#b5cea8;
  --syn-cyan:#9cdcfe;

  /* event-stream category colors (used on tag text only) */
  --c-conn:#8bc94e; --c-combat:#e5636b; --c-chat:#5aa7f0; --c-raid:#d9a13c;
  --c-base:#e9c34a; --c-punish:#e5636b; --c-clan:#a87bf0; --c-team:#5aa7f0;
  --c-econ:#e9c34a; --c-loot:#d9a13c; --c-vip:#e9c34a; --c-threat:#e5636b;
  --c-admin:#a87bf0; --c-spawn:#8bc94e; --c-bag:#5aa7f0; --c-misc:#7a7a7a;

  --mono:'JetBrains Mono',ui-monospace,'SFMono-Regular',Menlo,Consolas,'Vazirmatn',monospace;
  --font-ui:'Inter';
  --sans:var(--font-ui),system-ui,-apple-system,'Segoe UI',Roboto,'Vazirmatn',sans-serif;

  --r:10px; --r-sm:8px; --r-lg:12px;
  --gap:16px;
  --nav-w:236px;
  --ring:0 0 0 3px rgba(47,157,245,.22);
  --shadow:0 18px 50px -20px rgba(0,0,0,.7);
  --shadow-sm:0 1px 3px rgba(0,0,0,.35);
}

/* ============ THEME: Dark Night (pure/very black) ============ */
html.theme-darknight{
  --bg:#000000;
  --surface-1:#0a0a0a;
  --surface-2:#111111;
  --surface-3:#161616;
  --input:#050505;
  --line:#1a1a1a;
  --line-bright:#2a2a2a;
  --topbar:#050505;
  --text:#f4f4f4;
  --text-dim:#8a8a8a;
  --text-faint:#525252;
  --hover:#141414;
  --hover-strong:#1c1c1c;
  --pill-bg:rgba(10,10,10,.9);
  --pill-line:#242424;
  --map-bg:#000000;
  --border-hard:#000000;
  --track:#1a1a1a;
  --danger-text:#ff7d76;
  --chat-blue:#7ab5ff;
  --chat-green:#a9d97f;
  --lyr-on-bg:#e8e8e8;
  --lyr-on-text:#0a0a0a;
  --shadow:0 18px 50px -20px rgba(0,0,0,.9);
  --shadow-sm:0 1px 3px rgba(0,0,0,.6);
}

/* ============ THEME: Abyss (deep navy · teal accent) ============
   A cool deep-ocean palette: navy-slate surfaces that step cleanly,
   a bright teal-cyan as the interactive accent, and a soft aqua text
   tint. Every text/hover/status pair is contrast-checked. */
html.theme-abyss{
  --bg:#0a1622;
  --surface-1:#0f1f30;
  --surface-2:#16293c;
  --surface-3:#1d3348;
  --input:#0b1a29;
  --line:#1e3346;
  --line-bright:#2b455c;
  --topbar:#0c1c2c;

  --blue:#2dd4bf;
  --blue-strong:#14b8a6;
  --blue-deep:rgba(45,212,191,.12);

  --green:#4ade80;
  --green-dim:#38b866;
  --green-deep:rgba(74,222,128,.12);
  --green-glow:rgba(74,222,128,.28);

  --amber:#f0b445;
  --yellow:#f5cf5b;
  --red:#f4645c;
  --red-soft:rgba(244,100,92,.14);
  --purple:#a78bfa;

  --text:#e6f0f5;
  --text-dim:#8ba3b5;
  --text-faint:#5a7286;

  --c-conn:#4ade80; --c-combat:#f4645c; --c-chat:#2dd4bf; --c-raid:#f0b445;
  --c-base:#f5cf5b; --c-punish:#f4645c; --c-clan:#a78bfa; --c-team:#2dd4bf;
  --c-econ:#f5cf5b; --c-loot:#f0b445; --c-vip:#f5cf5b; --c-threat:#f4645c;
  --c-admin:#a78bfa; --c-spawn:#4ade80; --c-bag:#2dd4bf; --c-misc:#6b8397;

  --hover:#16293c;
  --hover-strong:#1d3348;
  --pill-bg:rgba(11,26,41,.85);
  --pill-line:#2b455c;
  --map-bg:#081320;
  --border-hard:#0a1622;
  --track:#1e3346;
  --danger-text:#f4645c;
  --chat-blue:#5eead4;
  --chat-green:#86efac;
  --lyr-on-bg:#2dd4bf;
  --lyr-on-text:#08141f;

  --ring:0 0 0 3px rgba(45,212,191,.22);
  --shadow:0 18px 50px -20px rgba(0,0,0,.75);
  --shadow-sm:0 1px 3px rgba(0,0,0,.5);
}
/* Abyss: avatar/badge glyphs sit on a teal fill. Keep them dark for contrast */
html.theme-abyss .acct-av,
html.theme-abyss .badge{color:#08141f}

/* ============ THEME: Desert (warm khaki · sand accent) ============
   Warm earth tones: dark coffee/olive surfaces, a sand-khaki accent,
   and cream text. Calm and premium, inspired by desert dusk. */
html.theme-desert{
  --bg:#1a150f;
  --surface-1:#211a12;
  --surface-2:#2c2318;
  --surface-3:#372c1e;
  --input:#181209;
  --line:#33291c;
  --line-bright:#463825;
  --topbar:#1c160e;

  --blue:#d4a24e;
  --blue-strong:#c28f3a;
  --blue-deep:rgba(212,162,78,.13);

  --green:#a3b56b;
  --green-dim:#8a9a56;
  --green-deep:rgba(163,181,107,.13);
  --green-glow:rgba(163,181,107,.26);

  --amber:#e0a955;
  --yellow:#e8c56a;
  --red:#d97757;
  --red-soft:rgba(217,119,87,.15);
  --purple:#c39bd3;

  --text:#f0e6d2;
  --text-dim:#b3a488;
  --text-faint:#7d7059;

  --c-conn:#a3b56b; --c-combat:#d97757; --c-chat:#d4a24e; --c-raid:#e0a955;
  --c-base:#e8c56a; --c-punish:#d97757; --c-clan:#c39bd3; --c-team:#d4a24e;
  --c-econ:#e8c56a; --c-loot:#e0a955; --c-vip:#e8c56a; --c-threat:#d97757;
  --c-admin:#c39bd3; --c-spawn:#a3b56b; --c-bag:#d4a24e; --c-misc:#8a7c63;

  --hover:#2c2318;
  --hover-strong:#372c1e;
  --pill-bg:rgba(24,18,9,.85);
  --pill-line:#463825;
  --map-bg:#14100a;
  --border-hard:#14100a;
  --track:#33291c;
  --danger-text:#e58b6d;
  --chat-blue:#e0b878;
  --chat-green:#bcca8f;
  --lyr-on-bg:#d4a24e;
  --lyr-on-text:#1a150f;

  --ring:0 0 0 3px rgba(212,162,78,.22);
  --shadow:0 18px 50px -20px rgba(0,0,0,.8);
  --shadow-sm:0 1px 3px rgba(0,0,0,.55);
}
html.theme-desert .acct-av,
html.theme-desert .badge{color:#1a150f}

/* ============ THEME: Rosé Pine (muted rose · iris) ============
   The soho-inspired Rosé Pine palette: deep muted-violet base, a warm
   rose accent, iris/foam supporting hues, and soft lavender-white text. */
html.theme-rosepine{
  --bg:#191724;
  --surface-1:#1f1d2e;
  --surface-2:#26233a;
  --surface-3:#2f2b45;
  --input:#16141f;
  --line:#2a273f;
  --line-bright:#3a3555;
  --topbar:#1b1927;

  --blue:#ebbcba;
  --blue-strong:#e0a3a1;
  --blue-deep:rgba(235,188,186,.13);

  --green:#9ccfd8;
  --green-dim:#7fb8c2;
  --green-deep:rgba(156,207,216,.13);
  --green-glow:rgba(156,207,216,.26);

  --amber:#f6c177;
  --yellow:#f6c177;
  --red:#eb6f92;
  --red-soft:rgba(235,111,146,.15);
  --purple:#c4a7e7;

  --text:#e0def4;
  --text-dim:#a4a0c4;
  --text-faint:#6e6a8a;

  --c-conn:#9ccfd8; --c-combat:#eb6f92; --c-chat:#ebbcba; --c-raid:#f6c177;
  --c-base:#f6c177; --c-punish:#eb6f92; --c-clan:#c4a7e7; --c-team:#31748f;
  --c-econ:#f6c177; --c-loot:#f6c177; --c-vip:#f6c177; --c-threat:#eb6f92;
  --c-admin:#c4a7e7; --c-spawn:#9ccfd8; --c-bag:#ebbcba; --c-misc:#908caa;

  --hover:#26233a;
  --hover-strong:#2f2b45;
  --pill-bg:rgba(22,20,31,.85);
  --pill-line:#3a3555;
  --map-bg:#14121d;
  --border-hard:#14121d;
  --track:#2a273f;
  --danger-text:#eb6f92;
  --chat-blue:#f0cbc9;
  --chat-green:#b3dde3;
  --lyr-on-bg:#ebbcba;
  --lyr-on-text:#191724;

  --ring:0 0 0 3px rgba(235,188,186,.22);
  --shadow:0 18px 50px -20px rgba(0,0,0,.7);
  --shadow-sm:0 1px 3px rgba(0,0,0,.5);
}
html.theme-rosepine .acct-av,
html.theme-rosepine .badge{color:#191724}

/* ================= THEME: Light (bright/white) ================
   Rebuilt with a cohesive slate-tinted palette. Every layer steps
   cleanly (bg < surface-2 < surface-1) and every text/hover pair is
   contrast-checked so nothing disappears on hover or on white. */
html.theme-light{
  --bg:#eef1f5;
  --surface-1:#ffffff;
  --surface-2:#f6f8fa;
  --surface-3:#eaeef2;
  --input:#ffffff;
  --line:#e4e8ee;
  --line-bright:#d3d9e1;
  --topbar:#ffffff;

  --blue:#2172d6;
  --blue-strong:#1560c4;
  --blue-deep:rgba(33,114,214,.10);

  --green:#3f9327;
  --green-dim:#357a21;
  --green-deep:rgba(63,147,39,.12);
  --green-glow:rgba(63,147,39,.22);

  --amber:#bd7a12;
  --yellow:#a8790a;
  --red:#d13a30;
  --red-soft:rgba(209,58,48,.10);
  --purple:#7c4fd0;

  --text:#1b2029;
  --text-dim:#5a6472;
  --text-faint:#8b95a3;

  /* semantic tokens. Tuned for a light surface */
  --hover:#eef1f5;
  --hover-strong:#e5e9ef;
  --pill-bg:#f0f3f7;
  --pill-line:#d8dee6;
  --map-bg:#d6e0ea;
  --border-hard:#e4e8ee;
  --track:#e2e7ee;
  --danger-text:#d13a30;
  --chat-blue:#2172d6;
  --chat-green:#357a21;
  --lyr-on-bg:#2b3340;
  --lyr-on-text:#ffffff;

  --c-conn:#3f9327; --c-combat:#d13a30; --c-chat:#2172d6; --c-raid:#bd7a12;
  --c-base:#a8790a; --c-punish:#d13a30; --c-clan:#7c4fd0; --c-team:#2172d6;
  --c-econ:#a8790a; --c-loot:#bd7a12; --c-vip:#a8790a; --c-threat:#d13a30;
  --c-admin:#7c4fd0; --c-spawn:#3f9327; --c-bag:#2172d6; --c-misc:#78828f;

  --ring:0 0 0 3px rgba(33,114,214,.18);
  --shadow:0 16px 44px -20px rgba(30,41,59,.26);
  --shadow-sm:0 1px 2px rgba(30,41,59,.10);
}

/* --- light-theme fine-tuning for spots that need explicit contrast --- */
html.theme-light .nav-link:hover{background:var(--hover-strong);color:var(--text)}
html.theme-light .nav-link.active{background:var(--blue-deep);color:var(--blue)}
html.theme-light .nav-link.active .ico{opacity:1}
html.theme-light .acct-trigger:hover,
html.theme-light .acct-trigger.open{background:var(--surface-2);border-color:var(--line-bright)}
html.theme-light .badge{color:#fff}
html.theme-light .tbl tr:hover td{background:var(--surface-2)}
html.theme-light .frow:hover{background:var(--surface-2)}
html.theme-light *::-webkit-scrollbar-thumb{background:#cdd4dd}
html.theme-light *::-webkit-scrollbar-thumb:hover{background:#b9c1cc}
html.theme-light .live-pill{background:var(--surface-2);border-color:var(--line-bright)}
html.theme-light .seg,html.theme-light .map-layers .lyr{background:var(--surface-2)}

/* player-authored strings are often Persian (RTL); pick direction per element */
.who,.cn,.nm,.namecell,.cx,.msg,.ch,.bw-name,.feed .ev,.frow .who,
.mu-a,.mu-v,.member .nm,.report .nm,.rep-name,.sign .nm,.pmeta .namecell{
  unicode-bidi:plaintext; text-align:start;
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:var(--sans); font-size:13.5px; line-height:1.5;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
a{color:inherit;text-decoration:none}
button{font-family:var(--sans);cursor:pointer}
::selection{background:rgba(47,157,245,.35);color:#fff}

*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--line-bright);border-radius:10px;border:2px solid var(--bg)}
*::-webkit-scrollbar-thumb:hover{background:#3f3f3f}

/* ---------- atoms ---------- */
.mono{font-family:var(--mono)}
.dim{color:var(--text-dim)}
.faint{color:var(--text-faint)}
.green{color:var(--green)}
.amber{color:var(--amber)}
.red{color:var(--red)}
.blue{color:var(--blue)}
.right{margin-left:auto}
.nowrap{white-space:nowrap}
.hidden{display:none !important}
.eyebrow{font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-faint);font-weight:600}
.coord{font-family:var(--mono);color:var(--text-dim);font-size:11px;letter-spacing:.02em}
.cup{font-variant-numeric:tabular-nums}

/* ============================================================
   LOGIN

   One card, one job. The old one had corner brackets, a stencil tagline and
   two stacked labels, which is a lot of furniture around two text fields.
   What is left is the mark, the two fields, and a button, with the labels
   living inside the inputs until you type.
   ============================================================ */
.lg-wrap{min-height:100dvh;display:grid;place-items:center;padding:24px;position:relative;
  background:var(--bg);overflow:hidden}
/* a slow, very low contrast wash so the card has something to sit on without
   the page turning into a wallpaper */
.lg-bg{position:absolute;inset:-30%;pointer-events:none;
  background:
    radial-gradient(46% 40% at 22% 18%, rgba(47,157,245,.12), transparent 70%),
    radial-gradient(40% 38% at 80% 82%, rgba(139,201,78,.07), transparent 70%);
  filter:blur(20px)}
@media(prefers-reduced-motion:no-preference){
  .lg-bg{animation:lg-drift 34s ease-in-out infinite alternate}
  @keyframes lg-drift{from{transform:translate3d(-2%,-1%,0) scale(1)}
                      to{transform:translate3d(2%,2%,0) scale(1.06)}}
}
.lg-card{position:relative;width:min(392px,100%);background:var(--surface-1);
  border:1px solid var(--line-bright);border-radius:16px;padding:30px 28px 24px;
  box-shadow:0 24px 60px -20px rgba(0,0,0,.7), 0 2px 0 0 rgba(255,255,255,.03) inset}

.lg-brand{display:flex;align-items:center;gap:13px;margin-bottom:26px}
.lg-mark{display:inline-flex;flex:0 0 auto}
.lg-name{font-size:19px;font-weight:750;letter-spacing:-.01em;color:var(--text);line-height:1.1}
.lg-tag{font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--text-faint);margin-top:3px}

.lg-form{display:flex;flex-direction:column;gap:12px}

/* The label starts where the text will be and moves up out of the way on
   focus, so an empty field is never a mystery and a full one is never
   covered. :placeholder-shown is what makes it work without any JS. */
.lg-field{position:relative}
.lg-in{width:100%;background:var(--input);border:1px solid var(--line-bright);color:var(--text);
  padding:22px 14px 9px;border-radius:10px;font-family:var(--sans);font-size:14.5px;
  transition:border-color .15s, box-shadow .15s, background .15s}
.lg-field:has(.lg-eye) .lg-in{padding-right:44px}
.lg-in:hover{background:var(--surface-2)}
.lg-in:focus{outline:none;border-color:var(--blue);box-shadow:var(--ring);background:var(--input)}
.lg-in:-webkit-autofill{-webkit-text-fill-color:var(--text);
  -webkit-box-shadow:0 0 0 40px var(--input) inset;caret-color:var(--text)}
.lg-field label{position:absolute;left:15px;top:7px;font-size:10px;font-weight:600;
  letter-spacing:.07em;text-transform:uppercase;color:var(--text-faint);
  pointer-events:none;transition:top .13s ease, font-size .13s ease, color .13s ease}
.lg-in:placeholder-shown + label{top:16px;font-size:13.5px;letter-spacing:0;
  text-transform:none;color:var(--text-dim)}
/* .filled is set from JS and wins over :placeholder-shown, because a field a
   password manager filled does not always get restyled on its own */
.lg-field.filled .lg-in + label,
.lg-in:focus + label{top:7px;font-size:10px;letter-spacing:.07em;
  text-transform:uppercase;color:var(--text-faint)}
.lg-in:focus + label{color:var(--blue)}

.lg-eye{position:absolute;right:6px;top:50%;transform:translateY(-50%);
  width:32px;height:32px;display:grid;place-items:center;border:0;background:none;
  color:var(--text-faint);border-radius:8px;cursor:pointer}
.lg-eye:hover{color:var(--text);background:var(--hover)}
.lg-eye:focus-visible{outline:none;box-shadow:var(--ring)}

.lg-err{display:none;align-items:flex-start;gap:8px;font-size:12.5px;line-height:1.55;
  color:var(--danger-text);background:var(--red-soft);
  border:1px solid rgba(224,52,43,.35);border-radius:9px;padding:9px 11px}
.lg-err.on{display:flex}
.lg-err .ico-svg{flex:0 0 auto;margin-top:1px}
/* being rate limited is not the same as being wrong */
.lg-err.wait{color:var(--amber);background:rgba(217,161,60,.1);border-color:rgba(217,161,60,.35)}

.lg-btn{margin-top:4px;width:100%;min-height:44px;display:flex;align-items:center;
  justify-content:center;gap:8px;background:var(--blue-strong);color:#fff;border:none;
  padding:12px;border-radius:10px;font-weight:700;letter-spacing:.02em;font-size:14px;
  cursor:pointer;transition:filter .15s, transform .06s}
.lg-btn:hover:not(:disabled){filter:brightness(1.09)}
.lg-btn:active:not(:disabled){transform:translateY(1px)}
.lg-btn:disabled{opacity:.85;cursor:default}
.lg-btn:focus-visible{outline:none;box-shadow:var(--ring)}
.lg-spin{width:15px;height:15px;border-radius:50%;flex:0 0 auto;
  border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:lg-spin .7s linear infinite}
@keyframes lg-spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.lg-spin{animation-duration:2s}}

.lg-foot{display:flex;align-items:center;justify-content:center;gap:6px;margin-top:20px;
  font-size:10.5px;color:var(--text-faint);letter-spacing:.02em}

@media(max-width:420px){
  .lg-card{padding:26px 20px 20px;border-radius:14px}
  .lg-wrap{padding:16px;align-items:start;padding-top:12vh}
}


/* ============================================================
   SHELL
   ============================================================ */
.app{display:grid;grid-template-columns:var(--nav-w) 1fr;min-height:100vh}

/* sidebar. LIGHTER than the content, like RustApp */
.nav{background:var(--surface-1);border-right:1px solid var(--border-hard);
  display:flex;flex-direction:column;position:sticky;top:0;height:100vh;padding:0}
.nav-brand{padding:16px 16px 12px;display:flex;flex-direction:column;gap:2px}
.nav-brand .mark{font-size:15.5px;font-weight:700;letter-spacing:.01em;color:var(--text);
  display:flex;align-items:center;gap:10px}
.nav-brand .mark .logo{width:36px;height:36px;flex:0 0 auto}
.nav-brand .sub{font-size:9px;letter-spacing:.14em;color:var(--text-faint);text-transform:uppercase;padding-left:40px}
.nav-items{padding:6px 10px 10px;overflow-y:auto;flex:1}
.nav-sec{font-size:10px;letter-spacing:.05em;color:var(--text-faint);
  padding:14px 10px 6px;font-weight:600;text-transform:capitalize}
.nav-link{display:flex;align-items:center;gap:11px;padding:8px 10px;margin:1px 0;
  color:var(--text-dim);font-size:13px;font-weight:500;letter-spacing:.01em;
  border-radius:var(--r-sm);position:relative;
  transition:background .13s,color .13s}
.nav-link .ico{width:17px;text-align:center;opacity:.75;flex:0 0 auto;font-size:13px}
.nav-link:hover{color:var(--text);background:var(--hover)}
.nav-link.active{color:var(--text);background:var(--surface-3)}
.nav-link.active .ico{opacity:1}
.nav-link .badge{margin-left:auto;background:var(--red);color:#fff;font-size:10px;font-weight:700;
  padding:1px 7px;border-radius:999px;min-width:18px;text-align:center}
.nav-foot{padding:10px 12px;border-top:1px solid var(--line);font-size:12.5px}
.nav-foot .who{color:var(--text);font-weight:600}
.nav-foot .out{color:var(--text-dim);margin-top:6px;display:inline-block}
.nav-foot .out:hover{color:var(--red)}

/* account/settings trigger at the bottom of the sidebar */
.acct-trigger{display:flex;align-items:center;gap:10px;width:100%;padding:9px 10px;border-radius:var(--r);
  background:transparent;border:1px solid transparent;color:var(--text);cursor:pointer;text-align:start;transition:background .12s,border-color .12s}
.acct-trigger:hover{background:var(--surface-2);border-color:var(--line-bright)}
.acct-trigger.open{background:var(--surface-2);border-color:var(--line-bright)}
.acct-av{width:30px;height:30px;flex:0 0 auto;border-radius:8px;background:linear-gradient(135deg,var(--blue),var(--blue-strong));
  display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:13px}
.acct-meta{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;line-height:1.2}
.acct-name{font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:13px;display:block}
.acct-sub{font-size:10px;color:var(--text-faint);letter-spacing:.05em;text-transform:uppercase;display:block}
.acct-caret{flex:0 0 auto;color:var(--text-faint);transition:transform .16s}
.acct-trigger.open .acct-caret{transform:rotate(180deg)}

/* Above the mobile drawer (220) and the bottom bar (200). It used to sit at
   200, so on a phone the account menu opened UNDERNEATH the drawer that had
   just launched it and only a corner of it was visible. */
.settings-pop{position:fixed;z-index:230;width:264px;background:var(--surface-1);border:1px solid var(--line-bright);
  border-radius:var(--r-lg);box-shadow:var(--shadow);padding:8px;animation:popin .14s ease}
@keyframes popin{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
.sp-sec{font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-faint);font-weight:700;padding:8px 8px 5px}
.sp-row{display:grid;grid-template-columns:1fr 1fr;gap:6px;padding:0 4px 4px}
.sp-opt{display:flex;align-items:center;gap:7px;padding:8px 9px;border-radius:8px;border:1px solid var(--line);
  background:var(--surface-2);color:var(--text);cursor:pointer;font-size:12px;font-weight:500;transition:border-color .12s,background .12s;width:100%;text-align:start}
.sp-opt:hover{border-color:var(--line-bright)}
.sp-opt.active{border-color:var(--blue);background:var(--blue-deep);color:var(--blue)}
.sp-swatch{width:15px;height:15px;border-radius:4px;flex:0 0 auto;border:1px solid rgba(128,128,128,.35)}
.sp-fopt{display:block;width:100%;text-align:start;padding:9px 11px;border-radius:8px;border:1px solid var(--line);
  background:var(--surface-2);color:var(--text);cursor:pointer;margin:0 4px 6px;transition:border-color .12s,background .12s}
.sp-fopt:hover{border-color:var(--line-bright)}
.sp-fopt.active{border-color:var(--blue);background:var(--blue-deep)}
.sp-fname{font-size:14px;font-weight:600}
.sp-fdesc{font-size:10.5px;color:var(--text-faint);margin-top:1px}
.sp-div{height:1px;background:var(--line);margin:8px 4px}
.sp-logout{display:flex;align-items:center;gap:9px;width:calc(100% - 8px);margin:2px 4px;padding:10px 11px;border-radius:8px;
  border:1px solid var(--red-soft);background:var(--red-soft);color:#ff6b6b;cursor:pointer;font-weight:600;font-size:12.5px;transition:background .12s}
.sp-logout:hover{background:rgba(224,52,43,.2)}
.nav-owner{margin-top:14px}
.role-badge{display:inline-block;margin-left:8px;padding:1px 8px;border:1px solid var(--line-bright);
  border-radius:999px;color:var(--text-dim);font-size:8.5px;letter-spacing:.12em;vertical-align:middle;font-weight:700;text-transform:uppercase}

/* main */
.main{min-width:0;display:flex;flex-direction:column}
.topbar{display:flex;align-items:center;gap:18px;padding:0 22px;height:56px;
  border-bottom:1px solid var(--border-hard);background:var(--topbar);
  position:sticky;top:0;z-index:40}
.topbar .host{font-size:13.5px;color:var(--text);font-weight:600;
  max-width:40ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tb-stat{display:flex;flex-direction:column;line-height:1.2}
.tb-stat .v{font-size:15px;color:var(--text);font-weight:700;font-variant-numeric:tabular-nums}
.tb-stat .k{font-size:9px;letter-spacing:.12em;color:var(--text-faint);text-transform:uppercase}
.tb-stat .v.on{color:var(--green)}

.live-pill{display:flex;align-items:center;gap:7px;padding:5px 12px;border-radius:999px;
  border:1px solid var(--line-bright);font-size:10px;letter-spacing:.1em;font-weight:700;
  text-transform:uppercase;color:#c9c9c9;background:var(--surface-2)}
.live-pill .dot{width:7px;height:7px;border-radius:50%;background:var(--green);animation:pulse 2s ease-in-out infinite}
.live-pill.stale{color:var(--text-dim)}
.live-pill.stale .dot{background:var(--text-faint);animation:none}

.view{padding:22px 24px;flex:1;min-width:0}
.view-head{display:flex;align-items:center;gap:14px;margin-bottom:18px}
.view-head h1{margin:0;font-size:19px;letter-spacing:0;font-weight:700}
.view-head .count{color:var(--text-dim);font-size:13px}

/* ============================================================
   PANELS / CARDS
   ============================================================ */
.panel,.card{background:var(--surface-1);border:1px solid var(--line);
  border-radius:var(--r-lg);position:relative;box-shadow:var(--shadow-sm)}
.panel-h,.card-h{display:flex;align-items:center;gap:10px;padding:13px 16px;
  border-bottom:1px solid var(--line)}
.panel-h h2{margin:0;font-size:12px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-dim);font-weight:700}
.panel-b{padding:14px 16px}
.panel-b.flush{padding:0}

.grid{display:grid;gap:var(--gap)}
/* Grid items default to min-width:auto, so a wide child (a long map URL, a table,
   a code block) refuses to shrink and pushes out over its neighbour. This is what
   made panels look like they were overlapping. */
.grid > *,.dash-grid > *,.dash-low > *,.rel-grid > *,.perm-cols > *,.chart-grid > *{min-width:0}
.dash-grid{grid-template-columns:1.55fr 1fr;align-items:start}

/* dashboard charts */
.chart-grid{grid-template-columns:1fr 1fr;margin-bottom:var(--gap)}
.chart-card{overflow:hidden}
.chart-h{gap:9px;flex-wrap:wrap}
.chart-title{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-dim);font-weight:700}
.chart-head-val{display:inline-flex;align-items:center}
.chv{font-size:11px;color:var(--text-faint);letter-spacing:.04em;text-transform:uppercase;font-weight:600}
.chv b{font-size:14px;font-weight:800;letter-spacing:0;margin-right:3px}
.chv.online b{color:var(--blue)}
.chv.fps b{color:var(--green)}
.chart-seg{padding:2px}
.chart-seg .seg-b{padding:3px 8px;font-size:10.5px}
.chart-body{padding:10px 12px 6px}
.chart-wrap{position:relative;width:100%}
.chart-svg{display:block;width:100%;height:176px}
.ch-hit{cursor:crosshair}
.ch-cross{stroke:var(--text-faint);stroke-width:1;stroke-dasharray:2 3;opacity:.55;pointer-events:none}
.ch-hdot{stroke:var(--surface-1);stroke-width:2;pointer-events:none}
.ch-tip{position:absolute;z-index:5;pointer-events:none;background:var(--surface-3);border:1px solid var(--line-bright);
  border-radius:8px;padding:6px 9px;box-shadow:var(--shadow);white-space:nowrap;transform:translateY(-100%)}
.ch-tip-v{font-size:13px;font-weight:700;color:var(--text);line-height:1.1}
.ch-tip-v b{font-size:15px;font-weight:800}
.ch-tip-t{font-size:10.5px;color:var(--text-dim);margin-top:2px;font-family:var(--mono);letter-spacing:.02em}
.ch-grid{stroke:var(--line);stroke-width:1;shape-rendering:crispEdges}
.ch-ylab{fill:var(--text-faint);font-size:9px;text-anchor:end;font-family:var(--mono)}
.ch-xlab{fill:var(--text-faint);font-size:9px;font-family:var(--mono)}
.ch-empty{fill:var(--text-faint);font-size:11px}
.ch-mark{stroke:var(--text-faint);stroke-width:1;stroke-dasharray:3 3;opacity:.5}
.ch-mlab{fill:var(--text-dim);font-size:9.5px;font-weight:700;font-family:var(--mono)}
.ch-dot{stroke:var(--surface-1);stroke-width:1.5}
.dash-low{grid-template-columns:1fr 1fr;margin-top:var(--gap)}
.stat-strip{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:var(--gap)}
.stat{background:var(--surface-1);border:1px solid var(--line);border-radius:var(--r);
  padding:14px 16px;transition:border-color .15s}
.stat:hover{border-color:var(--line-bright)}
.stat .v{font-size:25px;color:var(--text);font-weight:700;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.stat .v.green{color:var(--green)}
.stat .v.red{color:var(--danger-text)}
.stat .k{font-size:10px;letter-spacing:.1em;color:var(--text-faint);text-transform:uppercase;margin-top:4px;font-weight:600}

/* ============================================================
   TACTICAL MAP
   ============================================================ */
.map-panel{padding:0;overflow:hidden}
.map-bar{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--line)}
.map-stage{position:relative;width:100%;aspect-ratio:1/1;background:var(--map-bg);overflow:hidden;cursor:grab}
.map-stage.panning{cursor:grabbing}
.map-inner{position:absolute;inset:0;will-change:transform}
.map-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:saturate(.92) brightness(.88)}
.map-img.flip-y{transform:scaleY(-1)}
/* Rust-style labelled grid overlay (scales/pans with the map) */
.grid-layer{position:absolute;inset:0;pointer-events:none;display:none;overflow:hidden}
.grid-layer.on{display:block}
.grid-svg{position:absolute;inset:0;width:100%;height:100%}
.grid-lines{stroke:rgba(0,0,0,.28);stroke-width:1;vector-effect:non-scaling-stroke;fill:none}
/* per-cell labels, dark, slightly transparent serif, exactly like the in-game map */
.grid-cell-labels text{fill:#0d1418;fill-opacity:.42;font-family:Georgia,'Times New Roman',serif;
  font-weight:700;letter-spacing:.04em;user-select:none}
.ico-svg{display:inline-flex;align-items:center;justify-content:center}
.ico-svg svg{display:block}
/* leading icon inside a text button. Inline-flex so it works in plain buttons
   and anchors without turning them into flex containers */
.btn-ico{display:inline-flex;align-items:center;margin-right:6px;vertical-align:-2.5px;opacity:.9}
.btn-ico svg{display:block}
button:hover>.btn-ico,a:hover>.btn-ico{opacity:1}
.map-vignette{position:absolute;inset:0;pointer-events:none;box-shadow:inset 0 0 110px rgba(0,0,0,.35)}
.map-scan{display:none}
.map-empty{position:absolute;inset:0;display:grid;place-items:center;text-align:center;
  color:var(--text-faint);font-size:12px;letter-spacing:.08em;line-height:2}
.map-zoomhint{position:absolute;bottom:8px;right:10px;z-index:6;font-size:9.5px;
  color:var(--text-dim);opacity:.55;pointer-events:none}
.bracket{display:none}
.mk{position:absolute;transform:translate(-50%,-50%);
  transition:left .9s linear,top .9s linear;pointer-events:auto;z-index:5}
.mk .label{position:absolute;left:11px;top:-6px;font-size:9.5px;white-space:nowrap;
  color:var(--text);background:rgba(20,20,20,.92);padding:2px 7px;border-radius:6px;
  opacity:0;transition:opacity .12s;border:1px solid var(--pill-line)}
.mk:hover .label{opacity:1}
.mk:hover{z-index:20}
.mk-player .pip{width:9px;height:9px;border-radius:50%;background:var(--green);box-shadow:0 0 7px var(--green),0 0 2px #fff}
.mk-player.sleeping .pip{background:var(--text-dim);box-shadow:none}
.mk-player.wounded .pip{background:var(--amber);box-shadow:0 0 7px var(--amber)}
.mk-player.combat .pip{background:var(--red)!important;box-shadow:0 0 10px var(--red)}
.mk-player.combat{z-index:15}
.mk-player.combat .pip::after{content:"";position:absolute;left:50%;top:50%;width:14px;height:14px;
  border:2px solid var(--red);border-radius:50%;transform:translate(-50%,-50%);animation:ping 1.1s ease-out infinite}
.mk-player.shooting .pip::before{content:"";position:absolute;left:50%;top:50%;width:20px;height:20px;
  border-radius:50%;transform:translate(-50%,-50%);
  background:radial-gradient(circle,var(--yellow) 0%,rgba(233,195,74,.35) 40%,transparent 70%);
  animation:flash .45s ease-out infinite}
@keyframes flash{0%{opacity:.95;width:8px;height:8px}100%{opacity:0;width:26px;height:26px}}
.mk-sleeper .pip{width:6px;height:6px;border-radius:50%;background:var(--text-dim);opacity:.7}
.mk-sleeper:hover .pip{opacity:1}
.mk-bag{position:absolute;width:5px;height:5px;transform:translate(-50%,-50%) rotate(45deg);
  background:rgba(139,201,78,.35);border:1px solid rgba(139,201,78,.5)}
.mk-heli .pip,.mk-bradley .pip,.mk-cargoship .pip,.mk-chinook .pip{
  width:13px;height:13px;display:grid;place-items:center;font-size:11px;border-radius:4px}
.mk-heli .pip{color:var(--danger-text);filter:drop-shadow(0 0 6px var(--red))}
.mk-bradley .pip{color:var(--amber);filter:drop-shadow(0 0 6px var(--amber))}
.mk-cargoship .pip{color:var(--chat-blue);filter:drop-shadow(0 0 6px var(--blue-old))}
.mk-chinook .pip{color:var(--chat-blue);filter:drop-shadow(0 0 6px var(--blue-old))}
.mk-event .ring{position:absolute;left:50%;top:50%;width:13px;height:13px;
  border:2px solid currentColor;border-radius:50%;transform:translate(-50%,-50%);animation:ping 1.8s ease-out infinite}
.mk-heli{color:var(--danger-text)}.mk-bradley{color:var(--amber)}.mk-cargoship{color:var(--chat-blue)}.mk-chinook{color:var(--chat-blue)}
.mk-admin .pip{display:flex;align-items:center;justify-content:center;width:12px;height:12px;
  font-size:11px;line-height:1;color:var(--yellow);filter:drop-shadow(0 0 6px var(--yellow))}
.mk-admin.sleeping .pip{color:var(--text-dim);filter:none}
.mk-tc{z-index:3}
.mk-tc .pip{display:flex;align-items:center;justify-content:center;width:11px;height:11px;
  font-size:10px;line-height:1;color:var(--green);opacity:.8}
.mk-tc:hover .pip{opacity:1}
.tc-radius{position:absolute;transform:translate(-50%,-50%);border-radius:50%;
  border:1.5px solid;background:rgba(0,0,0,.35);pointer-events:none}
.pvp-circle{position:absolute;transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  border:1.5px dashed rgba(224,52,43,.55);background:rgba(224,52,43,.06)}
.pvp-tag{position:absolute;top:6px;left:50%;transform:translateX(-50%);font-family:var(--mono);
  font-size:9px;letter-spacing:.08em;color:var(--danger-text);background:rgba(20,10,10,.75);padding:1px 6px;border-radius:5px}
.map-layers{position:absolute;top:10px;left:10px;z-index:6;display:flex;gap:6px;flex-wrap:wrap}
.map-layers .lyr{font-size:10px;letter-spacing:.03em;text-transform:uppercase;font-weight:600;
  padding:4px 9px;border-radius:999px;cursor:pointer;color:var(--text-dim);
  background:var(--pill-bg);border:1px solid var(--pill-line);transition:all .13s}
.map-layers .lyr:hover{color:var(--text);border-color:var(--line-bright)}
.map-layers .lyr.on{color:var(--lyr-on-text);background:var(--lyr-on-bg);border-color:var(--lyr-on-bg)}
.hotcell{position:absolute;transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;mix-blend-mode:screen;
  background:radial-gradient(circle,rgba(224,52,43,.8) 0%,rgba(217,161,60,.4) 38%,rgba(224,52,43,0) 70%);
  transition:left .9s linear,top .9s linear,width .9s linear,height .9s linear,opacity .9s linear}
.map-legend{display:flex;gap:18px;flex-wrap:wrap;padding:12px 16px;border-top:1px solid var(--line);
  font-size:10.5px;color:var(--text-dim)}
.map-legend i{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:6px;vertical-align:middle}

/* ============================================================
   FEED / EVENT STREAM, calm rows, no rainbow borders
   ============================================================ */
.feed{max-height:640px;overflow-y:auto}
.feed.short{max-height:360px}
.frow{display:flex;align-items:center;gap:12px;padding:11px 16px;
  border-bottom:1px solid var(--line);font-size:13px;line-height:1.5;transition:background .13s}
.frow:hover{background:var(--hover)}
.frow:last-child{border-bottom:none}
.frow.ev-threat{background:rgba(224,52,43,.05)}
.frow .t{color:var(--text-faint);font-size:11px;min-width:52px;font-family:var(--mono);
  font-variant-numeric:tabular-nums;flex:0 0 auto;align-self:center}
.frow .body{flex:1;min-width:0;word-break:break-word;line-height:1.45}
.frow .who{color:var(--text);cursor:pointer;font-weight:600}
.frow .who:hover{color:var(--blue);text-decoration:underline;text-underline-offset:2px}
.frow .right.coord,.frow .coord{color:var(--text-dim);font-size:10.5px;font-weight:600;
  background:var(--surface-2);border:1px solid var(--pill-line);border-radius:6px;padding:2px 8px;flex:0 0 auto}

/* tags, neutral pills, category shows in TEXT color only */
.tag{font-size:9.5px;letter-spacing:.05em;font-weight:700;text-transform:uppercase;
  padding:3px 9px;border-radius:999px;border:1px solid var(--pill-line);
  background:var(--surface-2);color:var(--text-dim);white-space:nowrap;flex:0 0 auto;
  min-width:78px;text-align:center;align-self:center}
.tag.t-ban,.tag.t-kick,.tag.t-death,.tag.t-ipban,.tag.t-ipban_block,.tag.t-craft,
.tag.t-cheat_aim,.tag.t-cheat_norecoil,.tag.t-cheat_inrock,.tag.t-mlrs_fire,.tag.t-mlrs_strike,
.tag.t-rcon_cmd,.tag.t-sa_flag,.tag.t-sa_dossier{color:var(--c-combat)}
.tag.t-ipunban,.tag.t-connect,.tag.t-connect_info,.tag.t-respawn,
.tag.t-vending_buy,.tag.t-shop_trade{color:var(--c-conn)}
.tag.t-mute,.tag.t-unmute,.tag.t-admin_cmd,.tag.t-helicopter,.tag.t-bradley,
.tag.t-cargoship,.tag.t-supplysignal,.tag.t-lockedcrate,.tag.t-raid,
.tag.t-loot_container,.tag.t-loot_corpse,.tag.t-door_use,.tag.t-mount_entity{color:var(--c-raid)}
.tag.t-teleport,.tag.t-pm,.tag.t-bag_placed,.tag.t-bag_renamed,.tag.t-bag_assign{color:var(--c-chat)}
.tag.t-clan_create,.tag.t-clan_join,.tag.t-clan_invite,.tag.t-clan_ally,.tag.t-clan_ally_add,
.tag.t-clan_ally_remove,.tag.t-clan_promote,.tag.t-clan_demote,.tag.t-clan_leader,.tag.t-clan_ff,
.tag.t-clan_chat,.tag.t-clan_enemy,.tag.t-third_party,.tag.t-vanish_on,.tag.t-vanish_off,
.tag.t-godmode_on,.tag.t-godmode_off,.tag.t-adminradar{color:var(--c-clan)}
.who.amber,.frow .who.amber{color:var(--amber)}
.who.red,.frow .who.red{color:var(--danger-text)}
.who.purple,.frow .who.purple{color:var(--purple)}

/* ============================================================
   TABLE
   ============================================================ */
.tbl{width:100%;border-collapse:collapse;font-size:13px}
.tbl th{text-align:left;font-size:10px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-faint);font-weight:600;padding:12px 16px;border-bottom:1px solid var(--line);
  position:sticky;top:0;background:var(--surface-1);z-index:2}
.tbl td{padding:10px 16px;border-bottom:1px solid var(--line)}
.tbl tr:last-child td{border-bottom:none}
.tbl tr:hover td{background:var(--hover)}
.tbl .rowlink{cursor:pointer}
.statusdot{width:8px;height:8px;border-radius:50%;display:inline-block;background:var(--text-faint)}
.statusdot.on{background:var(--green);box-shadow:0 0 6px var(--green)}
.namecell{color:var(--text);cursor:pointer;font-weight:600}
.namecell:hover{color:var(--blue)}

/* circular initials avatar + stacked name/status (RustApp row shape) */
.ravi{position:relative;display:inline-grid;place-items:center;width:34px;height:34px;border-radius:50%;
  background:var(--surface-3);border:1px solid var(--line-bright);color:var(--text-dim);
  font-size:11.5px;font-weight:700;letter-spacing:.02em;flex:0 0 auto}
.ravi::before{content:attr(data-ini)}
.ravi::after{content:"";position:absolute;left:-1px;bottom:-1px;width:10px;height:10px;border-radius:50%;
  background:var(--text-faint);border:2px solid var(--surface-1)}
.ravi.on::after{background:var(--green)}
.tbl tr:hover .ravi::after{border-color:var(--hover)}
.pwrap{display:flex;align-items:center;gap:11px;min-width:0}
.pmeta{display:flex;flex-direction:column;line-height:1.3;min-width:0}
.pmeta .namecell{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:230px}
.psub{font-size:11px;color:var(--text-dim)}
.psub.on{color:var(--green)}

/* search + chips */
.toolbar{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap}
.search{flex:1;min-width:220px;background:var(--input);border:1px solid var(--track);
  color:var(--text);padding:11px 14px;border-radius:var(--r);font-family:var(--sans);font-size:13.5px}
.search:focus{outline:none;border-color:var(--blue);box-shadow:var(--ring)}
.search::placeholder{color:var(--text-faint)}
.chips{display:flex;gap:7px;flex-wrap:wrap}
.chip{background:transparent;border:1px solid var(--pill-line);color:var(--text-dim);
  padding:6px 13px;border-radius:999px;font-size:11px;letter-spacing:.03em;font-weight:600;
  text-transform:uppercase;transition:all .13s}
.chip:hover{color:var(--text);border-color:var(--line-bright);background:var(--surface-2)}
.chip.active,.chip.on{background:var(--surface-3);border-color:var(--line-bright);color:var(--text)}
.chip.tiny{padding:3px 9px;font-size:9.5px}

/* pager */
.pager{display:flex;align-items:center;gap:12px;justify-content:center;margin-top:18px}
.pager button{background:var(--surface-2);border:1px solid var(--pill-line);color:var(--text-dim);
  padding:8px 18px;border-radius:var(--r-sm);font-size:12px;font-weight:600;transition:all .13s}
.pager button:hover:not(:disabled){background:var(--surface-3);color:var(--text)}
.pager button:disabled{opacity:.35;cursor:not-allowed}
.pager .pg{color:var(--text-dim);font-size:12px}

/* ============================================================
   PLAYER DOSSIER
   ============================================================ */
.dossier-head{display:flex;align-items:center;gap:18px;flex-wrap:wrap;
  background:var(--surface-1);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:20px 22px;margin-bottom:var(--gap);position:relative}
.av{width:64px;height:64px;border-radius:50%;border:1px solid var(--line-bright);
  background:var(--surface-3) center/cover;flex:none;overflow:hidden}
.dossier-head .nm{font-size:21px;font-weight:700}
.dossier-head .sid{color:var(--text-dim);font-size:12px;font-family:var(--mono);cursor:pointer}
.dossier-head .sid:hover{color:var(--blue)}
.pill{font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;padding:4px 11px;
  border-radius:999px;border:1px solid var(--line-bright);color:var(--text-dim);font-weight:700;background:var(--surface-2)}
.pill.on{color:var(--green);border-color:rgba(139,201,78,.4)}
.pill.off{color:var(--text-dim)}
.dossier-grid{grid-template-columns:1fr 1fr 1fr;align-items:stretch}
.dossier-grid>.panel{display:flex;flex-direction:column}
.dossier-grid>.panel>.panel-b{flex:1 1 auto}
.kv{display:flex;justify-content:space-between;gap:10px;padding:7px 0;
  border-bottom:1px solid var(--line);font-size:12.5px}
.kv:last-child{border-bottom:none}
.kv .k{color:var(--text-dim)}
.kv .v{color:var(--text);text-align:right;word-break:break-word;font-weight:500}
.farm-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.farm-cell{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r);
  padding:11px 13px;transition:border-color .13s}
.farm-cell:hover{border-color:var(--line-bright)}
.farm-cell .n{font-size:19px;color:var(--text);font-weight:700;font-variant-numeric:tabular-nums}
.farm-cell .l{font-size:10.5px;color:var(--text-dim);margin-top:3px}

/* Steam account figures. One fact per cell, hairline-separated: at a glance
   you should be able to read "2 VAC, 1 game ban, 7 names" without parsing prose. */
.acct-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(112px,1fr));
  gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--r);overflow:hidden}
.acell{background:var(--surface-2);padding:13px 10px 12px;text-align:center;min-width:0}
.acell .n{font-size:19px;font-weight:800;letter-spacing:-.02em;line-height:1.2;color:var(--text);
  font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acell .l{font-size:9.5px;color:var(--text-dim);margin-top:5px;
  text-transform:uppercase;letter-spacing:.085em;font-weight:600}
.acell .s{font-size:10px;color:var(--text-faint);margin-top:4px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acell.good .n{color:var(--green)}
.acell.warn .n{color:var(--amber)}
.acell.bad{background:var(--red-soft)}
.acell.bad .n{color:var(--red)}
.acell.unknown .n{color:var(--text-faint);font-weight:600}

/* A wipe that gave up stays on the page until it is acknowledged. */
.wfail{border-color:var(--red);background:var(--red-soft);margin-bottom:var(--gap)}
.wfail-h{display:flex;align-items:flex-start;gap:12px;padding:15px 18px 13px;
  border-bottom:1px solid rgba(224,52,43,.32)}
.wfail-h .ico-svg{color:var(--red);flex:none;margin-top:2px}
.wfail-h h2{font-size:15.5px;font-weight:800;color:var(--red);text-transform:none;margin:0;line-height:1.35}
.wfail-h .abtn{flex:none}
.wfail-sub{font-size:11.5px;color:var(--text-dim);margin-top:3px}
.wfail-err{font-size:13px;line-height:1.6}

/* ---- wipe failure diagnosis ---- */
.wdiag{background:var(--red-soft);border:1px solid rgba(224,52,43,.45);
  border-radius:var(--r-sm);padding:12px 14px;margin:10px 0}
.wdiag-h{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--red)}
.wdiag-h .ico-svg{color:var(--red)}
.wdiag-h .dim{font-size:11px;font-weight:400}
.wdiag-cause{font-size:13px;margin-top:7px;line-height:1.55}
.wdiag-fix{font-size:12px;margin-top:6px;line-height:1.55}
.wdiag-more{margin-top:9px}
.wdiag-more summary{font-size:11px;color:var(--text-dim);cursor:pointer;
  text-transform:uppercase;letter-spacing:.06em;font-weight:600}
.wdiag-more summary:hover{color:var(--text)}
.wdiag-more pre{margin-top:7px;background:var(--input);border:1px solid var(--line);
  border-radius:6px;padding:10px;font-family:var(--mono);font-size:11px;line-height:1.55;
  max-height:280px;overflow:auto;white-space:pre-wrap;word-break:break-word;color:var(--text-dim)}

/* ---- replay ----
   The SVG viewBox is world coordinates, so the map image, the paths and the
   markers all share one space and none of it needs reconciling in CSS. */
/* The window a fight is drawn in is square, so the box has to be square too.
   With only a max-height the box stayed panel-wide and the SVG letterboxed
   itself inside it, leaving a third of the replay as black margin. */
/* Dragging to pan was selecting the player names and the whole panel went
   blue. Nothing on the map is text to be copied, and touch-action stops a
   one-finger pan scrolling the page out from under itself on a phone. */
.rp-stage,.rp-svg{user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.rp-svg{touch-action:none}
.rp-svg text{pointer-events:none}
.rp-stage{position:relative;width:100%;aspect-ratio:1/1;
  max-height:72vh;max-width:min(100%,72vh);margin-inline:auto;
  background:var(--map-bg);border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.rp-svg{width:100%;height:100%;display:block}
/* The whole-map photograph is the fallback and is pushed well back, because
   at fight zoom it is a blur that only exists so an unmeasured tile is not a
   black square. */
.rp-map{opacity:.5}
.rp-dim{fill:rgba(10,12,14,.35)}

/* ---- measured ground ----
   A 44-sample tile stretched over 128m is deliberately soft: it is terrain,
   not a plan of the doorways. The shapes drawn on top of it are the crisp
   part, and that is the right way round. */
.rp-ground{image-rendering:auto;opacity:.95}
/* Man-made shapes read warm against the greens and greys of ground, which is
   the whole reason a base is findable in a glance here. */
.rp-floor{fill:rgba(226,196,150,.30);stroke:rgba(236,206,160,.65);stroke-width:.12;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}
.rp-stairs{fill:rgba(226,196,150,.16);stroke:rgba(236,206,160,.4);stroke-width:.12;
  vector-effect:non-scaling-stroke}
.rp-wall-b{fill:rgba(246,222,182,.85);stroke:none}
/* Solid and edged rather than a soft blob: a translucent grey smudge over
   green reads as cloud, and cover you can see through is not cover. */
.rp-rock{fill:rgba(74,76,80,.72);stroke:rgba(150,154,162,.55);stroke-width:.1;
  vector-effect:non-scaling-stroke}
.rp-rock.tall{fill:rgba(52,54,58,.9);stroke:rgba(186,192,202,.75)}
.rp-legend .rp-key i.k-base{width:10px;height:10px;border-radius:2px;
  background:rgba(236,206,160,.75);border:0}
.rp-legend .rp-key i.k-rock{width:11px;height:8px;border-radius:50%;
  background:rgba(170,174,182,.6);border:0}
/* The path someone walked, drawn twice: the whole route faint, and the last
   two seconds of it brighter on top. Two weights read as direction without
   needing an arrowhead every few metres. */
.rp-trail{fill:none;stroke-linejoin:round;stroke-linecap:round;opacity:.34}
.rp-trail.head{opacity:.85}
.rp-trail.by{opacity:.2;stroke-dasharray:3 3}
.rp-trail.head.by{opacity:.45}
.rp-dot{stroke:#0b0d10;stroke-width:.4;paint-order:stroke}
.rp-ring{paint-order:stroke}
.rp-hitlayer{cursor:crosshair}
.rp-actor.hot .rp-ring{filter:brightness(1.5)}
/* One shot, one tracer, in the colour of whoever fired it. The stroke comes
   from the marker so the two can never disagree; a headshot adds a white core
   rather than a third colour. */
.rp-shot{stroke-linecap:round}
.rp-shot.core{stroke:#ffffff;stroke-linecap:round}
.rp-impact{fill:none}
.rp-impact.head{stroke:#ffffff}

/* ---- where they were looking ----
   Free to draw: the plugin has always recorded yaw and pitch alongside the
   position track. A cone, not an arrow: an arrow gives a direction, a cone
   gives the ground they were covering, which is the thing you are trying to
   work out from a replay. */
.rp-cone{stroke:none;pointer-events:none}
.rp-cone.wide{opacity:.2}
.rp-cone.tight{opacity:.3}
/* dashed, because a tracer is solid and in the same colour: without this the
   sight line and the bullets it fired read as one broken line */
.rp-ray{opacity:.8;stroke-linecap:round;pointer-events:none;
  stroke-dasharray:2.2 2.2;vector-effect:non-scaling-stroke;stroke-width:1.6px}

/* ---- stance, as height rather than as an icon ----
   Airborne is bigger and casts a shadow; crouched is smaller and denser;
   standing is neither. One property, three readings, nothing to learn. */
.rp-shadow{fill:rgba(0,0,0,.55);pointer-events:none}
.rp-actor.st-air .rp-ring{filter:brightness(1.25)}
.rp-actor.st-crouch{opacity:.92}
/* the line between them, cut by a bar: "these two cannot see each other right
   now". On its own the bar was an unexplained white stick floating in a field. */
.rp-blockline{stroke:#dfe6ef;opacity:.35;stroke-dasharray:1.5 2.5;
  vector-effect:non-scaling-stroke;stroke-width:1.2px;pointer-events:none}
.rp-wall{fill:#dfe6ef;opacity:.9;rx:.4}
/* who died, held on screen for a few seconds after the last shot */
.rp-killed{font-weight:800;letter-spacing:.14em;text-anchor:middle;fill:#ff6a5e;
  paint-order:stroke;stroke:#0b0d10}
.rp-dead{stroke:#ff6a5e;stroke-linecap:round;opacity:.95;pointer-events:none}
.rp-heal{fill:none;stroke:#6fe08a;opacity:.9}
.rp-name{font-weight:700;paint-order:stroke;stroke:#0b0d10;text-anchor:middle}
/* the stance keys are the marker itself at its three sizes, so the legend and
   the map are the same object rather than a picture of one */
.rp-legend .rp-key i.k-air{width:13px;height:13px;border-radius:50%;background:none;
  border:2px solid var(--text-dim);box-shadow:0 3px 0 -1px rgba(0,0,0,.6)}
.rp-legend .rp-key i.k-stand{width:10px;height:10px;border-radius:50%;background:none;
  border:2px solid var(--text-dim)}
.rp-legend .rp-key i.k-crouch{width:7px;height:7px;border-radius:50%;background:none;
  border:3px solid var(--text-dim)}
.rp-legend .rp-key i.k-block{width:12px;height:3px;border-radius:1px;background:#dfe6ef;border:0}
.rp-legend .rp-key i.k-cone{width:0;height:0;border-radius:0;background:none;
  border-inline-start:6px solid transparent;border-inline-end:6px solid transparent;
  border-bottom:9px solid rgba(141,141,141,.55)}

.rp-bar{display:flex;align-items:center;gap:10px;margin-top:10px;flex-wrap:wrap}
.rp-scrub{flex:1;min-width:140px;accent-color:var(--blue);height:22px}
.rp-time{font-family:var(--mono);font-size:11.5px;color:var(--text-dim);
  min-width:88px;text-align:right;font-variant-numeric:tabular-nums}
.rp-legend{display:flex;gap:14px;flex-wrap:wrap;margin-top:10px;font-size:11px;color:var(--text-dim)}
.rp-legend span{display:inline-flex;align-items:center;gap:6px}
.rp-legend i{width:10px;height:10px;border-radius:50%;display:block}
@media(max-width:640px){
  .rp-stage{max-height:none}
  .rp-time{min-width:0;flex:1;text-align:left}
  .rp-bar{gap:8px}
}

/* ---- named verdicts ----
   Above the prose, because they are why the page was opened. Nothing here
   claims proof: "suspected" is the strongest word the copy uses. */
.verdicts{display:flex;flex-direction:column;gap:7px;margin-bottom:16px}
.verdict{display:flex;gap:9px;align-items:flex-start;padding:10px 12px;
  border-radius:var(--r-sm);font-size:12.5px;line-height:1.6}
.verdict .v-ico{flex:none;margin-top:1px}
.verdict.high{background:var(--red-soft);border:1px solid rgba(224,52,43,.45);color:var(--text)}
.verdict.high .v-ico{color:var(--red)}
.verdict.watch{background:var(--surface-2);border:1px solid var(--line-bright)}
.verdict.watch .v-ico{color:var(--amber)}
.verdicts.rtl .verdict{flex-direction:row-reverse;text-align:right}
.gear-grid{margin-top:5px}
/* attachment icons inside the item tooltip */
.it-modrow{display:flex;gap:4px;flex-wrap:wrap;margin-top:5px}
.it-modimg{width:26px;height:26px;object-fit:contain;background:#1b1f26;
  border:1px solid #2a3038;border-radius:5px;padding:2px}
.it-modtxt{font-size:10px;color:var(--text-dim);background:#1b1f26;
  border:1px solid #2a3038;border-radius:5px;padding:3px 6px;text-transform:capitalize}

/* ---- hit map ----
   The figure is a silhouette, not an anatomy drawing: it has to stay readable
   at phone width. Five colour steps rather than a gradient, so a reader can
   name the step they are looking at. */
/* The figure box and the label coordinates are the same 100 x 105 space, which
   only holds if the SVG fills the box exactly. With the default fit it is
   letterboxed inside it and every label drifts by the size of the bars. */
.bodywrap{position:relative;width:100%;max-width:380px;margin:6px auto 0}
.bodyfig{width:100%;aspect-ratio:100/105}
.bodysvg{width:100%;height:100%;display:block;overflow:visible}
.bodyparts .bz{stroke:var(--line-bright);stroke-width:.7;transition:fill .15s}
.bz-none{fill:#20242a}
.bz-low{fill:#2f6b3a}
.bz-mid{fill:#5f9440}
.bz-warm{fill:#c9b03c}
.bz-hot{fill:#d9772f}
.bz-peak{fill:#d93b2b}
.bodylines polyline{fill:none;stroke:var(--line-bright);stroke-width:.5;opacity:.75}
.bodylines circle{fill:var(--text-faint)}
.bz-label{position:absolute;display:flex;flex-direction:column;line-height:1.2;
  transform:translateY(-50%);width:21%;white-space:nowrap}
.bz-label.r{text-align:left;align-items:flex-start}
.bz-label.l{text-align:right;align-items:flex-end}
.bz-name{font-size:10px;text-transform:uppercase;letter-spacing:.07em;color:var(--text-dim);font-weight:600}
.bodywrap.rtl .bz-name{text-transform:none;letter-spacing:0;font-size:11.5px}
.bz-pct{font-size:15px;font-weight:800;font-variant-numeric:tabular-nums;color:var(--text)}
.bz-hits{font-size:10px;color:var(--text-faint)}
.bz-label.heat-peak .bz-pct{color:#e8564a}
.bz-label.heat-hot .bz-pct{color:#e08a45}
.bz-label.heat-warm .bz-pct{color:#d9c04f}
.bz-label.heat-none .bz-pct{color:var(--text-faint)}
/* find a fight: three ways in, because that is how people remember them */
.fs-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px}
.fs-field{display:flex;flex-direction:column;gap:5px;min-width:0}
.fs-field label{font-size:10px;text-transform:uppercase;letter-spacing:.07em;color:var(--text-faint);font-weight:600}
.fs-field .inp{width:100%}
.ftype.reported{background:var(--red-soft);color:#ff8079;border:1px solid rgba(224,52,43,.5);margin-inline-start:6px}

.bodylegend{display:flex;gap:5px;align-items:center;justify-content:center;
  margin-top:10px;font-size:9.5px;color:var(--text-faint);text-transform:uppercase;letter-spacing:.07em}
.bodylegend i{width:16px;height:7px;border-radius:2px;display:block}

/* ---- the written account ----
   Sized for reading on a phone: longer line height, a real reading measure, and
   Persian gets its own font stack and direction rather than being crammed into
   a left-to-right layout. */
.story-panel{border-color:var(--line-bright)}
/* The reading measure is a box narrower than the panel, so switching to
   Persian has to move the BOX to the right edge, not just flip the alignment
   inside it. Without this the language toggle re-aligned the words while the
   column they sat in stayed exactly where it was, which looks like the toggle
   half worked. */
.story{max-width:74ch;margin-inline-end:auto}
.story.rtl{direction:rtl;text-align:right;font-family:'Vazirmatn',var(--font,inherit);
  margin-inline-end:0;margin-inline-start:auto}
.story-p+.story-p{margin-top:14px}
.story-h{font-size:9.5px;text-transform:uppercase;letter-spacing:.09em;color:var(--text-faint);
  font-weight:700;margin-bottom:4px}
.story.rtl .story-h{text-transform:none;letter-spacing:0;font-size:11px}
/* The prose sits one step below full brightness on purpose. Emphasis in a
   report should come from lowering everything else, not from making the
   important words louder: with a dimmed baseline a coloured name reads as
   information, and with a bright one it reads as decoration. */
.story-t{font-size:13.5px;line-height:1.85;color:#c9c9c9;white-space:pre-line}
.story.rtl .story-t{line-height:2.05}

/* ---- coloured terms inside the prose ----
   One hue per kind of thing, and no more kinds than an admin can hold. The two
   players take the exact colours the replay paints them, so a name in a
   sentence and a dot on the map are the same player without being told.

   Suspicion is deliberately NOT a fourth red. It is the ordinary text colour
   with a red rule under it, because a third red next to two player colours
   stops meaning anything, and an underline reads as "this is the claim" at any
   size, including on a phone. */
.tx-p1{color:#4fb0f6;font-weight:600}
.tx-p2{color:#ea6a5d;font-weight:600}
.tx-num{color:#f2f2f2;font-weight:600;font-variant-numeric:tabular-nums}
.tx-time{color:#f2f2f2;font-weight:600;font-variant-numeric:tabular-nums}
.tx-zone{color:#b18cf0}
.tx-gun{color:#d5ab6b}
.tx-place{color:#5fbfae;font-weight:600;letter-spacing:.02em}
.tx-clan{color:#8d8d8d}
.tx-ok{color:var(--green)}
.tx-warn{color:#f2f2f2;text-decoration:underline;text-decoration-thickness:1px;
  text-decoration-color:rgba(224,52,43,.7);text-underline-offset:3px}
.verdict .tx-num,.verdict .tx-time{color:inherit}
.verdict .tx-warn{text-decoration:none}
/* the side buttons wear their player's colour so the toggle matches the text */
.seg-b.sd-a.active{color:#4fb0f6}
.seg-b.sd-b.active{color:#ea6a5d}

/* ---- the two accounts, side by side ----
   Same panel, one rule between them. border-inline-start rather than
   border-left so the divider moves to the correct edge in Persian without a
   second rule. */
.story-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:26px}
.story-col{min-width:0}
.story-col+.story-col{border-inline-start:1px solid var(--line-bright);padding-inline-start:26px}
.story-cap{font-size:9.5px;text-transform:uppercase;letter-spacing:.1em;font-weight:700;
  color:var(--text-faint);margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--line)}

/* ---- the fight, in order ---- */
.tl{display:flex;flex-direction:column;gap:2px}
.tl.rtl{direction:rtl;text-align:right;font-family:'Vazirmatn',var(--font,inherit)}
.tl-row{display:flex;gap:11px;align-items:baseline;padding:6px 9px;border-radius:var(--r-sm);
  border-inline-start:2px solid transparent;font-size:13px;line-height:1.75;color:#c9c9c9}
.tl-row:hover{background:var(--hover)}
.tl-t{flex:none;min-width:44px;text-align:end;font-size:10.5px;font-weight:700;
  font-variant-numeric:tabular-nums;color:var(--text-faint);letter-spacing:.02em}
.tl-x{min-width:0}
.tl-row.tone-open{border-inline-start-color:var(--line-bright);background:var(--surface-2)}
.tl-row.tone-hit{border-inline-start-color:rgba(224,52,43,.55)}
.tl-row.tone-miss{border-inline-start-color:var(--line-bright)}
.tl-row.tone-heal{border-inline-start-color:rgba(139,201,78,.6)}
.tl-row.tone-cover{border-inline-start-color:rgba(168,123,240,.55)}
.tl-row.tone-end{border-inline-start-color:var(--text-faint);background:var(--surface-2)}
.tl-note{margin-top:12px;padding:10px 12px;background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-sm);font-size:12.5px;line-height:1.8;color:#c9c9c9}
.tl-note+.tl-note{margin-top:6px}
.tl.rtl .tl-note{text-align:right}

@media(max-width:1000px){
  .story-split{grid-template-columns:minmax(0,1fr);gap:20px}
  .story-col+.story-col{border-inline-start:0;padding-inline-start:0;
    border-block-start:1px solid var(--line-bright);padding-block-start:20px}
}
.bestlist{margin-top:16px;display:flex;flex-direction:column;gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.bestrow{display:flex;align-items:center;gap:12px;padding:10px 13px;background:var(--surface-2);
  cursor:pointer;font-size:12.5px}
.bestrow:hover{background:var(--hover)}
.bl-label{flex:0 0 118px;font-size:10px;text-transform:uppercase;letter-spacing:.07em;font-weight:700}
.bestrow.good .bl-label{color:var(--green)}
.bestrow.bad .bl-label{color:var(--red)}
.bl-body{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(max-width:640px){
  .story-t{font-size:14px}
  .bl-label{flex-basis:100%}
  .bestrow{flex-wrap:wrap;gap:4px 10px}
}

/* ---- combat: the fight list ----
   Laid out as a grid so the columns line up without a table, which lets the
   whole row collapse into a readable block on a phone. */
.fhead,.frow-fight{display:grid;gap:10px;align-items:center;
  grid-template-columns:150px 46px minmax(0,1fr) minmax(0,1.1fr) 52px 46px;
  padding:9px 15px;border-bottom:1px solid var(--line)}
.fhead{font-size:9.5px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint);
  font-weight:600;background:var(--surface-1)}
.frow-fight{font-size:12.5px;cursor:pointer}
.frow-fight:hover{background:var(--hover)}
.frow-fight.cleared{opacity:.45}
.ff-when{font-size:11px;color:var(--text-dim)}
.ff-res{font-size:10px;font-weight:800;letter-spacing:.05em;color:var(--text-faint)}
.ff-res.won{color:var(--green)}
.ff-res.lost{color:var(--red);font-weight:600}
.ff-opp,.ff-type{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ff-grid{font-family:var(--mono);font-size:11px;color:var(--text-dim)}
.ff-score{text-align:right}
.ftype{display:inline-block;font-size:10px;font-weight:700;padding:2px 8px;border-radius:999px;
  border:1px solid var(--line-bright);color:var(--text-dim);max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ftype.clan{border-color:var(--amber);color:var(--amber)}
.ftype.warn{border-color:var(--red);color:var(--red)}
.fscore{display:inline-block;min-width:26px;text-align:center;font-weight:800;font-size:12px;
  padding:2px 6px;border-radius:6px;background:var(--surface-3);font-variant-numeric:tabular-nums}
.fscore.red{background:var(--red);color:#fff}
.fscore.amber{background:var(--amber);color:#141414}
.fscore.green{color:var(--green)}
.fscore.dim{color:var(--text-dim)}

/* ---- one fight ---- */
.fight-chips{margin-bottom:var(--gap)}
.fchip{font-size:11px;font-weight:600;padding:4px 10px;border-radius:999px;
  background:var(--surface-2);border:1px solid var(--line);color:var(--text)}
.fchip.dimchip{color:var(--text-faint)}
.fchip.warnchip{border-color:var(--red);color:var(--red)}
.fight-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap)}
.fside.won{border-color:rgba(139,201,78,.45)}
.tlist{margin-top:14px;display:flex;flex-direction:column;gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.trow{display:grid;grid-template-columns:118px 62px minmax(0,1fr);gap:8px;align-items:baseline;
  padding:8px 11px;background:var(--surface-2);font-size:12px}
.trow.na{opacity:.62}
.tname{font-weight:600}
.tval{font-weight:800;font-variant-numeric:tabular-nums}
.tval.red{color:var(--red)} .tval.amber{color:var(--amber)} .tval.green{color:var(--green)}
.twhy{font-size:11px;color:var(--text-dim);min-width:0;line-height:1.5}

.shotline{position:relative;height:26px;background:var(--input);border:1px solid var(--line);
  border-radius:6px;margin-top:4px}
.sdot{position:absolute;top:50%;width:7px;height:7px;border-radius:50%;transform:translate(-50%,-50%)}
.sdot.side-b{top:72%} .sdot.side-a{top:28%}
.sdot.red{background:var(--red)} .sdot.green{background:var(--green)}
.sdot.amber{background:var(--amber)} .sdot.blue{background:var(--blue)}
.shotlegend{display:flex;justify-content:space-between;font-size:10px;margin-top:4px}

.gcols{display:grid;grid-template-columns:1fr 1fr;gap:20px}
.gcol{min-width:0}
.gname{font-weight:700;font-size:13.5px;margin-bottom:8px}
.glabel{font-size:9.5px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint);
  font-weight:600;margin-top:10px}
.gitems{display:flex;gap:5px;flex-wrap:wrap;margin-top:5px}
.gitem{font-size:11px;padding:3px 8px;border-radius:6px;background:var(--surface-3);
  border:1px solid var(--line);text-transform:capitalize}
.gitem.sm{font-size:10px;padding:2px 6px}
.gunname{font-weight:600;text-transform:capitalize}
.arsenal td,.arsenal th{white-space:nowrap}

@media(max-width:820px){
  .fight-grid,.gcols{grid-template-columns:1fr}
}
@media(max-width:700px){
  .fhead{display:none}
  .frow-fight{grid-template-columns:1fr auto;gap:4px 10px;padding:11px 14px}
  .ff-when{grid-column:1;font-size:10.5px}
  .ff-score{grid-column:2;grid-row:1 / span 2}
  .ff-opp{grid-column:1;font-size:13px;font-weight:600}
  .ff-res{grid-column:1;order:3}
  .ff-type{grid-column:1;order:4;white-space:normal}
  .ff-grid{grid-column:1;order:5}
  .trow{grid-template-columns:1fr auto;gap:2px 8px}
  .twhy{grid-column:1 / -1}
}

/* ---- plugin cost ---- */
.perf-list{margin-top:12px;display:flex;flex-direction:column;gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.perf-row{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--surface-2);font-size:12.5px}
.perf-name{flex:0 0 190px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
.perf-warn{margin-left:8px;font-size:9.5px;font-weight:700;text-transform:uppercase;
  letter-spacing:.05em;color:#141414;background:var(--amber);border-radius:4px;padding:1px 5px}
.perf-bar{flex:1;min-width:40px;height:6px;background:var(--input);border-radius:3px;overflow:hidden}
.perf-bar span{display:block;height:100%;background:var(--blue);border-radius:3px}
.perf-num{flex:0 0 86px;text-align:right;font-variant-numeric:tabular-nums;font-weight:700}
.perf-num .dim{font-weight:400;font-size:10.5px}
.perf-spark{flex:0 0 96px;color:var(--blue);display:flex;align-items:center}
.perf-spark svg{display:block}
@media(max-width:760px){
  .perf-row{flex-wrap:wrap;gap:6px 10px}
  .perf-name{flex-basis:100%}
  .perf-spark{flex:1 1 auto;justify-content:flex-end}
}

/* ---- bulk selection ---- */
.selcol{width:34px;text-align:center;padding-left:12px !important;padding-right:0 !important}
.selcol input{cursor:pointer;width:15px;height:15px;accent-color:var(--blue)}
.bulkbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  background:var(--surface-2);border:1px solid var(--blue);border-radius:var(--r-sm);
  padding:9px 14px;margin-bottom:10px}
.bulkbar.hidden{display:none}
.bulk-n{font-size:17px;font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.bulk-lbl{font-size:12.5px;color:var(--text-dim)}
.bulk-acts{display:flex;gap:7px;flex-wrap:wrap;margin-left:8px}
.bulk-x{background:none;border:none;color:var(--text-faint);font-size:11.5px;
  font-weight:600;margin-left:auto;padding:4px 8px;border-radius:6px}
.bulk-x:hover{color:var(--text);background:var(--hover)}
.bulk-names{max-height:220px;overflow-y:auto;border:1px solid var(--line);
  border-radius:var(--r-sm);background:var(--input);margin-top:10px}
.bulk-name{display:flex;justify-content:space-between;gap:12px;align-items:center;
  padding:6px 11px;border-bottom:1px solid var(--line);font-size:12.5px}
.bulk-name:last-child{border-bottom:none}
.bulk-name .mono{font-size:10.5px}

/* ---- ban history ---- */
.ban-list{margin-top:12px;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.ban-row{display:flex;gap:14px;align-items:flex-start;padding:11px 13px;
  border-bottom:1px solid var(--line);font-size:12.5px;background:var(--surface-2)}
.ban-row:last-child{border-bottom:none}
.ban-row.active{background:var(--red-soft)}
.ban-row.minor{padding:8px 13px;font-size:12px}
.ban-when{flex:0 0 130px;font-size:11px;color:var(--text-dim);line-height:1.5}
.ban-mid{flex:1;min-width:0}
.ban-reason{line-height:1.5;word-break:break-word}
.ban-meta{font-size:11px;color:var(--text-dim);margin-top:3px}
.ban-kind{font-size:9.5px;text-transform:uppercase;letter-spacing:.07em;font-weight:700;
  color:var(--text-faint)}
.ban-kind.amber{color:var(--amber)}
.ban-end{flex:0 0 130px;text-align:right;font-size:11px;line-height:1.45}
.ban-end.red{color:var(--red);font-weight:700}
.ban-end.amber{color:var(--amber)}
.ban-end.dim{color:var(--text-faint)}
@media(max-width:640px){
  .ban-row{flex-wrap:wrap;gap:6px}
  .ban-when{flex-basis:100%}
  .ban-end{flex-basis:100%;text-align:left}
  .bulk-acts{margin-left:0;width:100%}
  .bulk-x{margin-left:0}
}

/* ---- command palette ---- */
.tb-search{display:inline-flex;align-items:center;gap:7px;background:var(--surface-2);
  border:1px solid var(--line);color:var(--text-dim);border-radius:var(--r-sm);
  padding:6px 10px;font-size:12px;font-weight:600;transition:all .13s}
.tb-search:hover{border-color:var(--blue);color:var(--text)}
.tb-search kbd{font-family:var(--mono);font-size:9.5px;background:var(--surface-3);
  border:1px solid var(--line-bright);border-radius:4px;padding:1px 5px;color:var(--text-faint)}
.pal-back{position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:400;
  display:flex;justify-content:center;align-items:flex-start;padding:12vh 16px 16px;backdrop-filter:blur(2px)}
.pal{width:100%;max-width:620px;background:var(--surface-1);border:1px solid var(--line-bright);
  border-radius:var(--r);overflow:hidden;box-shadow:0 24px 60px rgba(0,0,0,.6)}
.pal-top{padding:6px}
.pal-input{width:100%;background:transparent;border:none;color:var(--text);
  font:inherit;font-size:16px;padding:12px 14px}
.pal-input:focus{outline:none}
.pal-results{max-height:52vh;overflow-y:auto;border-top:1px solid var(--line)}
.pal-hint{padding:22px;text-align:center;color:var(--text-faint);font-size:12.5px}
.pal-row{display:flex;align-items:center;gap:11px;padding:10px 14px;cursor:pointer;
  border-bottom:1px solid var(--line)}
.pal-row:last-child{border-bottom:none}
.pal-row.on{background:var(--blue-deep)}
.pal-kind{flex:0 0 52px;font-size:9px;text-transform:uppercase;letter-spacing:.07em;
  font-weight:700;color:var(--text-faint)}
.pal-kind.player{color:var(--blue)} .pal-kind.ip{color:var(--amber)} .pal-kind.clan{color:var(--purple)}
.pal-title{font-size:13.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:0 1 auto}
.pal-on{margin-left:7px;font-size:9px;color:var(--green);text-transform:uppercase;letter-spacing:.06em}
.pal-sub{margin-left:auto;font-size:11px;color:var(--text-faint);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;flex:0 1 auto;padding-left:10px}
@media(max-width:760px){ .tb-search-lbl,.tb-search kbd{display:none} .pal-back{padding-top:6vh} }

/* ---- watch button + alert rows ---- */
.pl-topbar{display:flex;align-items:center;gap:12px;margin-bottom:12px;flex-wrap:wrap}
.watch-btn{display:inline-flex;align-items:center;gap:7px;margin-left:auto;
  background:var(--surface-3);border:1px solid transparent;color:#e2e2e2;
  padding:7px 13px;border-radius:var(--r-sm);font-size:12px;font-weight:600;transition:all .13s}
.watch-btn:hover{background:var(--hover-strong)}
.watch-btn.on{background:var(--amber);color:#141414;border-color:var(--amber)}
.alert-row .body{min-width:0;flex:1}
.alert-row.acked{opacity:.5}
.alert-why{font-size:11px;color:var(--text-faint);margin-top:3px;line-height:1.45}
.alert-acts{display:flex;align-items:center;gap:2px;margin-left:auto;flex:none}
.alert-acts .note-x{margin-left:0}
.alert-score{font-family:var(--mono);font-size:11px;font-weight:700;color:var(--amber);
  background:var(--surface-3);border-radius:5px;padding:2px 6px;margin-right:6px}
.chip-n{margin-left:6px;font-size:10px;opacity:.7;font-variant-numeric:tabular-nums}

/* ---- admin notes ---- */
.notes-list{display:flex;flex-direction:column;gap:8px}
.note-row{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-sm);padding:10px 12px}
.note-row.pinned{border-color:var(--amber)}
.note-body{font-size:13px;line-height:1.55;white-space:pre-wrap;word-break:break-word}
.note-meta{display:flex;align-items:center;gap:4px;margin-top:7px;font-size:10.5px;color:var(--text-dim)}
.note-x{background:none;border:none;color:var(--text-faint);font-size:10.5px;
  padding:2px 5px;border-radius:5px;margin-left:auto;font-weight:600}
.note-x+.note-x{margin-left:0}
.note-x:hover{color:var(--text);background:var(--hover)}
.note-x.danger:hover{color:var(--red)}
.note-add{display:flex;gap:8px;align-items:flex-start;margin-top:12px}
.note-add textarea{flex:1;min-width:0;background:var(--input);border:1px solid var(--line);
  color:var(--text);border-radius:var(--r-sm);padding:9px 11px;font:inherit;font-size:13px;resize:vertical}
.note-add textarea:focus{outline:none;border-color:var(--blue)}
.note-add .abtn{flex:none}

/* ---- combat record ---- */
.kd-stats{display:flex;gap:22px;flex-wrap:wrap}
.kd-stat .v{font-size:20px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.kd-stat .v.red{color:var(--red)}
.kd-stat .k{font-size:9.5px;color:var(--text-dim);text-transform:uppercase;letter-spacing:.08em;margin-top:3px}
.kd-chart{margin-top:14px;width:100%}
.kd-chart svg{display:block;width:100%;height:190px;overflow:visible}

/* ---- session timeline ----
   A rail down the left with one row per event. The time column is fixed width
   so the dots line up and the eye can run straight down them. */
.tl{position:relative;padding-left:2px}
.tl-row{display:flex;align-items:flex-start;gap:11px;padding:5px 0;font-size:12.5px;line-height:1.5}
.tl-time{flex:0 0 58px;text-align:right;font-family:var(--mono);font-size:10.5px;
  color:var(--text-faint);padding-top:2px;font-variant-numeric:tabular-nums}
.tl-dot{flex:0 0 9px;width:9px;height:9px;border-radius:50%;margin-top:5px;position:relative;
  background:var(--text-faint)}
.tl-dot::after{content:'';position:absolute;left:50%;top:11px;width:1px;height:calc(100% + 14px);
  transform:translateX(-50%);background:var(--line)}
.tl-row:last-child .tl-dot::after{display:none}
.tl-dot.green{background:var(--green)} .tl-dot.red{background:var(--red)}
.tl-dot.amber{background:var(--amber)} .tl-dot.blue{background:var(--blue)}
.tl-dot.dim{background:var(--text-faint)}
.tl-txt{min-width:0;flex:1;word-break:break-word}
.tl-kind{font-size:9.5px;text-transform:uppercase;letter-spacing:.07em;font-weight:700;margin-right:7px}
.tl-kind.green{color:var(--green)} .tl-kind.red{color:var(--red)}
.tl-kind.amber{color:var(--amber)} .tl-kind.blue{color:var(--blue)}
.tl-kind.dim{color:var(--text-faint)}
.tl-say{color:var(--text);opacity:.85}
.tl-row.start,.tl-row.end{font-size:12.5px}
.lyr.on{border-color:var(--blue);color:var(--text);background:var(--blue-deep)}
@media(max-width:640px){
  .tl-time{flex-basis:46px;font-size:9.5px}
  .tl-row{gap:8px}
  .kd-stats{gap:16px}
}

/* Ban evasion. Loud on purpose: this is the one finding on the page that
   usually ends in an action, so it names the accounts and addresses outright. */
.evasion{border-color:var(--red);background:var(--red-soft);margin-bottom:var(--gap)}
.evasion-h{display:flex;gap:13px;align-items:flex-start;padding:15px 18px 13px;
  border-bottom:1px solid rgba(224,52,43,.32)}
.evasion-ico{color:var(--red);flex:none;display:inline-flex;margin-top:1px}
.evasion-h h2{font-size:16px;font-weight:800;letter-spacing:-.01em;color:var(--red);
  text-transform:none;margin:0}
.evasion-sub{font-size:12.5px;color:var(--text);margin-top:3px;opacity:.85}
.evasion-b{padding:4px 18px 15px}
.evasion-row{display:flex;gap:14px;align-items:center;flex-wrap:wrap;
  padding:11px 0;border-bottom:1px solid rgba(224,52,43,.18)}
.evasion-row:last-child{border-bottom:none}
.ev-who{min-width:170px;flex:1 1 170px}
.ev-who .who{font-weight:700;font-size:14px}
.ev-sid{display:block;font-family:var(--mono);font-size:10.5px;color:var(--text-faint);margin-top:2px}
.ev-ips{display:flex;gap:6px;flex-wrap:wrap;flex:0 1 auto;min-width:0}
.ev-ip{font-family:var(--mono);font-size:12px;font-weight:700;color:var(--text);
  background:rgba(224,52,43,.18);border:1px solid rgba(224,52,43,.4);
  border-radius:6px;padding:3px 8px;cursor:pointer}
.ev-ip:hover{background:rgba(224,52,43,.3)}
.ev-meta{text-align:right;font-size:11px;flex:0 0 auto;min-width:120px;margin-left:auto}
.ev-reason{color:var(--amber);max-width:230px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.evasion-foot{display:flex;gap:12px;align-items:center;flex-wrap:wrap;
  margin-top:12px;font-size:11.5px}
.evasion-foot .dim{flex:1 1 260px;line-height:1.5}
@media(max-width:640px){
  .evasion-row{gap:8px}
  .ev-meta{text-align:left;min-width:0;flex:1 1 100%}
  .ev-reason{max-width:none}
}

.acct-score{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;margin-top:14px}
.acct-score .sc-n{font-size:26px;font-weight:800;letter-spacing:-.03em;line-height:1}
.acct-score .sc-l{font-size:11.5px;color:var(--text-dim)}
.acct-score .sc-c{font-size:11.5px}
.acct-score .right{margin-left:auto}
@media(max-width:560px){
  .acct-grid{grid-template-columns:repeat(auto-fit,minmax(96px,1fr))}
  .acell .n{font-size:17px}
}

/* action bar */
.actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:4px}
.abtn{background:var(--surface-3);border:1px solid transparent;color:#e2e2e2;
  padding:8px 15px;border-radius:var(--r-sm);font-size:12.5px;font-weight:600;transition:all .13s}
.abtn:hover{background:var(--hover-strong)}
.abtn.danger{background:var(--red);color:#fff}
.abtn.danger:hover{background:#c72d25}
.abtn.warn{background:var(--surface-3);color:var(--amber)}
.abtn.warn:hover{background:var(--hover-strong)}
.abtn.info{background:var(--blue-strong);color:#fff}
.abtn.info:hover{background:#0b7dd0}
.codes{font-size:12.5px;max-height:320px;overflow-y:auto;overflow-x:hidden}
.codes .row{display:flex;align-items:center;gap:10px;padding:7px 0;border-bottom:1px solid var(--line)}
.codes .row:last-child{border-bottom:none}
.codes .code{font-family:var(--mono);font-size:15px;letter-spacing:.26em;color:var(--text);
  background:var(--surface-3);border:1px solid var(--line-bright);padding:2px 9px;border-radius:7px}

/* ============================================================
   CLANS
   ============================================================ */
.member{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--line);font-size:12.5px}
.member:last-child{border-bottom:none}
.member .nm{color:var(--text);cursor:pointer;font-weight:600}
.member .nm:hover{color:var(--blue)}
.rel-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap)}
.taglist{display:flex;gap:8px;flex-wrap:wrap}
.tagchip{padding:6px 12px;border-radius:999px;font-size:12px;font-weight:600;
  border:1px solid var(--pill-line);color:var(--text-dim);background:var(--surface-2)}
.tagchip.ally{color:var(--green)}
.tagchip.enemy{color:var(--danger-text)}
.matchup-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px;padding:14px 16px}
.matchup{display:flex;align-items:center;gap:9px;background:var(--surface-2);border:1px solid var(--track);
  border-radius:var(--r);padding:11px 13px;cursor:pointer;transition:background .12s}
.matchup:hover{background:var(--surface-3)}
.matchup .mu-a{color:var(--amber);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:96px}
.matchup .mu-arrow{color:var(--text-faint);flex:none}
.matchup .mu-v{color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:96px;flex:1}
.matchup .mu-c{margin-left:auto;color:var(--text);font-weight:700;font-size:14px;flex:none}

/* ============================================================
   REPORTS
   ============================================================ */
.report{background:var(--surface-1);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:15px 17px;margin-bottom:12px;position:relative}
.report.handled{opacity:.55}
.report .top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:9px}
.report .vs{color:var(--text-dim)}
.report .nm{color:var(--text);cursor:pointer;font-weight:600}
.report .nm:hover{color:var(--blue)}
.report .nm.suspect{color:var(--danger-text)}
.report .nm.suspect:hover{color:var(--danger-text);text-decoration:underline}
.report .subj{font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;font-weight:700;
  padding:3px 9px;border:1px solid var(--line-bright);border-radius:999px;color:var(--amber);background:var(--surface-2)}
.report .msg{font-size:14px;color:var(--text);line-height:1.55;
  background:var(--surface-2);padding:11px 14px;border-radius:var(--r-sm);margin:10px 0}
.report .meta{display:flex;gap:16px;flex-wrap:wrap;font-size:11.5px;color:var(--text-dim)}
.rep-board{display:flex;flex-direction:column;gap:4px}
.rep-rank{display:flex;align-items:center;gap:10px;width:100%;text-align:left;
  background:transparent;border:1px solid transparent;border-radius:var(--r-sm);padding:8px 11px;cursor:pointer}
.rep-rank:hover{background:var(--surface-2)}
.rep-rank.on{background:var(--surface-3)}
.rep-rank .rep-n{color:var(--text-faint);font-size:11px;min-width:30px;font-variant-numeric:tabular-nums}
.rep-rank .rep-name{color:var(--text);font-size:12.5px;flex:0 1 auto;max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rep-rank .rep-bar{flex:1;height:6px;background:var(--track);border-radius:999px;overflow:hidden;min-width:40px}
.rep-rank .rep-bar i{display:block;height:100%;background:var(--red);border-radius:999px}
.rep-rank .rep-c{color:var(--danger-text);font-weight:700;font-size:12px;min-width:34px;text-align:right}
.rep-badge{margin-left:8px;cursor:pointer;background:var(--red-soft);border:1px solid rgba(224,52,43,.4);
  color:var(--danger-text);font-size:10px;font-weight:700;padding:2px 9px;border-radius:999px;white-space:nowrap}
.rep-badge:hover{background:rgba(224,52,43,.2)}

/* ============================================================
   SIGNS. RustApp card: image, avatar+name+date, kv rows
   ============================================================ */
.signs-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:var(--gap)}
.sign{background:var(--surface-1);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;position:relative;transition:border-color .13s}
.sign:hover{border-color:var(--line-bright)}
.sign .thumb{width:100%;aspect-ratio:16/10;background:var(--map-bg) center/cover no-repeat;
  display:grid;place-items:center;cursor:pointer}
.sign .thumb.empty{color:var(--text-faint);font-size:10.5px;letter-spacing:.08em}
.sign .head{display:flex;align-items:center;gap:10px;padding:11px 13px 7px}
.sign .head .ravi{width:32px;height:32px;font-size:11px}
.sign .head .nm{color:var(--text);cursor:pointer;font-weight:600;font-size:13px}
.sign .head .nm:hover{color:var(--blue)}
.sign .kvs{padding:0 13px 12px}
.sign .kvs .kv{font-size:12px;padding:5px 0;border-bottom:none}
.sign .kvs .kv .v{font-family:var(--mono);font-size:11.5px}
.kindtag{display:none}
.lightbox{position:fixed;inset:0;background:rgba(10,10,10,.92);z-index:200;display:grid;place-items:center;padding:30px}
.lightbox img{max-width:90vw;max-height:80vh;border:1px solid var(--pill-line);border-radius:var(--r);background:var(--map-bg)}
.lightbox .lb-meta{margin-top:14px;text-align:center;font-size:12.5px;color:var(--text-dim)}
.lightbox .lb-close{position:absolute;top:20px;right:26px;font-size:26px;color:var(--text-dim);cursor:pointer}
.lightbox .lb-close:hover{color:var(--text)}

/* ============================================================
   LIVE CHAT
   ============================================================ */
.chat-wrap{display:flex;flex-direction:column;height:calc(100vh - 56px - 44px)}
.chat-log{flex:1;overflow-y:auto;padding:8px 0;display:flex;flex-direction:column}
.cmsg{padding:6px 18px;font-size:13.5px;display:flex;gap:10px;align-items:baseline;min-width:0}
.cmsg .ct{color:var(--text-faint);font-size:10px;flex:0 0 48px;font-family:var(--mono)}
/* The name used to be flex:none, so a long clan-tagged name took the whole row
   and squeezed the message into a one-character column. It shrinks with an
   ellipsis now; the message keeps the space it needs. */
.cmsg .cn{color:var(--text);cursor:pointer;flex:0 1 auto;min-width:0;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cmsg .cn:hover{color:var(--blue)}
.cmsg .ch{flex:0 0 auto}
.cmsg .cx{color:var(--text);word-break:break-word;flex:1 1 auto;min-width:0}
.cmsg.team .cn,.cmsg.team .ch{color:var(--chat-blue)}
.cmsg.pm{background:rgba(90,167,240,.05)}
.cmsg.pm .ch{color:var(--chat-blue)}
.cmsg.server{background:rgba(139,201,78,.05)}
.cmsg.server .cx{color:var(--chat-green);font-style:italic}
.cmsg .ch{font-size:9px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);font-weight:700}
.chat-send{display:flex;gap:10px;padding:13px 18px;border-top:1px solid var(--line);background:var(--surface-1)}
.chat-send input{flex:1;background:var(--input);border:1px solid var(--track);color:var(--text);
  padding:11px 14px;border-radius:var(--r-sm);font-family:var(--sans);font-size:14px}
.chat-send input:focus{outline:none;border-color:var(--blue);box-shadow:var(--ring)}
.chat-send .pm-to{width:170px;font-size:13px}
.chat-send button{background:var(--blue-strong);color:#fff;border:none;padding:0 22px;
  border-radius:var(--r-sm);font-weight:700;font-size:12.5px;transition:filter .15s}
.chat-send button:hover{filter:brightness(1.1)}

/* ============================================================
   CONSOLES
   ============================================================ */
.live-term{height:min(56vh,520px);overflow-y:auto;padding:12px 14px;margin:0;background:var(--term-bg);color:var(--term-text);
  border-radius:0 0 var(--r-lg) var(--r-lg);font-family:var(--mono);font-size:12px;line-height:1.55}
.lc-line{display:flex;gap:10px;padding:1px 0;white-space:pre-wrap;word-break:break-word}
.lc-line .lc-t{color:var(--text-faint);flex:0 0 auto;font-variant-numeric:tabular-nums;opacity:.7}
.lc-line .lc-x{flex:1;min-width:0}
.lc-line.lc-log .lc-x{color:#c2c2c2}
.lc-line.lc-warn .lc-x{color:var(--yellow)}
.lc-line.lc-err{background:rgba(224,52,43,.07)}
.lc-line.lc-err .lc-x{color:var(--danger-text)}
.console-out{max-height:380px;overflow:auto;padding:10px 16px;font-size:12px}
.con-line{padding:6px 0;border-bottom:1px solid var(--line)}
.con-line:last-child{border-bottom:none}
.con-cmd{display:flex;align-items:center;gap:5px;font-family:var(--mono);color:var(--text)}
.con-prompt{color:var(--blue)}
.con-meta{margin-left:auto;font-size:10px;color:var(--text-dim);letter-spacing:.04em;text-transform:uppercase}
.con-meta.ok{color:var(--green)}
.con-meta.pend{color:var(--amber)}
.con-output{margin:7px 0 2px;padding:9px 11px;background:var(--term-bg);
  border-left:2px solid var(--pill-line);white-space:pre-wrap;word-break:break-word;
  color:var(--term-text);font-family:var(--mono);font-size:11px;max-height:200px;overflow:auto;border-radius:0 var(--r-sm) var(--r-sm) 0}

/* ============================================================
   CHEAT FLAGS / CONVARS / PLUGINS
   ============================================================ */
.vbadge{font-size:9px;letter-spacing:.06em;text-transform:uppercase;font-weight:700;padding:3px 9px;border-radius:999px;
  border:1px solid var(--pill-line);color:var(--text-dim);background:var(--surface-2);min-width:74px;text-align:center;flex:none}
.vbadge.red{color:var(--danger-text)}
.vbadge.amber{color:var(--amber)}
.vbadge.clk{cursor:pointer;user-select:none}
.vbadge.clk:hover{border-color:var(--line-bright);color:var(--text)}
.vbadge.clk.on{background:#e8e8e8;color:#111;border-color:#e8e8e8}
.cheat-detail{display:none;margin:0 18px 10px 66px;padding:11px 13px;background:var(--map-bg);
  border:1px solid var(--line);border-radius:var(--r);font-family:var(--mono);font-size:11px;
  color:var(--text-dim);white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}
.cheat-detail.open{display:block}
.convar-cat{margin-bottom:16px}
.convar-cat-h{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--text-dim);
  margin:0 0 8px;padding-bottom:5px;border-bottom:1px solid var(--line);font-weight:700}
.convar-row{display:flex;align-items:center;gap:8px;padding:4px 0}
.convar-name{flex:0 0 210px;font-family:var(--mono);font-size:12px;color:var(--text);cursor:pointer}
.convar-name:hover{color:var(--blue)}
.convar-in{flex:1}
.pm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px}
.pm-row{display:flex;align-items:center;gap:10px;padding:11px 13px;background:var(--surface-2);
  border:1px solid var(--track);border-radius:var(--r)}
.pm-row.core{opacity:.7}
.pm-row .pm-meta{flex:1;min-width:0}
.pm-row .pm-name{font-size:12.5px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pm-row .pm-ver{color:var(--text-faint);font-weight:400;font-size:11px}
.pm-row .pm-core{margin-left:6px;font-size:9px;letter-spacing:.04em;text-transform:uppercase;color:var(--text-faint);border:1px solid var(--pill-line);border-radius:999px;padding:1px 7px}
.pm-row .pm-auth{font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--text-dim)}
.pm-row .pm-btns{display:flex;gap:6px;flex:0 0 auto}
.pm-row .pm-btns .lyr{padding:6px 11px;font-size:11px;border-radius:var(--r-sm);cursor:pointer;
  background:var(--surface-3);border:1px solid transparent;color:var(--text-dim)}
.pm-row .pm-btns .lyr:hover{background:var(--hover-strong);color:var(--text)}
.pm-row .pm-btns .lyr.danger{background:var(--red);color:#fff}
.pm-row .pm-btns .lyr.danger:hover{background:#c72d25}

/* ============================================================
   MODAL
   ============================================================ */
.modal-bg{position:fixed;inset:0;background:rgba(8,8,8,.72);z-index:150;display:grid;place-items:center;padding:24px}
.modal{width:min(460px,100%);background:var(--surface-1);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--shadow);position:relative;display:flex;flex-direction:column;max-height:88vh}
.modal-h{padding:16px 18px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px;flex:0 0 auto}
.modal-h h3{margin:0;font-size:14px;font-weight:700}
.modal-h .x{margin-left:auto;color:var(--text-dim);cursor:pointer;font-size:20px}
.modal-h .x:hover{color:var(--text)}
.modal-b{padding:18px;overflow-y:auto;flex:1 1 auto;min-height:0}
.field{margin-bottom:14px}
.field label{display:block;font-size:11px;letter-spacing:.04em;
  color:var(--text-dim);margin-bottom:7px;font-weight:600}
.field input,.field select{width:100%;background:var(--input);border:1px solid var(--track);
  color:var(--text);padding:11px 13px;border-radius:var(--r-sm);font-family:var(--sans);font-size:13.5px}
.field input:focus,.field select:focus{outline:none;border-color:var(--blue);box-shadow:var(--ring)}
.field select{cursor:pointer}
.preset-chips{margin-top:8px}
.preset-chips .chip{cursor:pointer}
.ip-opts{display:flex;flex-direction:column;gap:6px}
.ip-opt{display:flex;align-items:center;gap:10px;width:100%;text-align:left;
  background:var(--surface-2);border:1px solid var(--track);color:var(--text);
  padding:10px 13px;border-radius:var(--r-sm);font-family:var(--mono);font-size:12px;cursor:pointer;transition:all .13s}
.ip-opt:hover{background:var(--surface-3)}
.ip-opt.sel{border-color:var(--red)}
.note{font-size:11.5px;line-height:1.6;border-radius:var(--r-sm);padding:10px 13px;margin-top:4px}
.warn-note{color:var(--amber);background:rgba(217,161,60,.08);border:1px solid rgba(217,161,60,.3)}
.modal-foot{display:flex;gap:10px;justify-content:flex-end;padding:15px 18px;border-top:1px solid var(--line);flex:0 0 auto}
.modal-foot .cancel{background:var(--surface-3);border:1px solid transparent;color:var(--text-dim);
  padding:10px 18px;border-radius:var(--r-sm);font-size:12.5px;font-weight:600}
.modal-foot .cancel:hover{background:var(--hover-strong);color:var(--text)}
.modal-foot .confirm{background:var(--blue-strong);color:#fff;border:none;padding:10px 22px;
  border-radius:var(--r-sm);font-weight:700;font-size:12.5px;transition:filter .15s}
.modal-foot .confirm:hover{filter:brightness(1.1)}
.modal-foot .confirm.danger{background:var(--red)}
.modal-foot .confirm.warn{background:var(--amber);color:#1a1304}
.mlrs-targets{max-height:min(42vh,300px);overflow-y:auto;padding-right:5px}
.mlrs-targets .ip-opt{width:100%}
.mini-x{margin-left:8px;flex:0 0 auto;width:22px;height:22px;line-height:1;border-radius:6px;
  background:transparent;border:1px solid var(--pill-line);color:var(--text-faint);cursor:pointer;font-size:11px}
.mini-x:hover{background:var(--red-soft);border-color:rgba(224,52,43,.6);color:#ffd7d4}

/* ============================================================
   TC POPUP
   ============================================================ */
.tc-popup{position:fixed;z-index:1000;width:262px;max-height:340px;overflow:auto;
  background:var(--surface-1);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--shadow);padding:13px 14px;font-size:12px}
.tc-pop-h{display:flex;justify-content:space-between;align-items:center;
  color:var(--text);font-size:11px;letter-spacing:.04em;text-transform:uppercase;margin-bottom:9px;font-weight:700}
.tc-pop-h .x{cursor:pointer;color:var(--text-dim)}
.tc-pop-h .x:hover{color:var(--text)}
.tc-pop-row{display:flex;gap:8px;margin:4px 0;align-items:center}
.tc-pop-row .k{flex:0 0 52px;color:var(--text-dim)}
.tc-pop-h2{margin:10px 0 6px;font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-dim);border-top:1px solid var(--line);padding-top:8px;font-weight:600}
.tc-auth-list{display:flex;flex-wrap:wrap;gap:5px}
.tc-auth{font-family:var(--mono);font-size:11px;padding:2px 8px;border:1px solid var(--pill-line);
  border-radius:999px;color:var(--text);text-decoration:none}
.tc-auth:hover{border-color:var(--line-bright);color:var(--text)}

/* ============================================================
   LIVE INVENTORY
   ============================================================ */
.inv-meta{font-size:11.5px;margin:2px 2px 14px;color:var(--text-dim);display:flex;align-items:center;gap:7px}
.inv-meta .dot{width:7px;height:7px;border-radius:50%;background:var(--text-faint)}
.inv-meta .dot.on{background:var(--green);box-shadow:0 0 6px var(--green)}
.inv-wrap{display:flex;flex-direction:column;gap:18px}
.inv-gl{font-size:10px;letter-spacing:.12em;color:var(--text-faint);margin:0 0 9px 1px;font-weight:700;text-transform:uppercase}
/* fixed-column slot grid like the in-game inventory */
/* One cell size for every section. It used to be left to `1fr` inside a
   max-width, which resolved differently per section: MAIN came out at 90px,
   BELT at 71px and WORN at 56px, so the same item looked like three sizes
   depending on which row it sat in. A fixed track removes the ambiguity. */
:root{--inv-cell:68px}
.inv-grid{display:grid;grid-template-columns:repeat(var(--cols,6),var(--inv-cell));
  gap:6px;justify-content:start}
.inv-cell{position:relative;aspect-ratio:1/1;background:#15181d;border:1px solid #262b32;border-radius:8px;
  display:grid;place-items:center;overflow:hidden;transition:border-color .12s,background .12s}
.inv-cell.empty{background:#101216;border-color:#20242a;border-style:dashed;opacity:.55}
.inv-cell:not(.empty):hover{border-color:#4a5361;background:#1b1f26;z-index:2}
.inv-img{width:82%;height:82%;max-width:100%;max-height:100%;object-fit:contain;filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))}
.inv-fallback{font-family:var(--mono);font-size:13px;color:var(--text-dim);font-weight:700}
.inv-amt{position:absolute;right:4px;bottom:3px;font-size:11px;font-weight:700;color:#fff;
  text-shadow:0 1px 2px #000,0 0 3px #000;font-family:var(--mono);letter-spacing:-.02em}
.inv-ammo{position:absolute;left:4px;bottom:3px;font-size:9.5px;font-weight:700;color:var(--amber);
  text-shadow:0 1px 2px #000;font-family:var(--mono)}
.inv-mods{position:absolute;right:3px;top:3px;font-size:9px;font-weight:700;color:#cfe8b0;
  background:rgba(139,201,78,.15);border:1px solid rgba(139,201,78,.35);border-radius:5px;padding:0 3px}
.inv-cond{position:absolute;left:4px;right:4px;bottom:0;height:3px;background:#000a;border-radius:2px;overflow:hidden}
.inv-cond>i{display:block;height:100%;background:linear-gradient(90deg,var(--red),var(--amber),var(--green))}
.inv-worn .inv-grid{grid-template-columns:repeat(var(--cols,7),var(--inv-cell))}

/* floating item name tooltip (Rust-style black pill) */
.item-tip{position:fixed;z-index:9999;pointer-events:none;opacity:0;transform:translateY(3px);
  transition:opacity .1s,transform .1s;background:rgba(12,14,17,.97);border:1px solid rgba(255,255,255,.12);
  border-radius:8px;padding:7px 12px;box-shadow:0 8px 26px rgba(0,0,0,.6);display:flex;flex-direction:column;gap:2px;
  max-width:280px}
.item-tip.show{opacity:1;transform:translateY(0)}
.item-tip .it-name{font-size:13px;font-weight:700;color:#fff;white-space:nowrap}
.item-tip .it-meta{font-size:10.5px;color:var(--text-dim);font-family:var(--mono)}
.item-tip .it-mods{font-size:10px;color:#cfe8b0}

/* ============================================================
   SERVER SWITCHER
   ============================================================ */
.srv-switch{display:flex;align-items:center;gap:8px;padding:6px 11px;border:1px solid var(--track);
  border-radius:var(--r-sm);background:var(--surface-1)}
.srv-switch.single{background:transparent;border-color:transparent;padding-left:0}
.srv-label{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-faint);font-weight:600}
.srv-select{background:var(--surface-3);border:1px solid transparent;color:var(--text);
  font-family:var(--sans);font-size:12.5px;padding:6px 10px;border-radius:7px;outline:none;cursor:pointer;
  font-weight:600;max-width:220px}
.srv-select:focus{border-color:var(--blue);box-shadow:var(--ring)}
.srv-dot{width:8px;height:8px;border-radius:50%;background:var(--text-faint);display:inline-block;flex:none}
.srv-dot.on{background:var(--green)}
.srv-name{font-size:13.5px;color:var(--text);font-weight:600}

/* ============================================================
   TOAST / EMPTY / LOADING / ONBOARDING / MISC
   ============================================================ */
.toasts{position:fixed;bottom:22px;right:22px;z-index:300;display:flex;flex-direction:column;gap:9px}
.toast{background:var(--surface-2);border:1px solid #383838;
  padding:12px 16px;border-radius:var(--r);font-size:12.5px;color:var(--text);min-width:240px;
  box-shadow:var(--shadow);animation:slidein .2s ease}
.toast.err{border-color:rgba(224,52,43,.55)}
.toast .h{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--text-dim);margin-bottom:3px;font-weight:700}
.empty{padding:44px;text-align:center;color:var(--text-faint);font-size:12.5px}
.empty-title{color:var(--text-dim);font-size:14px;font-weight:600}
.empty-hint{color:var(--text-faint);font-size:12.5px;line-height:1.6;margin:8px auto 0;max-width:440px}
.filter-banner{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  background:var(--surface-2);border:1px solid var(--pill-line);
  border-radius:var(--r);padding:10px 14px;margin-bottom:14px;font-size:12.5px;color:var(--text)}
.gs-panel{margin-bottom:var(--gap)}
.gs-lead{color:var(--text);font-size:13.5px;line-height:1.6;margin-bottom:16px}
.gs-step{display:flex;gap:13px;align-items:flex-start;padding:12px 0;border-top:1px solid var(--line)}
.gs-num{flex:none;width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
  background:var(--surface-3);color:var(--text);border:1px solid var(--line-bright);font-size:12px;font-weight:700}
.gs-step-t{color:var(--text);font-size:13.5px;font-weight:600;margin-bottom:3px}
.gs-step-b{color:var(--text-dim);font-size:12.5px;line-height:1.6}
.gs-step-b code,.gs-foot code{font-family:var(--mono);color:#d6e9ff;background:var(--surface-3);padding:1px 6px;border-radius:5px}
.gs-foot{margin-top:14px;padding-top:13px;border-top:1px solid var(--line);color:var(--text-faint);font-size:11.5px;line-height:1.6}
.loading{padding:44px;text-align:center;color:var(--text-dim);font-size:12.5px;letter-spacing:.1em}
.loading::after{content:'';animation:dots 1.4s steps(4,end) infinite}
.build-warn{position:fixed;left:0;right:0;bottom:0;z-index:9999;display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:12px 16px;font-size:12.5px;background:#2a1413;color:#ffd7d4;
  border-top:1px solid var(--red);box-shadow:0 -8px 26px rgba(0,0,0,.5)}
.build-warn strong{color:var(--danger-text)}
.build-warn .bw-x{margin-left:auto;background:transparent;border:1px solid #5a2c29;color:#ffd7d4;border-radius:7px;padding:4px 10px;font-size:11px}
.build-warn .bw-x:hover{border-color:var(--red);color:var(--text)}

/* ============================================================
   ANIMATIONS
   ============================================================ */
@keyframes ping{0%{transform:translate(-50%,-50%) scale(.6);opacity:.9}100%{transform:translate(-50%,-50%) scale(2.6);opacity:0}}
@keyframes dots{0%{content:''}25%{content:'.'}50%{content:'..'}75%{content:'...'}}
@keyframes slidein{from{transform:translateX(20px);opacity:0}to{transform:translateX(0);opacity:1}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}

/* ============================================================
   RESPONSIVE
   ============================================================ */
/* Control rows sitting directly on a page, tab bars, filter chips, action
   buttons. Carried no bottom margin, so the panel underneath touched them.
   .toolbar and .view-head already had one; these three did not.

   Scoped on purpose: the same classes are reused inside panels, list rows and
   modals, where the extra gap would be wrong. div:not(.panel) keeps it off rows
   nested in a panel that happens to be a div.

   Depth 1 is handled by the catch-all below; this covers views that wrap their
   content in an extra div (Ranks does), which the catch-all cannot reach. */
.view > div:not(.panel) > .seg,
.view > div:not(.panel) > .chips,
.view > div:not(.panel) > .actions{margin-bottom:var(--gap)}
.view > div:not(.panel) > .panel + .panel{margin-top:var(--gap)}

/* Catch-all for page-level stacking. .view is a plain block, so this margin
   COLLAPSES against any margin-bottom the previous sibling already has, the
   larger of the two wins and nothing doubles up. That is why it is safe to apply
   broadly; it only shows up where a section had no spacing at all.
   The map view is excluded: it is a deliberately full-bleed, padding-free layout. */
.view:not(.map-view) > * + *{margin-top:var(--gap)}

/* Two equal panels side by side. As a class rather than an inline style so the
   media queries below can actually collapse it: an inline grid-template-columns
   outranks them and the panels just squeeze into each other instead. */
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap);align-items:start}
.two-col > *{min-width:0}

@media (max-width:1080px){
  .dash-grid{grid-template-columns:1fr}
  .chart-grid{grid-template-columns:1fr}
  .dossier-grid{grid-template-columns:1fr 1fr}
  .stat-strip{grid-template-columns:repeat(3,1fr)}
  .two-col{grid-template-columns:1fr}
  .perm-cols{grid-template-columns:1fr}
}
.nav-toggle{display:none;background:none;border:1px solid var(--pill-line);color:var(--text);
  width:36px;height:36px;border-radius:var(--r-sm);align-items:center;justify-content:center;font-size:16px}

/* ==============================================================================
   MOBILE: a layout of its own, not a squeezed desktop.

   The shape changes, not just the widths: the sidebar becomes a drawer plus a
   bottom tab bar, tables become stacked cards, dialogs become bottom sheets, and
   nothing interactive is smaller than a fingertip.

   --bn-h is the bottom bar's height; .main reserves it as padding so every view,
   including the full-bleed map, keeps clear of it.
   ============================================================================== */
.scrim{display:none}
.bottomnav{display:none}

@media (max-width:760px){
  :root{--bn-h:56px;--gap:14px}

  /* ---- shell ---- */
  .app{grid-template-columns:1fr}
  .main{padding-bottom:calc(var(--bn-h) + env(safe-area-inset-bottom,0px))}
  .view{padding:14px}
  .view.map-view{padding:0}
  body.nav-open{overflow:hidden}          /* page behind the drawer must not scroll */

  /* ---- drawer ---- */
  .nav{position:fixed;left:0;top:0;bottom:0;width:min(84vw,300px);z-index:220;
    transform:translateX(-100%);transition:transform .22s ease;
    padding-bottom:env(safe-area-inset-bottom,0px);overflow-y:auto;box-shadow:var(--shadow)}
  .nav.open{transform:translateX(0)}
  .scrim{display:block;position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:210;
    opacity:0;pointer-events:none;transition:opacity .22s ease}
  .scrim.on{opacity:1;pointer-events:auto}
  .nav-toggle{display:inline-flex !important;width:42px;height:42px;font-size:18px}
  .nav-link{padding:13px 16px;font-size:14px;border-radius:var(--r-sm)}
  .nav-brand{padding:16px}
  .acct-trigger{min-height:52px}

  /* ---- top bar ----
     Stays stuck to the top on purpose: which server and which wipe you are
     looking at is the context that stops a ban landing on the wrong box.
     The long hostname is dropped: the server picker already names it, which
     keeps the whole thing on one row instead of three. */
  .topbar{height:auto;min-height:54px;padding:8px 10px;gap:8px;flex-wrap:wrap;
    position:sticky;top:0;z-index:90}
  /* Every child needs an explicit order. The search button was added later
     without one, defaulted to 0, and so sorted ahead of the hamburger's 1,
     which is why the menu button ended up in the middle of the bar. */
  .topbar .nav-toggle{order:0;flex:0 0 auto;margin-inline-end:2px}
  .topbar .host{display:none}
  /* The two things you press live together on the left, under the thumb, and
     the pickers take the rest of the row. */
  .topbar .tb-search{order:1;flex:0 0 auto;padding:8px 10px;margin-inline-end:2px}
  .topbar .srv-select{order:2;flex:1 1 26%;min-width:0}
  .topbar #wipe-select{order:3;flex:1 1 26%;min-width:0}
  .topbar .live-pill{order:4;flex:0 0 auto;padding:5px 9px;font-size:9.5px}
  .topbar .right{display:none}
  .topbar .hide-sm{display:none}

  /* ---- bottom tab bar ---- */
  .bottomnav{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:200;
    background:var(--surface-1);border-top:1px solid var(--border-hard);
    padding-bottom:env(safe-area-inset-bottom,0px)}
  .bn-item{flex:1 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:3px;height:var(--bn-h);background:none;border:none;color:var(--text-faint);
    font-size:9.5px;letter-spacing:.02em;text-decoration:none;position:relative;min-width:0}
  .bn-item.active{color:var(--blue)}
  .bn-ico{font-size:17px;line-height:1;position:relative;display:grid;place-items:center;height:20px}
  .bn-ico .ico-svg svg{width:18px;height:18px}
  .bn-lbl{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
  .bn-badge{position:absolute;top:-5px;left:11px;min-width:15px;height:15px;padding:0 4px;
    border-radius:999px;background:var(--red);color:#fff;font-size:9px;font-weight:700;
    display:grid;place-items:center}
  .bn-badge.hidden{display:none}

  /* ---- touch targets: nothing tappable under ~44px ---- */
  .abtn,.lyr,.tbtn,.chip,.seg-b,.pager button,.modal-foot button{min-height:42px}
  .abtn{padding:10px 16px;font-size:13px}
  .chip{padding:10px 14px;font-size:12px}
  .seg-b{padding:9px 16px;font-size:12.5px}
  .perm-item{padding:10px 8px}
  .perm-item input,.wrow input{width:20px;height:20px}
  .wrow{padding:11px 8px}
  .x,.acct-trigger,.nav-toggle{min-height:42px}

  /* ---- inputs: 16px stops iOS zooming the page on focus ---- */
  input,select,textarea,.search{font-size:16px !important;min-height:44px}
  textarea{min-height:96px}
  .field{margin-bottom:14px}
  .srv-select{height:38px;min-height:38px;font-size:13px !important}

  /* ---- scrollable strips instead of wrapping/overflowing ---- */
  .seg{overflow-x:auto;max-width:100%;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .seg::-webkit-scrollbar{display:none}
  .seg-b{white-space:nowrap;flex:0 0 auto}
  .chips{gap:6px}

  /* ---- grids collapse ---- */
  .dash-grid,.chart-grid,.dash-low,.dossier-grid,.rel-grid,.two-col,.perm-cols,
  .farm-grid,.signs-grid,.pm-grid,.matchup-grid{grid-template-columns:1fr}
  .stat-strip{grid-template-columns:repeat(2,1fr);gap:8px}
  .perm-grid{grid-template-columns:1fr}
  .pmeta .namecell{max-width:none}

  /* ---- tables become stacked cards ----
     data-l is stamped onto every cell from its column header at render time, so
     each line still says what it is once the header row is gone. */
  .tbl,.tbl tbody,.tbl tr,.tbl td{display:block;width:auto}
  .tbl thead{display:none}
  .tbl tr{padding:12px 14px;border-bottom:1px solid var(--line)}
  .tbl tr:last-child{border-bottom:none}
  .tbl tr:hover td{background:none}
  .tbl td{border:none;padding:3px 0;display:flex;align-items:center;
    justify-content:space-between;gap:14px;font-size:13px;text-align:right}
  .tbl td[data-l]::before{content:attr(data-l);color:var(--text-faint);font-size:9.5px;
    text-transform:uppercase;letter-spacing:.07em;font-weight:700;flex:0 0 auto;text-align:left}
  .tbl td:first-child{padding:0 0 8px;justify-content:flex-start;text-align:left}
  .panel-b.flush .tbl tr{padding-left:16px;padding-right:16px}

  /* ---- dialogs become bottom sheets ---- */
  .modal-bg{padding:0;place-items:end center}
  .modal{width:100%;max-width:none;max-height:92vh;border-radius:16px 16px 0 0;
    border-bottom:none;animation:sheet-up .2s ease-out}
  .modal.wide{width:100%}
  @keyframes sheet-up{from{transform:translateY(14px);opacity:.6}to{transform:none;opacity:1}}
  .modal-h{padding:14px 16px;position:sticky;top:0;background:var(--surface-1);z-index:2}
  .modal-b{padding:14px 16px}
  .modal-foot{position:sticky;bottom:0;background:var(--surface-1);gap:10px;
    padding:12px 16px calc(12px + env(safe-area-inset-bottom,0px))}
  .modal-foot button{flex:1 1 0}
  .wlist,.perm-results{max-height:46vh}

  /* ---- per-view ---- */
  /* 150px covers the sticky topbar, the view heading and the view padding.
     dvh so it follows the browser's collapsing URL bar; vh first as a fallback. */
  .chat-wrap{height:calc(100vh - var(--bn-h) - 150px);height:calc(100dvh - var(--bn-h) - 150px)}
  /* chat reads as two lines on a phone: who and when, then what they said */
  .cmsg{flex-wrap:wrap;row-gap:2px;padding:8px 14px;column-gap:8px}
  .cmsg .ct{flex:0 0 42px;font-size:9.5px}
  .cmsg .cn{max-width:58vw}
  .cmsg .cx{flex:1 1 100%;font-size:13.5px;line-height:1.45}
  .chat-send{flex-wrap:wrap;gap:8px;padding:10px 12px calc(10px + env(safe-area-inset-bottom,0px))}
  .chat-send .pm-to{flex:1 1 100%;width:auto}
  .chat-send input{min-width:0}
  .chat-send button{flex:0 0 auto;padding:0 18px;min-height:44px}
  .live-term{max-height:44vh}
  :root{--inv-cell:52px}
  .inv-grid{grid-template-columns:repeat(auto-fill,var(--inv-cell))}
  .inv-worn .inv-grid{grid-template-columns:repeat(auto-fill,var(--inv-cell))}
  .dbar{grid-template-columns:1fr 70px;row-gap:2px}
  .dbar-t{grid-column:1 / -1;order:3}
  .dbar-r{display:none}
  .drow{grid-template-columns:1fr 72px 72px;font-size:12px}
  .rep-rank .rep-name{max-width:none}
  .settings-pop,.tc-popup{width:min(92vw,300px)}
  .notif{min-width:0;max-width:calc(100vw - 24px)}
}

/* very small phones. Trim the last bits of horizontal pressure */
@media (max-width:400px){
  .view{padding:12px 10px}
  .panel-b{padding:12px}
  .tbl tr,.panel-b.flush .tbl tr{padding-left:12px;padding-right:12px}
  .stat-strip{grid-template-columns:1fr 1fr;gap:6px}
  .bn-lbl{font-size:9px}
  .abtn{padding:10px 13px}
  .adm-row{gap:9px;padding:11px 12px}
}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
}
:focus-visible{outline:2px solid var(--blue);outline-offset:2px}

/* ============================================================
   v47. Fullscreen Map view, avatar markers + trails,
   Alerts / Bans / Admins views, Steam avatar images
   ============================================================ */

/* real avatar images inside the circular initials chips */
.ravi{overflow:hidden}
.ravi .avimg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:50%}
.ravi::after{z-index:2}
.av{position:relative;display:grid;place-items:center;color:var(--text-dim);font-weight:700;font-size:20px}
.av::before{content:attr(data-ini)}
.av .avimg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:50%}
.frow>.ravi{width:28px;height:28px;font-size:10px;flex:0 0 auto}
.frow>.ravi::after{border-color:var(--surface-1)}

/* ---------- fullscreen map view ---------- */
.view.map-view{padding:0;overflow:hidden}
.mapfull{height:calc(100vh - 56px);display:flex;flex-direction:column;min-width:0}
.map-topbar{display:flex;align-items:center;gap:10px;padding:0 14px;height:46px;flex:0 0 auto;
  background:var(--topbar);border-bottom:1px solid var(--border-hard)}
.map-topbar .coord{font-size:10.5px}
.mk-size{display:flex;align-items:center;gap:2px;background:var(--surface-2);border:1px solid var(--pill-line);
  border-radius:var(--r-sm);padding:2px}
.mk-size-v{font-size:11px;color:var(--text-dim);min-width:42px;text-align:center;font-variant-numeric:tabular-nums}
.szbtn{width:26px;height:26px;background:transparent;border:none;color:var(--text-dim);font-size:14px;
  border-radius:6px;display:grid;place-items:center}
.szbtn:hover{background:var(--surface-3);color:var(--text)}
.tbtn{background:var(--surface-2);border:1px solid var(--pill-line);color:var(--text-dim);padding:7px 13px;
  border-radius:var(--r-sm);font-size:11.5px;font-weight:600;transition:all .13s;white-space:nowrap}
.tbtn:hover{background:var(--surface-3);color:var(--text)}
.map-search{width:240px;background:var(--pill-bg);border:1px solid var(--pill-line);color:var(--text);
  padding:8px 12px;border-radius:var(--r-sm);font-family:var(--sans);font-size:12.5px}
.map-search:focus{outline:none;border-color:var(--blue);box-shadow:var(--ring)}
.map-search::placeholder{color:var(--text-faint)}
.mapfull .map-stage{flex:1 1 auto;aspect-ratio:auto;min-height:0;width:100%}
.map-layers{top:auto;bottom:12px;left:12px}
.map-layers .lyr{display:flex;align-items:center;gap:6px;font-size:11px;padding:6px 10px}
.map-layers .lyr .lyr-t{font-size:9.5px;letter-spacing:.04em}
.map-zoomhint{bottom:12px;right:12px}

/* ---------- RustApp-style player markers ---------- */
#marker-layer{--mksize:36px}
.mk-p{z-index:6}
.mk-p .mkwrap{position:relative;display:block}
.mkav{position:relative;display:grid;place-items:center;width:var(--mksize);height:var(--mksize);
  border-radius:50%;border:2px solid var(--surface-1);background:var(--surface-3);color:var(--text-dim);font-weight:700;
  font-size:calc(var(--mksize) * .32);overflow:hidden;box-shadow:0 1px 5px rgba(0,0,0,.55);
  transition:border-color .3s}
.mkav::before{content:attr(data-ini)}
.mkav .avimg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.mkav .mkdot{position:absolute;left:0;bottom:0;width:calc(var(--mksize) * .26);height:calc(var(--mksize) * .26);
  border-radius:50%;background:var(--green);border:2px solid var(--border-hard);z-index:2}
.mkav.adm::after{content:"★";position:absolute;right:-2px;top:-4px;font-size:calc(var(--mksize) * .34);
  color:var(--yellow);text-shadow:0 1px 2px #000;z-index:2}

/* name label: HIDDEN by default, revealed only while hovering THIS marker.
   pointer-events:none so the (hidden or shown) label can never itself catch
   the hover, which previously made the tooltip flicker/stick. */
.mkname{position:absolute;top:100%;left:50%;transform:translateX(-50%);margin-top:4px;
  font-size:10px;font-weight:600;color:#fff;text-shadow:0 1px 2px #000,0 0 4px #000;
  white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .12s;
  background:rgba(10,10,10,.72);padding:1px 6px;border-radius:5px;z-index:20}
.mk-p:hover .mkname{opacity:1}
.mk-p:hover{z-index:30}
/* opt-in: the "names" layer toggle forces every name visible at once */
.map-names-on .mk-p .mkname{opacity:1;background:transparent;padding:0}

.mk-p.sleeping .mkav{filter:grayscale(1);opacity:.55}
.mk-p.sleeping .mkdot{background:var(--text-faint)}
.mk-p.wounded .mkav{border-color:var(--amber)}
.mk-p.wounded .mkdot{background:var(--amber)}

/* in-combat: a red glow ring that pulses in and out around the avatar
   (replaces the old opacity blink, which was hard to read). */
.mk-p.combat{z-index:14}
.mk-p.combat .mkav{border-color:var(--red)}
.mk-p.combat .mkdot{background:var(--red)}
.mk-p.combat .mkwrap::after{content:"";position:absolute;left:50%;top:calc(var(--mksize) / 2);
  width:var(--mksize);height:var(--mksize);transform:translate(-50%,-50%);border-radius:50%;
  pointer-events:none;box-shadow:0 0 0 0 rgba(224,52,43,.55);animation:mkHalo 1.15s ease-out infinite}
@keyframes mkHalo{
  0%  {box-shadow:0 0 0 0 rgba(224,52,43,.55), 0 0 6px 2px rgba(224,52,43,.5)}
  70% {box-shadow:0 0 0 calc(var(--mksize) * .55) rgba(224,52,43,0), 0 0 10px 3px rgba(224,52,43,.15)}
  100%{box-shadow:0 0 0 0 rgba(224,52,43,0), 0 0 6px 2px rgba(224,52,43,0)}
}
.mk-p.shooting .mkav{box-shadow:0 0 0 3px rgba(233,195,74,.45),0 1px 5px rgba(0,0,0,.55)}
.mk-p .label{display:none}   /* old title bubble replaced by the hover name + native title */

/* ---------- alerts ---------- */
.tag.a-multiacc{color:var(--amber)}
.tag.a-evasion{color:var(--danger-text)}
.tag.a-tc{color:var(--danger-text)}
.tag.a-report{color:var(--amber)}
.tag.a-cheat{color:var(--danger-text)}

/* ---------- bans ---------- */
.pill.exp-perm{color:var(--danger-text);border-color:rgba(224,52,43,.4)}

/* ---------- admins ---------- */
.adm-row{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--line)}
.adm-row:last-child{border-bottom:none}
.adm-row:hover{background:var(--hover)}
.adm-row .ravi{width:38px;height:38px;font-size:12px}
.adm-row .ravi::after{display:none}
.modal.wide{width:min(680px,100%)}
.perm-h{display:flex;align-items:center;gap:8px;font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-dim);font-weight:700;margin:16px 0 8px;padding-bottom:6px;border-bottom:1px solid var(--line)}
.perm-h:first-child{margin-top:0}
.perm-h .who{cursor:pointer}
.perm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:4px 12px}
.perm-item{display:flex;align-items:center;gap:9px;padding:6px 8px;border-radius:var(--r-sm);
  font-size:12.5px;color:var(--text);cursor:pointer;user-select:none}
.perm-item:hover{background:var(--surface-2)}
.perm-item input{accent-color:var(--blue-strong);width:15px;height:15px;cursor:pointer;flex:0 0 auto}
.perm-item.danger span{color:var(--danger-text)}

/* ---------- account intelligence ---------- */
/* Deliberately a hard red rectangle, not a soft pill: this is the one badge that
   should be impossible to miss while scanning a list of names. */
.vpn-tag{display:inline-flex;align-items:center;background:var(--red);color:#fff;
  font-size:9.5px;font-weight:800;letter-spacing:.08em;padding:3px 7px;border-radius:3px;
  line-height:1;white-space:nowrap;vertical-align:middle}
.tbl .vpn-tag,.pmeta .vpn-tag{margin-left:6px}
.kvs{display:flex;flex-direction:column}
.kvs .kv:last-child{border-bottom:none}
.risk-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;flex:none}
.risk-high{background:var(--red)} .risk-medium,.risk-low{background:var(--amber)}
.risk-clean{background:var(--green)} .risk-unknown{background:var(--text-faint)}

/* ---------- compare two players ---------- */
.cmp{display:flex;flex-direction:column}
.cmp-row{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:14px;
  padding:9px 0;border-bottom:1px solid var(--line);font-size:13.5px;font-variant-numeric:tabular-nums}
.cmp-row:last-child{border-bottom:none}
.cmp-row > span:first-child{text-align:right;font-weight:600}
.cmp-row > span:last-child{text-align:left;font-weight:600}
.cmp-row > span:nth-child(2){font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;
  min-width:130px;text-align:center;font-weight:600}

/* ---------- peak-hours heatmap ---------- */
.heat{display:grid;grid-template-columns:38px repeat(24,1fr);gap:2px;font-size:9px}
.heat-h{color:var(--text-faint);text-align:center;font-size:8.5px;line-height:1}
.heat-d{color:var(--text-dim);font-size:9.5px;display:flex;align-items:center}
.heat-c{aspect-ratio:1;border-radius:2px;background:var(--surface-2)}
.heat-c.on{outline:1px solid var(--blue)}

/* ---------- Wipe automation ---------- */
.wcount{font-size:30px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums;margin-bottom:6px}
.wcount .dim{font-size:13px;font-weight:500;letter-spacing:0}
.wsteps{display:flex;flex-wrap:wrap;gap:4px;margin:12px 0}
.wstep{font-size:10.5px;padding:3px 8px;border-radius:999px;background:var(--surface-2);
  color:var(--text-dim);border:1px solid var(--line);white-space:nowrap}
.wstep.done{color:var(--green);border-color:rgba(60,190,120,.4)}
.wstep.on{background:var(--blue-strong);color:#fff;border-color:transparent;font-weight:700}
.wlog{max-height:260px;overflow:auto;font-size:11.5px;line-height:1.7;
  font-family:var(--mono,ui-monospace,monospace);margin-top:10px}
.wlog-l{padding:1px 0;border-bottom:1px solid var(--line)}
.wlog-l:last-child{border-bottom:none}
.wpaths{max-height:170px;overflow:auto;padding:8px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--surface-2);font-size:11.5px}
.wcrumbs{padding:6px 2px 10px;font-size:12.5px;border-bottom:1px solid var(--line);margin-bottom:8px}
.wcrumbs .who{cursor:pointer}
.wlist{max-height:400px;overflow:auto}
.wrow{display:flex;align-items:center;gap:10px;padding:6px 8px;border-radius:var(--r-sm);font-size:12.5px}
.wrow:hover{background:var(--surface-2)}
.wrow input{accent-color:var(--blue-strong);width:15px;height:15px;flex:0 0 auto;cursor:pointer}
.chip.on{background:var(--blue-strong);color:#fff;border-color:transparent}

/* ---------- console: echoed command + its reply ---------- */
.lc-line.lc-cmd .lc-x{color:var(--blue);font-weight:600}
.lc-line.lc-out .lc-x{color:var(--text);white-space:pre-wrap}

/* ---------- chat: optimistic local echo ---------- */
.cmsg.pending{opacity:.55}
.cmsg.pending .cx::after{content:' ·  sending…';font-size:10.5px;color:var(--text-dim)}
.cmsg.pending.failed{opacity:1}
.cmsg.pending.failed .cx::after{content:' ·  not delivered';color:var(--red)}

/* ---------- Data & Storage (owner) ---------- */
.dbars{display:flex;flex-direction:column;gap:7px}
.dbar{display:grid;grid-template-columns:150px 1fr 76px 74px;align-items:center;gap:10px;font-size:12.5px}
.dbar-n{color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dbar-n .role-badge{margin-left:6px}
.dbar-t{background:var(--surface-2);border-radius:var(--r-sm);height:9px;overflow:hidden}
.dbar-t i{display:block;height:100%;border-radius:var(--r-sm);
  background:linear-gradient(90deg,var(--blue-strong),var(--blue))}
.dbar-v{text-align:right;font-variant-numeric:tabular-nums;color:var(--text)}
.dbar-r{text-align:right;font-variant-numeric:tabular-nums}
.dtable{display:flex;flex-direction:column;gap:2px;margin:10px 0}
.drow{display:grid;grid-template-columns:1fr 90px 90px;gap:10px;padding:6px 8px;
  border-radius:var(--r-sm);font-size:12.5px;font-variant-numeric:tabular-nums}
.drow:nth-child(odd){background:var(--surface-2)}
.drow b,.drow span:not(:first-child){text-align:right}
.drow.total{margin-top:6px;border-top:1px solid var(--line);background:none;font-weight:700}
@media(max-width:640px){
  .dbar{grid-template-columns:110px 1fr 66px;}
  .dbar-r{display:none}
}

/* ============================================================
   v48, SmartAdmin: notifications, item picker, JSON editor,
   plugins view, players toggle, labeled dossier pills
   ============================================================ */

/* ---------- notifications (progress bar depletes; hover pauses) ---------- */
.notif{position:relative;overflow:hidden;background:var(--surface-2);border:1px solid var(--line-bright);
  padding:12px 16px 15px;border-radius:var(--r);font-size:12.5px;color:var(--text);
  min-width:260px;max-width:360px;box-shadow:var(--shadow);animation:slidein .2s ease}
.notif .n-h{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--text);font-weight:700;margin-bottom:3px}
.notif .n-b{color:var(--text-dim);line-height:1.5;word-break:break-word}
.notif .n-bar{position:absolute;left:0;right:0;bottom:0;height:3px;background:rgba(255,255,255,.06)}
.notif .n-bar i{display:block;height:100%;background:var(--blue);transition:width .12s linear}
.notif.err{border-color:rgba(224,52,43,.55)}
.notif.err .n-h{color:var(--danger-text)}
.notif.err .n-bar i{background:var(--red)}
.notif.warn{border-color:rgba(217,161,60,.5)}
.notif.warn .n-h{color:var(--amber)}
.notif.warn .n-bar i{background:var(--amber)}
.notif.clk{cursor:pointer}
.notif.clk:hover{border-color:var(--line-bright)}

/* ---------- players: segmented toggle + pager in the toolbar ---------- */
.seg{display:flex;background:var(--surface-2);border:1px solid var(--pill-line);border-radius:999px;padding:3px;flex:0 0 auto}
.seg-b{background:transparent;border:none;color:var(--text-dim);font-size:11.5px;font-weight:600;
  letter-spacing:.02em;padding:6px 15px;border-radius:999px;transition:all .13s}
.seg-b:hover{color:var(--text)}
.seg-b.active{background:var(--surface-3);color:var(--text)}
/* The profile's tabs sit under the header and stay put while the body scrolls,
   so switching question does not mean scrolling back up to find the switch. */
.pl-tabs{position:sticky;top:0;z-index:4;margin-bottom:var(--gap);flex-wrap:wrap;
  backdrop-filter:blur(6px)}
.pager-top{margin-left:auto}
.pager-top .pager{margin-top:0}

/* ---------- dossier: labeled info pills ---------- */
.pinfo{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.pill.ip{display:inline-flex;gap:6px;align-items:baseline;text-transform:none;letter-spacing:0}
.pill.ip .ik{color:var(--text-dim);font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em}
.pill.ip .iv{color:var(--text);font-weight:700;font-size:11.5px}

/* ---------- give item picker ---------- */
.item-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:8px;
  max-height:min(46vh,380px);overflow-y:auto;padding:4px 2px;margin-top:4px}
.item-cell{background:var(--surface-2);border:1px solid var(--track);border-radius:var(--r-sm);
  padding:9px 7px 7px;display:flex;flex-direction:column;align-items:center;gap:6px;cursor:pointer;
  transition:border-color .12s,background .12s;text-align:center}
.item-cell:hover{border-color:var(--line-bright);background:var(--surface-3)}
.item-cell.sel{border-color:var(--blue);box-shadow:0 0 0 1px var(--blue)}
.item-cell img{width:44px;height:44px;object-fit:contain}
.item-cell .item-n{font-size:10.5px;line-height:1.3;color:var(--text);overflow:hidden;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:2.6em}
.item-cell .inv-fallback{width:44px;height:44px;display:grid;place-items:center}
.item-picked{margin-top:10px;font-size:13px;min-height:20px}

/* ---------- plugins view ---------- */
.plg-row{display:flex;align-items:center;gap:12px;padding:11px 16px;border-bottom:1px solid var(--line)}
.plg-row:last-child{border-bottom:none}
.plg-row:hover{background:var(--hover)}
.plg-dot{width:9px;height:9px;border-radius:50%;background:var(--green);flex:0 0 auto;box-shadow:0 0 5px var(--green)}
.plg-dot.off{background:var(--text-faint);box-shadow:none}
.plg-row .pm-ver{color:var(--text-faint);font-weight:400;font-size:11px}

/* ---------- JSON config editor (VS Code dark+ palette) ---------- */
.modal.xwide{width:min(940px,96vw)}
.jed-body{padding-bottom:12px}
.jed{position:relative;display:flex;height:min(58vh,560px);background:var(--surface-1);border:1px solid var(--line);
  border-radius:var(--r-sm);overflow:hidden;font-family:var(--mono);font-size:12.5px;line-height:1.55}
.jed-gut{flex:0 0 44px;overflow:hidden;padding:10px 0;background:var(--surface-1);border-right:1px solid var(--line);
  text-align:right;color:var(--text-faint);user-select:none}
.jed-gut i{display:block;font-style:normal;padding-right:10px;font:inherit;line-height:inherit}
.jed-hl,.jed-ta{position:absolute;left:44px;right:0;top:0;bottom:0;margin:0;padding:10px 14px;
  font:inherit;line-height:inherit;white-space:pre;overflow:auto;tab-size:2}
.jed-hl{pointer-events:none;color:var(--text);background:transparent}
.jed-ta{background:transparent;color:transparent;caret-color:var(--term-text);border:none;resize:none;outline:none}
.jed-ta::selection{background:rgba(47,157,245,.32);color:transparent}
.j-key{color:var(--syn-cyan)}
.j-str{color:var(--syn-orange)}
.j-num{color:var(--syn-green)}
.j-bool{color:var(--syn-blue)}
.j-null{color:var(--syn-blue)}
.j-pun{color:var(--text)}

/* ============================================================
   v49, account-type badges, clan management, player picker
   ============================================================ */

/* ---------- account authenticity badge ---------- */
.acct{display:inline-block;padding:2px 9px;border-radius:999px;font-size:10.5px;font-weight:700;
  letter-spacing:.03em;border:1px solid transparent;white-space:nowrap}
.acct.ac-orig{color:var(--green);border-color:rgba(139,201,78,.4);background:rgba(139,201,78,.08)}
.acct.ac-crack{color:var(--danger-text);border-color:rgba(224,52,43,.45);background:rgba(224,52,43,.09)}
.acct.ac-gold{color:var(--amber);border-color:rgba(217,161,60,.45);background:rgba(217,161,60,.09)}

/* account-type breakdown chips next to the Players count */
.acct-counts{display:inline-flex;align-items:center;gap:6px;margin-left:10px;flex-wrap:wrap}
.acnt{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:999px;
  font-size:10.5px;font-weight:600;letter-spacing:.02em;border:1px solid;cursor:default}
.acnt b{font-size:11.5px;font-weight:800}
.acnt.ac-orig{color:var(--green);border-color:rgba(139,201,78,.4);background:rgba(139,201,78,.08)}
.acnt.ac-crack{color:var(--danger-text);border-color:rgba(224,52,43,.45);background:rgba(224,52,43,.09)}
.acnt.ac-gold{color:var(--amber);border-color:rgba(217,161,60,.45);background:rgba(217,161,60,.09)}
.acnt.ac-unk{color:var(--text-faint);border-color:var(--line-bright);background:var(--surface-2)}
.pill.ip .acct{margin-left:0}

/* ---------- clan management ---------- */
.member .role-badge{font-size:8.5px;padding:1px 6px}
.m-tools{display:inline-flex;gap:5px;margin-left:12px;flex-wrap:wrap}
.abtn.tiny{padding:3px 9px;font-size:10.5px;border-radius:6px}
@media (max-width:760px){ .m-tools{margin-left:6px} }

/* ---------- player picker modal ---------- */
.pick-list{max-height:min(46vh,360px);overflow-y:auto;margin-top:6px;border:1px solid var(--line);border-radius:var(--r-sm)}
.pick-row{display:flex;align-items:center;gap:10px;padding:8px 12px;border-bottom:1px solid var(--line);cursor:pointer}
.pick-row:last-child{border-bottom:none}
.pick-row:hover{background:var(--surface-2)}
.pick-row.sel{background:rgba(47,157,245,.14);box-shadow:inset 2px 0 0 var(--blue)}

/* ---------- plain textarea used by clan message / config ---------- */
.ta{width:100%;min-height:96px;background:var(--input);border:1px solid var(--line-bright);color:var(--text);
  border-radius:var(--r-sm);padding:10px 12px;font-family:var(--sans);font-size:13px;resize:vertical;line-height:1.5}
.ta:focus{outline:none;border-color:var(--blue);box-shadow:var(--ring)}

/* ---------- sign delete action (v51) ---------- */
.sign .sign-actions{display:flex;align-items:center;gap:8px;padding:8px 12px;border-top:1px solid var(--line)}
.sign .sign-actions .abtn.tiny{padding:4px 10px;font-size:11px}

/* ============================================================
   v55. Map hover player card (top-center, live)
   ============================================================ */
.map-hover{position:absolute;top:14px;left:50%;transform:translateX(-50%) translateY(-8px);
  z-index:40;pointer-events:none;display:flex;align-items:center;gap:18px;
  background:rgba(16,18,22,.92);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid rgba(255,255,255,.10);border-radius:16px;padding:11px 18px 11px 12px;
  box-shadow:0 12px 40px rgba(0,0,0,.55),inset 0 1px 0 rgba(255,255,255,.05);
  opacity:0;transition:opacity .13s ease,transform .13s ease;max-width:min(92vw,720px)}
.map-hover.show{opacity:1;transform:translateX(-50%) translateY(0)}

.map-hover .mh-id{display:flex;align-items:center;gap:11px;min-width:0}
.map-hover .mh-av{position:relative;width:42px;height:42px;flex:0 0 auto;border-radius:11px;
  overflow:hidden;background:var(--surface-3);display:grid;place-items:center;color:var(--text);
  font-weight:700;font-size:15px;border:1px solid rgba(255,255,255,.12)}
.map-hover .mh-av::before{content:attr(data-ini)}
.map-hover .mh-av img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.map-hover .mh-name-wrap{min-width:0}
.map-hover .mh-name{font-size:15px;font-weight:700;color:#fff;line-height:1.15;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}
.map-hover .mh-sub{display:flex;align-items:center;gap:8px;margin-top:3px}
.map-hover .mh-badge{font-size:9.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  padding:2px 8px;border-radius:999px;border:1px solid transparent}
.map-hover .mh-badge.st-alive{color:var(--green);border-color:rgba(139,201,78,.4);background:rgba(139,201,78,.08)}
.map-hover .mh-badge.st-combat{color:var(--red);border-color:rgba(224,52,43,.45);background:rgba(224,52,43,.10)}
.map-hover .mh-badge.st-wound{color:var(--amber);border-color:rgba(255,180,84,.45);background:rgba(255,180,84,.10)}
.map-hover .mh-badge.st-sleep{color:var(--dim);border-color:rgba(255,255,255,.14);background:rgba(255,255,255,.04)}
.map-hover .mh-clan{font-size:11.5px;color:var(--blue);font-weight:600}

.map-hover .mh-stats{display:flex;align-items:stretch;gap:0}
.map-hover .mh-stat{display:flex;flex-direction:column;gap:3px;padding:0 15px;justify-content:center;
  border-left:1px solid rgba(255,255,255,.08)}
.map-hover .mh-k{font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);font-weight:600}
.map-hover .mh-v{font-size:13px;color:#e8ebef;font-weight:600}
.map-hover .mh-hp{display:flex;align-items:center;gap:8px}
.map-hover .mh-hpbar{display:inline-block;width:52px;height:5px;border-radius:3px;background:rgba(255,255,255,.12);overflow:hidden}
.map-hover .mh-hpfill{display:block;height:100%;border-radius:3px;transition:width .2s}
.map-hover .mh-open{font-size:9px;color:var(--faint);letter-spacing:.03em;padding-left:14px;
  border-left:1px solid rgba(255,255,255,.08);align-self:center;max-width:80px;line-height:1.3}
@media (max-width:640px){
  .map-hover .mh-open{display:none}
  .map-hover .mh-name{max-width:120px}
}

/* ============================================================
   v61. Permissions view + offline-ban + perm alert
   ============================================================ */
.tbtn.danger{color:var(--red);border-color:rgba(224,52,43,.4)}
.tbtn.danger:hover{background:rgba(224,52,43,.12);border-color:rgba(224,52,43,.6)}
.confirm.danger{background:var(--red);border-color:var(--red);color:#fff}
.confirm.danger:hover{filter:brightness(1.08)}

.perm-note{font-size:12px;margin:10px 2px 14px}
.perm-results{display:flex;flex-direction:column;gap:4px;margin:8px 0}
.perm-result{display:flex;align-items:center;gap:10px;padding:9px 12px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:9px;cursor:pointer;text-align:left;transition:border-color .12s,background .12s}
.perm-result:hover{border-color:var(--line-bright);background:var(--hover)}
.pr-name{font-weight:600;color:var(--text);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pr-sid{font-size:11.5px;color:var(--text-faint)}
.pr-dot{width:8px;height:8px;border-radius:50%;background:var(--text-faint);flex:none}
.pr-dot.on{background:var(--green);box-shadow:0 0 6px var(--green)}

.perm-cols{display:grid;grid-template-columns:290px 1fr;gap:16px;align-items:start}
.perm-col-l{position:sticky;top:0}
@media (max-width:820px){.perm-cols{grid-template-columns:1fr}}
.grp-row{display:flex;flex-direction:column;gap:2px;width:100%;text-align:left;padding:10px 12px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:9px;cursor:pointer;margin-bottom:6px;transition:border-color .12s}
.grp-row:hover{border-color:#3a4250}
.grp-row.active{border-color:var(--blue);background:rgba(74,163,255,.08)}
.grp-n{font-weight:700;color:var(--text)}
.grp-meta{font-size:11px;color:var(--text-faint)}

.perm-card{background:var(--surface-2);border:1px solid var(--line);border-radius:12px;padding:16px 18px}
.perm-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:6px}
.perm-title{font-size:17px;font-weight:700;color:var(--text)}
.perm-sub{font-size:12px;color:var(--text-faint);margin-top:2px}
.perm-gl{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-faint);font-weight:700;margin:16px 0 8px}
.perm-list{display:flex;flex-wrap:wrap;gap:6px}
.perm-list.dimmed{opacity:.75}
.perm-pill{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:11.5px;
  padding:4px 9px;border-radius:7px;background:var(--surface-3);border:1px solid var(--line-bright);color:var(--text-dim)}
.perm-pill.danger{background:var(--red-soft);border-color:rgba(224,52,43,.45);color:var(--danger-text)}
.perm-pill.ghost{background:transparent;border-style:dashed;opacity:.85}
.perm-pill .perm-src{font-size:9px;color:var(--text-faint);border-left:1px solid var(--line-bright);padding-left:5px;margin-left:2px}
.perm-x{background:none;border:none;color:inherit;opacity:.55;cursor:pointer;font-size:11px;padding:0 0 0 2px;line-height:1}
.perm-x:hover{opacity:1;color:var(--red)}
.grp-pill{display:inline-block;font-size:12px;font-weight:600;color:var(--blue);background:rgba(74,163,255,.1);
  border:1px solid rgba(74,163,255,.3);border-radius:7px;padding:4px 10px;cursor:pointer;transition:background .12s}
.grp-pill:hover{background:rgba(74,163,255,.2)}
.empty.small{font-size:12px;padding:8px 2px;color:var(--text-faint)}
.perm-warn{margin-top:10px;font-size:12px;color:var(--amber);background:rgba(255,180,84,.1);
  border:1px solid rgba(255,180,84,.35);border-radius:8px;padding:8px 11px}

.op-badge{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:2px 8px;border-radius:999px}
.op-grant{color:var(--green);background:rgba(139,201,78,.1);border:1px solid rgba(139,201,78,.35)}
.op-revoke{color:var(--text-dim);background:rgba(255,255,255,.05);border:1px solid var(--line-bright)}
tr.row-imp td{background:rgba(224,52,43,.06)}
.a-perm{background:rgba(224,52,43,.16);color:#ff9b94}

/* phone number cell (from SMS-auth data file) */
.phone-cell{cursor:pointer;font-variant-numeric:tabular-nums;color:var(--text);border-bottom:1px dashed transparent}
.phone-cell:hover{border-bottom-color:var(--line-bright);color:var(--text)}
.phone-ok{color:var(--green);font-weight:700;font-size:11px}

/* Payback modal */

/* nothing fired: still a statement, not an empty space */
.verdict.clear{background:var(--surface-2);border:1px solid var(--line);color:var(--text-dim)}
.verdict.clear .v-ico{color:var(--green)}

/* Persian names carry a bracketed clan tag. Left to itself the bidi algorithm
   moves that tag to the far end of the line, so "[k7] Tigmo" rendered as
   "Tigmo [k7]" reversed. Isolating each name keeps it whole and in order. */
.story.rtl .story-t bdi,.verdicts.rtl bdi{unicode-bidi:isolate}

/* ---- every shot, in order ----
   A table without a <table>: one grid so the columns line up and the whole
   thing still collapses sensibly on a phone. */
.sl-head,.sl-row{display:grid;gap:10px;align-items:center;
  grid-template-columns:34px 58px minmax(90px,1.4fr) minmax(70px,1fr) 62px 74px minmax(64px,1fr) minmax(96px,1.1fr);
  padding:7px 13px;font-size:12.5px}
.sl-head{font-size:9.5px;text-transform:uppercase;letter-spacing:.07em;color:var(--text-faint);
  font-weight:700;border-bottom:1px solid var(--line);background:var(--surface-2)}
.sl-list{display:flex;flex-direction:column}
.sl-row{border-bottom:1px solid var(--line)}
.sl-row:last-child{border-bottom:0}
.sl-row:hover{background:var(--hover)}
/* a miss is context, not a finding: it stays legible and stops there */
.sl-row.miss{color:var(--text-dim)}
.sl-n{color:var(--text-faint);font-variant-numeric:tabular-nums;font-size:11px}
.sl-t{font-family:var(--mono);font-size:11.5px;color:var(--text-dim);font-variant-numeric:tabular-nums}
.sl-who{display:flex;align-items:center;gap:7px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sl-who .dot{width:8px;height:8px;border-radius:50%;flex:0 0 auto}
.sl-who .dot.a{background:#3fa7f5}
.sl-who .dot.b{background:#e0574a}
.sl-gun{color:#d5ab6b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sl-dist{font-variant-numeric:tabular-nums;color:var(--text)}
.sl-stance{font-size:11px;color:var(--text-dim)}
.sl-stance.crouched{color:#b18cf0}
.sl-stance.airborne{color:#5fbfae}
.sl-zone{color:#b18cf0}
.sl-zone .head{color:#e8564a;font-weight:700}
.sl-dmg{font-variant-numeric:tabular-nums}

/* the pair in a fight row: both named, the one who lived in green */
.ff-opp .vs,.fight-title .vs{color:var(--text-faint);font-weight:400}
.namecell.won{color:var(--green);font-weight:600}
.namecell.lost{color:var(--text-dim)}
.fight-title{display:flex;align-items:baseline;gap:2px;flex-wrap:wrap}
.fight-title .won{color:var(--green)}
.fight-title .lost{color:var(--text-dim)}
.ff-res.won{color:var(--green)}

@media(max-width:820px){
  .sl-head{display:none}
  .sl-row{grid-template-columns:46px 1fr 1fr;grid-auto-rows:auto;row-gap:3px;padding:10px 12px}
  .sl-row .sl-n{grid-row:1;grid-column:1}
  .sl-row .sl-t{grid-row:1;grid-column:2}
  .sl-row .sl-who{grid-row:1;grid-column:3}
  .sl-row .sl-gun{grid-row:2;grid-column:2}
  .sl-row .sl-dist{grid-row:2;grid-column:3}
  .sl-row .sl-stance{grid-row:3;grid-column:2}
  .sl-row .sl-zone{grid-row:3;grid-column:3}
  .sl-row .sl-dmg{grid-row:4;grid-column:2/4}
}

/* ---- recoil panels (fight + profile) ----
   One block for both, so the two pages cannot drift apart visually while
   claiming to show the same measurement. */
.rc-cards{display:grid;grid-template-columns:1fr;gap:10px}
.rc-card{border:1px solid var(--line);border-radius:10px;padding:12px 14px;background:rgba(255,255,255,.015)}
.rc-card.amber{border-color:rgba(226,163,58,.4)}
.rc-card.red{border-color:rgba(214,78,78,.45);background:rgba(214,78,78,.05)}
.rc-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.rc-gun{font-weight:600;font-size:14px}
.rc-verdict{margin-left:auto;font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid var(--line)}
.rc-verdict.green{color:var(--green);border-color:rgba(90,180,120,.4)}
.rc-verdict.amber{color:var(--amber);border-color:rgba(226,163,58,.45)}
.rc-verdict.red{color:var(--red);border-color:rgba(214,78,78,.5)}
.rc-body{display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap}
.rc-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(88px,1fr));gap:10px;flex:1;min-width:220px}
.rc-stat{padding:6px 0}
.rc-v{font-size:20px;font-weight:600;line-height:1.15;font-variant-numeric:tabular-nums}
.rc-u{font-size:12px;opacity:.6;margin-left:1px}
.rc-l{font-size:11px;color:var(--dim);margin-top:2px}
.rc-p{font-size:10.5px;color:var(--dim);opacity:.75;margin-top:1px}
.rc-patwrap{flex:none;text-align:center}
.rc-cap{font-size:10.5px;color:var(--dim);margin-top:4px}
.rc-pat{border-radius:8px;display:block}
.rc-bg{fill:rgba(255,255,255,.02)}
.rc-ax{stroke:rgba(255,255,255,.10);stroke-width:1}
.rc-line{fill:none;stroke:var(--accent,#5b9dd9);stroke-width:1.4;stroke-linejoin:round;stroke-linecap:round}
.rc-dot{fill:var(--accent,#5b9dd9);opacity:.85}
.rc-start{fill:none;stroke:#e2a33a;stroke-width:1.2}
.rc-scale{fill:var(--dim);font-size:9px;text-anchor:middle}
.rc-top{display:flex;gap:16px;align-items:center;padding:12px 14px;border:1px solid var(--line);
  border-radius:10px;margin-bottom:12px;flex-wrap:wrap}
.rc-top.amber{border-color:rgba(226,163,58,.4)}
.rc-top.red{border-color:rgba(214,78,78,.45);background:rgba(214,78,78,.05)}
.rc-big{font-size:30px;font-weight:700;line-height:1;font-variant-numeric:tabular-nums}
.rc-sum{flex:1;min-width:220px;font-size:12.5px;line-height:1.7;color:#c9c9c9}
@media (max-width:640px){
  .rc-body{flex-direction:column}
  .rc-patwrap{align-self:center}
}

/* ---- 3D map ----
   The canvas owns the space; every control floats over it so the world is never
   boxed into a corner of the page. */
.map3d-view{display:flex;flex-direction:column;height:calc(100vh - 96px)}
.m3-wrap{position:relative;flex:1;min-height:0;border:1px solid var(--line);
  border-radius:10px;overflow:hidden;background:#0d1117}
.m3-stage{position:absolute;inset:0}
.m3-stage canvas{display:block;width:100%;height:100%;outline:none}
.m3-hud{position:absolute;top:12px;left:12px;pointer-events:none}
.m3-panel{pointer-events:auto;background:rgba(13,17,23,.86);border:1px solid var(--line);
  border-radius:10px;padding:10px 12px;backdrop-filter:blur(6px);min-width:150px}
.m3-h{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--dim);margin-bottom:6px}
.m3-panel .perm-item{margin:0;padding:3px 0;font-size:12.5px}
.m3-tools{position:absolute;top:12px;right:12px;display:flex;flex-direction:column;gap:6px}
.m3-tb{width:34px;height:34px;display:grid;place-items:center;font-size:15px;cursor:pointer;
  background:rgba(13,17,23,.86);border:1px solid var(--line);border-radius:8px;color:var(--text);
  backdrop-filter:blur(6px);transition:border-color .15s cubic-bezier(.22,1,.36,1),color .15s}
.m3-tb:hover{border-color:var(--accent,#5b9dd9);color:var(--accent,#5b9dd9)}
.m3-tb:focus-visible{outline:2px solid var(--accent,#5b9dd9);outline-offset:2px}
.m3-tip{position:absolute;left:50%;top:12px;transform:translateX(-50%);pointer-events:none;
  background:rgba(13,17,23,.92);border:1px solid var(--line);border-radius:8px;
  padding:6px 12px;font-size:12.5px;white-space:nowrap}

/* The 3D map's control hint. Sits under the toolbar, out of the way of the
   scene but readable against any part of it. */
.m3-hint {
  position: absolute; left: 12px; bottom: 12px; z-index: 4;
  padding: 6px 10px; border-radius: 6px;
  background: rgba(10, 12, 16, .72); border: 1px solid var(--line);
  color: var(--text-dim); font-size: 11.5px; letter-spacing: .01em;
  pointer-events: none; max-width: 70%;
}
.m3-tb.on { border-color: var(--accent); color: var(--accent); }

/* 3D map: player search, in the toolbar column under the buttons. */
.m3-search-wrap{position:absolute;top:12px;right:56px;width:230px;z-index:5}
.m3-search{width:100%;padding:8px 10px;border-radius:7px;border:1px solid var(--line);
  background:rgba(10,12,16,.82);color:var(--text);font-size:13px;outline:none}
.m3-search:focus{border-color:var(--accent)}
.m3-search-results{margin-top:6px;background:rgba(12,14,18,.96);border:1px solid var(--line);
  border-radius:8px;overflow:hidden;box-shadow:0 8px 24px rgba(0,0,0,.4)}
.m3-sr-row{display:flex;justify-content:space-between;gap:10px;padding:7px 10px;cursor:pointer;font-size:12.5px}
.m3-sr-row:hover{background:var(--accent);color:#fff}
.m3-sr-empty{padding:8px 10px;color:var(--text-dim);font-size:12px}

/* 3D map: the right-click menu on a player. */
.m3-menu{position:fixed;z-index:60;min-width:186px;background:rgba(14,16,20,.98);
  border:1px solid var(--line-bright,#333);border-radius:9px;padding:5px;
  box-shadow:0 10px 30px rgba(0,0,0,.5)}
.m3-menu-h{padding:6px 8px 8px;border-bottom:1px solid var(--line);margin-bottom:4px;font-size:12.5px}
.m3-mi{display:block;width:100%;text-align:left;padding:8px 9px;border:0;border-radius:6px;
  background:none;color:var(--text);font-size:12.5px;cursor:pointer}
.m3-mi:hover{background:var(--accent);color:#fff}
.m3-mi.danger:hover{background:var(--danger,#d64e4e)}

/* 3D map: the control strip above the scene. Switches belong outside the
   viewport, not floating over the corner of the map they hide. */
.m3-bar{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:9px 12px;margin-bottom:10px;
  border:1px solid var(--line);border-radius:10px;background:var(--panel,rgba(255,255,255,.02))}
.m3-bar-group{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.m3-bar-sep{width:1px;align-self:stretch;background:var(--line);margin:0 2px}
.m3-bar-note{font-size:11.5px;margin-left:auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:38%}
.m3-chip{padding:5px 11px;border-radius:999px;border:1px solid var(--line);background:none;
  color:var(--text-dim);font-size:12px;cursor:pointer;transition:border-color .15s,color .15s,background .15s}
.m3-chip:hover{border-color:var(--accent,#5b9dd9);color:var(--text)}
.m3-chip.on{border-color:var(--accent,#5b9dd9);color:#fff;background:color-mix(in srgb,var(--accent,#5b9dd9) 22%,transparent)}
/* A mode switch reads differently from an on/off chip: square corners, and a
   width that does not change as it steps through its states, so the controls
   next to it stay where they were. */
.m3-cycle{border-radius:5px;min-width:158px;text-align:left}
.m3-bar-slider{display:flex;align-items:center;gap:7px;font-size:11.5px;padding-left:4px}
.m3-slider{width:110px}

/* 3D map: the one-time model download. Only ever seen on a first visit. */
.m3-dl{margin-top:8px;max-width:280px}
.m3-dl-text{font-size:11.5px;line-height:1.6}
.m3-dl-track{height:5px;border-radius:3px;background:rgba(255,255,255,.10);overflow:hidden;margin-top:7px}
.m3-dl-fill{height:100%;width:0%;border-radius:3px;background:var(--accent,#5b9dd9);transition:width .25s ease}

/* The player card on the 3D map is the same one the 2D map uses, so it only
   needs to be told where to sit: the 3D page has its own wrapper and a toolbar
   down the right, and the card has to clear both. It stays click-through, since
   the click underneath it is what opens the menu. */
.m3-hover{top:64px}
.m3-wrap{position:relative}

/* Reset sits with the sliders rather than with the layer chips: it undoes the
   whole row, so it should not look like one more thing to switch on. */
.m3-chip.m3-reset{margin-inline-start:auto;opacity:.72;border-style:dashed}
.m3-chip.m3-reset:hover{opacity:1;border-style:solid}

/* The folded-away controls.

   Twelve layer chips and three sliders in two rows put every control the map
   has on screen at once, at the same weight. The two that get switched
   constantly looked exactly like the nine that get touched once a week. These
   hold the rare ones so the common ones can be found. */
.m3-pop-btn::after{content:'';display:inline-block;margin-inline-start:7px;
  border:4px solid transparent;border-top-color:currentColor;transform:translateY(2px);opacity:.6}
.m3-pop{position:fixed;z-index:60;min-width:250px;max-width:min(92vw,460px);
  background:rgba(18,20,25,.97);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid rgba(255,255,255,.11);border-radius:12px;padding:11px;
  box-shadow:0 16px 44px rgba(0,0,0,.6)}
.m3-pop-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
.m3-pop-grid .m3-chip{width:100%;justify-content:flex-start;text-align:start}
.m3-pop-rows{display:flex;flex-direction:column;gap:9px}
.m3-pop-rows .m3-bar-slider{display:flex;align-items:center;gap:9px}
.m3-pop-rows .m3-slider{flex:1;min-width:110px}

/* A divider on the right rail, between moving the camera and changing what is
   drawn. Two different kinds of action should not read as one list. */
.m3-tb-sep{height:1px;margin:5px 6px;background:rgba(255,255,255,.12)}
.m3-tb-toggle{opacity:.5}
.m3-tb-toggle:hover{opacity:.85}
.m3-tb-toggle.on{opacity:1;color:var(--accent,#6ea8fe);
  box-shadow:inset 0 0 0 1px rgba(110,168,254,.55)}

/* The bar goes full screen with the map. It normally sits above the scene,
   which is outside the element that goes full screen, so every switch on it
   became unreachable exactly when the map is biggest. */
.m3-wrap.m3-fs{display:flex;flex-direction:column}
.m3-wrap.m3-fs .m3-bar{flex:0 0 auto;margin:0;border-radius:0;
  border-left:0;border-right:0;border-top:0;z-index:30}
/* The stage is absolutely positioned so the scene fills the wrapper, which in
   full screen put it straight over the bar. In full screen it joins the flow
   instead and takes whatever is left under the bar. */
.m3-wrap.m3-fs .m3-stage{position:relative;inset:auto;flex:1 1 auto;min-height:0}
/* The floating pieces are positioned against the wrapper, so in full screen
   they have to clear the bar rather than start at its top edge. */
.m3-wrap.m3-fs .m3-tools{top:auto}
.m3-wrap.m3-fs .m3-hover{top:12px}

/* ---- the 3D replay ----
   Opens over the fight rather than replacing it, so the shot list and the
   narrative the admin was reading are still underneath when they close it.
   The bar sits above the scene, not floating on it: a control covering a
   corner of the world is a control in the way. */
.r3-back{position:fixed;inset:0;z-index:90;background:rgba(0,0,0,.72);
  display:flex;align-items:center;justify-content:center;padding:16px}
.r3-sheet{display:flex;flex-direction:column;width:min(1400px,100%);height:min(900px,100%);
  background:var(--surface-1);border:1px solid var(--line-bright);border-radius:8px;overflow:hidden}
.r3-bar{display:flex;align-items:center;gap:10px;padding:10px 12px;flex-wrap:wrap;
  background:var(--topbar);border-bottom:1px solid var(--line)}
.r3-bar .rp-scrub{flex:1;min-width:160px}
.r3-sep{font-size:11px;color:var(--text-dim);margin-inline-start:6px}
.r3-speed{background:var(--input);color:var(--text);border:1px solid var(--line-bright);
  border-radius:4px;padding:4px 6px;font-size:12px}
.r3-close{margin-inline-start:auto;background:var(--surface-3);color:var(--text);
  border:1px solid var(--line-bright);border-radius:4px;padding:5px 12px;font-size:12px;cursor:pointer}
.r3-close:hover{background:var(--surface-2);border-color:var(--blue)}
.r3-close:focus-visible,.r3-bar button:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.r3-stage{flex:1;min-height:0;position:relative;background:#0d1117}
.r3-stage canvas{display:block;width:100%;height:100%}
@media(max-width:640px){
  .r3-back{padding:0}
  .r3-sheet{height:100%;border-radius:0;border:0}
  .r3-bar{gap:8px;padding:8px}
  .r3-sep{display:none}
  .r3-close{margin-inline-start:0}
}

/* wipe page, map pool */
.maplevel{margin-bottom:var(--gap);padding:12px 16px;border:1px solid var(--line-bright);border-radius:8px;background:var(--surface-1)}
.maplevel.ok{border-color:var(--green-dim);background:var(--green-deep)}
.maplevel.warn{border-color:rgba(224,160,43,.55);background:rgba(224,160,43,.08)}
.ml-h{display:flex;align-items:center;gap:8px}
.ml-t{font-weight:600}
.ml-u{margin-top:8px;display:flex;gap:10px;align-items:center;word-break:break-all;font-size:12px;color:var(--text-dim)}
.mapcards{display:grid;gap:10px}
.mapcard{padding:12px 16px;border:1px solid var(--line);border-left:3px solid var(--line-bright);border-radius:8px;background:var(--surface-1)}
.mapcard.active{border-color:var(--green-dim);border-left-color:var(--green);background:var(--green-deep);box-shadow:0 0 0 1px var(--green-glow)}
.mapcard.off{opacity:.55}
.mc-h{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:8px}
.mc-h .role-badge{margin-left:0}
.mc-n{font-weight:700;font-size:15px;margin-right:4px}
.mc-live{color:var(--green);border-color:var(--green-dim)}
.mc-actions{margin-left:auto;display:flex;gap:8px}
.mc-row{display:flex;align-items:center;gap:10px;padding:3px 0;min-width:0}
.mc-k{flex:0 0 78px;font-size:11px;color:var(--text-dim);text-transform:uppercase;letter-spacing:.08em}
.mc-v{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px}
.mc-mine{color:var(--green)}
.mc-meta{margin-top:6px;font-size:11px;color:var(--text-dim)}
.abtn.mini{padding:2px 10px;font-size:11px}
@media (max-width:700px){.mc-row{flex-wrap:wrap}.mc-k{flex-basis:100%}.mc-v{white-space:normal;word-break:break-all}.mc-actions{margin-left:0;width:100%}}
.notif .n-x{position:absolute;top:6px;right:8px;width:22px;height:22px;display:grid;place-items:center;padding:0;border:0;border-radius:4px;background:transparent;color:var(--text-dim);font-size:18px;line-height:1;cursor:pointer}
.notif .n-x:hover,.notif .n-x:focus-visible{background:var(--surface-3);color:var(--text)}
.notif .n-h{padding-right:22px}
