/* ==========================================================================
   FALCON-RECON — PREMIUM PURPLE DASHBOARD THEME
   Palette: #05060A → #0B0D14 → #11131D → #A855F7 → #A855F7 → #FFFFFF
   Vibe: premium violet / void / luminous
   Note: legacy --red* token names retained for stability; values now violet.
   ========================================================================== */

:root {
  /* ── COLOR ───────────────────────────────────────────── */
  --bg-0:        #05060A;          /* main background */
  --bg-1:        #0B0D14;          /* panels / cards */
  --bg-2:        #11131D;          /* elevated surface */
  --bg-3:        #181B27;          /* hover surface */
  --ink:         #FFFFFF;          /* primary text */
  --ink-dim:     #C9C5D8;          /* secondary text */
  --ink-ghost:   #928BA6;          /* muted text / disabled — lifted to clear WCAG AA (~5.5:1) on panels */
  --red:         #A855F7;          /* primary violet (brand — warmer than 8B5CF6 to fight blue cast) */
  --red-bright:  #C084FC;          /* hover / active (soft bright violet) */
  --red-deep:    #7C3AED;          /* deep violet */
  --red-soft:    #DDD6FE;          /* lightest violet wash */
  --red-glow:    rgba(168,85,247,0.6);
  --red-glow-2:  rgba(168,85,247,0.18);
  --amber:       #ffb000;
  --cyber:       #00ff9f;          /* rare accent — good findings / resolved */
  --grid:        rgba(168,85,247,0.08);
  --crt-scan:    rgba(168,85,247,0.04);
  --shadow-red:  0 0 20px rgba(168,85,247,0.45), 0 0 40px rgba(168,85,247,0.15);
  --shadow-deep: 0 0 0 1px var(--red-deep), 0 8px 32px rgba(0,0,0,0.8);

  /* ── SEVERITY (semantic — NEVER swap to brand purple)
        Critical = dark red, High = normal red (classic SOC palette). ── */
  --sev-critical: #B91C1C;          /* dark red */
  --sev-high:     #EF4444;          /* normal red */
  --sev-medium:   #F59E0B;
  --sev-low:      #22C55E;
  --sev-info:     #38BDF8;
  --sev-critical-glow: rgba(185,28,28,0.55);
  --sev-high-glow:     rgba(239,68,68,0.45);
  /* Foreground twin of high: #EF4444 reads ~4.0:1 as TEXT on near-black (just
     under AA). Use this lifted same-hue red wherever high is rendered as
     text / icon / outline-badge on a dark surface. Badge BACKGROUNDS keep
     #EF4444 (dark/black text on them passes). Mirrors --sev-critical-fg. */
  --sev-high-fg:       #FF6B6B;          /* ~5:1 on panels */
  /* Foreground twin of critical: #B91C1C is too dark as TEXT on near-black
     (~2.9:1, fails AA). Use this brighter red wherever critical is rendered as
     text/icon on a dark surface. Badge BACKGROUNDS keep #B91C1C (white-on-it
     stays ~10:1). Same-hue, just lifted for legibility. */
  --sev-critical-fg:   #FF5A60;          /* ~5.9:1 on panels */

  /* ── BRAND BORDER / GLOW (per spec) ─────────────────────────────── */
  --brand-border: rgba(168,85,247,0.25);
  --brand-glow:   rgba(168,85,247,0.35);

  /* ── STRUCTURAL BORDERS (boxes, tables, panels — light grey) ────── */
  --border:        #2a2e34;
  --border-strong: #3a3a3e;

  /* ── TYPE ────────────────────────────────────────────── */
  --mono:        "JetBrains Mono", "Fira Code", "Courier New", monospace;
  /* Display + numeric pairing — Geist for hero typography and tabular numerics,
     JetBrains Mono retained for data, code, IDs, and timestamps. */
  --font-display: "Geist", "Inter Tight", -apple-system, BlinkMacSystemFont, sans-serif;
  --font-num:     "Geist Mono", "JetBrains Mono", "Fira Code", monospace;

  /* ── SPACING (8-pt scale) ────────────────────────────── */
  --sp-1:  4px;
  --sp-2:  8px;
  --sp-3:  12px;
  --sp-4:  16px;
  --sp-5:  20px;
  --sp-6:  24px;
  --sp-8:  32px;
  --sp-10: 40px;
  --sp-12: 48px;

  /* ── MOTION ──────────────────────────────────────────── */
  --t-fast:   0.12s ease;
  --t-med:    0.22s cubic-bezier(.3,0,.3,1);
  --t-slow:   0.32s cubic-bezier(.3,0,.3,1);
  --t-modal:  0.28s cubic-bezier(.3,0,.3,1);

  /* ── BREAKPOINTS (reference; @media still inlines literals) ── */
  --bp-sm: 720px;
  --bp-md: 900px;
  --bp-lg: 1100px;
  --bp-xl: 1400px;

  /* ── Z-INDEX SCALE ───────────────────────────────────── */
  --z-base:   0;
  --z-sticky: 100;
  --z-drawer: 8000;
  --z-modal:  10000;
  --z-toast:  11000;
}

/* ---------- reset / base -------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg-0);
  min-height: 100vh;
  overflow-x: hidden;
  cursor: default;
}

/* ---------- CRT scanline overlay (entire viewport) ------------------------ */
body::before {
  content: "";
  position: fixed; inset: 0;
  background:
    linear-gradient(var(--crt-scan) 50%, transparent 50%) 0 0 / 100% 3px,
    radial-gradient(ellipse at center, transparent 40%, rgba(0,0,0,0.65) 100%);
  pointer-events: none;
  z-index: 9998;
  mix-blend-mode: overlay;
}
body::after {
  content: "";
  position: fixed; inset: 0;
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 60px 60px;
  pointer-events: none;
  z-index: -1;
  opacity: 0.6;
}

/* matrix canvas sits behind everything */
#matrix-rain {
  position: fixed; inset: 0;
  z-index: -2;
  opacity: 0.28;
  pointer-events: none;
}

/* ---------- a11y: reduced motion ---------------------------------------- */
/* Users with vestibular disorders or motion sensitivity get a near-static UI.
   Always-on pulses (pulse-crit, fr-node-crit-pulse, fr-globe-ring-rotate,
   ticker-scroll, blink) are neutralised; matrix rain + CRT scanlines hidden. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  #matrix-rain { display: none; }
  body::before { display: none; }
  .blink::after { animation: none; opacity: 1; }
}

/* ---------- a11y: keyboard focus rings ---------------------------------- */
/* Every interactive element gets a visible focus ring when reached via
   keyboard. Mouse users (-> :focus without -visible) are unaffected. */
:where(a, button, .btn, input, textarea, select,
       [role="button"], [role="tab"], [role="link"],
       [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(168,85,247,0.18);
}
/* Inputs already have a border-on-focus treatment; keep the ring outside the
   border for clarity. */
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline-offset: 0;
}

/* ---------- skin system (data-skin on <body>) --------------------------- */
/* Four skins swap theatrics without forking templates:
     ops      — daily operator (no matrix, no CRT, dim grid)
     ambient  — current vibe, full theatrics (default rules above apply)
     briefing — flat editorial mode for client deliverables / PDF export
     demo     — ambient + extras (matrix + CRT + grid full)
   Body attribute is set by base.html pre-paint script; localStorage key
   "fr.skin" persists it. ?skin=… query param overrides for print/export. */

/* OPS — minimal */
body[data-skin="ops"] #matrix-rain { display: none; }
body[data-skin="ops"]::before { display: none; }
body[data-skin="ops"]::after  { opacity: 0.18; }

/* BRIEFING — flat */
body[data-skin="briefing"] #matrix-rain { display: none; }
body[data-skin="briefing"]::before { display: none; }
body[data-skin="briefing"]::after  { display: none; }
body[data-skin="briefing"] .glitch { text-shadow: none; }
body[data-skin="briefing"] .glitch::before,
body[data-skin="briefing"] .glitch::after { display: none; }
body[data-skin="briefing"] .blink::after { animation: none; opacity: 0; }
/* Hold red as a single accent in briefing mode — neutralise glow. */
body[data-skin="briefing"] h1 { text-shadow: none; }
body[data-skin="briefing"] .card .value { text-shadow: none; }

/* AMBIENT and DEMO — no overrides yet; layered as briefing variants ship. */

/* ---------- selection + scrollbar ---------------------------------------- */
::selection { background: var(--red); color: #000; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg-0); }
::-webkit-scrollbar-thumb { background: var(--red-deep); border-radius: 2px; }
::-webkit-scrollbar-thumb:hover { background: var(--red); box-shadow: var(--shadow-red); }

/* ---------- typography ---------------------------------------------------- */
/* Headings use the display font (Geist) for visual hierarchy contrast against
   the JetBrains Mono body. Section labels stay mono. */
h1, h2, h3, h4, h5 { font-family: var(--font-display); font-weight: 700; letter-spacing: 0.02em; margin: 0; text-transform: uppercase; }
h1 { font-size: 1.9rem; color: var(--ink); letter-spacing: 0.04em; font-weight: 700; text-shadow: none; }
h2 { font-size: 1.15rem; color: var(--ink); letter-spacing: 0.05em; font-weight: 600; }
h3 { font-size: 0.95rem; color: var(--ink); font-family: var(--mono); letter-spacing: 0.12em; }
a { color: var(--red-bright); text-decoration: none; border-bottom: 1px dotted var(--border); transition: color var(--t-fast), border-color var(--t-fast); }
a:hover { color: #fff; border-color: var(--red); text-shadow: 0 0 8px var(--red-glow); }
code, pre, .mono { font-family: var(--mono); }
pre { background: var(--bg-1); border-left: 2px solid var(--red); padding: 12px 16px; overflow-x: auto; color: var(--ink); }

.dim { color: var(--ink-dim); }
.ghost { color: var(--ink-ghost); }
.accent { color: var(--red-bright); }
.label { text-transform: uppercase; font-size: 11px; letter-spacing: 0.15em; color: var(--ink-dim); }
.divider { border: none; border-top: 1px solid var(--border); margin: 24px 0; opacity: 0.6; }

/* ---------- glitch text (DISABLED — static professional headers) ---------
   Class kept for template compatibility; render as plain heading. */
.glitch {
  position: relative;
  display: inline-block;
  color: var(--ink);
  text-shadow: none;
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 0.04em;
  animation: none !important;
}
.glitch::before, .glitch::after { content: none !important; display: none !important; animation: none !important; }
@keyframes glitch-1 { 0%, 100% { transform: none; } }
@keyframes glitch-2 { 0%, 100% { transform: none; } }

/* ---------- blinking cursor ---------------------------------------------- */
.blink::after {
  content: "_";
  animation: blink 1s step-end infinite;
  color: var(--red);
  margin-left: 2px;
}
@keyframes blink { 50% { opacity: 0; } }

/* ---------- layout: app shell -------------------------------------------- */
.shell { display: grid; grid-template-columns: 240px 1fr; min-height: 100vh; }
.sidebar {
  background: linear-gradient(180deg, var(--bg-1), var(--bg-0));
  border-right: 1px solid var(--border);
  padding: 20px 16px;
  position: sticky; top: 0; height: 100vh;
  /* Column layout so a tall nav scrolls inside itself instead of overflowing
     under the absolutely-positioned .foot (which caused the footer to overlap
     the lower nav links on shorter viewports). */
  display: flex; flex-direction: column;
}
/* nav takes the space between brand and foot; scrolls when the link list is
   taller than the viewport. min-height:0 lets a flex child actually shrink. */
.sidebar nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.sidebar .brand {
  font-size: 1.4rem; font-weight: 900; color: var(--red);
  text-shadow: 0 0 12px var(--red-glow);
  letter-spacing: 0.1em;
  padding-bottom: 16px; border-bottom: 1px solid var(--border); margin-bottom: 16px;
}
.sidebar .brand .tag { display: block; font-size: 10px; color: var(--ink-dim); font-weight: 400; letter-spacing: 0.3em; margin-top: 2px; }
.sidebar nav a {
  display: block; padding: 10px 12px; margin: 4px 0;
  color: var(--ink); border: 1px solid transparent; border-left: 2px solid transparent;
  text-transform: uppercase; font-size: 12px; letter-spacing: 0.12em;
  transition: all 0.15s;
}
.sidebar nav a:hover, .sidebar nav a.active {
  background: var(--bg-2); color: var(--red);
  border-left-color: var(--red); text-shadow: 0 0 8px var(--red-glow);
}
.sidebar .foot {
  /* Static (not absolute) so it always sits below the nav in flow — never
     overlapping it. flex-shrink:0 keeps it full-height when the nav scrolls. */
  flex-shrink: 0; margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 10px; color: var(--ink-ghost); letter-spacing: 0.2em;
}

.main { padding: 24px 32px 64px; min-width: 0; overflow-x: clip; }
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 0 20px 0; border-bottom: 1px solid var(--border); margin-bottom: 24px;
}
.topbar .crumbs { font-size: 11px; color: var(--ink-dim); letter-spacing: 0.2em; text-transform: uppercase; }
.topbar .user { font-size: 11px; color: var(--ink-dim); }
.topbar .user span { color: var(--red); font-weight: 700; }

/* Active-engagement indicator — always-legible so the operator can never
   mistake which client's isolated workspace they are currently viewing. */
.engagement-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px; font-size: 10px; letter-spacing: 0.1em; font-weight: 700;
  text-transform: uppercase; white-space: nowrap; border-radius: 2px;
  border: 1px solid var(--cyber); color: var(--cyber); cursor: help;
}
.engagement-pill span { color: var(--ink); }
.engagement-pill--shared {
  border-color: var(--border); color: var(--ink-ghost); font-weight: 500;
}

/* ---------- cards -------------------------------------------------------- */
.card {
  background: var(--bg-1);
  border: 1px solid var(--border);
  padding: 16px 20px;
  position: relative;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.card:hover { border-color: var(--red); box-shadow: var(--shadow-red); }
.card .title { font-size: 11px; color: var(--ink-dim); letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: 8px; font-family: var(--mono); }
/* Hero metric: dramatic numeric display, tabular-nums so columns align,
   display font for the modern operator-console feel. The new size (3.4rem)
   lifts the dashboard from "card with number" to "hero readout". */
.card .value {
  font-family: var(--font-num);
  font-size: 3.4rem;
  color: var(--red);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "ss01" 1;
  text-shadow: 0 0 14px var(--red-glow);
  line-height: 1;
  letter-spacing: -0.01em;
  margin: 4px 0 6px;
}
.card .sub { font-size: 11px; color: var(--ink-dim); margin-top: 4px; font-family: var(--mono); letter-spacing: 0.1em; }
/* Compact metric variant — for places where 3.4rem is too dramatic
   (e.g. crowded module dashboards, sidebar pills). */
.card .value.compact { font-size: 1.75rem; }
/* data-tone — replaces inline style="border-color:var(--X)" overrides on
   .card. Mirrors the fr-card[data-tone] rules so legacy .card markup gets
   the same semantic tinting without restructuring every page-level tile. */
.card[data-tone="critical"] { border-color: var(--sev-critical); box-shadow: 0 0 14px var(--sev-critical-glow); }
.card[data-tone="high"]     { border-color: var(--sev-high); }
.card[data-tone="med"]      { border-color: var(--amber); }
.card[data-tone="low"]      { border-color: var(--cyber); }
.card[data-tone="info"]     { border-color: var(--ink-ghost); }
.card[data-tone="critical"] .value { color: var(--sev-critical); }
.card[data-tone="high"]     .value { color: var(--sev-high); }
.card[data-tone="med"]      .value { color: var(--amber); }
.card[data-tone="low"]      .value { color: var(--cyber); }
.card[data-tone="info"]     .value { color: var(--ink-dim); }
.card::before { /* corner tick */
  content: ""; position: absolute; top: -1px; left: -1px; width: 12px; height: 12px;
  border-top: 2px solid var(--red); border-left: 2px solid var(--red);
}
.card::after {
  content: ""; position: absolute; bottom: -1px; right: -1px; width: 12px; height: 12px;
  border-bottom: 2px solid var(--red); border-right: 2px solid var(--red);
}

.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
@media (max-width: 900px) { .grid-4, .grid-3 { grid-template-columns: 1fr 1fr; } .grid-2 { grid-template-columns: 1fr; } .shell { grid-template-columns: 1fr; } .sidebar { position: relative; height: auto; } }

/* ---------- tables ------------------------------------------------------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--border); background: var(--bg-1); }
table.recon {
  width: 100%; border-collapse: collapse; font-size: 13px;
}
table.recon th {
  text-align: left; padding: 10px 14px; color: var(--red); font-weight: 700;
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  border-bottom: 1px solid var(--border); background: var(--bg-2);
}
table.recon td { padding: 9px 14px; border-bottom: 1px solid rgba(168,85,247,0.1); }
table.recon tr:hover td { background: var(--bg-3); color: #fff; }
table.recon td.value { color: var(--ink); font-weight: 600; font-size: inherit; }
table.recon .pill { display: inline-block; padding: 1px 8px; border: 1px solid var(--border); font-size: 10px; color: var(--ink-dim); letter-spacing: 0.1em; text-transform: uppercase; margin-right: 4px; }
table.recon .pill.src { border-color: var(--cyber); color: var(--cyber); }
.pill.src              { border-color: var(--cyber); color: var(--cyber); }

/* ---------- buttons ------------------------------------------------------ */
.btn, button.btn, a.btn {
  /* Inline-block with explicit line-height + vertical-align so <a>.btn and
     <button>.btn sit on the same baseline in a table row. Without this,
     browsers pick different defaults for <a> vs <button> and they look offset. */
  display: inline-block; padding: 10px 20px;
  background: transparent; color: var(--red);
  border: 1px solid var(--red); border-radius: 0;
  font-family: var(--mono); font-size: 12px; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; cursor: pointer;
  transition: all 0.15s; position: relative; overflow: hidden;
  line-height: 1.2;
  vertical-align: middle;
  text-decoration: none;
  box-sizing: border-box;
  margin: 2px 0;   /* tiny gap when wrapping */
}
a.btn, a.btn:hover { text-decoration: none; border-bottom: 1px solid var(--red); }
a.btn.ghost, a.btn.ghost:hover { border-bottom-color: var(--border); }

/* Compact row-action pills for list tables — guarantees baseline alignment
   between <a> and <button> children by using flex with center alignment. */
.row-actions {
  display: inline-flex; align-items: center; justify-content: flex-end;
  gap: 6px; flex-wrap: wrap;
}
.row-btn {
  padding: 5px 11px !important;
  font-size: 10px !important;
  line-height: 1 !important;
  height: auto;
  margin: 0 !important;
  min-height: 24px;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
}
.row-btn.danger { border-color: var(--red) !important; color: var(--red) !important; }
.row-btn.danger:hover { background: var(--red) !important; color: #000 !important; }
.btn:hover { background: var(--red); color: #000; box-shadow: var(--shadow-red); text-shadow: none; }
.btn:active { transform: translate(1px, 1px); }
.btn.ghost { border-color: var(--border); color: var(--ink-dim); }
.btn.ghost:hover { border-color: var(--red); color: var(--red); background: transparent; box-shadow: none; }

/* ---------- forms -------------------------------------------------------- */
input[type=text], input[type=password], input[type=email], input[type=number], textarea, select {
  background: var(--bg-0); color: var(--ink); border: 1px solid var(--border);
  font-family: var(--mono); font-size: 14px; padding: 10px 14px; width: 100%;
  transition: all 0.15s; letter-spacing: 0.05em;
}
input:focus, textarea:focus, select:focus {
  outline: none; border-color: var(--red); box-shadow: inset 0 0 0 1px var(--red), 0 0 16px var(--red-glow-2);
}
label { display: block; font-size: 11px; color: var(--ink-dim); letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: 6px; }
.form-row { margin-bottom: 18px; }

/* ---------- severity badges ---------------------------------------------- */
.sev { display: inline-block; padding: 2px 10px; font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; font-weight: 700; border: 1px solid currentColor; white-space: nowrap; }
.sev.critical { color: #fff; background: var(--sev-critical); border-color: var(--sev-critical); box-shadow: 0 0 12px var(--sev-critical-glow); animation: pulse-crit 1.5s ease-in-out infinite; }
.sev.high     { color: var(--sev-high); border-color: var(--sev-high); }
.sev.medium   { color: var(--sev-medium); border-color: var(--sev-medium); }
.sev.low      { color: var(--sev-low); border-color: var(--sev-low); }
.sev.info     { color: var(--sev-info); border-color: var(--sev-info); }
/* ---------- confidence tier badges (proof/confidence FP-control layer) ------
   confirmed = proven (green go) · firm = default (neutral) · tentative =
   unproven active-module heuristic (amber caution). Reuses the severity palette
   vars so it stays theme-aware in both light and briefing skins. */
.conf { display: inline-block; padding: 1px 8px; font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase; font-weight: 700; border: 1px solid currentColor; white-space: nowrap; border-radius: 2px; vertical-align: middle; }
.conf.confirmed { color: var(--sev-low); border-color: var(--sev-low); }
.conf.firm      { color: var(--ink-dim); border-color: var(--ink-dim); }
.conf.tentative { color: var(--amber); border-color: var(--amber); }
/* Reduced-coverage badge — a module ran a weaker fallback / absent tool /
   truncated page. Amber annotation next to a green "done", NOT a red error. */
.badge-degraded { display: inline-block; margin-left: 6px; padding: 1px 7px; font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; color: var(--amber); border: 1px solid var(--amber); border-radius: 2px; white-space: nowrap; vertical-align: middle; cursor: help; }
@keyframes pulse-crit {
  0%, 100% { box-shadow: 0 0 12px var(--red-glow); }
  50% { box-shadow: 0 0 22px var(--red), 0 0 40px var(--red-glow); }
}

/* ---------- status dot --------------------------------------------------- */
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
.dot.ok { background: var(--cyber); box-shadow: 0 0 8px var(--cyber); }
.dot.warn { background: var(--amber); box-shadow: 0 0 8px var(--amber); }
.dot.err { background: var(--red); box-shadow: 0 0 10px var(--red-glow); animation: pulse 1.2s infinite; }
@keyframes pulse { 50% { opacity: 0.3; } }

/* ---------- tabs --------------------------------------------------------- */
.tabs {
  display: flex; gap: 2px; flex-wrap: wrap;
  border-bottom: 1px solid var(--border); margin-bottom: 20px;
  row-gap: 0;
}
.tabs .tab {
  padding: 8px 14px; color: var(--ink-dim); cursor: pointer;
  border: 1px solid transparent; border-bottom: none;
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  white-space: nowrap;                /* keep "EMAILS (1)" on one line */
  display: inline-flex; align-items: center; gap: 6px;
  transition: color 0.12s ease, background 0.12s ease;
}
.tabs .tab .tab-count {
  font-size: 10px; letter-spacing: 0.06em;
  color: var(--ink-dim); opacity: 0.75;
  padding: 1px 6px; border-radius: 2px;
  background: rgba(168,85,247,0.08);
}
.tabs .tab.active .tab-count { color: var(--red); opacity: 1; background: rgba(168,85,247,0.14); }
.tabs .tab:hover { color: var(--red); background: rgba(168,85,247,0.04); }
.tabs .tab.active { color: var(--red); border-color: var(--border); background: var(--bg-1); position: relative; top: 1px; text-shadow: 0 0 8px var(--red-glow); }
.tab-panel { display: none; }
.tab-panel.active { display: block; animation: fade-in 0.25s ease-out; }

/* FrTabs .tab-count badge — same visual treatment as legacy .tabs .tab .tab-count
   so the count chip keeps its red-pill look inside fr-tabs buttons. */
.fr-tabs > button .tab-count {
  font-size: 10px; letter-spacing: 0.06em;
  color: var(--ink-dim); opacity: 0.75;
  padding: 1px 6px; border-radius: 2px;
  background: rgba(168,85,247,0.08);
}
.fr-tabs > button[aria-selected="true"] .tab-count {
  color: var(--red); opacity: 1; background: rgba(168,85,247,0.14);
}
.fr-tabs > button { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; text-transform: uppercase; letter-spacing: 0.1em; font-size: 11px; }
/* Glow treatment on data-tone tabs — the visual tell that the tab has hot
   content (a non-empty critical/high count). Pairs with the color rules
   from the FrTabs commit. */
.fr-tabs > button[data-tone="critical"] { text-shadow: 0 0 8px var(--sev-critical-glow); }
.fr-tabs > button[data-tone="high"]     { text-shadow: 0 0 8px var(--sev-high-glow); }
.fr-tabs > button[data-tone="med"]      { text-shadow: 0 0 8px rgba(255,153,0,0.5); }
.fr-tabs > button[data-tone="low"]      { text-shadow: 0 0 8px rgba(0,255,153,0.4); }
[data-tab-panel][aria-hidden="false"] { animation: fade-in 0.25s ease-out; }

/* sub-tabs inside a tab-panel (APIs tab has Endpoints/Specs/GraphQL/Postman) */
.subtabs {
  display: flex; gap: 2px; flex-wrap: wrap;
  border-bottom: 1px dashed var(--border); margin-bottom: 14px;
  padding-bottom: 0;
}
.subtabs .subtab {
  padding: 6px 12px; color: var(--ink-dim); cursor: pointer;
  border: 1px solid transparent; border-bottom: none;
  font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px;
  transition: color 0.12s ease, background 0.12s ease;
}
.subtabs .subtab:hover { color: var(--red); background: rgba(168,85,247,0.04); }
.subtabs .subtab.active { color: var(--red-bright); border-color: var(--border); background: var(--bg-1); text-shadow: 0 0 6px var(--red-glow); }
.subpanel { display: none; }
.subpanel.active { display: block; }

/* ---------- live Terminal pane (SSE-tailed scan console.log) ---------- */
.terminal-pane {
  background: #000;
  border: 1px solid var(--border);
  padding: 10px 14px;
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink);
  line-height: 1.55;
  min-height: 420px;
  max-height: 65vh;
  overflow-y: auto;
  overflow-x: auto;
  white-space: pre;
  box-shadow: inset 0 0 20px rgba(168,85,247,0.08);
  scrollbar-color: var(--red-deep) transparent;
}
.terminal-pane::-webkit-scrollbar { width: 8px; }
.terminal-pane::-webkit-scrollbar-track { background: #000; }
.terminal-pane::-webkit-scrollbar-thumb { background: var(--red-deep); border-radius: 2px; }
.term-pane-mini {
  min-height: 180px;
  max-height: 35vh;
}
.t-line {
  white-space: pre-wrap;
  word-break: break-all;
}
.t-crit { color: var(--red); font-weight: 700; text-shadow: 0 0 6px var(--red-glow); }
.t-high { color: var(--red-bright); font-weight: 700; }
.t-med  { color: var(--amber); font-weight: 700; }
.t-low  { color: #ffcc55; }
.t-info { color: var(--cyber); }
.t-warn { color: var(--amber); }
.t-err  { color: var(--red); font-weight: 700; }
.t-dim  { color: var(--ink-dim); }

/* Mobile Secrets table — click-to-reveal (styling only; server sends only redacted) */
.secret-value { cursor: help; }
.sec-row:hover .secret-value { color: var(--red-bright); }

/* filter chips used in APIs Endpoints panel */
.filter-chip {
  cursor: pointer; user-select: none;
  background: transparent; border: 1px solid var(--border);
  color: var(--ink-dim); padding: 4px 10px;
  font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  transition: all 0.12s ease;
}
.filter-chip:hover { color: var(--red); border-color: var(--red); }
.filter-chip.active { color: var(--red-bright); border-color: var(--red-bright); background: rgba(168,85,247,0.08); text-shadow: 0 0 6px var(--red-glow); }
@keyframes fade-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }

/* ---------- terminal output box ----------------------------------------- */
.terminal {
  background: #000; border: 1px solid var(--border); padding: 14px 18px;
  font-family: var(--mono); font-size: 13px; color: var(--ink);
  box-shadow: inset 0 0 30px rgba(168,85,247,0.1);
}
.terminal .prompt { color: var(--red); }
.terminal .line { display: block; }

/* ---------- login screen ------------------------------------------------- */
.login-wrap {
  display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 20px;
}
.login-box {
  width: 460px; max-width: 100%;
  background: var(--bg-1);
  border: 1px solid var(--red);
  box-shadow: var(--shadow-red), 0 0 80px rgba(168,85,247,0.15);
  padding: 36px 36px 28px;
  position: relative;
  animation: login-entry 0.6s cubic-bezier(.3,0,.3,1);
}
@keyframes login-entry {
  0% { opacity: 0; transform: translateY(20px); filter: blur(6px); }
  100% { opacity: 1; transform: translateY(0); filter: blur(0); }
}
.login-box::before, .login-box::after {
  content: ""; position: absolute; width: 20px; height: 20px;
  border-color: var(--red);
}
.login-box::before { top: -1px; left: -1px; border-top: 2px solid; border-left: 2px solid; }
.login-box::after  { bottom: -1px; right: -1px; border-bottom: 2px solid; border-right: 2px solid; }

.login-box .logo {
  text-align: center; font-size: 2rem; font-weight: 900; color: var(--red);
  letter-spacing: 0.25em; text-shadow: 0 0 20px var(--red-glow);
  margin-bottom: 6px;
}
.login-box .sub-logo { text-align: center; color: var(--ink-dim); font-size: 10px; letter-spacing: 0.4em; margin-bottom: 28px; }

.login-box .banner {
  font-size: 10px; color: var(--ink-dim); text-align: center; line-height: 1.7;
  border-top: 1px dashed var(--border); border-bottom: 1px dashed var(--border);
  padding: 10px; margin-bottom: 24px;
  letter-spacing: 0.1em;
}

.login-error {
  background: rgba(168,85,247,0.1);
  border: 1px solid var(--red);
  color: var(--red-bright);
  padding: 10px 14px;
  font-size: 12px;
  letter-spacing: 0.1em;
  margin-bottom: 16px;
  text-align: center;
  animation: shake 0.35s;
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}

/* ---------- boot sequence ------------------------------------------------ */
.boot-seq { font-size: 11px; color: var(--ink-dim); line-height: 1.8; letter-spacing: 0.05em; }
.boot-seq .ok { color: var(--cyber); }
.boot-seq .crit { color: var(--red); }

/* ---------- D3 graph ----------------------------------------------------- */
/* Sphere-aesthetic graph — dark backdrop, glowing tiny nodes, soft curves. */
#graph-viewport {
  width: 100%; height: 680px;
  border: 1px solid var(--border);
  background:
    radial-gradient(ellipse at center, rgba(168,85,247,0.05) 0%, transparent 70%),
    var(--bg-0);
  position: relative; overflow: hidden;
}
/* Particle backdrop canvas, rendered BEHIND the interactive SVG at ~18%
   opacity — ambient sphere motion without fighting for attention. */
#graph-viewport .fr-graph-bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0.18;
  pointer-events: none;
  z-index: 1;
}
#graph-viewport svg {
  position: relative; z-index: 2;
  width: 100%; height: 100%;
  cursor: grab;
}
#graph-viewport svg:active { cursor: grabbing; }

/* Ring guides (concentric circles under the graph) */
#graph-viewport .rings { pointer-events: none; }

/* Nodes — tiny dots, all types a shade of red/amber/cyber, glow via filter */
#graph-viewport .node { cursor: grab; transition: opacity 0.18s; }
#graph-viewport .node:active { cursor: grabbing; }
#graph-viewport .node.faded { opacity: 0.18; }
#graph-viewport .node.pinned circle {
  stroke-width: 2.2;
  /* subtle inner dash to say "this one is pinned" */
  stroke-dasharray: 2 2;
}
#graph-viewport .node circle {
  stroke-width: 1.3;
  fill-opacity: 0.7;
}
/* Asset-type colour palette — all red-family except the accent types so
   the graph reads as one visual family with the rest of the app. */
#graph-viewport .node.domain           circle { fill: var(--red);       stroke: #ffffff; }
#graph-viewport .node.subdomain        circle { fill: #4a0008;          stroke: var(--red); }
#graph-viewport .node.ip               circle { fill: #1a1200;          stroke: var(--amber); }
#graph-viewport .node.webapp           circle { fill: #001a12;          stroke: var(--cyber); }
#graph-viewport .node.certificate      circle { fill: #1a1200;          stroke: var(--amber); }
#graph-viewport .node.asn              circle { fill: #2a1500;          stroke: #ff9933; }
#graph-viewport .node.netblock         circle { fill: #0a1a0a;          stroke: #66cc66; }
#graph-viewport .node.wayback_endpoint circle { fill: #0a0010;          stroke: #9966ff; }
#graph-viewport .node.typosquat_domain circle { fill: #2a1500;          stroke: var(--amber); }
#graph-viewport .node.email            circle { fill: #0a0010;          stroke: #9966ff; }
#graph-viewport .node.credential       circle { fill: var(--red);       stroke: #ffffff; }
#graph-viewport .node text {
  fill: var(--ink-dim);
  font-family: var(--mono); font-size: 10px;
  pointer-events: none;
  paint-order: stroke;
  stroke: rgba(0,0,0,0.85); stroke-width: 3px;  /* halo so labels stay legible */
}
#graph-viewport .node:hover text { fill: var(--red-bright); }

/* Links — soft arcs, red-deep by default, bright red on hover */
#graph-viewport .link {
  stroke: var(--red-deep); stroke-opacity: 0.42;
  transition: stroke-opacity 0.15s;
}
#graph-viewport .link.hover { stroke: var(--red); stroke-opacity: 1; filter: url(#fr-glow); }
#graph-viewport .link.faded { stroke-opacity: 0.08; }
.graph-legend { position: absolute; top: 56px; right: 10px; background: var(--bg-1); border: 1px solid var(--border); padding: 8px 12px; font-size: 10px; letter-spacing: 0.1em; z-index: 4; }
.graph-legend div { margin: 3px 0; }
.graph-legend .swatch { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
/* Clickable legend rows toggle visibility — give them affordance */
.graph-legend div.clickable {
  cursor: pointer;
  padding: 2px 4px;
  margin: 1px -4px;
  transition: background 0.12s, color 0.12s;
  user-select: none;
}
.graph-legend div.clickable:hover { background: rgba(168,85,247,0.1); color: var(--red-bright); }
.graph-legend div.clickable.hidden-type {
  opacity: 0.4;
  text-decoration: line-through;
}
.graph-legend div.clickable.hidden-type .swatch { opacity: 0.3; }
.graph-legend div.clickable:focus-visible { outline: 1px solid var(--red); outline-offset: 1px; }

/* Hide labels by default — only show on hover, selection, and pinning so the
   sphere doesn't become an unreadable wall of overlapping text. */
#graph-viewport .node text {
  opacity: 0;
  transition: opacity 0.15s;
}
#graph-viewport .node:hover text,
#graph-viewport .node.selected text,
#graph-viewport .node.pinned text { opacity: 1; }
#graph-viewport .node.search-hit text { opacity: 1; }
#graph-viewport .node.search-hit circle {
  stroke: #fff;
  stroke-width: 2.4;
  filter: drop-shadow(0 0 8px var(--red));
}
#graph-viewport .node.search-miss { opacity: 0.12; }
#graph-viewport .node.type-hidden, #graph-viewport .link.type-hidden { display: none; }
#graph-viewport .node.selected circle {
  stroke: var(--cyber);
  stroke-width: 2.5;
  filter: drop-shadow(0 0 10px var(--cyber));
}

/* ── graph control bar (search + counts + reset/fit/unpin) ────────── */
.fr-graph-controls {
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  background: linear-gradient(180deg, rgba(12,2,5,0.92), rgba(12,2,5,0.78));
  border: 1px solid var(--border);
  z-index: 5;
  font-family: var(--mono);
}
.fr-graph-controls .fr-graph-search {
  flex: 1;
  background: var(--bg-0);
  border: 1px solid var(--border);
  color: var(--ink);
  padding: 6px 10px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  min-width: 120px;
  max-width: 360px;
}
.fr-graph-controls .fr-graph-search:focus {
  outline: none;
  border-color: var(--red);
  box-shadow: inset 0 0 0 1px var(--red), 0 0 14px var(--red-glow-2);
}
.fr-graph-controls .fr-graph-counts {
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--ink-dim);
  text-transform: uppercase;
  white-space: nowrap;
  flex-shrink: 0;
}
.fr-graph-controls .fr-graph-btns {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}
.fr-graph-controls .fr-graph-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--ink-dim);
  padding: 6px 10px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: all 0.12s;
}
.fr-graph-controls .fr-graph-btn:hover {
  color: var(--red);
  border-color: var(--red);
  background: rgba(168,85,247,0.06);
}
.fr-graph-controls .fr-graph-btn:active { transform: translate(1px, 1px); }
@media (max-width: 720px) {
  .fr-graph-controls { flex-wrap: wrap; }
  .fr-graph-controls .fr-graph-search { min-width: 100%; max-width: 100%; }
}

/* ── graph error state ─────────────────────────────────────────────── */
.fr-graph-error {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--red);
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.1em;
  text-align: center;
  padding: 24px;
}

/* ── selected-node detail panel (slides in from right) ─────────────── */
.fr-graph-detail {
  position: absolute;
  top: 56px;
  right: -440px;
  bottom: 10px;
  width: 420px;
  max-width: 90%;
  background: var(--bg-1);
  border: 1px solid var(--border);
  border-right: none;
  box-shadow: -8px 0 32px rgba(168,85,247,0.18);
  z-index: 6;
  transition: right 0.32s cubic-bezier(.3,0,.3,1);
  overflow-y: auto;
  font-family: var(--mono);
}
.fr-graph-detail.open { right: 10px; }
.fr-graph-detail-close {
  position: absolute;
  top: 6px; right: 8px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--red-bright);
  width: 26px; height: 26px;
  font-size: 16px; line-height: 22px;
  cursor: pointer;
  font-family: var(--mono);
  transition: all 0.12s;
  z-index: 2;
}
.fr-graph-detail-close:hover { color: #fff; background: var(--red); border-color: var(--red); }
.fr-graph-detail-body { padding: 14px 18px 18px; }
.fr-graph-detail-head {
  border-bottom: 1px solid var(--border);
  padding-bottom: 10px;
  margin-bottom: 12px;
  padding-right: 36px;
}
.fr-graph-detail-head .d-type {
  font-size: 9px;
  letter-spacing: 0.32em;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin-bottom: 4px;
}
.fr-graph-detail-head .d-label {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--red-bright);
  letter-spacing: 0.02em;
  word-break: break-all;
  line-height: 1.25;
  text-shadow: 0 0 10px var(--red-glow-2);
}
.fr-graph-detail-section {
  margin-bottom: 16px;
}
.fr-graph-detail-section .sec-h {
  font-size: 9px;
  letter-spacing: 0.28em;
  color: var(--red);
  text-transform: uppercase;
  margin-bottom: 8px;
  padding-bottom: 4px;
  border-bottom: 1px dashed var(--border);
}
.fr-graph-detail .src-row {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}
.fr-graph-detail .src-pill {
  display: inline-block;
  border: 1px solid var(--border);
  background: rgba(168,85,247,0.04);
  padding: 2px 8px;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
  text-transform: uppercase;
}
.fr-graph-detail .kv-list { display: flex; flex-direction: column; gap: 4px; }
.fr-graph-detail .kv {
  display: flex;
  gap: 12px;
  font-size: 11px;
  line-height: 1.5;
  padding: 4px 0;
  border-bottom: 1px dotted rgba(168,85,247,0.06);
}
.fr-graph-detail .kv .k {
  flex-shrink: 0;
  width: 110px;
  color: var(--ink-dim);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 10px;
}
.fr-graph-detail .kv .v {
  color: var(--ink);
  word-break: break-all;
  flex: 1;
}
.fr-graph-detail .rel-group { margin-bottom: 12px; }
.fr-graph-detail .rel-h {
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--ink);
  margin-bottom: 6px;
}
.fr-graph-detail .rel-h .ghost { color: var(--ink-dim); margin-left: 4px; }
.fr-graph-detail .rel-body {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}
.fr-graph-detail .rel-pill {
  display: inline-block;
  background: var(--bg-0);
  border: 1px solid var(--border);
  padding: 3px 9px;
  font-size: 11px;
  color: var(--ink);
  cursor: pointer;
  word-break: break-all;
  max-width: 100%;
  letter-spacing: 0.02em;
  transition: all 0.12s;
}
.fr-graph-detail .rel-pill:hover {
  border-color: var(--red);
  color: var(--red-bright);
  text-shadow: 0 0 6px var(--red-glow);
}

/* Density mode tightens the graph chrome to give the network more room */
body.dense-mode #graph-viewport .graph-legend { padding: 4px 8px; font-size: 9px; }
body.dense-mode .fr-graph-controls { padding: 5px 8px; }
body.dense-mode .fr-graph-controls .fr-graph-btn { padding: 4px 8px; font-size: 9px; }
body.dense-mode .fr-graph-detail { width: 360px; }

/* ==========================================================================
   GRAPH v3 — CTI-grade node treatment
   - Type-specific shapes (rendered as <polygon>, <rect>, <circle>) get
     a generic .node-shape class. JS sets fill/stroke per node so we don't
     need per-type CSS for the shape colors.
   - Severity tier classes: .node.sev-critical pulses; .node.hot has a
     subtle outline on the parent <g>.
   - Inline badges (.node-badge) sit beside the shape.
   - Labels via .node-label — hidden by default, revealed on hover/select.
   ========================================================================== */

/* The old `.node circle { fill:..; stroke:..; }` rules from §D3 graph
   are now obsolete (JS sets these per shape). Override to make sure the
   per-type circle palette doesn't fight the new severity-driven strokes. */
#graph-viewport .node .node-shape { transition: stroke 0.18s, stroke-width 0.18s, filter 0.18s; }
#graph-viewport .node:hover .node-shape { filter: drop-shadow(0 0 8px currentColor); }

/* Critical-severity pulse — the most important CTI signal in the graph.
   Pulses the stroke-width and glow strength so a CRITICAL asset is
   IMMEDIATELY identifiable across the whole network. */
@keyframes fr-node-crit-pulse {
  0%, 100% { stroke-width: 2.4; filter: drop-shadow(0 0 10px var(--sev-critical)); }
  50%      { stroke-width: 3.2; filter: drop-shadow(0 0 22px var(--sev-critical)); }
}
#graph-viewport .node.sev-critical .node-shape {
  animation: fr-node-crit-pulse 1.6s ease-in-out infinite;
}

/* Hot-but-not-critical — a faint highlight ring on the parent group */
#graph-viewport .node.hot:not(.sev-critical):not(.sev-high) .node-shape {
  filter: drop-shadow(0 0 6px currentColor);
}

/* Old per-type circle styling was replaced by JS-driven fills — keep
   the .person/.service/.port circles consistent with the rest. */
#graph-viewport .node circle.node-shape { /* placeholder, JS handles styling */ }

/* ── node labels (now hidden by default, shown on hover/select) ───── */
#graph-viewport .node-label {
  opacity: 0;
  transition: opacity 0.15s;
  fill: var(--ink-dim);
  font-family: var(--mono);
  font-size: 10.5px;
  pointer-events: none;
  paint-order: stroke;
  stroke: rgba(0,0,0,0.92);
  stroke-width: 3.5px;
  letter-spacing: 0.02em;
}
#graph-viewport .node:hover .node-label,
#graph-viewport .node.selected .node-label,
#graph-viewport .node.pinned .node-label,
#graph-viewport .node.search-hit .node-label,
#graph-viewport .node.sev-critical .node-label,
#graph-viewport .node.sev-high .node-label,
#graph-viewport .node.domain .node-label,
#graph-viewport .node.asn .node-label { opacity: 1; }
#graph-viewport .node:hover .node-label,
#graph-viewport .node.selected .node-label { fill: #fff; }
#graph-viewport .node.sev-critical .node-label { fill: var(--sev-critical); }
#graph-viewport .node.sev-high .node-label     { fill: var(--sev-high); }
#graph-viewport .node.sev-medium .node-label   { fill: var(--sev-medium); }
#graph-viewport .node.sev-low .node-label      { fill: var(--sev-low); }

/* Badges — finding count, port count — visible always (the whole point) */
#graph-viewport .node-badge {
  pointer-events: none;
}
#graph-viewport .node:hover .node-badge rect {
  filter: drop-shadow(0 0 6px currentColor);
}

/* Selected highlight — slightly different from the v2 cyber outline:
   uses a thicker, brighter stroke so it works on top of the new shapes. */
#graph-viewport .node.selected .node-shape {
  stroke: var(--cyber) !important;
  stroke-width: 2.8 !important;
  filter: drop-shadow(0 0 12px var(--cyber)) !important;
}

/* Hot-only filter — used by the ▲ HOT button to show only nodes with
   findings (plus their 1-hop neighbours) */
#graph-viewport .node.hot-hidden { display: none; }
#graph-viewport .link.hot-hidden { display: none; }

/* Search/filter visual states (preserved from v2 but adapted to shapes) */
#graph-viewport .node.search-hit .node-shape {
  stroke: #fff !important;
  stroke-width: 2.6 !important;
  filter: drop-shadow(0 0 10px var(--red)) !important;
}
#graph-viewport .node.search-miss { opacity: 0.12; }
#graph-viewport .node.faded { opacity: 0.18; }

/* ── severity-totals summary in the control bar ──────────────────── */
.fr-graph-controls .fr-graph-sevsummary {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
  flex-wrap: wrap;
}
.fr-graph-controls .fr-graph-sevsummary:empty { display: none; }
.fr-graph-controls .fr-graph-sevsummary .seg {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  padding: 3px 7px;
  border: 1px solid currentColor;
  border-radius: 1px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.fr-graph-controls .fr-graph-sevsummary .seg.sev-critical {
  color: var(--sev-critical);
  background: rgba(185,28,28,0.1);
  box-shadow: 0 0 10px var(--sev-critical-glow);
  animation: pulse-crit 1.8s ease-in-out infinite;
}
.fr-graph-controls .fr-graph-sevsummary .seg.sev-high   { color: var(--sev-high); }
.fr-graph-controls .fr-graph-sevsummary .seg.sev-medium { color: var(--sev-medium); }
.fr-graph-controls .fr-graph-sevsummary .seg.sev-low    { color: var(--sev-low); }

/* Active state on toolbar buttons (HOT toggle) */
.fr-graph-controls .fr-graph-btn.active {
  color: var(--red-bright);
  border-color: var(--red);
  background: rgba(168,85,247,0.12);
  box-shadow: inset 0 0 8px rgba(168,85,247,0.18);
}

/* ── detail panel additions: severity row + edge tag + relation sev dot ─── */
.fr-graph-detail .sev-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 4px;
}
.fr-graph-detail .sev-pill {
  display: inline-flex;
  align-items: center;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  padding: 3px 9px;
  border: 1px solid currentColor;
  font-weight: 700;
}
.fr-graph-detail .sev-pill.sev-critical {
  color: var(--sev-critical);
  background: rgba(185,28,28,0.12);
  box-shadow: 0 0 10px var(--sev-critical-glow);
}
.fr-graph-detail .sev-pill.sev-high     { color: var(--sev-high); }
.fr-graph-detail .sev-pill.sev-medium   { color: var(--sev-medium); }
.fr-graph-detail .sev-pill.sev-low      { color: var(--sev-low); }
.fr-graph-detail .sev-pill.sev-info     { color: var(--sev-info); }

.fr-graph-detail .rel-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
}
.fr-graph-detail .rel-pill .rel-sev {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
.fr-graph-detail .rel-pill .rel-sev.sev-critical { background: var(--sev-critical); box-shadow: 0 0 6px var(--sev-critical); }
.fr-graph-detail .rel-pill .rel-sev.sev-high     { background: var(--sev-high); }
.fr-graph-detail .rel-pill .rel-sev.sev-medium   { background: var(--sev-medium); }
.fr-graph-detail .rel-pill .rel-sev.sev-low      { background: var(--sev-low); }
.fr-graph-detail .rel-pill .rel-sev.sev-info     { background: var(--sev-info); }
.fr-graph-detail .rel-pill .edge-tag {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  color: var(--ink-dim);
  background: rgba(168,85,247,0.08);
  padding: 1px 5px;
  border-radius: 1px;
  text-transform: uppercase;
  flex-shrink: 0;
}

/* Edge hover: bring it forward */
#graph-viewport .link {
  transition: stroke-opacity 0.15s, stroke-width 0.15s;
}
#graph-viewport .link.hover {
  stroke-opacity: 1 !important;
  stroke-width: 1.8 !important;
  filter: drop-shadow(0 0 4px currentColor);
}
#graph-viewport .link.faded { stroke-opacity: 0.06; }

/* The legacy per-type stroke colours from the original .node.<type> circle
   rules don't apply to polygons/rects, but they DON'T hurt either since
   our new shapes all have explicit fill/stroke. Keep them for the few
   remaining circle-type nodes (person/service/port/wayback_endpoint). */

/* ---------- misc utility ------------------------------------------------- */
.flex { display: flex; }
.flex.gap { gap: 12px; }
.flex.between { justify-content: space-between; }
.flex.center { align-items: center; }
.mt-8 { margin-top: 8px; } .mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; }
.mb-8 { margin-bottom: 8px; } .mb-16 { margin-bottom: 16px; } .mb-24 { margin-bottom: 24px; }
.text-right { text-align: right; }
.nowrap { white-space: nowrap; }
/* Section sub-heading — replaces style="color:var(--red-bright); letter-spacing:0.12em; margin:16px 0 8px;" on h3 */
.sec-title { color: var(--red-bright) !important; letter-spacing: 0.12em; margin: 16px 0 8px; }
/* Amber accent — dorks/dorking section theme */
.accent-amber { color: var(--amber) !important; }
.sec-title-amber { color: var(--amber) !important; letter-spacing: 0.12em; margin: 16px 0 8px; }
.fs-9  { font-size: 9px;  }
.fs-10 { font-size: 10px; }
.fs-11 { font-size: 11px; }
.fs-12 { font-size: 12px; }
.w-full { width: 100%; }
.d-block { display: block; }
.d-inline { display: inline; }
.d-flex { display: flex; }
.flex-wrap { flex-wrap: wrap; }
.w-full { width: 100%; }
.hidden { display: none !important; }

/* ---------- typewriter --------------------------------------------------- */
.typewriter {
  overflow: hidden;
  border-right: 2px solid var(--red);
  white-space: nowrap;
  margin: 0;
  letter-spacing: 0.05em;
  animation: typing 2s steps(40, end), blink 0.9s step-end infinite;
}
@keyframes typing { from { width: 0; } to { width: 100%; } }

/* ---------- themed modal (replaces native alert/confirm/prompt) --------- */
.fr-modal-overlay {
  position: fixed; inset: 0;
  background: radial-gradient(ellipse at center, rgba(0,0,0,0.82) 0%, rgba(0,0,0,0.96) 100%);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  z-index: 10000;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: fr-modal-fade-in 0.18s ease-out;
}
.fr-modal-overlay.fr-modal-closing { animation: fr-modal-fade-out 0.15s ease-in forwards; }
@keyframes fr-modal-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fr-modal-fade-out { to { opacity: 0; } }

.fr-modal-card {
  width: 520px; max-width: 100%;
  background: var(--bg-1);
  border: 1px solid var(--red);
  box-shadow: var(--shadow-red), 0 0 80px rgba(168,85,247,0.12);
  position: relative;
  animation: fr-modal-entry 0.28s cubic-bezier(.3,0,.3,1);
  font-family: var(--mono);
}
.fr-modal-card::before, .fr-modal-card::after {
  content: ""; position: absolute; width: 14px; height: 14px; border-color: var(--red);
}
.fr-modal-card::before { top: -1px; left: -1px; border-top: 2px solid; border-left: 2px solid; }
.fr-modal-card::after  { bottom: -1px; right: -1px; border-bottom: 2px solid; border-right: 2px solid; }
.fr-modal-card-danger {
  border-color: var(--red);
  box-shadow: 0 0 24px var(--red-glow), 0 0 80px rgba(168,85,247,0.2);
}
.fr-modal-card-danger::before, .fr-modal-card-danger::after {
  border-color: var(--red-bright);
}

@keyframes fr-modal-entry {
  0%   { opacity: 0; transform: translateY(12px) scale(0.97); filter: blur(4px); }
  100% { opacity: 1; transform: translateY(0)    scale(1);    filter: blur(0);  }
}

.fr-modal-header {
  padding: 14px 20px 10px;
  border-bottom: 1px dashed var(--border);
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
}
.fr-modal-title {
  font-size: 14px; font-weight: 900; color: var(--red);
  letter-spacing: 0.18em; text-transform: uppercase;
  text-shadow: 0 0 10px var(--red-glow);
}
.fr-modal-sub {
  font-size: 9px; color: var(--ink-dim); letter-spacing: 0.25em;
  text-transform: uppercase; white-space: nowrap;
}

.fr-modal-body {
  padding: 20px;
  background:
    linear-gradient(var(--crt-scan) 50%, transparent 50%) 0 0 / 100% 3px;
}
.fr-modal-msg {
  color: var(--ink); font-size: 13px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word;
  letter-spacing: 0.02em;
}
.fr-modal-msg::after {
  content: "_";
  color: var(--red);
  margin-left: 2px;
  animation: blink 1s step-end infinite;
}
.fr-modal-input {
  margin-top: 14px;
  width: 100%;
  background: var(--bg-0);
  color: var(--ink);
  border: 1px solid var(--border);
  font-family: var(--mono); font-size: 14px;
  padding: 10px 12px;
  letter-spacing: 0.03em;
}
.fr-modal-input:focus {
  outline: none;
  border-color: var(--red);
  box-shadow: inset 0 0 0 1px var(--red), 0 0 16px var(--red-glow-2);
}

.fr-modal-actions {
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  display: flex; justify-content: flex-end; gap: 10px;
  background: var(--bg-0);
}
.fr-modal-ok, .fr-modal-cancel {
  padding: 8px 18px !important;
  font-size: 11px !important;
  line-height: 1.2 !important;
  min-width: 110px;
}
.fr-modal-danger {
  background: var(--red) !important;
  color: #000 !important;
  border-color: var(--red) !important;
  box-shadow: 0 0 14px var(--red-glow);
  animation: pulse-crit 1.8s ease-in-out infinite;
}
.fr-modal-danger:hover {
  background: #fff !important;
  color: #000 !important;
  box-shadow: 0 0 22px var(--red-glow);
}

/* ---------- sparkle / target acquired ----------------------------------- */
.target-acquired {
  position: fixed; inset: 0; pointer-events: none; z-index: 9000;
  background: radial-gradient(circle at center, transparent 0%, transparent 40%, rgba(168,85,247,0.1) 100%);
  opacity: 0; animation: flash 0.6s ease-out;
}
@keyframes flash { 0% { opacity: 1; } 100% { opacity: 0; } }


/* ---------- hero globe (dashboard) --------------------------------------- */
.fr-hero {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 440px;
  gap: 32px;
  align-items: center;
  margin-bottom: 32px;
  padding: 24px 28px;
  border: 1px solid var(--border);
  background:
    radial-gradient(ellipse at right center, rgba(168,85,247,0.06) 0%, transparent 70%),
    linear-gradient(180deg, var(--bg-1) 0%, var(--bg-0) 100%);
  overflow: hidden;
}
.fr-hero::before {
  /* Thin grid lines on the left side, faint */
  content: "";
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(168,85,247,0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(168,85,247,0.04) 1px, transparent 1px);
  background-size: 24px 24px;
  pointer-events: none;
}
.fr-hero-title {
  position: relative;
  z-index: 1;
}
.fr-hero-title h1 {
  font-size: 2.4rem;
  letter-spacing: 0.22em;
  color: var(--red-bright);
  text-shadow: 0 0 14px var(--red-glow), 0 0 28px var(--red-glow-2);
  margin: 0 0 8px;
  font-weight: 900;
}
.fr-hero-title .tagline {
  color: var(--ink);
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  line-height: 1.6;
  max-width: 520px;
}
.fr-hero-title .ops-line {
  color: var(--ink-dim);
  font-size: 11px;
  letter-spacing: 0.2em;
  margin-top: 12px;
  font-family: var(--mono);
}
.fr-hero-title .ops-line b { color: var(--red); }
.fr-hero-title .cta {
  margin-top: 18px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.fr-globe-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  max-width: 420px;
  margin: 0 auto;
  z-index: 1;
}
.fr-globe-wrap::before {
  /* outer ring — subtle red scanner ring effect */
  content: "";
  position: absolute; inset: 4%;
  border: 1px solid rgba(168,85,247,0.18);
  border-radius: 50%;
  animation: fr-globe-ring-rotate 18s linear infinite;
  pointer-events: none;
}
.fr-globe-wrap::after {
  /* inner glow halo */
  content: "";
  position: absolute; inset: 12%;
  border-radius: 50%;
  box-shadow: 0 0 80px 10px rgba(168,85,247,0.12) inset;
  pointer-events: none;
}
#fr-globe {
  width: 100%;
  height: 100%;
  display: block;
  background: transparent;
}
@keyframes fr-globe-ring-rotate {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
/* Mobile / narrow viewports — stack + shrink the globe */
@media (max-width: 960px) {
  .fr-hero { grid-template-columns: 1fr; }
  .fr-globe-wrap { max-width: 280px; }
  .fr-hero-title h1 { font-size: 1.8rem; }
}

/* -------------------- Module drill-down drawer -------------------- */
.fr-drawer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.72);
  z-index: 8000;
  display: flex;
  justify-content: flex-end;
  animation: fr-drawer-fade 0.18s ease-out;
}
.fr-drawer-overlay.fr-drawer-closing { animation: fr-drawer-fadeout 0.14s ease-in; }
@keyframes fr-drawer-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes fr-drawer-fadeout { from { opacity: 1; } to { opacity: 0; } }
.fr-drawer {
  background: var(--bg-0, #0b0b0f);
  border-left: 1px solid var(--border);
  width: min(92vw, 1120px);
  height: 100%;
  overflow-y: auto;
  box-shadow: -8px 0 32px rgba(168,85,247,0.18);
  animation: fr-drawer-slide 0.22s ease-out;
}
@keyframes fr-drawer-slide {
  from { transform: translateX(32px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
.fr-drawer-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 22px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(90deg, rgba(168,85,247,0.06), transparent 60%);
  position: sticky;
  top: 0;
  z-index: 2;
  backdrop-filter: blur(4px);
}
.fr-drawer-title { display: flex; gap: 12px; align-items: baseline; }
.fr-drawer-label { color: var(--red-deep); font-size: 11px; letter-spacing: 0.25em; }
.fr-drawer-name { color: var(--red-bright, #A855F7); font-size: 20px; font-weight: 700; letter-spacing: 0.12em; }
.fr-drawer-actions { display: flex; gap: 8px; }

.fr-drawer-status {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--border);
  background: rgba(168,85,247,0.02);
  align-items: center;
}
.fr-drawer-status-item { min-width: 90px; }
.fr-drawer-status-item .k { font-size: 10px; letter-spacing: 0.22em; color: var(--ink-dim); }
.fr-drawer-status-item .v { font-size: 18px; color: var(--ink); font-weight: 700; }
.fr-drawer-status-item .v.state { letter-spacing: 0.18em; font-size: 14px; }
.fr-drawer-status-item .v.state.running  { color: var(--amber); }
.fr-drawer-status-item .v.state.done     { color: var(--cyber); }
.fr-drawer-status-item .v.state.error    { color: var(--red); }
.fr-drawer-status-item .v.state.cancelled{ color: var(--ink-dim); }
.fr-drawer-status-item .v.state.skipped  { color: var(--ink-dim); }
.fr-drawer-status-item .v.state.pending  { color: var(--ink-dim); }
.fr-drawer-status-note {
  flex-basis: 100%;
  color: var(--ink-dim);
  font-size: 12px;
  font-family: var(--mono, monospace);
  margin-top: 4px;
}

.fr-drawer-body { padding: 16px 22px 60px; }
.fr-drawer-sec { margin-bottom: 28px; }
.fr-drawer-sec h3 {
  color: var(--red-bright);
  font-size: 12px;
  letter-spacing: 0.2em;
  margin: 0 0 10px;
}
.fr-drawer-log {
  max-height: 280px;
  overflow-y: auto;
  font-size: 12px;
  line-height: 1.55;
}
.fr-drawer-log .line { padding: 1px 0; }
.fr-drawer-log .line .t { color: var(--red-deep); margin-right: 8px; }
.fr-drawer-log .level-error { color: var(--red); }
.fr-drawer-log .level-warn  { color: var(--amber); }
.fr-drawer-log .level-info  { color: var(--ink); }

.fr-drawer-assetgroup { margin-bottom: 18px; }
.fr-drawer-assetgroup-h { font-size: 12px; letter-spacing: 0.18em; margin-bottom: 6px; color: var(--ink); }

/* Clickable module rows cue */
tr[data-module] { cursor: pointer; transition: background 0.12s; }
tr[data-module]:hover { background: rgba(168,85,247,0.06); }
tr[data-module]:hover td:first-child { text-shadow: 0 0 8px rgba(168,85,247,0.35); }

/* Row action buttons (VIEW / STOP) in the MODULE EXECUTION table */
.cell-action { white-space: nowrap; text-align: right; }
.cell-action button.row-btn { margin-left: 6px; font-size: 10px; padding: 4px 10px; letter-spacing: 0.14em; }
.cell-action .view-btn {
  color: var(--cyber);
  border-color: var(--cyber);
}
.cell-action .view-btn:hover {
  background: rgba(0,240,255,0.08);
  box-shadow: 0 0 10px rgba(0,240,255,0.35);
}

/* ==========================================================================
   DENSITY MODE — operator console toggle
   When body has .dense-mode, drop atmospheric chrome so dense data tables
   on long pages (scan_detail.html ~2113 lines, target_view.html, etc.) read
   without fighting the matrix-rain / scanline overlays. Persisted in
   localStorage as fr.density = "dense" | "ambient".
   ========================================================================== */
body.dense-mode #matrix-rain { opacity: 0.06; }
body.dense-mode::before {
  /* Drop the CRT scanline pass; the data IS the texture in dense mode. */
  display: none;
}
body.dense-mode::after {
  /* Keep the grid but ghost it back so it doesn't compete with rows. */
  opacity: 0.18;
}
body.dense-mode .card { padding: 12px 14px; }
body.dense-mode .card .value { font-size: 2.4rem; text-shadow: 0 0 8px var(--red-glow); }
body.dense-mode table.recon th { padding: 7px 12px; font-size: 9px; }
body.dense-mode table.recon td { padding: 6px 12px; }
body.dense-mode .topbar { padding-bottom: 14px; margin-bottom: 16px; }
body.dense-mode .terminal-pane { box-shadow: inset 0 0 8px rgba(168,85,247,0.05); }
body.dense-mode h1 { font-size: 1.7rem; }
body.dense-mode h2 { font-size: 1rem; margin-bottom: 12px; }
@media (prefers-reduced-motion: reduce) {
  /* Reduced-motion users get density mode atmosphere by default to avoid
     fighting both motion AND visual noise. */
  body { /* no-op; density toggle still works */ }
}

/* Density toggle button in topbar — small, glyph-driven */
.density-toggle {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--ink-dim);
  background: transparent;
  border: 1px solid var(--border);
  padding: 5px 10px;
  cursor: pointer;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
  margin-right: 12px;
}
.density-toggle:hover { color: var(--red); border-color: var(--red); }
.density-toggle .density-glyph { font-size: 13px; line-height: 1; transform: translateY(-1px); }
body.dense-mode .density-toggle { color: var(--red-bright); border-color: var(--red); }

/* ==========================================================================
   COUNT-UP — animated numeric reveal on .card .value[data-count-to]
   ========================================================================== */
.card .value[data-count-to] {
  /* Slight uniform width so the digits don't reflow as they animate up.
     ch unit + tabular-nums (set above) keeps columns aligned. */
  display: inline-block;
  min-width: 2ch;
}

/* ==========================================================================
   MODULE IDENTITY — every scan module gets a distinctive glyph + accent tint
   within the existing palette family. Drop a `<span class="mod-glyph"
   data-mod="MODULE_NAME"></span>` into a template and CSS does the rest.
   The glyph appears via ::before; the accent tint colors both the glyph
   and an optional surrounding pill via currentColor.
   ========================================================================== */
.mod-glyph {
  display: inline-block;
  width: 22px; height: 22px;
  line-height: 22px;
  text-align: center;
  border: 1px solid currentColor;
  font-family: var(--mono);
  font-size: 13px;
  vertical-align: middle;
  margin-right: 8px;
  flex-shrink: 0;
  border-radius: 2px;
  /* Default: red palette */
  color: var(--red-bright);
  background: rgba(168,85,247,0.04);
  transition: box-shadow 0.15s, color 0.15s, transform 0.15s;
}
.mod-glyph:hover {
  box-shadow: 0 0 10px currentColor;
  transform: translateY(-1px);
}
.mod-glyph::before { content: attr(data-glyph); }
/* Larger variant for hero placement (page titles, drawer headers) */
.mod-glyph.lg {
  width: 38px; height: 38px;
  line-height: 38px;
  font-size: 22px;
  margin-right: 14px;
  border-radius: 3px;
}
/* Inline variant for cramped pills / table cells */
.mod-glyph.sm {
  width: 16px; height: 16px;
  line-height: 16px;
  font-size: 10px;
  margin-right: 5px;
  border-radius: 2px;
}

/* Category accents — five tints within the established palette family.
   Identity = red-bright; Web = cyber; Cloud = amber; Network = red default;
   OSINT = red-deep with extra ghosting. */
/* IDENTITY group */
.mod-glyph[data-mod="email_osint"]            { color: var(--red-bright); }
.mod-glyph[data-mod="sso_idp"]                { color: var(--red-bright); }
.mod-glyph[data-mod="breaches"]               { color: var(--red-bright); }
.mod-glyph[data-mod="leaked_check_internal"]  { color: var(--red-bright); }
/* WEB group */
.mod-glyph[data-mod="subdomain"]              { color: var(--cyber); }
.mod-glyph[data-mod="web_probe"]              { color: var(--cyber); }
.mod-glyph[data-mod="web_pivot"]              { color: var(--cyber); }
.mod-glyph[data-mod="js_deep"]                { color: var(--cyber); }
.mod-glyph[data-mod="api_discovery"]          { color: var(--cyber); }
.mod-glyph[data-mod="screenshots"]            { color: var(--cyber); }
/* CLOUD / DEV group */
.mod-glyph[data-mod="cloud_buckets"]          { color: var(--amber); }
.mod-glyph[data-mod="github_recon"]           { color: var(--amber); }
.mod-glyph[data-mod="secrets_beyond_github"]  { color: var(--amber); }
.mod-glyph[data-mod="mobile_attack_surface"]  { color: var(--amber); }
/* NETWORK / INFRA group — red default */
.mod-glyph[data-mod="ports"]                  { color: var(--red); }
.mod-glyph[data-mod="nuclei_mod"]             { color: var(--red); }
.mod-glyph[data-mod="dns_deep"]               { color: var(--red); }
.mod-glyph[data-mod="asn"]                    { color: var(--red); }
.mod-glyph[data-mod="whois_mod"]              { color: var(--red); }
.mod-glyph[data-mod="certs"]                  { color: var(--red); }
/* OSINT / RECON group — red-deep tone */
.mod-glyph[data-mod="dorks"]                  { color: var(--red-bright); }
.mod-glyph[data-mod="chatter"]                { color: var(--red-bright); }
.mod-glyph[data-mod="typosquat"]              { color: var(--red-bright); }
.mod-glyph[data-mod="wayback"]                { color: var(--red-bright); }
/* OT/ICS — special case, amber with stronger weight */
.mod-glyph[data-mod="ot_ics_exposure"]        { color: var(--amber); border-width: 2px; }
.mod-glyph[data-mod="ot_aggregate"]           { color: var(--amber); border-width: 2px; }

/* Glyph values via data-glyph attribute — set in JS or inline.
   Defining ::before content via attr() keeps the markup minimal and lets
   templates drop glyph + identity together. */

/* ==========================================================================
   HERO METRIC ROW — used on dashboard for the headline 4-up
   Numbers occupy real estate. Subordinate label sits beneath in mono.
   ========================================================================== */
.hero-metrics {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
  margin-bottom: 28px;
}
.hero-metrics .hero-card {
  border: 1px solid var(--border);
  background: linear-gradient(180deg, var(--bg-1) 0%, var(--bg-0) 100%);
  padding: 22px 24px 18px;
  position: relative;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
  text-decoration: none;
  display: block;
}
.hero-metrics .hero-card:hover {
  border-color: var(--red);
  box-shadow: var(--shadow-red);
  transform: translateY(-1px);
}
.hero-metrics .hero-card::before,
.hero-metrics .hero-card::after {
  content: "";
  position: absolute;
  width: 14px; height: 14px;
}
.hero-metrics .hero-card::before {
  top: -1px; left: -1px;
  border-top: 2px solid var(--red);
  border-left: 2px solid var(--red);
}
.hero-metrics .hero-card::after {
  bottom: -1px; right: -1px;
  border-bottom: 2px solid var(--red);
  border-right: 2px solid var(--red);
}
.hero-metrics .hero-card .k {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.hero-metrics .hero-card .n {
  font-family: var(--font-num);
  font-size: 3.6rem;
  font-weight: 700;
  color: var(--red);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "ss01" 1;
  text-shadow: 0 0 16px var(--red-glow);
  line-height: 1;
  letter-spacing: -0.01em;
  margin-bottom: 4px;
  display: inline-block;
}
.hero-metrics .hero-card .sub {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--ink-dim);
  margin-top: 8px;
}
.hero-metrics .hero-card.accent .n { color: var(--red-bright); }
.hero-metrics .hero-card.cyber .n { color: var(--cyber); text-shadow: 0 0 14px rgba(0,255,159,0.4); }
.hero-metrics .hero-card.amber .n { color: var(--amber); text-shadow: 0 0 14px rgba(255,176,0,0.4); }
body.dense-mode .hero-metrics .hero-card { padding: 14px 16px 12px; }
body.dense-mode .hero-metrics .hero-card .n { font-size: 2.4rem; }
@media (max-width: 900px) {
  .hero-metrics { grid-template-columns: repeat(2, 1fr); }
  .hero-metrics .hero-card .n { font-size: 2.6rem; }
}


/* ==========================================================================
   DASHBOARD PAGE — SITREP hero, severity ribbon, last-op recency
   ========================================================================== */

/* SITREP hero strip — top of dashboard. Single-line, formatted, professional. */
.fr-sitrep {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 24px;
  padding: 14px 22px;
  border: 1px solid var(--border);
  background: var(--bg-1);
  margin-bottom: 24px;
  overflow-x: auto;
}
.fr-sitrep::before, .fr-sitrep::after { content: none; }
.fr-sitrep .sitrep-stamp {
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: 0.22em;
  text-shadow: none;
  text-transform: uppercase;
  border-right: 1px solid var(--border);
  padding-right: 20px;
  white-space: nowrap;
}
.fr-sitrep .sitrep-stamp::before, .fr-sitrep .sitrep-stamp::after { content: none; }
.fr-sitrep .sitrep-body {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 28px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--ink);
  text-transform: uppercase;
  flex: 1;
  overflow-x: auto;
}
.fr-sitrep .sitrep-body .sitrep-item {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  white-space: nowrap;
}
.fr-sitrep .sitrep-body .sitrep-item .n {
  font-family: var(--font-num);
  font-size: 1.15rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  line-height: 1;
}
.fr-sitrep .sitrep-body .sitrep-item .n.cyber { color: var(--cyber); }
.fr-sitrep .sitrep-body .sitrep-item .n.amber { color: var(--sev-medium); }
.fr-sitrep .sitrep-body .sitrep-item .n.crit  { color: var(--sev-critical); text-shadow: none; }
.fr-sitrep .sitrep-body .sitrep-item .k {
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--ink-dim);
}
.fr-sitrep .sitrep-cta { white-space: nowrap; margin-left: auto; }
.fr-sitrep .sitrep-cta .btn { padding: 6px 16px; font-size: 11px; }

@media (max-width: 900px) {
  .fr-sitrep { flex-wrap: wrap; }
  .fr-sitrep .sitrep-stamp { border-right: none; border-bottom: 1px solid var(--border); padding: 0 0 10px; width: 100%; }
}

/* Severity ribbon — proportional bar showing CRIT/HIGH/MED/LOW/INFO totals */
.fr-sevribbon {
  margin-bottom: 26px;
}
.fr-sevribbon .sev-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 8px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  color: var(--ink-dim);
  text-transform: uppercase;
}
.fr-sevribbon .sev-head .total {
  font-family: var(--font-num);
  font-size: 1.1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  letter-spacing: 0;
}
.fr-sevribbon .sev-bar {
  display: flex;
  height: 12px;
  border: 1px solid var(--border);
  background: var(--bg-0);
  overflow: hidden;
}
.fr-sevribbon .sev-bar > div {
  height: 100%;
  position: relative;
  transition: filter 0.2s;
  cursor: help;
}
.fr-sevribbon .sev-bar > div:hover { filter: brightness(1.4); }
.fr-sevribbon .sev-bar .b-critical { background: var(--sev-critical); box-shadow: 0 0 12px var(--sev-critical-glow) inset; }
.fr-sevribbon .sev-bar .b-high     { background: var(--sev-high); }
.fr-sevribbon .sev-bar .b-medium   { background: var(--sev-medium); }
.fr-sevribbon .sev-bar .b-low      { background: var(--sev-low); }
.fr-sevribbon .sev-bar .b-info     { background: var(--sev-info); }
.fr-sevribbon .sev-legend {
  display: flex;
  gap: 18px;
  margin-top: 8px;
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.fr-sevribbon .sev-legend .leg {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ink-dim);
}
.fr-sevribbon .sev-legend .leg .swatch {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 1px;
}
.fr-sevribbon .sev-legend .leg .n {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--ink);
  margin-left: 2px;
}
.fr-sevribbon .sev-legend .leg.critical .swatch { background: var(--sev-critical); }
.fr-sevribbon .sev-legend .leg.high     .swatch { background: var(--sev-high); }
.fr-sevribbon .sev-legend .leg.medium   .swatch { background: var(--sev-medium); }
.fr-sevribbon .sev-legend .leg.low      .swatch { background: var(--sev-low); }
.fr-sevribbon .sev-legend .leg.info     .swatch { background: var(--sev-info); }

/* ==========================================================================
   FR COMPONENT LIBRARY v1
   Reusable building blocks. Old selectors (.card, .recon, .pill, .sev-pill,
   .filter-chip) keep working unchanged; new templates use these and existing
   ones migrate per commit. Severity + state encoded via data-attrs so a single
   rule replaces N conditional inline-style escapes.
   ========================================================================== */

/* ---- FrCard ------------------------------------------------------------- */
.fr-card {
  background: var(--bg-1);
  border: 1px solid var(--border);
  padding: var(--sp-4) var(--sp-5);
  position: relative;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.fr-card:hover { border-color: var(--red); box-shadow: var(--shadow-red); }
.fr-card[data-tone="critical"] { border-color: var(--sev-critical); box-shadow: 0 0 0 1px var(--sev-critical), 0 0 18px var(--sev-critical-glow); }
.fr-card[data-tone="high"]     { border-color: var(--sev-high); }
.fr-card[data-tone="med"]      { border-color: var(--amber); }
.fr-card[data-tone="low"]      { border-color: var(--cyber); }
.fr-card[data-tone="info"]     { border-color: var(--ink-ghost); }
.fr-card[data-tone="neutral"]  { border-color: var(--border); }
.fr-card .fr-card-title { font-size: 11px; color: var(--ink-dim); letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: var(--sp-2); font-family: var(--mono); }
.fr-card .fr-card-value {
  font-family: var(--font-num);
  font-size: 3rem;
  color: var(--red);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "ss01" 1;
  text-shadow: 0 0 14px var(--red-glow);
  line-height: 1;
  letter-spacing: -0.01em;
  margin: var(--sp-1) 0 6px;
}
.fr-card .fr-card-sub { font-size: 11px; color: var(--ink-dim); margin-top: var(--sp-1); font-family: var(--mono); letter-spacing: 0.1em; }
/* corner ticks for the operator-console feel */
.fr-card::before, .fr-card::after { content: ""; position: absolute; width: 12px; height: 12px; }
.fr-card::before { top: -1px; left: -1px;  border-top: 2px solid var(--red); border-left:  2px solid var(--red); }
.fr-card::after  { bottom: -1px; right: -1px; border-bottom: 2px solid var(--red); border-right: 2px solid var(--red); }
body[data-skin="briefing"] .fr-card { box-shadow: none !important; }
body[data-skin="briefing"] .fr-card::before,
body[data-skin="briefing"] .fr-card::after { display: none; }

/* ---- FrTable ------------------------------------------------------------ */
.fr-table-wrap { overflow-x: auto; border: 1px solid var(--border); background: var(--bg-1); }
table.fr-table { width: 100%; border-collapse: collapse; font-size: 13px; }
table.fr-table th {
  text-align: left; padding: var(--sp-3) var(--sp-4);
  color: var(--red); font-weight: 700;
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  border-bottom: 1px solid var(--border); background: var(--bg-2);
}
table.fr-table td { padding: var(--sp-2) var(--sp-4); border-bottom: 1px solid rgba(168,85,247,0.1); }
table.fr-table tr:hover td { background: var(--bg-3); color: #fff; }
table.fr-table td.value { color: var(--ink); font-weight: 600; }
table.fr-table[data-density="compact"] th { padding: 7px var(--sp-3); font-size: 9px; }
table.fr-table[data-density="compact"] td { padding: 6px var(--sp-3); font-size: 12px; }
table.fr-table[data-density="loose"] th  { padding: var(--sp-4) var(--sp-5); }
table.fr-table[data-density="loose"] td  { padding: var(--sp-3) var(--sp-5); }

/* ---- FrPill ------------------------------------------------------------- */
.fr-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px var(--sp-2);
  font-family: var(--mono);
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; font-weight: 700;
  border: 1px solid var(--ink-ghost); color: var(--ink-dim);
  background: transparent;
}
.fr-pill[data-tone="critical"] { color: #fff; background: var(--sev-critical); border-color: var(--sev-critical); box-shadow: 0 0 12px var(--sev-critical-glow); }
.fr-pill[data-tone="high"]     { color: var(--sev-high); border-color: var(--sev-high); }
.fr-pill[data-tone="med"]      { color: var(--amber); border-color: var(--amber); }
.fr-pill[data-tone="low"]      { color: var(--cyber); border-color: var(--cyber); }
.fr-pill[data-tone="info"]     { color: var(--cyber); border-color: var(--cyber); }
.fr-pill[data-tone="done"]     { color: var(--cyber); border-color: var(--cyber); }
.fr-pill[data-state="active"]  { background: rgba(168,85,247,0.12); color: var(--red); border-color: var(--red); }
.fr-pill[data-state="inactive"] { opacity: 0.45; }
.fr-pill[data-state="live"]::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--cyber); box-shadow: 0 0 6px var(--cyber);
  animation: pulse 1.2s ease-in-out infinite;
}

/* ---- FrSegmented (skin/density/filter toggles) -------------------------- */
.fr-segmented {
  display: inline-flex;
  border: 1px solid var(--border);
  background: var(--bg-1);
  font-family: var(--mono);
}
.fr-segmented > button {
  all: unset; box-sizing: border-box;
  padding: 5px var(--sp-3);
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-dim); cursor: pointer;
  transition: color var(--t-fast), background var(--t-fast), text-shadow var(--t-fast);
}
.fr-segmented > button + button { border-left: 1px solid var(--border); }
.fr-segmented > button:hover { color: var(--red); background: var(--bg-2); }
.fr-segmented > button[aria-pressed="true"],
.fr-segmented > button.active {
  color: var(--red);
  background: rgba(168,85,247,0.08);
  text-shadow: 0 0 6px var(--red-glow);
}

/* ---- FrFormField -------------------------------------------------------- */
.fr-field { margin-bottom: var(--sp-4); }
.fr-field > label {
  display: block;
  font-size: 11px; color: var(--ink-dim);
  letter-spacing: 0.2em; text-transform: uppercase;
  margin-bottom: 6px;
}
.fr-field input,
.fr-field textarea,
.fr-field select { width: 100%; }
.fr-field .fr-field-hint  { margin: 6px 0 0; font-size: 11px; color: var(--ink-ghost); letter-spacing: 0.05em; }
.fr-field .fr-field-error { margin: 6px 0 0; font-size: 11px; color: var(--red-bright); letter-spacing: 0.05em; }
.fr-field[data-invalid="true"] input,
.fr-field[data-invalid="true"] textarea,
.fr-field[data-invalid="true"] select { border-color: var(--red); }

/* ---- FrProgressBar ------------------------------------------------------ */
/* Caller sets style="--fr-pbar-pct: 42%" — width animates via CSS var. */
.fr-pbar {
  position: relative;
  height: 6px;
  background: var(--bg-0);
  border: 1px solid var(--border);
  overflow: hidden;
}
.fr-pbar::after {
  content: "";
  position: absolute; top: 0; left: 0; bottom: 0;
  width: var(--fr-pbar-pct, 0%);
  background: var(--red);
  box-shadow: 0 0 8px var(--red-glow);
  transition: width var(--t-med);
}
.fr-pbar[data-tone="critical"]::after { background: var(--sev-critical); }
.fr-pbar[data-tone="high"]::after     { background: var(--sev-high); }
.fr-pbar[data-tone="med"]::after      { background: var(--amber); box-shadow: none; }
.fr-pbar[data-tone="low"]::after      { background: var(--cyber); box-shadow: 0 0 6px rgba(0,255,159,0.4); }
.fr-pbar[data-tone="info"]::after     { background: var(--ink-ghost); box-shadow: none; }
.fr-pbar.fr-pbar-lg  { height: 12px; }
.fr-pbar.fr-pbar-xl  { height: 20px; }

/* ---- FrTabs (CSS scaffold; JS handler ships next commit) --------------- */
.fr-tabs {
  display: flex; gap: 0; flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--sp-5);
}
.fr-tabs > button {
  all: unset; box-sizing: border-box;
  padding: var(--sp-3) var(--sp-4);
  font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--ink-dim); cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.fr-tabs > button:hover { color: var(--red-bright); }
.fr-tabs > button[aria-selected="true"] {
  color: var(--red);
  border-bottom-color: var(--red);
  text-shadow: 0 0 6px var(--red-glow);
}
.fr-tabs > button[data-tone="critical"] { color: var(--sev-critical); }
.fr-tabs > button[data-tone="high"]     { color: var(--sev-high); }
.fr-tabs > button[data-tone="med"]      { color: var(--amber); }
.fr-tabs > button[data-tone="low"]      { color: var(--cyber); }
[data-tab-panel]:not([aria-hidden="false"]) { display: none; }
[data-tab-panel][aria-hidden="false"]       { display: block; }

/* ---- FrExpandRow (table inline-detail) --------------------------------- */
.fr-row[data-expanded="true"] td { background: var(--bg-3); }
.fr-row-detail > td {
  background: var(--bg-0) !important;
  padding: var(--sp-4) var(--sp-5) !important;
  border-bottom: 1px solid var(--border);
}
.fr-row-detail[aria-hidden="true"] { display: none; }

/* ---- BX drawer (breaches inline provenance + raw-line viewer) ----------
   Used by breaches_lookup.html + breaches_domain.html. Extracted from
   per-template <style> blocks so both pages share one source of truth.
   ---------------------------------------------------------------------- */
.bx-expand-btn {
  background: transparent; border: 1px solid var(--red); color: var(--red-bright);
  cursor: pointer; font-family: inherit; font-size: 10px;
  padding: 1px 5px; margin-right: 6px;
}
.bx-expand-btn:hover { background: rgba(168,85,247,0.12); }
.bx-expand-btn[disabled] { opacity: 0.25; cursor: default; }
.bx-expand-btn.open { background: var(--red); color: #000; }
.bx-expand-tr td { background: rgba(168,85,247,0.04); border-top: 1px dashed var(--red); }
.bx-detail { padding: 8px 4px; }
.bx-rawline {
  background: #0a0a0a; color: var(--amber);
  padding: 8px 10px; margin: 0 0 10px;
  white-space: pre-wrap; word-break: break-all;
  font-size: 11px; font-family: monospace;
  max-height: 320px; overflow: auto;
  border: 1px solid rgba(168,85,247,0.25);
}
.bx-prov-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 6px 12px; font-size: 11px;
}
.bx-prov-grid .lbl {
  display: inline-block; color: var(--red-bright);
  min-width: 60px; text-transform: uppercase;
  letter-spacing: 0.08em; font-size: 10px;
}
.bx-prov-grid .val { color: var(--amber); word-break: break-all; }
.bx-prov-grid .val.mono { font-family: monospace; }
.bx-copy {
  background: transparent; border: 1px solid var(--ink-ghost); color: var(--ink-ghost);
  cursor: pointer; font-family: inherit; font-size: 9px;
  padding: 0 4px; margin-left: 6px;
}
.bx-copy:hover { color: var(--red-bright); border-color: var(--red); }

/* ---- BX pager (creds pagination on /breaches/lookup + /breaches/domain) -- */
.bx-pager {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 14px 0 4px; padding: 6px 0;
  font-family: 'Geist Mono', monospace; font-size: 11px;
  letter-spacing: 0.04em;
}
.bx-pager-meta {
  color: var(--ink-dim); margin-right: auto;
  text-transform: uppercase; letter-spacing: 0.12em; font-size: 10px;
}
.bx-pager-link {
  display: inline-block; min-width: 26px; padding: 3px 8px;
  border: 1px solid var(--border); color: var(--ink);
  background: transparent; text-align: center; text-decoration: none;
  font-family: inherit; font-size: 11px; cursor: pointer;
}
.bx-pager-link:hover { border-color: var(--red); color: var(--red-bright); }
.bx-pager-link.active {
  background: var(--red); border-color: var(--red); color: #000; font-weight: 600;
}
.bx-pager-link.disabled {
  opacity: 0.35; cursor: default; color: var(--ink-dim);
}
.bx-pager-link.disabled:hover {
  border-color: var(--border); color: var(--ink-dim);
}
.bx-pager-gap { color: var(--ink-dim); padding: 0 2px; }

/* ==========================================================================
   Dorks Ops Dashboard — extracted from dorks.html inline <style>.
   Page-local class prefixes:
     .dorks-*          single-screen ops layout
     .dork-card*       template gallery cards
     .dork-preview*    right-rail dork preview drawer
   ========================================================================== */

/* ── ops dashboard layout ─────────────────────────────────────────────── */
.dorks-shell{display:flex;flex-direction:column;gap:18px}
.dorks-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap}
.dorks-stat-strip{font-size:11px;letter-spacing:0.14em;color:var(--ink-dim);margin-top:6px;display:flex;gap:14px;flex-wrap:wrap;font-family:'Geist Mono',monospace}
.dorks-stat-strip strong{color:var(--amber);font-weight:600}
.dorks-stat-strip .sep{color:var(--border)}
.dorks-stat-strip .hot{color:var(--red-bright)}

.dorks-advisory{display:flex;gap:14px;align-items:center;padding:12px 14px;border:1px solid var(--amber);background:rgba(255,153,0,0.06);font-size:12px;line-height:1.55}

/* ── quick-fire ──────────────────────────────────────────────────────── */
.dorks-quickfire{border:1px solid var(--border);background:linear-gradient(180deg, rgba(255,153,0,0.04), transparent);padding:14px 16px}
.dorks-qf-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.dorks-qf-label{font-size:10px;letter-spacing:0.18em;color:var(--ink-dim);font-family:'Geist Mono',monospace}
#dorks-qf-target{flex:1;min-width:240px;background:#070809;border:1px solid var(--border);color:var(--amber);font:600 14px 'Geist Mono',monospace;padding:10px 14px;letter-spacing:0.04em;outline:none}
#dorks-qf-target:focus{border-color:var(--amber)}
.dorks-qf-btn-corpus{background:var(--amber);color:#000;border-color:var(--amber);font-weight:600;padding:9px 18px}
.dorks-qf-btn-corpus:hover{background:#000;color:var(--amber)}
.dorks-qf-recent{margin-top:10px;display:flex;gap:6px;flex-wrap:wrap;align-items:center;font-size:10px;letter-spacing:0.12em}
.dorks-recent-chip{background:transparent;border:1px solid var(--border);color:var(--ink);padding:3px 8px;font-family:inherit;font-size:11px;cursor:pointer;letter-spacing:0.04em}
.dorks-recent-chip:hover{border-color:var(--amber);color:var(--amber)}

/* ── body split ──────────────────────────────────────────────────────── */
.dorks-body{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(0,1fr);gap:18px}
@media (max-width:1200px){.dorks-body{grid-template-columns:1fr}}

.dorks-section-title{font-size:11px;letter-spacing:0.18em;color:var(--cyber);font-weight:600}

/* ── gallery ─────────────────────────────────────────────────────────── */
.dorks-gallery{border:1px solid #1a1d22;padding:14px 16px;background:rgba(0,0,0,0.2)}
.dorks-gallery-head{display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:12px;flex-wrap:wrap;gap:8px}
.dorks-gallery-sub{font-size:10px;letter-spacing:0.06em}
.dorks-filters{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
#dorks-search{width:100%;background:#070809;border:1px solid var(--border);color:var(--ink);font:500 12px 'Geist Mono',monospace;padding:8px 12px;outline:none;letter-spacing:0.02em}
#dorks-search:focus{border-color:var(--amber)}
.dorks-cat-chips,.dorks-sev-chips{display:flex;gap:6px;flex-wrap:wrap}
.dorks-chip{background:transparent;border:1px solid var(--border);color:var(--ink-dim);padding:4px 10px;font-family:'Geist Mono',monospace;font-size:10px;letter-spacing:0.12em;cursor:pointer;display:inline-flex;align-items:center;gap:5px}
.dorks-chip:hover{border-color:var(--amber);color:var(--amber)}
.dorks-chip.active{background:var(--amber);color:#000;border-color:var(--amber)}
.dorks-chip-count{font-size:9px;opacity:0.7}
.dorks-sev-chip[data-sev="critical"].active{background:var(--sev-critical);color:#fff;border-color:var(--sev-critical)}
.dorks-sev-chip[data-sev="high"].active{background:var(--sev-high);color:#000;border-color:var(--sev-high)}
.dorks-sev-chip[data-sev="medium"].active{background:var(--sev-medium);color:#000;border-color:var(--sev-medium)}
.dorks-sev-chip[data-sev="low"].active{background:var(--sev-low);color:#000;border-color:var(--sev-low)}

.dorks-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(260px, 1fr));gap:8px;max-height:62vh;overflow-y:auto;padding-right:4px}
.dorks-grid-loading{grid-column:1/-1;text-align:center;padding:30px;color:var(--ink-dim);font-size:11px;letter-spacing:0.14em}
.dorks-grid-empty{grid-column:1/-1;text-align:center;padding:24px;color:var(--ink-dim);font-size:11px;letter-spacing:0.12em;border:1px dashed var(--border)}

.dork-card{border:1px solid #1a1d22;padding:10px 12px;background:#070809;cursor:pointer;display:flex;flex-direction:column;gap:6px;transition:border-color .12s,box-shadow .12s}
.dork-card:hover{border-color:var(--amber);box-shadow:0 0 0 1px rgba(255,153,0,0.15)}
.dork-card.sev-critical{border-left:3px solid var(--sev-critical)}
.dork-card.sev-high{border-left:3px solid var(--sev-high)}
.dork-card.sev-medium{border-left:3px solid var(--sev-medium)}
.dork-card.sev-low{border-left:3px solid var(--sev-low)}
.dork-card.sev-info{border-left:3px solid var(--sev-info)}
.dork-card-top{display:flex;justify-content:space-between;align-items:center;font-size:9px;letter-spacing:0.16em;color:var(--ink-dim)}
.dork-card-cat{font-weight:600}
.dork-card-sev{padding:1px 6px;border:1px solid currentColor}
.dork-card.sev-critical .dork-card-sev{color:var(--sev-critical)}
.dork-card.sev-high .dork-card-sev{color:var(--sev-high)}
.dork-card.sev-medium .dork-card-sev{color:var(--sev-medium)}
.dork-card.sev-low .dork-card-sev{color:var(--sev-low)}
.dork-card-template{font-family:'Geist Mono',monospace;font-size:11px;color:var(--ink);line-height:1.45;word-break:break-word}
.dork-card-note{font-size:9px;color:var(--ink-dim);letter-spacing:0.04em;line-height:1.4}

/* pin / checkbox / selected */
.dork-card-pin{background:transparent;border:0;color:var(--ink-dim);font-size:13px;cursor:pointer;padding:0 2px;line-height:1;font-family:inherit}
.dork-card-pin:hover{color:var(--amber)}
.dork-card-pin.active{color:var(--amber);text-shadow:0 0 6px rgba(255,153,0,0.5)}
.dork-card-check{display:inline-flex;align-items:center;cursor:pointer;margin-right:2px}
.dork-card-check-box{margin:0;cursor:pointer;accent-color:var(--amber)}
.dork-card-selected{background:rgba(255,153,0,0.06);box-shadow:0 0 0 1px rgba(255,153,0,0.25)}

/* bulk-fire floating bar (fixed, only shown when SELECTED.size > 0) */
.dorks-bulk-bar{position:fixed;left:50%;bottom:-80px;transform:translateX(-50%);min-width:480px;max-width:92vw;background:#0b0d10;border:1px solid var(--amber);box-shadow:0 -16px 40px rgba(0,0,0,0.5),0 0 60px rgba(255,153,0,0.08);padding:10px 16px;display:flex;align-items:center;gap:14px;z-index:9500;font-family:'Geist Mono',monospace;font-size:11px;letter-spacing:0.06em;transition:bottom .22s cubic-bezier(.2,.8,.2,1)}
.dorks-bulk-bar.open{bottom:24px}
.dorks-bulk-count{font-weight:600;color:var(--amber)}
.dorks-bulk-target{font-size:10px}
.dorks-bulk-target.ghost{color:var(--ink-dim)}
.dorks-bulk-fire{background:var(--amber);color:#000;border-color:var(--amber);font-weight:600;padding:6px 14px}
.dorks-bulk-fire:hover{background:#000;color:var(--amber)}
.dorks-bulk-fire:disabled{opacity:0.35;cursor:not-allowed}

/* feed row inline expand */
.dorks-feed-row-wrap{display:flex;flex-direction:column;gap:0}
.dorks-feed-row-q{display:grid;grid-template-columns:auto auto 1fr auto auto auto;gap:8px;align-items:center;padding:5px 8px;font-size:11px}
.dorks-feed-row-q .dorks-feed-query{color:var(--ink);text-decoration:none;font-family:'Geist Mono',monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dorks-feed-row-q .dorks-feed-query:hover{color:var(--amber)}
.dorks-feed-toggle{background:transparent;border:1px solid var(--border);color:var(--ink-dim);padding:1px 6px;font-size:10px;cursor:pointer;font-family:inherit;line-height:1}
.dorks-feed-toggle:hover{border-color:var(--amber);color:var(--amber)}
.dorks-feed-expand{display:none;padding:0}
.dorks-feed-expand.open{display:block;border-top:1px dashed #1a1d22;background:rgba(0,0,0,0.25);padding:8px 12px}
.dorks-feed-expand-loading,.dorks-feed-expand-empty,.dorks-feed-expand-error{padding:10px;text-align:center;font-size:10px;letter-spacing:0.12em;color:var(--ink-dim)}
.dorks-feed-expand-error{color:var(--red)}
.dorks-feed-expand-row{padding:4px 0;border-bottom:1px dashed #15181c;display:grid;grid-template-columns:auto 1fr;gap:10px;align-items:flex-start}
.dorks-feed-expand-row:last-child{border-bottom:0}
.dorks-feed-expand-sev{font-size:9px;letter-spacing:0.14em;padding:1px 5px;border:1px solid currentColor;align-self:flex-start}
.dorks-feed-expand-row.sev-critical .dorks-feed-expand-sev{color:var(--sev-critical)}
.dorks-feed-expand-row.sev-high .dorks-feed-expand-sev{color:var(--sev-high)}
.dorks-feed-expand-row.sev-medium .dorks-feed-expand-sev{color:var(--sev-medium)}
.dorks-feed-expand-row.sev-low .dorks-feed-expand-sev{color:var(--sev-low)}
.dorks-feed-expand-row.sev-info .dorks-feed-expand-sev{color:var(--sev-info)}
.dorks-feed-expand-link{color:var(--ink);font-size:11px;font-family:'Geist Mono',monospace;text-decoration:none;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;grid-column:2/3}
.dorks-feed-expand-link:hover{color:var(--amber)}
.dorks-feed-expand-snippet{grid-column:2/3;font-size:10px;color:var(--ink-dim);line-height:1.45;margin-top:2px;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.dorks-feed-expand-more{padding:6px 0 0;font-size:10px;letter-spacing:0.1em;text-align:center}
.dorks-feed-expand-more a{color:var(--amber);text-decoration:none}
.dorks-feed-expand-more a:hover{text-decoration:underline}

/* ── feed ────────────────────────────────────────────────────────────── */
.dorks-feed{border:1px solid #1a1d22;padding:14px 16px;background:rgba(0,0,0,0.2);display:flex;flex-direction:column;gap:14px}
.dorks-feed-head{display:flex;justify-content:space-between;align-items:flex-end;flex-wrap:wrap;gap:8px}
.dorks-feed-sub{font-size:10px;letter-spacing:0.08em;display:flex;align-items:center;gap:6px}
.dorks-pulse{color:var(--cyber);animation:dpulse 1.4s ease-in-out infinite}
@keyframes dpulse{0%,100%{opacity:0.4}50%{opacity:1}}
.dorks-feed-block{display:flex;flex-direction:column;gap:6px}
.dorks-feed-label{font-size:9px;letter-spacing:0.18em;color:var(--ink-dim);font-weight:600}
.dorks-feed-list{display:flex;flex-direction:column;gap:3px;max-height:34vh;overflow-y:auto}
.dorks-feed-row{display:grid;grid-template-columns:auto auto 1fr auto auto;gap:8px;align-items:center;padding:5px 8px;text-decoration:none;color:inherit;border-left:2px solid transparent;font-size:11px}
.dorks-feed-row:hover{background:rgba(255,255,255,0.03);border-left-color:var(--amber)}
.dorks-feed-sev{width:6px;height:6px;border-radius:50%;background:var(--ink-dim);flex-shrink:0}
.dorks-feed-sev.crit{background:var(--red);box-shadow:0 0 6px var(--red)}
.dorks-feed-sev.ok{background:var(--cyber)}
.dorks-feed-target{color:var(--amber);font-weight:600;font-family:'Geist Mono',monospace;letter-spacing:0.02em}
.dorks-feed-query{color:var(--ink);font-family:'Geist Mono',monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:0.01em}
.dorks-feed-engines .pill{font-size:9px;padding:1px 5px}
.dorks-feed-stat{font-size:10px;color:var(--ink-dim);letter-spacing:0.08em;font-family:'Geist Mono',monospace}
.dorks-feed-status{font-size:9px;letter-spacing:0.14em;padding:1px 5px;border:1px solid currentColor}
.dorks-feed-status.status-done{color:var(--cyber)}
.dorks-feed-status.status-running{color:var(--amber)}
.dorks-feed-status.status-error,.dorks-feed-status.status-blocked,
.dorks-feed-status.status-captcha,.dorks-feed-status.status-quota_exhausted{color:var(--red)}
.dorks-feed-empty{padding:12px;text-align:center;font-size:11px;letter-spacing:0.06em;border:1px dashed #1a1d22}

/* ── engine health collapsible ───────────────────────────────────────── */
.dorks-eng-health{border:1px solid #1a1d22;padding:12px 16px}
.dorks-eng-health summary{cursor:pointer;list-style:none;outline:none}
.dorks-eng-health summary::-webkit-details-marker{display:none}
.dorks-eng-health summary::before{content:'▸  ';color:var(--ink-dim);font-size:10px}
.dorks-eng-health[open] summary::before{content:'▾  '}

/* ── card preview drawer (right rail) ─────────────────────────────────── */
.dork-preview-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.55);z-index:9700;display:none;backdrop-filter:blur(2px)}
.dork-preview-overlay.open{display:block}
.dork-preview{position:fixed;top:0;right:-720px;width:min(640px,92vw);height:100vh;background:#0b0d10;border-left:1px solid var(--amber);box-shadow:-32px 0 80px rgba(0,0,0,0.7),0 0 60px rgba(255,153,0,0.06);z-index:9710;display:flex;flex-direction:column;font-family:'Geist Mono',monospace;color:var(--ink);transition:right .22s cubic-bezier(.2,.8,.2,1)}
.dork-preview.open{right:0}
.dork-preview-head{padding:14px 22px;border-bottom:1px solid #1a1d22;display:flex;justify-content:space-between;align-items:flex-start;gap:14px;background:linear-gradient(180deg, rgba(255,153,0,0.06), transparent)}
.dork-preview-cat{font-size:9px;letter-spacing:0.18em;color:var(--ink-dim)}
.dork-preview-cat .sev{margin-left:8px;padding:1px 6px;border:1px solid currentColor;font-weight:600}
.dork-preview-cat .sev.critical{color:var(--sev-critical)}
.dork-preview-cat .sev.high{color:var(--sev-high)}
.dork-preview-cat .sev.medium{color:var(--sev-medium)}
.dork-preview-cat .sev.low{color:var(--sev-low)}
.dork-preview-close{background:transparent;border:1px solid var(--border);color:var(--ink);padding:4px 10px;font-family:inherit;cursor:pointer;font-size:11px;letter-spacing:0.12em}
.dork-preview-close:hover{border-color:var(--red);color:var(--red)}
.dork-preview-body{flex:1;overflow-y:auto;padding:16px 22px;font-size:12px;line-height:1.55}
.dork-preview-section{margin-bottom:18px}
.dork-preview-section h4{font-size:9px;letter-spacing:0.18em;color:var(--cyber);margin:0 0 8px 0;font-weight:600}
.dork-preview-template{background:#070809;border:1px solid #15181c;padding:10px 12px;font-family:inherit;font-size:11px;color:var(--ink);word-break:break-all;line-height:1.55}
.dork-preview-rendered{background:#070809;border:1px solid var(--amber);padding:10px 12px;font-family:inherit;font-size:13px;color:var(--amber);word-break:break-all;line-height:1.55}
.dork-launch-row{display:flex;flex-wrap:wrap;gap:6px}
.dork-launch-btn{background:transparent;border:1px solid currentColor;color:var(--ink);padding:5px 10px;font-family:inherit;font-size:10px;letter-spacing:0.1em;cursor:pointer;text-decoration:none;display:inline-block}
.dork-launch-btn[data-eng="google"]{color:#4285F4}
.dork-launch-btn[data-eng="bing"]{color:#008373}
.dork-launch-btn[data-eng="duckduckgo"]{color:#DE5833}
.dork-launch-btn[data-eng="brave"]{color:#FB542B}
.dork-launch-btn[data-eng="yandex"]{color:#FFCC00}
.dork-launch-btn[data-eng="startpage"]{color:#97c2de}
.dork-fire-btn{background:var(--amber);color:#000;border:1px solid var(--amber);padding:8px 14px;font-family:inherit;font-size:11px;letter-spacing:0.12em;font-weight:600;cursor:pointer;width:100%;margin-top:6px}
.dork-fire-btn:hover{background:#000;color:var(--amber)}
.dork-fire-btn:disabled{opacity:0.4;cursor:not-allowed}

/* ==========================================================================
   UNIVERSAL COLOR SYSTEM — OVERRIDE LAYER (appended last, wins by source order)
   --------------------------------------------------------------------------
   Doctrine:
   1. Brand violet (--red, --red-bright, --red-deep) is RESERVED for
      interaction state ONLY: focus, hover affordance, active tab marker,
      primary CTA background, link hover. Never for decoration, never for
      static metric numbers, never for static text.
   2. Severity colors (--sev-critical .. --sev-info) are the ONLY tokens
      allowed to colorize finding badges, severity chips, severity counts.
   3. Everything else neutral: text uses --ink / --ink-dim / --ink-ghost,
      surfaces use --bg-0/1/2/3, borders use --border / --border-strong.
   4. No decorative glow text-shadows anywhere — they read as "AI demo".
   ========================================================================== */

/* (1) Kill ALL decorative text-shadow glows globally. Severity badges with
       their own box-shadow rules survive (those use box-shadow, not text-shadow). */
h1, h2, h3, h4, h5,
.card .value, .fr-card .value,
.tabs .tab, .tabs .tab.active,
.subtabs .subtab, .subtabs .subtab.active,
.tab.active, .filter-chip, .filter-chip.active,
.t-crit, .t-err, .t-high,
.boot-seq, .boot-seq .crit,
a, a:hover,
.fr-hero-title, .fr-hero-title .ops-line b,
.terminal .prompt,
.density-toggle, body.dense-mode .density-toggle,
.fr-graph-detail .sev-pill,
.fr-sevribbon .sev-head,
.fr-sitrep .sitrep-stamp, .fr-sitrep .sitrep-body .sitrep-item .n,
body.dense-mode .card .value { text-shadow: none !important; }

/* (2) Static metric numerics — white, not violet. Violet shouts; the number
       itself is what should read. */
.card .value,
.fr-card .value,
.card[data-tone="neutral"] .value { color: var(--ink); }

/* Severity tones still color the value with semantic red — these stay. */
.card[data-tone="critical"] .value { color: var(--sev-critical); }
.card[data-tone="high"]     .value { color: var(--sev-high); }
.card[data-tone="med"]      .value,
.card[data-tone="medium"]   .value { color: var(--sev-medium); }
.card[data-tone="low"]      .value { color: var(--sev-low); }
.card[data-tone="info"]     .value { color: var(--sev-info); }

/* (3) Headings — always neutral white. No accent color on static headings. */
h1, h2 { color: var(--ink) !important; }
h1 .blink::after { color: var(--ink-dim); }

/* (4) Topbar user chip — neutral text (was violet shout). */
.topbar .user span { color: var(--ink); font-weight: 600; }

/* (5) Card hover — subtle accent border, no shadow bloom. */
.card:hover { border-color: var(--border-strong); box-shadow: none; }

/* (6) Tab active marker — single underline accent, no glow, no full-text violet. */
.tabs .tab.active,
.subtabs .subtab.active,
.tabs .tab:hover,
.subtabs .subtab:hover { color: var(--ink); }
.tabs .tab.active { box-shadow: inset 0 -2px 0 0 var(--red); }
.subtabs .subtab.active { box-shadow: inset 0 -2px 0 0 var(--red); }
.tabs .tab.active .tab-count,
.subtabs .subtab.active .tab-count { color: var(--ink-dim); background: var(--bg-3); }

/* (7) FrTabs unified: only severity-tagged tabs get color; the rest neutral
       white with a single violet underline when active. */
.fr-tabs > button { color: var(--ink-dim); }
.fr-tabs > button:hover { color: var(--ink); }
.fr-tabs > button[aria-selected="true"] {
  color: var(--ink);
  box-shadow: inset 0 -2px 0 0 var(--red);
}
.fr-tabs > button[aria-selected="true"][data-tone="critical"] {
  color: var(--sev-critical);
  box-shadow: inset 0 -2px 0 0 var(--sev-critical);
}
.fr-tabs > button[aria-selected="true"][data-tone="high"] {
  color: var(--sev-high);
  box-shadow: inset 0 -2px 0 0 var(--sev-high);
}

/* (8) Links — neutral resting, violet hover underline. */
a { color: var(--ink); border-bottom: 1px dotted var(--border); }
a:hover { color: var(--red); border-bottom-color: var(--red); }

/* (9) .accent helper class — only this class explicitly opts in to violet text. */
.accent { color: var(--red); }

/* (10) Module glyph data tints — unify to neutral grey to stop the rainbow.
        Severity badge already conveys risk; the glyph next to a row name
        should not also fight for attention. */
.mod-glyph,
.mod-glyph[data-mod] { color: var(--ink-dim) !important; }

/* (11) Boot sequence + terminal log levels — semantic severity, not brand. */
.t-crit, .t-err, .boot-seq .crit { color: var(--sev-critical); }
.t-high { color: var(--sev-high); }

/* (12) Drawer labels + log timestamps — muted grey instead of violet. */
.fr-drawer-label,
.fr-drawer-log .line .t { color: var(--ink-ghost); }
.fr-drawer-status-item .v.state.error,
.fr-drawer-log .level-error { color: var(--sev-critical); }

/* (13) SITREP — make absolutely sure nothing inside shouts violet decoratively. */
.fr-sitrep .sitrep-body .sitrep-item .n { color: var(--ink); }
.fr-sitrep .sitrep-body .sitrep-item .n.crit { color: var(--sev-critical); }
.fr-sitrep .sitrep-body .sitrep-item .n.cyber { color: var(--ink); }
.fr-sitrep .sitrep-body .sitrep-item .n.amber { color: var(--sev-medium); }

/* (14) Page hero title / ops-line accents (intro page) — neutral with one
        accent word allowed via .accent class. */
.fr-hero-title { color: var(--ink); }
.fr-hero-title .ops-line b { color: var(--ink); }

/* (15) Buttons — keep violet only for solid CTA. Ghost button hover gets
        subtle accent border without text fill. */
.btn.ghost:hover { border-color: var(--red); color: var(--ink); background: transparent; }

/* (16) Selection + scrollbar — violet stays here (interaction surface). */
::selection { background: var(--red); color: var(--ink); }
::-webkit-scrollbar-thumb { background: var(--border-strong); }
::-webkit-scrollbar-thumb:hover { background: var(--red); }

/* ════════════════════════════════════════════════════════════════════════════
   WAR-ROOM STRIP — global situational-awareness bar (injected in base.html)
   ════════════════════════════════════════════════════════════════════════════ */
.fr-warroom {
  display: flex; align-items: center; gap: 0;
  background: var(--bg-0); border-bottom: 1px solid var(--border);
  height: 30px; overflow: hidden;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.13em;
  color: var(--ink-ghost);
  /* bust out of .main padding so the strip spans edge-to-edge */
  margin: -24px -32px 20px;
  width: calc(100% + 64px);
}
.wr-item { display: flex; align-items: center; gap: 7px; padding: 0 18px; flex-shrink: 0; }
.wr-divider { width: 1px; height: 14px; background: var(--border); flex-shrink: 0; }
.wr-label { color: var(--ink-ghost); text-transform: uppercase; flex-shrink: 0; }
.wr-value { color: var(--ink); font-weight: 600; }
.wr-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--border-strong); flex-shrink: 0;
  transition: background 0.4s, box-shadow 0.4s;
}
.wr-dot.active { background: var(--cyber); box-shadow: 0 0 5px rgba(0,255,159,0.7); }
.wr-dot.hot    { background: var(--sev-critical); box-shadow: 0 0 7px var(--sev-critical-glow); animation: wr-dot-pulse 1.2s ease-in-out infinite; }
@keyframes wr-dot-pulse {
  0%,100% { opacity: 1; transform: scale(1); }
  50%     { opacity: 0.55; transform: scale(1.5); }
}
.wr-threat-calm     { color: var(--cyber) !important; }
.wr-threat-elevated { color: var(--amber) !important; }
.wr-threat-hot      { color: var(--sev-critical) !important; }
.wr-ticker-wrap { flex: 1; overflow: hidden; min-width: 0; }
.wr-ticker { display: inline-block; color: var(--ink-ghost); white-space: nowrap; transition: opacity 0.28s ease; }
.wr-ticker.fade { opacity: 0; }
.wr-palette-hint {
  margin-left: auto; padding: 0 18px; flex-shrink: 0;
  color: var(--ink-ghost); cursor: pointer; transition: color 0.15s;
}
.wr-palette-hint:hover { color: var(--red); }

/* ════════════════════════════════════════════════════════════════════════════
   TARGET RISK CARDS — radar polygon + severity mini-bars
   ════════════════════════════════════════════════════════════════════════════ */
@keyframes tc-card-in  { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:none; } }
@keyframes tc-radar-in { from { transform:scale(0.25); opacity:0; } to { transform:scale(1); opacity:1; } }

.target-card {
  display: flex; flex-direction: column;
  padding: 0; overflow: hidden; text-decoration: none !important; border-bottom: none !important;
  animation: tc-card-in 0.45s ease-out backwards;
  animation-delay: calc(var(--i, 0) * 0.07s);
  transition: border-color 0.18s, transform 0.15s, box-shadow 0.18s;
}
.target-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 28px rgba(0,0,0,0.55), 0 0 0 1px var(--red-deep);
}
.tc-header {
  padding: 10px 14px 6px;
  display: flex; align-items: center; justify-content: space-between;
}
.tc-label     { font-size: 9px; letter-spacing: 0.2em; color: var(--ink-ghost); text-transform: uppercase; }
.tc-top-badge { font-size: 9px; letter-spacing: 0.13em; color: var(--sev-critical); font-weight: 700; }
.tc-domain {
  padding: 0 14px 10px;
  font-size: 12px; font-weight: 700; color: var(--red-bright);
  word-break: break-all; font-family: var(--mono); line-height: 1.25;
}
.tc-body {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.tc-radar { flex-shrink: 0; }
.tc-radar polygon { transform-origin: 36px 36px; animation: tc-radar-in 0.7s cubic-bezier(0.16,1,0.3,1) both; }
.tc-bars  { flex: 1; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.tc-bar-row   { display: flex; align-items: center; gap: 6px; }
.tc-bar-label {
  font-size: 8px; letter-spacing: 0.12em; font-family: var(--mono);
  min-width: 26px; text-align: right; flex-shrink: 0; color: var(--ink-ghost);
}
.tc-bar-track { flex: 1; height: 2px; background: rgba(255,255,255,0.04); border-radius: 1px; overflow: hidden; min-width: 0; }
.tc-bar-fill  { height: 100%; width: 0; border-radius: 1px; transition: width 0.75s cubic-bezier(0.16,1,0.3,1); }
.tc-bar-n     { font-size: 9px; font-family: var(--mono); min-width: 22px; text-align: right; flex-shrink: 0; color: var(--ink-ghost); }

.tc-bar-row[data-sev="critical"] .tc-bar-label,
.tc-bar-row[data-sev="critical"] .tc-bar-n    { color: var(--sev-critical); }
.tc-bar-row[data-sev="critical"] .tc-bar-fill { background: var(--sev-critical); box-shadow: 0 0 5px var(--sev-critical-glow); }
.tc-bar-row[data-sev="high"]     .tc-bar-label,
.tc-bar-row[data-sev="high"]     .tc-bar-n    { color: var(--sev-high); }
.tc-bar-row[data-sev="high"]     .tc-bar-fill { background: var(--sev-high); }
.tc-bar-row[data-sev="medium"]   .tc-bar-label,
.tc-bar-row[data-sev="medium"]   .tc-bar-n    { color: var(--amber); }
.tc-bar-row[data-sev="medium"]   .tc-bar-fill { background: var(--amber); }
.tc-bar-row[data-sev="low"]      .tc-bar-label,
.tc-bar-row[data-sev="low"]      .tc-bar-n    { color: var(--sev-low); }
.tc-bar-row[data-sev="low"]      .tc-bar-fill { background: var(--sev-low); }
.tc-bar-row[data-sev="info"]     .tc-bar-fill { background: var(--sev-info); }
.tc-meta {
  padding: 8px 14px;
  font-size: 10px; color: var(--ink-ghost); letter-spacing: 0.06em;
}

/* ════════════════════════════════════════════════════════════════════════════
   EDITORIAL SEVERITY — tr[data-sev] typographic hierarchy
   Targets finding rows in chatter, scan_detail, target_view, dorks
   ════════════════════════════════════════════════════════════════════════════ */
tr[data-sev="critical"] { border-left: 3px solid var(--sev-critical); }
tr[data-sev="critical"] td:first-child { color: var(--sev-critical); font-weight: 700; letter-spacing: 0.02em; }
tr[data-sev="critical"]:hover { background: rgba(185,28,28,0.07) !important; }
tr[data-sev="high"]     { border-left: 3px solid var(--sev-high); }
tr[data-sev="high"] td:first-child { color: var(--sev-high); font-weight: 600; }
tr[data-sev="high"]:hover { background: rgba(239,68,68,0.05) !important; }
tr[data-sev="medium"] td:first-child { color: var(--amber); font-weight: 500; }
tr[data-sev="low"]    td:first-child { color: var(--sev-low); }
tr[data-sev="info"]   td:first-child { color: var(--ink-ghost); font-size: 0.88em; letter-spacing: 0.06em; text-transform: uppercase; }

/* .sev-badge — inline severity pill, use anywhere */
.sev-badge {
  display: inline-block; padding: 1px 8px; border-radius: 2px;
  font-size: 10px; letter-spacing: 0.12em; font-weight: 700;
  text-transform: uppercase; font-family: var(--mono);
}
.sev-badge.critical { color: var(--sev-critical); border: 1px solid var(--sev-critical); background: rgba(185,28,28,0.12); }
.sev-badge.high     { color: var(--sev-high);     border: 1px solid var(--sev-high);     background: rgba(239,68,68,0.10); }
.sev-badge.medium   { color: var(--amber);         border: 1px solid var(--amber);         background: rgba(255,176,0,0.10); }
.sev-badge.low      { color: var(--sev-low);       border: 1px solid var(--sev-low);       background: rgba(34,197,94,0.10); }
.sev-badge.info     { color: var(--ink-ghost);     border: 1px solid var(--border);        background: transparent; }

/* ════════════════════════════════════════════════════════════════════════════
   TOAST NOTIFICATIONS — fr.toast(msg, opts)
   Stack: fixed top-right, z-index: var(--z-toast) = 11000
   Tones: success | error | warn | info
   API: fr.toast(message, { tone, title, duration })  duration=0 → sticky
   ════════════════════════════════════════════════════════════════════════════ */

.fr-toast-stack {
  position: fixed;
  top: 20px; right: 20px;
  z-index: var(--z-toast);
  display: flex; flex-direction: column; gap: 8px;
  width: 320px; max-width: calc(100vw - 40px);
  pointer-events: none;
}

.fr-toast {
  position: relative;
  background: var(--bg-1);
  border: 1px solid var(--border);
  padding: 11px 32px 16px 14px;
  font-family: var(--mono);
  pointer-events: all;
  overflow: hidden;
  animation: fr-toast-in 0.22s cubic-bezier(.3,0,.3,1) forwards;
}
.fr-toast::before, .fr-toast::after {
  content: ""; position: absolute; width: 8px; height: 8px; border-color: var(--border);
}
.fr-toast::before { top: -1px; left: -1px; border-top: 1px solid; border-left: 1px solid; }
.fr-toast::after  { bottom: 2px; right: -1px; border-bottom: 1px solid; border-right: 1px solid; }

.fr-toast[data-tone="success"] { border-color: var(--sev-low); }
.fr-toast[data-tone="success"]::before,
.fr-toast[data-tone="success"]::after { border-color: var(--sev-low); }
.fr-toast[data-tone="error"]   { border-color: var(--sev-high); }
.fr-toast[data-tone="error"]::before,
.fr-toast[data-tone="error"]::after   { border-color: var(--sev-high); }
.fr-toast[data-tone="warn"]    { border-color: var(--amber); }
.fr-toast[data-tone="warn"]::before,
.fr-toast[data-tone="warn"]::after    { border-color: var(--amber); }
.fr-toast[data-tone="info"]    { border-color: var(--red); }
.fr-toast[data-tone="info"]::before,
.fr-toast[data-tone="info"]::after    { border-color: var(--red); }

.fr-toast-label {
  font-size: 9px; letter-spacing: 0.2em; text-transform: uppercase;
  margin-bottom: 4px;
}
.fr-toast[data-tone="success"] .fr-toast-label { color: var(--sev-low); }
.fr-toast[data-tone="error"]   .fr-toast-label { color: var(--sev-high); }
.fr-toast[data-tone="warn"]    .fr-toast-label { color: var(--amber); }
.fr-toast[data-tone="info"]    .fr-toast-label,
.fr-toast:not([data-tone])     .fr-toast-label { color: var(--red); }

.fr-toast-msg {
  font-size: 12px; color: var(--ink); line-height: 1.5; letter-spacing: 0.02em;
}

.fr-toast-close {
  position: absolute; top: 7px; right: 8px;
  background: none; border: none;
  color: var(--ink-dim); font-size: 14px;
  cursor: pointer; padding: 2px 4px; line-height: 1;
  font-family: var(--mono);
}
.fr-toast-close:hover { color: var(--ink); }

/* Shrinking progress bar at bottom */
.fr-toast-bar {
  position: absolute; bottom: 0; left: 0;
  height: 2px; width: 100%;
  transform-origin: left;
  background: var(--border);
  animation: fr-toast-bar-shrink linear forwards;
}
.fr-toast[data-tone="success"] .fr-toast-bar { background: var(--sev-low); }
.fr-toast[data-tone="error"]   .fr-toast-bar { background: var(--sev-high); }
.fr-toast[data-tone="warn"]    .fr-toast-bar { background: var(--amber); }
.fr-toast[data-tone="info"]    .fr-toast-bar { background: var(--red); }

.fr-toast.fr-toast-out {
  animation: fr-toast-out 0.18s ease-in forwards;
  pointer-events: none;
}

@keyframes fr-toast-in {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes fr-toast-out {
  to { opacity: 0; transform: translateX(32px); }
}
@keyframes fr-toast-bar-shrink {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

@media (prefers-reduced-motion: reduce) {
  .fr-toast, .fr-toast.fr-toast-out { animation: none; opacity: 1; transform: none; }
  .fr-toast-bar { animation: none; transform: scaleX(0); }
}

/* ════════════════════════════════════════════════════════════════════════════
   SKELETON LOADING — shimmer placeholders for async content
   Usage: <div class="skeleton skeleton-card"></div>
          <div class="skeleton skeleton-text w-3q"></div>
   ════════════════════════════════════════════════════════════════════════════ */

@keyframes fr-shimmer {
  0%   { background-position: -600px 0; }
  100% { background-position:  600px 0; }
}

.skeleton {
  background: linear-gradient(
    90deg,
    var(--bg-1) 25%,
    var(--bg-2) 50%,
    var(--bg-1) 75%
  );
  background-size: 1200px 100%;
  animation: fr-shimmer 1.6s ease-in-out infinite;
  border-radius: 2px;
  color: transparent !important;
  pointer-events: none;
  user-select: none;
}

/* text-line skeletons */
.skeleton-text      { height: 11px; margin: 5px 0; }
.skeleton-text.w-full { width: 100%; }
.skeleton-text.w-3q   { width: 75%; }
.skeleton-text.w-half { width: 50%; }
.skeleton-text.w-1q   { width: 25%; }

/* block skeletons */
.skeleton-card      { height: 80px; width: 100%; }
.skeleton-row       { height: 36px; width: 100%; margin-bottom: 2px; }
.skeleton-metric    { height: 64px; width: 100%; }
.skeleton-pill      { height: 20px; width: 56px; display: inline-block; }

/* repeat helper — wrap N .skeleton-row children */
.skeleton-table     { display: flex; flex-direction: column; gap: 2px; }

@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; background: var(--bg-2); }
}

/* ════════════════════════════════════════════════════════════════════════════
   SPINNER — inline loading indicator
   Sizes: default (20px) | .fr-spinner-sm (14px) | .fr-spinner-lg (32px)
   Tones: default (brand red/violet) | data-tone="success|warn|info"
   ════════════════════════════════════════════════════════════════════════════ */

@keyframes fr-spin {
  to { transform: rotate(360deg); }
}

.fr-spinner {
  display: inline-block;
  width: 20px; height: 20px;
  border: 2px solid var(--border);
  border-top-color: var(--red);
  border-radius: 50%;
  animation: fr-spin 0.7s linear infinite;
  flex-shrink: 0;
  vertical-align: middle;
}
.fr-spinner-sm { width: 14px; height: 14px; border-width: 1.5px; }
.fr-spinner-lg { width: 32px; height: 32px; border-width: 3px; }

.fr-spinner[data-tone="success"] { border-top-color: var(--sev-low); }
.fr-spinner[data-tone="warn"]    { border-top-color: var(--amber); }
.fr-spinner[data-tone="info"]    { border-top-color: var(--ink-dim); }

/* Loading row — spinner + label inline */
.fr-loading-row {
  display: flex; align-items: center; gap: 10px;
  padding: 20px; color: var(--ink-dim);
  font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.12em; text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .fr-spinner { animation: none; border-top-color: var(--red); opacity: 0.6; }
}

/* ════════════════════════════════════════════════════════════════════════════
   EMPTY STATE — fr-empty-state
   Usage: <div class="fr-empty-state">
            <div class="fr-empty-glyph">◎</div>
            <div class="fr-empty-title">NO TARGETS ONBOARDED</div>
            <div class="fr-empty-msg">Run a scan to populate this view.</div>
            <button class="btn">START SCAN</button>
          </div>
   ════════════════════════════════════════════════════════════════════════════ */

.fr-empty-state {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 48px 24px; text-align: center;
  font-family: var(--mono);
  min-height: 160px;
}

.fr-empty-glyph {
  font-size: 28px; line-height: 1;
  margin-bottom: 16px;
  opacity: 0.25;
  filter: grayscale(1);
}

.fr-empty-title {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--ink-dim);
  margin-bottom: 8px;
}

.fr-empty-msg {
  font-size: 11px; color: var(--ink-ghost);
  line-height: 1.6; max-width: 300px;
  margin-bottom: 20px; letter-spacing: 0.03em;
}

/* compact variant — tighter padding for table empty rows */
.fr-empty-state.compact {
  padding: 24px 16px; min-height: 80px;
}
.fr-empty-state.compact .fr-empty-glyph { font-size: 18px; margin-bottom: 8px; }
.fr-empty-state.compact .fr-empty-title { font-size: 10px; }

/* ════════════════════════════════════════════════════════════════════════════
   MOBILE TYPOGRAPHY — responsive font scaling
   h1 stays 1.9rem on desktop; .card .value stays 3.4rem on desktop.
   Both need scaling at ≤720px to avoid overflow / cramping on phone.
   ════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 720px) {
  h1 { font-size: 1.4rem; letter-spacing: 0.03em; }
  h2 { font-size: 1.05rem; }
  h3 { font-size: 0.95rem; }

  .card .value,
  .fr-card .value         { font-size: 2.2rem; }
  .card .value.compact    { font-size: 1.4rem; }

  /* hero metrics strip — shrink giant numbers */
  .hero-card .n           { font-size: 2rem; }

  /* SITREP hero strip — stays readable at narrow width */
  .fr-sitrep              { gap: 12px; flex-wrap: wrap; }
  .fr-sitrep-cell         { min-width: 80px; }
}

@media (max-width: 480px) {
  h1 { font-size: 1.2rem; }
  h2 { font-size: 0.95rem; }

  .card .value,
  .fr-card .value         { font-size: 1.8rem; }
  .card .value.compact    { font-size: 1.2rem; }

  .hero-card .n           { font-size: 1.7rem; }

  /* War-room ticker — hide on very small screens to avoid clipping */
  .wr-ticker              { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   dorks_new: engine-branded launch buttons
   ═══════════════════════════════════════════════════════════════════ */
/* Launch buttons — grey outline across all engines (no brand colours).
   Override the per-engine selectors below as a flat grey set. */
.dork-eng-btn,
.dork-eng-btn[data-engine="google"],
.dork-eng-btn[data-engine="bing"],
.dork-eng-btn[data-engine="duckduckgo"],
.dork-eng-btn[data-engine="yandex"],
.dork-eng-btn[data-engine="brave"],
.dork-eng-btn[data-engine="startpage"] {
  border-color: var(--border);
  color: var(--ink-dim);
  background: var(--bg-0);
}
.dork-eng-btn:hover {
  border-color: var(--border);
  color: var(--ink);
  background: var(--bg-0);
  box-shadow: none;
}
/* dorks_new IN-PROCESS engine pill — grey outline, no brand colour */
.fr-pill.ip-engine-pill {
  border-color: var(--border);
  color: var(--ink-dim);
  background: var(--bg-0);
}
.fr-pill.ip-engine-pill:has(input:checked) {
  border-color: var(--ink);
  color: var(--ink);
}

/* ═══════════════════════════════════════════════════════════════════
   dorks_new: sticky query-preview + fire bar
   ═══════════════════════════════════════════════════════════════════ */
.dork-new-sticky{position:sticky;bottom:0;z-index:var(--z-drawer);background:var(--bg-1);border-top:1px solid var(--amber);padding:var(--sp-4);margin-top:var(--sp-4)}
.dork-new-sticky .dork-query-pre{font-family:var(--mono);color:var(--amber);font-size:13px;word-break:break-word;white-space:pre-wrap;min-height:1.4em;margin:0}

/* ═══════════════════════════════════════════════════════════════════
   dorks_new: advanced-operators collapsible
   ═══════════════════════════════════════════════════════════════════ */
details.dork-advanced>summary{cursor:pointer;color:var(--amber);font-size:11px;letter-spacing:0.1em;padding:var(--sp-2) 0}
details.dork-advanced>summary::marker{color:var(--amber)}

/* ═══════════════════════════════════════════════════════════════════
   target_view: posture score card — data-posture drives color
   ═══════════════════════════════════════════════════════════════════ */
.card[data-posture]           {--p:var(--sev-info);border-color:var(--p)}
.card[data-posture="critical"]{--p:var(--sev-critical);box-shadow:0 0 14px var(--sev-critical)}
.card[data-posture="high"]    {--p:var(--sev-high)}
.card[data-posture="medium"]  {--p:var(--sev-medium)}
.card[data-posture="low"]     {--p:var(--sev-low)}
.card[data-posture] .posture-value,
.card[data-posture] .posture-tier,
.card[data-posture] .posture-title{color:var(--p)}

/* ══════════════════════════════════════════════════════════════════════════
   BUTTON LOADING / DISABLED — SaaS polish
   ══════════════════════════════════════════════════════════════════════════ */
.btn[disabled], .btn:disabled {
  opacity: 0.38;
  cursor: not-allowed;
  pointer-events: none;
}
.btn.loading {
  pointer-events: none;
  color: transparent !important;
  text-shadow: none !important;
  box-shadow: none !important;
}
.btn.loading::after {
  content: "";
  position: absolute;
  width: 13px; height: 13px;
  top: 50%; left: 50%;
  margin: -6px 0 0 -7px;
  border: 2px solid rgba(168,85,247,0.22);
  border-top-color: var(--red);
  border-radius: 50%;
  animation: btn-spin 0.55s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* ══════════════════════════════════════════════════════════════════════════
   FILTER BAR — input + inline ✕ clear button
   ══════════════════════════════════════════════════════════════════════════ */
.filter-bar {
  position: relative;
  display: block;
  margin-bottom: 16px;
}
.filter-bar input[type="text"] {
  padding-right: 38px;
  width: 100%;
  margin-bottom: 0;
}
.filter-clear {
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: 36px;
  background: none;
  border: none;
  color: var(--ink-ghost);
  cursor: pointer;
  font-size: 14px;
  letter-spacing: 0;
  font-family: var(--mono);
  padding: 0;
  display: none;
  align-items: center;
  justify-content: center;
  transition: color 0.12s;
  text-transform: none;
  font-weight: 400;
}
.filter-clear:hover { color: var(--red); background: none; box-shadow: none; }

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE SIDEBAR TOGGLE
   ══════════════════════════════════════════════════════════════════════════ */
.sidebar-toggle {
  display: none;
  background: none;
  border: 1px solid var(--border);
  color: var(--ink-dim);
  padding: 5px 10px;
  cursor: pointer;
  font-size: 14px;
  letter-spacing: 0.06em;
  line-height: 1;
  font-family: var(--mono);
  transition: border-color 0.12s, color 0.12s;
  text-transform: uppercase;
}
.sidebar-toggle:hover { border-color: var(--red); color: var(--red); }

.sidebar-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.65);
  z-index: calc(var(--z-drawer) - 10);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

@media (max-width: 900px) {
  .sidebar-toggle { display: inline-flex; align-items: center; gap: 6px; }
  .sidebar {
    position: fixed;
    top: 0; left: -260px;
    width: 240px;
    height: 100vh;
    z-index: var(--z-drawer);
    transition: left var(--t-med);
    background: var(--bg-1);
    overflow-y: auto;
  }
  body.sidebar-open .sidebar { left: 0; }
  body.sidebar-open .sidebar-overlay { display: block; }
  .main { padding: 16px 16px 64px; }
}

@media (max-width: 480px) {
  .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr; }
  .main { padding: 12px 12px 64px; }
  .row-actions { flex-wrap: wrap; gap: 4px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   BUTTON SIZE VARIANTS
   ══════════════════════════════════════════════════════════════════════════ */
.btn-lg { padding: 14px 28px !important; font-size: 13px !important; }
.btn-sm { padding: 4px 12px  !important; font-size: 10px !important; }

/* ══════════════════════════════════════════════════════════════════════════
   BUTTON COLOR VARIANTS — filled primary CTAs, replaces inline style="background:…"
   ══════════════════════════════════════════════════════════════════════════ */
.btn-filled       { background: var(--red);    color: #000 !important; border-color: var(--red);    text-shadow: none !important; }
.btn-filled:hover { background: var(--red-bright); color: #000 !important; border-color: var(--red-bright); box-shadow: var(--shadow-red); }
.btn-amber        { background: var(--amber);  color: #000 !important; border-color: var(--amber);  text-shadow: none !important; }
.btn-amber:hover  { background: #ffd060;       color: #000 !important; border-color: #ffd060; box-shadow: 0 0 16px rgba(255,176,0,0.4); }
.btn-cyber        { background: var(--cyber);  color: #000 !important; border-color: var(--cyber);  text-shadow: none !important; }
.btn-cyber:hover  { background: #00ffbb;       color: #000 !important; border-color: #00ffbb; }

/* ══════════════════════════════════════════════════════════════════════════
   TABLE SEVERITY COLUMN CLASSES — replaces inline style="color:var(--sev-*)"
   ══════════════════════════════════════════════════════════════════════════ */
table.recon th.th-crit   { color: var(--sev-critical) !important; }
table.recon th.th-high   { color: var(--sev-high)     !important; }
table.recon th.th-med    { color: var(--sev-medium)   !important; }
table.recon th.th-info   { color: var(--sev-info)     !important; }
table.recon td.td-crit   { color: var(--sev-critical); font-weight: 600; }
table.recon td.td-high   { color: var(--sev-high);     font-weight: 600; }
table.recon td.td-med    { color: var(--sev-medium);   font-weight: 600; }
table.recon td.td-info   { color: var(--sev-info);     font-weight: 600; }

/* ══════════════════════════════════════════════════════════════════════════
   TABLE EMPTY STATE ROW — remove padding when using fr-empty-state inline
   ══════════════════════════════════════════════════════════════════════════ */
table.recon td.td-empty { padding: 0; }
table.recon tr.tr-empty:hover td { background: transparent; }

/* ══════════════════════════════════════════════════════════════════════════
   CARD LINK — a.card removes link decorations (used on dashboard metric tiles)
   ══════════════════════════════════════════════════════════════════════════ */
a.card { text-decoration: none; border-bottom: none; display: block; }
a.card:hover { border-bottom: none; }

/* ══════════════════════════════════════════════════════════════════════════
   GHOST BUTTON COLOR VARIANTS — inline style="border-color:var(--amber)…" replacements
   ══════════════════════════════════════════════════════════════════════════ */
.btn.ghost.btn-amber-ghost        { border-color: var(--amber); color: var(--amber); }
.btn.ghost.btn-amber-ghost:hover  { border-color: var(--amber); background: rgba(255,176,0,0.12); color: var(--amber); }
.btn.ghost.btn-cyber-ghost        { border-color: var(--cyber); color: var(--cyber); }
.btn.ghost.btn-cyber-ghost:hover  { border-color: var(--cyber); background: rgba(0,255,159,0.08); color: var(--cyber); }
/* Danger ghost — red border+text in normal state (replaces inline style="border-color:var(--red); color:var(--red);") */
/* Quiet button — black bg, grey outline, NO hover transform. For static CTAs
   that should look like a navigation pill (chatter ADVERSARY SEARCH +
   COLLECT NOW, breaches NEW LOOKUP). */
.btn.btn-quiet,
a.btn.btn-quiet,
a.btn.btn-quiet:hover {
  background: var(--bg-0);
  color: var(--ink-dim);
  border: 1px solid var(--border);
  box-shadow: none;
  text-shadow: none;
  border-bottom: 1px solid var(--border);
}
.btn.btn-quiet:hover {
  background: var(--bg-0);
  color: var(--ink-dim);
  border-color: var(--border);
  box-shadow: none;
  text-shadow: none;
}
/* Severity-count columns on scans + targets tables — tight, centered.
   Numeric counts only — kill border / background / box-shadow / animation
   inherited from the .sev base class so the cell is plain coloured text. */
td.sev-cell, th.sev-cell { text-align: center; font-variant-numeric: tabular-nums; min-width: 48px; width: 56px; }
td.sev-cell .sev {
  border: none;
  background: none;
  box-shadow: none;
  animation: none;
  padding: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
}
td.sev-cell .sev.critical { color: var(--sev-critical); }
td.sev-cell .sev.high     { color: var(--sev-high); }
td.sev-cell .sev.medium   { color: var(--sev-medium); }
td.sev-cell .sev.low      { color: var(--sev-low); }
td.sev-cell .sev.info     { color: var(--sev-info); }
.btn.ghost.danger                 { border-color: var(--red); color: var(--red); }
.btn.ghost.danger:hover           { background: var(--red); color: #000; }

/* ══════════════════════════════════════════════════════════════════════════
   FR-BULK-BAR — generic floating bulk-action strip (any table)
   Add/remove class "open" to show/hide. Use data-action on buttons.
   ══════════════════════════════════════════════════════════════════════════ */
.fr-bulk-bar {
  position: fixed; left: 50%; bottom: -80px;
  transform: translateX(-50%);
  min-width: 460px; max-width: 92vw;
  background: var(--bg-1);
  border: 1px solid var(--red);
  box-shadow: 0 -16px 40px rgba(0,0,0,.6), 0 0 48px rgba(168,85,247,.1);
  padding: 10px 16px;
  display: flex; align-items: center; gap: 12px;
  z-index: 9500;
  font-family: 'Geist Mono', monospace; font-size: 11px; letter-spacing: .06em;
  transition: bottom .22s cubic-bezier(.2,.8,.2,1);
}
.fr-bulk-bar.open { bottom: 24px; }
.fr-bulk-count    { font-weight: 600; color: var(--red-bright); min-width: 72px; }
.fr-bulk-label    { color: var(--ink-dim); font-size: 10px; }
.fr-bulk-actions  { display: flex; gap: 8px; align-items: center; margin-left: auto; }
/* row checkbox */
.row-sel, .select-all-cb {
  accent-color: var(--red); width: 14px; height: 14px; cursor: pointer; vertical-align: middle;
}
th:has(.select-all-cb), td:has(.row-sel) { width: 30px; padding: 0 8px; }

/* ══════════════════════════════════════════════════════════════════════════
   TEXT HELPERS — single-property utility tokens
   ══════════════════════════════════════════════════════════════════════════ */
.text-cyber { color: var(--cyber); }
.text-amber { color: var(--amber); }
.text-red   { color: var(--red-bright); }

/* ══════════════════════════════════════════════════════════════════════════
   API KEYS PAGE — migrated from api_keys.html inline <style>
   ══════════════════════════════════════════════════════════════════════════ */
.key-input { flex: 1; font-size: 12px; }
.key-card-set .value { color: var(--cyber); }
.key-section-label {
  font-size: 10px; letter-spacing: .25em; color: var(--ink-ghost);
  text-transform: uppercase; margin: 24px 0 10px;
  padding-bottom: 6px; border-bottom: 1px solid var(--border);
}
.key-section-label span          { color: var(--cyber); }
.key-section-label.unset span   { color: var(--ink-dim); }

/* ══════════════════════════════════════════════════════════════════════════
   CHATTER SEARCH — hit cards + sev-toggle + search input
   ══════════════════════════════════════════════════════════════════════════ */
.chatter-search-input {
  flex: 1; padding: 12px 16px; font-size: 1.1rem;
  font-family: var(--mono); background: var(--bg-0);
  border: 1px solid var(--red); color: var(--red-bright);
}
.hit-card { border-left: 4px solid transparent; padding: 10px 14px; }
.hit-card[data-sev="critical"] { border-left-color: var(--sev-critical); }
.hit-card[data-sev="high"]     { border-left-color: var(--sev-high); }
.hit-card[data-sev="medium"]   { border-left-color: var(--sev-medium); }
.hit-card[data-sev="low"]      { border-left-color: var(--sev-low); }
.hit-card[data-sev="info"]     { border-left-color: var(--sev-info); }
.sev-toggle         { opacity: .5; }
.sev-toggle.active  { opacity: 1; border-color: var(--red); color: var(--red); }

/* ══════════════════════════════════════════════════════════════════════════
   LIVE TERMINAL — live_scan.html progress bar + log pane + search
   ══════════════════════════════════════════════════════════════════════════ */
.bar-outer { background: var(--bg-0); border: 1px solid var(--border); height: 8px; width: 100%; }
.bar-inner  { background: linear-gradient(90deg, var(--red-deep), var(--red)); height: 100%; box-shadow: 0 0 8px var(--red-glow); transition: width .3s; }
.state.running   { color: var(--amber); }
.state.done      { color: var(--cyber); }
.state.error     { color: var(--red); }
.state.timeout   { color: var(--red); }
.state.cancelled { color: var(--ink-dim); }
.state.pending   { color: var(--ink-dim); }
.state.paused    { color: var(--amber); }
#log-pane .line          { padding: 2px 0; font-size: 12px; line-height: 1.6; }
#log-pane .level-error   { color: var(--red); }
#log-pane .level-warn    { color: var(--amber); }
#log-pane .level-info    { color: var(--ink); }
#log-pane .line .t       { color: var(--red-deep); margin-right: 8px; user-select: none; }
/* terminal search bar */
.terminal-search-wrap {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 6px;
}
.terminal-search-wrap .filter-bar { flex: 1; max-width: 360px; }
.terminal-match-count { font-size: 10px; color: var(--ink-dim); letter-spacing: .06em; min-width: 80px; }
.terminal-scroll-hint {
  font-size: 10px; color: var(--amber); letter-spacing: .06em;
  cursor: pointer; padding: 2px 8px; border: 1px solid var(--amber);
  background: none; font-family: inherit;
}
.terminal-scroll-hint:hover { background: rgba(255,176,0,.1); }

/* ══════════════════════════════════════════════════════════════════════════
   BRIEFING SKIN — full editorial override for client deliverables / PDF
   CSS variable overrides cascade to all var() references automatically.
   Specific element overrides handle hard-coded colors.
   Activated by body[data-skin="briefing"] (?skin=briefing or skin switcher).
   ══════════════════════════════════════════════════════════════════════════ */
body[data-skin="briefing"] {
  --bg-0: #ffffff; --bg-1: #f7f8fa; --bg-2: #eef0f4;
  --border: #d4d8e0; --red-deep: #e8d0d3;
  --ink: #1a1d24; --ink-dim: #4a5568; --ink-ghost: #6b7280;
  --red: #c92a2a; --red-bright: #e03131;
  --red-glow: transparent; --shadow-red: none;
  --shadow-card: 0 1px 3px rgba(0,0,0,.08);
  --amber: #c05800; --cyber: #0a7a52;
}
body[data-skin="briefing"]                    { color: var(--ink); background: var(--bg-0); }
body[data-skin="briefing"] .sidebar           { background: var(--bg-1); border-right-color: var(--border); }
body[data-skin="briefing"] .topbar            { background: var(--bg-1); border-bottom: 1px solid var(--border); }
body[data-skin="briefing"] nav a              { color: var(--ink-dim); }
body[data-skin="briefing"] nav a:hover,
body[data-skin="briefing"] nav a.active       { color: var(--red); background: rgba(201,42,42,.06); text-shadow: none; }
body[data-skin="briefing"] .card              { background: #fff; border-color: var(--border); box-shadow: var(--shadow-card); }
body[data-skin="briefing"] a                  { color: var(--red); border-bottom-color: var(--border); }
body[data-skin="briefing"] a:hover            { color: var(--red-bright); text-shadow: none; }
body[data-skin="briefing"] .btn.ghost         { border-color: var(--border); color: var(--ink-dim); }
body[data-skin="briefing"] code               { background: var(--bg-2); color: var(--ink); padding: 1px 4px; }
body[data-skin="briefing"] .terminal-pane     { background: var(--bg-2); border-color: var(--border); color: var(--ink); }
body[data-skin="briefing"] .fr-table th,
body[data-skin="briefing"] .recon th          { background: var(--bg-2); color: var(--ink); border-color: var(--border); }
body[data-skin="briefing"] .fr-table td,
body[data-skin="briefing"] .recon td,
body[data-skin="briefing"] .recon th          { border-color: var(--border); }
body[data-skin="briefing"] input,
body[data-skin="briefing"] select,
body[data-skin="briefing"] textarea           { background: var(--bg-1); color: var(--ink); border-color: var(--border); }
body[data-skin="briefing"] .ghost             { color: var(--ink-dim); }
body[data-skin="briefing"] .fr-warroom        { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   FR-BRIEF-BLOCK — executive summary section (briefing skin only)
   <section class="fr-brief-block">
     <div class="fr-brief-header">
       <h2 class="fr-brief-title">Executive Summary</h2>
       <span class="fr-brief-rating" data-risk="critical|high|medium|low|info">CRITICAL</span>
     </div>
     <div class="fr-brief-body">…</div>
     <div class="fr-brief-footer">Prepared by …</div>
   </section>
   Hidden by default; shown only when data-skin="briefing" is active.
   ══════════════════════════════════════════════════════════════════════════ */
.fr-brief-block                 { display: none; border: 1px solid var(--border); margin-bottom: var(--sp-6); overflow: hidden; }
body[data-skin="briefing"] .fr-brief-block { display: block; }
.fr-brief-header    { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: var(--sp-4) var(--sp-6); background: var(--bg-2); border-bottom: 1px solid var(--border); }
.fr-brief-title     { font-size: 0.8rem; letter-spacing: .14em; margin: 0; color: var(--ink-dim); }
.fr-brief-body      { padding: var(--sp-6); line-height: 1.7; font-size: 13px; max-width: 72ch; }
.fr-brief-footer    { padding: var(--sp-3) var(--sp-6); background: var(--bg-2); border-top: 1px solid var(--border); font-size: 10px; color: var(--ink-ghost); letter-spacing: .08em; }
.fr-brief-rating    { font-size: 10px; font-weight: 700; letter-spacing: .1em; padding: 3px 10px; white-space: nowrap; }
.fr-brief-rating[data-risk="critical"] { background: var(--sev-critical); color: #fff; }
.fr-brief-rating[data-risk="high"]     { background: var(--sev-high);     color: #fff; }
.fr-brief-rating[data-risk="medium"]   { background: var(--sev-medium);   color: #000; }
.fr-brief-rating[data-risk="low"]      { background: var(--sev-low);      color: #000; }
.fr-brief-rating[data-risk="info"]     { background: var(--sev-info);     color: #000; }
.fr-brief-stats     { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin-bottom: 16px; }
.fr-brief-stat      { padding: 12px 16px; background: var(--bg-1); border: 1px solid var(--border); }
.fr-brief-stat .label { font-size: 9px; letter-spacing: .15em; color: var(--ink-ghost); text-transform: uppercase; }
.fr-brief-stat .value { font-size: 1.4rem; font-weight: 700; color: var(--ink); margin-top: 4px; }
.fr-brief-stat .sub   { font-size: 10px; color: var(--ink-dim); margin-top: 2px; }

/* ══════════════════════════════════════════════════════════════════════════
   PRINT STYLESHEET — commit 22
   Strips operator chrome, forces page-break-aware layout, removes glow.
   ══════════════════════════════════════════════════════════════════════════ */
@media print {
  #matrix-rain, .sidebar, .sidebar-overlay, .fr-warroom, .fr-bulk-bar,
  .filter-bar, .terminal-search-wrap, .palette, .fr-segmented[data-fr-segmented="skin"],
  .sidebar-toggle, .topbar .user, .engagement-pill, .crumbs, canvas { display: none !important; }
  .shell   { grid-template-columns: 1fr !important; }
  .content { margin: 0 !important; padding: 24px 32px !important; max-width: 100% !important; }
  :root {
    --bg-0: #ffffff; --bg-1: #f7f8fa; --bg-2: #eef0f4; --border: #d4d8e0;
    --ink: #1a1d24; --ink-dim: #4a5568;
    --red: #c92a2a; --red-bright: #e03131; --red-glow: transparent; --shadow-red: none;
  }
  body                              { color: #1a1d24; background: #fff; }
  .fr-table, .recon                 { page-break-inside: auto; border-collapse: collapse; width: 100%; }
  .fr-table tr, .recon tr           { page-break-inside: avoid; }
  .fr-table th, .recon th           { background: #eef0f4 !important; color: #1a1d24 !important; border: 1px solid #d4d8e0 !important; }
  .fr-table td, .recon td           { border: 1px solid #d4d8e0 !important; }
  .card                             { box-shadow: none !important; border: 1px solid #d4d8e0 !important; page-break-inside: avoid; }
  h1, h2, h3, h4                    { page-break-after: avoid; text-shadow: none !important; color: #1a1d24 !important; }
  a                                 { color: #c92a2a !important; border: none !important; text-decoration: none !important; }
  a[href^="http"]::after            { content: " (" attr(href) ")"; font-size: 9px; color: #6b7280; }
  a[href^="/"]::after               { content: ""; }
  .fr-brief-block                   { display: block !important; }
  .glitch::before, .glitch::after,
  .blink::after, body::before, body::after { display: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   AI PICKER — inline provider+model selector next to AI buttons
   ══════════════════════════════════════════════════════════════════════════ */
.ai-picker {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px;
  border: 1px solid var(--cyber);
  background: rgba(0,255,159,.04);
  font-family: 'Geist Mono', monospace; font-size: 10px;
  letter-spacing: .05em;
}
.ai-picker label { color: var(--cyber); margin: 0; font-size: 9px; letter-spacing: .12em; }
.ai-picker select {
  background: var(--bg-0); border: 1px solid var(--border);
  color: var(--ink); padding: 2px 6px; font-size: 11px;
  font-family: inherit; min-width: 100px; max-width: 220px;
}
.ai-picker select:focus { border-color: var(--cyber); outline: none; }
.ai-result-meta {
  font-size: 10px; color: var(--cyber); letter-spacing: .06em;
  margin-top: 6px; opacity: .85;
}



/* ============================================================================
   PREMIUM COMMAND-CENTER REFINEMENT LAYER — added 2026-06-12
   Dials the heavy hacker-terminal styling toward an enterprise security
   console (CrowdStrike/Wiz/SentinelOne register): removes the cosplay
   overlays (matrix rain, CRT scanlines, blink, glitch echoes), softens the
   sharp DOS corners, and trades neon glow for real depth — while keeping the
   violet brand identity and the semantic severity palette intact.

   Appended LAST so it wins on equal specificity. Scoped away from the
   briefing skin (which has its own light theme). Pure visual layer — no
   layout/markup dependencies, fully revertible by deleting this block.
   ============================================================================ */

:root{
  --radius-sm: 8px;
  --radius:    12px;
  --radius-lg: 18px;
  --elev-1: 0 1px 2px rgba(0,0,0,.45), 0 2px 10px rgba(0,0,0,.35);
  --elev-2: 0 8px 24px rgba(0,0,0,.55), 0 18px 60px rgba(0,0,0,.40);
  --hairline: rgba(255,255,255,.06);
  --surface-1: linear-gradient(180deg, #13162200 0%, #0d0f18 100%), #11131d;
  --surface-2: linear-gradient(180deg, #121524 0%, #0d0f1a 100%);
}

/* ── 1. Kill the cosplay overlays ─────────────────────────────────────── */
#matrix-rain{ display:none !important; }

/* CRT scanlines + heavy vignette  →  a single soft top-down vignette */
body::before{
  background: radial-gradient(140% 130% at 50% -10%, transparent 66%, rgba(0,0,0,.40) 100%) !important;
  mix-blend-mode: normal !important;
  opacity: 1 !important;
}
/* faint structural grid — keep as texture, but quiet it right down */
body::after{ opacity:.30 !important; background-size:74px 74px !important; }

/* harsh on/off blink  →  gentle "alive" pulse */
@keyframes fr-soft-pulse{ 0%,100%{opacity:1} 50%{opacity:.45} }
.blink{ animation: fr-soft-pulse 2.4s ease-in-out infinite !important; }
.glitch, .login-box .logo{ text-shadow:none !important; }

/* ── 2. Surfaces: round the corners, swap glow for depth ──────────────── */
body:not([data-skin="briefing"]) .card,
body:not([data-skin="briefing"]) .fr-card,
body:not([data-skin="briefing"]) .fr-sitrep,
body:not([data-skin="briefing"]) .fr-sevribbon,
body:not([data-skin="briefing"]) .table-wrap,
body:not([data-skin="briefing"]) .login-box{
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--elev-1);
}
.card, .fr-card, .fr-sitrep, .fr-sevribbon, .table-wrap,
.login-box, .fr-hero{ border-radius: var(--radius); }

/* drop the L-shaped corner ticks on metric cards (both card systems) */
.card::before, .card::after,
.fr-card::before, .fr-card::after{ display:none !important; }
/* keep .fr-card hover consistent with the calm .card hover — no neon box */
body:not([data-skin="briefing"]) .fr-card:hover{
  border-color: var(--brand-border) !important;
  box-shadow: var(--elev-2) !important;
  transform: translateY(-2px);
}

/* metric cards: calm border + real lift on hover (no neon box) */
.card{ padding:18px 20px; transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease; }
.card:hover{
  border-color: var(--brand-border) !important;
  box-shadow: var(--elev-2) !important;
  transform: translateY(-2px);
}
.card .title{ color: var(--ink-ghost); letter-spacing:.16em; }
.card .value{ text-shadow:none !important; }
.card[data-tone="critical"]{ box-shadow: var(--elev-1), inset 0 0 0 1px rgba(185,28,28,.35) !important; }

/* clickable cards shouldn't underline */
a.card, a.card:hover{ text-decoration:none; }

/* ── 3. Buttons: pill radius, filled-gradient primary, calm ghost ─────── */
.btn, button.btn, a.btn{
  border-radius: var(--radius-sm) !important;
  text-transform: none;
  letter-spacing: .04em;
  font-weight: 600;
  font-family: var(--font-display);
  border-bottom-width: 1px;
}
.btn:not(.ghost){
  background: linear-gradient(180deg, var(--red-bright), var(--red-deep));
  color:#fff !important;
  border:1px solid transparent !important;
  box-shadow: var(--elev-1);
  text-shadow:none;
}
.btn:not(.ghost):hover{
  background: linear-gradient(180deg, var(--red-bright), var(--red));
  color:#fff !important;
  box-shadow: var(--elev-2), 0 0 0 1px var(--brand-glow);
  transform: translateY(-1px);
}
a.btn:not(.ghost), a.btn:not(.ghost):hover{ border-bottom:1px solid transparent !important; }
.btn.ghost{
  background: rgba(255,255,255,.02);
  border:1px solid var(--border) !important;
  color: var(--ink-dim) !important;
  box-shadow:none;
}
.btn.ghost:hover{
  border-color: var(--brand-border) !important;
  color: var(--ink) !important;
  background: rgba(168,85,247,.10);
}

/* ── 4. Inputs: rounded, soft focus ring ──────────────────────────────── */
input[type=text], input[type=password], input[type=email],
input[type=number], textarea, select{
  border-radius: var(--radius-sm) !important;
  background: rgba(8,9,14,.85) !important;
  transition: border-color .15s ease, box-shadow .15s ease !important;
}
input[type=text]:focus, input[type=password]:focus, input[type=email]:focus,
input[type=number]:focus, textarea:focus, select:focus{
  outline:none !important;
  border-color: var(--red) !important;
  box-shadow: 0 0 0 3px var(--red-glow-2) !important;
}

/* ── 5. Sidebar + topbar: calm enterprise nav ─────────────────────────── */
.sidebar{ background: var(--surface-2); border-right:1px solid var(--hairline); }
.sidebar .brand{ text-shadow:none; letter-spacing:.06em; }
.sidebar nav a{
  border-radius: var(--radius-sm);
  border-left:0 !important;
  text-transform: none;
  letter-spacing:.02em;
  font-weight: 500;
  font-size: 12.5px;
  color: var(--ink-dim) !important;
  margin:2px 0;
}
.sidebar nav a:hover, .sidebar nav a.active{
  background: rgba(168,85,247,.12);
  color: var(--ink) !important;
  text-shadow:none;
  box-shadow: inset 2px 0 0 var(--red);
}
.nav-divider{ text-transform:uppercase; }
.topbar{ border-bottom:1px solid var(--hairline); }
.topbar .user span{ color: var(--ink); }

/* ── 6. Tables: rounded container, quieter rules ──────────────────────── */
.table-wrap{ overflow:hidden; }
table.recon th{ background: rgba(255,255,255,.02); color: var(--ink-ghost); }
table.recon td{ border-bottom:1px solid var(--hairline); }
table.recon tr:hover td{ background: rgba(168,85,247,.06); }

/* ── 7. Severity ribbon + bars get rounded ends ───────────────────────── */
.sev-bar{ border-radius: 999px; overflow:hidden; }
.fr-hero, .fr-sitrep{ border:1px solid var(--hairline); }

/* ── 8. Login: premium auth card ──────────────────────────────────────── */
/* soft violet pool behind the card so it doesn't float in the void */
.login-wrap{
  background:
    radial-gradient(60% 48% at 50% 36%, rgba(168,85,247,.14), transparent 72%),
    radial-gradient(80% 60% at 50% 120%, rgba(124,58,237,.10), transparent 70%);
}
.login-box{
  background: linear-gradient(180deg, #181c2b 0%, #0f111c 100%) !important;
  border:1px solid #30344a !important;
  box-shadow:
    0 24px 80px rgba(0,0,0,.70),
    inset 0 1px 0 rgba(255,255,255,.05),
    0 0 0 1px rgba(168,85,247,.10),
    0 0 90px rgba(168,85,247,.12) !important;
  padding:42px 38px 30px !important;
}
.login-box::before, .login-box::after{ display:none !important; }
.login-box .logo{
  font-weight:800; letter-spacing:.14em; font-family: var(--font-display);
  color:#ffffff !important;
  text-shadow: 0 0 22px rgba(168,85,247,.50) !important;
}
.login-box .sub-logo{ color:#9a95ac !important; letter-spacing:.34em; }
.login-box label{ color:#d8d5e6 !important; }
.login-box input{ background: rgba(6,7,11,.9) !important; border-color:#33374b !important; min-height:44px; padding:11px 14px !important; }
.login-box .banner{
  border:1px solid var(--hairline); border-radius: var(--radius-sm);
  background: rgba(255,255,255,.02); letter-spacing:.06em;
}
.login-box label{ text-transform:none !important; letter-spacing:.04em; color: var(--ink-dim); }

/* primary CTA: one obvious full-width action, properly sized for touch */
.login-submit{
  display:block; width:100%;
  padding:13px 20px !important;
  min-height:46px;
  font-size:13px !important;
  letter-spacing:.08em !important;
}
.login-status-row{
  display:flex; align-items:center; justify-content:center; gap:7px;
  margin-top:16px;
  font-size:10px; letter-spacing:.1em;
}


/* ── 10. Misc: kill stray neon text-shadows on headings ───────────────── */
body:not([data-skin="briefing"]) h1,
body:not([data-skin="briefing"]) h2{ text-shadow:none; }

/* ── 11. Critical-as-TEXT legibility ──────────────────────────────────────
   #B91C1C reads ~2.9:1 as text on near-black (fails AA) — and critical is the
   one severity that must POP, not recede. Repoint every TEXT/foreground use of
   critical to --sev-critical-fg (brighter same-hue red, ~5.9:1). Badge/pill
   BACKGROUNDS, borders, glows, and left-rails keep #B91C1C untouched (white
   text on them stays well above AA). One place to tune; easy to revert.
   Excludes filled badges (.sev.critical / .fr-pill / .dorks-sev-chip.active /
   .fr-brief-rating) where the dark red is the BACKGROUND. */
body:not([data-skin="briefing"]) .card[data-tone="critical"] .value,
body:not([data-skin="briefing"]) .fr-graph-controls .fr-graph-sevsummary .seg.sev-critical,
body:not([data-skin="briefing"]) .fr-graph-detail .sev-pill.sev-critical,
body:not([data-skin="briefing"]) .fr-sitrep .sitrep-body .sitrep-item .n.crit,
body:not([data-skin="briefing"]) .fr-tabs > button[data-tone="critical"],
body:not([data-skin="briefing"]) .fr-tabs > button[aria-selected="true"][data-tone="critical"],
body:not([data-skin="briefing"]) .dork-card.sev-critical .dork-card-sev,
body:not([data-skin="briefing"]) .dorks-feed-expand-row.sev-critical .dorks-feed-expand-sev,
body:not([data-skin="briefing"]) .dork-preview-cat .sev.critical,
body:not([data-skin="briefing"]) .t-crit,
body:not([data-skin="briefing"]) .t-err,
body:not([data-skin="briefing"]) .boot-seq .crit,
body:not([data-skin="briefing"]) .fr-drawer-log .level-error,
body:not([data-skin="briefing"]) .tc-top-badge,
body:not([data-skin="briefing"]) .tc-bar-row[data-sev="critical"] .tc-bar-n,
body:not([data-skin="briefing"]) tr[data-sev="critical"] td:first-child,
body:not([data-skin="briefing"]) .sev-badge.critical,
body:not([data-skin="briefing"]) table.recon th.th-crit,
body:not([data-skin="briefing"]) table.recon td.td-crit {
  color: var(--sev-critical-fg) !important;
}
/* threat-hot already uses !important; match specificity */
body:not([data-skin="briefing"]) .wr-threat-hot { color: var(--sev-critical-fg) !important; }
/* graph node labels use SVG fill, not color */
body:not([data-skin="briefing"]) #graph-viewport .node.sev-critical .node-label { fill: var(--sev-critical-fg); }

/* ── 11b. High-as-TEXT legibility ─────────────────────────────────────────
   Same fix as §11 for HIGH: #EF4444 reads ~4.0:1 as text on near-black (just
   under AA). Repoint TEXT / foreground / outline-badge uses of high to
   --sev-high-fg. Filled badges where high is the BACKGROUND
   (.fr-brief-rating[data-risk=high], .dorks-sev-chip.active, .rel-sev,
   .b-high ribbon, .tc-bar-fill) keep #EF4444 untouched. */
body:not([data-skin="briefing"]) .sev.high,
body:not([data-skin="briefing"]) .fr-pill[data-tone="high"],
body:not([data-skin="briefing"]) .card[data-tone="high"] .value,
body:not([data-skin="briefing"]) .fr-graph-controls .fr-graph-sevsummary .seg.sev-high,
body:not([data-skin="briefing"]) .fr-graph-detail .sev-pill.sev-high,
body:not([data-skin="briefing"]) .fr-tabs > button[data-tone="high"],
body:not([data-skin="briefing"]) .dork-card.sev-high .dork-card-sev,
body:not([data-skin="briefing"]) .dorks-feed-expand-row.sev-high .dorks-feed-expand-sev,
body:not([data-skin="briefing"]) .dork-preview-cat .sev.high,
body:not([data-skin="briefing"]) .t-high,
body:not([data-skin="briefing"]) .tc-bar-row[data-sev="high"] .tc-bar-label,
body:not([data-skin="briefing"]) .tc-bar-row[data-sev="high"] .tc-bar-n,
body:not([data-skin="briefing"]) tr[data-sev="high"] td:first-child,
body:not([data-skin="briefing"]) .sev-badge.high,
body:not([data-skin="briefing"]) table.recon th.th-high,
body:not([data-skin="briefing"]) table.recon td.td-high,
body:not([data-skin="briefing"]) td.sev-cell .sev.high,
body:not([data-skin="briefing"]) .fr-toast[data-tone="error"] .fr-toast-label {
  color: var(--sev-high-fg) !important;
}
body:not([data-skin="briefing"]) #graph-viewport .node.sev-high .node-label { fill: var(--sev-high-fg); }

/* ── 12. AI citations + grounding (ai_citations.js) ───────────────────────
   Clickable evidence tokens in grounded AI answers, the grounding badge, and
   the RBAC-gated action buttons the analyst proposes. */
.ai-answer { white-space: pre-wrap; line-height: 1.55; max-width: 72ch; }
a.cite {
  display: inline-block;
  font-family: var(--font-num);
  font-size: .82em;
  font-weight: 600;
  letter-spacing: .02em;
  padding: 0 4px;
  margin: 0 1px;
  border-radius: 4px;
  color: var(--red-bright);
  background: rgba(168,85,247,.12);
  border: 1px solid var(--brand-border);
  text-decoration: none;
  vertical-align: baseline;
  transition: background .12s ease, color .12s ease;
}
a.cite:hover { background: var(--red); color: #fff; border-color: var(--red); }
.cite-bad {
  font-family: var(--font-num);
  font-size: .82em;
  padding: 0 4px;
  border-radius: 4px;
  color: var(--sev-critical-fg);
  background: rgba(255,90,96,.10);
  border: 1px dashed var(--sev-critical-fg);
  cursor: help;
}
.ground-badge {
  display: inline-block;
  margin-top: 10px;
  font-family: var(--font-num);
  font-size: 10.5px;
  letter-spacing: .04em;
  padding: 2px 9px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
}
.ground-badge.ok   { color: var(--cyber); border-color: rgba(0,255,159,.30); background: rgba(0,255,159,.06); }
.ground-badge.warn { color: var(--amber); border-color: rgba(255,176,0,.30); background: rgba(255,176,0,.07); }
.ai-action-bar { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; align-items: center; }
.ai-action-bar .ai-action-hint { font-size: 10.5px; color: var(--ink-ghost); letter-spacing: .04em; }
.ai-action-btn { font-size: 10px !important; }

