/* ============================================================================
   briefviz.css — shared visualization core for oxint.io intelligence briefs
   ----------------------------------------------------------------------------
   W0-VIZCORE scaffold. Tokens mirror the existing brief design system EXACTLY
   (see briefs/*/index.html :root and the appended .tag.* confidence classes).
   NO external @import, NO font fetch — JetBrains Mono is already loaded by the
   host brief page; we only *reference* it as a fallback-chained family.
   Every component (bv-table/bv-bar/bv-donut/bv-timeline/bv-network/bv-map)
   renders inside .bv-box, which reserves layout height up front so CLS == 0.
   ========================================================================== */

:root {
  /* --- Canonical brief hex tokens (verbatim from the brief design system) --- */
  --bv-void: #07070b;        /* page chrome / panel background        */
  --bv-accent: #00b4ff;      /* primary accent (links, axes)          */
  --bv-mark: #00ff88;        /* signal / positive highlight           */
  --bv-red: #f05060;         /* critical / danger                     */
  --bv-gold: #e8b84a;        /* estimated / high-confidence amber      */

  /* --- Confidence palette: maps 1:1 to the existing .tag.* classes -------- */
  /* conf = Confirmed, rep = Reported, hi = High, est = Estimated, crit = Critical */
  --bv-conf: #2dd4a0;        /* matches .tag.conf (var(--green))      */
  --bv-rep: #a7a7b8;         /* matches .tag.rep                       */
  --bv-hi: #e8b84a;          /* matches .tag.hi (var(--gold))         */
  --bv-est: #e8b84a;         /* matches .tag.est                       */
  --bv-crit: #f05060;        /* matches .tag.crit (var(--red))        */

  /* --- Neutral scale (kept in-family with brief --line/--mute/--text) ----- */
  --bv-line: rgba(255, 255, 255, .09);
  --bv-line-2: rgba(255, 255, 255, .14);
  --bv-mute: rgba(255, 255, 255, .32);
  --bv-text: rgba(255, 255, 255, .7);
  --bv-bright: rgba(255, 255, 255, .85);
  --bv-panel: rgba(5, 5, 8, .6);

  /* --- Typography: reference only; no fetch. JetBrains Mono is host-loaded. */
  --bv-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* --- Motion / timing (respected unless prefers-reduced-motion) ---------- */
  --bv-ease: .4s cubic-bezier(.2, .6, .2, 1);
}

/* ----------------------------------------------------------------------------
   .bv-box — the zero-CLS container.
   Authors set an aspect-ratio (default 16/9) OR an explicit --bv-h height.
   Height is reserved BEFORE any JS runs, so enhancement never reflows.
   -------------------------------------------------------------------------- */
.bv-box {
  position: relative;
  width: 100%;
  background: var(--bv-panel);
  border: 1px solid var(--bv-line);
  /* aspect-ratio reserves vertical space immediately -> CLS = 0 */
  aspect-ratio: var(--bv-aspect, 16 / 9);
  /* when an author needs a fixed pixel height (e.g. maps), they set --bv-h;
     min-height then wins and aspect-ratio becomes a no-op floor. */
  min-height: var(--bv-h, 0px);
  overflow: hidden;
  contain: layout paint;
}

/* A box that has been hydrated by a component flips this attribute on.
   Until then the fallback content (table / ol) shows through. */
.bv-box[data-bv-ready='1'] > .bv-fallback {
  display: none;
}

/* Fallback content (the source <table>/<ol>) is the progressive-enhancement
   floor: visible with no JS, hidden once a component takes over. */
.bv-fallback {
  display: block;
  width: 100%;
  height: 100%;
  overflow: auto;
}

/* ----------------------------------------------------------------------------
   bvBadge confidence chip.
   These chips ONLY restyle text that already exists in the source brief
   (Confirmed / Reported / Unverified / High / Estimated / Critical). The JS
   in _core.js refuses to emit any chip whose label is absent from the source,
   so the visual layer can never invent a confidence claim. CSS just paints.
   -------------------------------------------------------------------------- */
.bv-badge {
  display: inline-block;
  font-family: var(--bv-mono);
  font-size: .65rem;
  line-height: 1.4;
  padding: 2px 8px;
  border-radius: 4px;
  letter-spacing: 1px;
  text-transform: uppercase;
  white-space: nowrap;
  border: 1px solid transparent;
  vertical-align: baseline;
}

/* One class per canonical confidence level — visually identical to .tag.* */
.bv-badge--conf { background: rgba(45, 212, 160, .15); color: var(--bv-conf); border-color: rgba(45, 212, 160, .25); }
.bv-badge--rep  { background: rgba(138, 138, 154, .16); color: var(--bv-rep); border-color: rgba(138, 138, 154, .22); }
.bv-badge--hi   { background: rgba(232, 184, 74, .15); color: var(--bv-hi); border-color: rgba(232, 184, 74, .2); }
.bv-badge--est  { background: rgba(232, 184, 74, .12); color: var(--bv-est); border-color: rgba(232, 184, 74, .2); }
.bv-badge--crit { background: rgba(240, 80, 96, .15); color: var(--bv-crit); border-color: rgba(240, 80, 96, .25); }

/* ----------------------------------------------------------------------------
   Shared component primitives (consumed by bv-table/bv-bar/... in W1-VIZ-*).
   Kept here so per-component files stay tiny and the core owns the look.
   -------------------------------------------------------------------------- */
.bv-caption {
  font-family: var(--bv-mono);
  font-size: .7rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--bv-mute);
  padding: 8px 0;
}

.bv-svg { display: block; width: 100%; height: 100%; }

.bv-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 8px 0;
  font-family: var(--bv-mono);
  font-size: .7rem;
  color: var(--bv-mute);
}

.bv-controls button,
.bv-controls input[type='search'] {
  font-family: var(--bv-mono);
  font-size: .7rem;
  color: var(--bv-text);
  background: rgba(255, 255, 255, .03);
  border: 1px solid var(--bv-line-2);
  border-radius: 2px;
  padding: 4px 10px;
  cursor: pointer;
  transition: border-color var(--bv-ease), color var(--bv-ease);
}

.bv-controls button:hover,
.bv-controls input[type='search']:focus {
  border-color: var(--bv-accent);
  color: var(--bv-bright);
  outline: none;
}

/* Visible focus ring for keyboard users — accessibility floor. */
.bv-box :focus-visible,
.bv-controls :focus-visible {
  outline: 2px solid var(--bv-accent);
  outline-offset: 2px;
}

/* Screen-reader-only helper for live regions / sort announcements. */
.bv-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ----------------------------------------------------------------------------
   Accessibility overrides
   -------------------------------------------------------------------------- */

/* Honor reduced-motion: kill all transitions/animations inside viz. */
@media (prefers-reduced-motion: reduce) {
  .bv-box *,
  .bv-controls * {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

/* Honor increased-contrast: stronger borders, opaque chip fills. */
@media (prefers-contrast: more) {
  .bv-box { border-color: var(--bv-line-2); }
  .bv-badge { border-width: 1px; font-weight: 600; }
  .bv-badge--conf { background: #0a2a22; color: #5fe8c0; }
  .bv-badge--rep  { background: #1a1a22; color: #c9c9d6; }
  .bv-badge--hi,
  .bv-badge--est  { background: #2a2410; color: #ffd770; }
  .bv-badge--crit { background: #2a1014; color: #ff8a96; }
  .bv-controls button,
  .bv-controls input[type='search'] { border-color: var(--bv-line-2); }
}

/* Forced-colors (Windows High Contrast) — let the OS palette take over. */
@media (forced-colors: active) {
  .bv-box,
  .bv-badge,
  .bv-controls button { border: 1px solid CanvasText; }
  .bv-svg { forced-color-adjust: none; }
}

/* Print: never lose the fallback data. */
@media print {
  .bv-box[data-bv-ready='1'] > .bv-fallback { display: block; }
  .bv-controls { display: none; }
}
