/* cyber.panotechgrp.com — blueprint stylesheet.
 * Design contract: docs/adr/010-dashboard-design-system.md.
 * ALL colour lives here as tokens (the page ships zero inline styles under
 * CSP style-src 'self'). ONE accent — zones are distinguished by eyebrow +
 * band alternation + numbering, never by extra hues (ADR 010 §8). No
 * gradients. RED appears in exactly one place: the Infocon scale. An
 * unavailable feed is GREY. Accent + status colours validated (dataviz
 * six-checks) 2026-07-16. */

:root {
  /* GROUND — anchored on the parent site's authoritative #0a1a3c */
  --pt-base: #0a1a3c;
  --pt-dark: #0c1e42;
  --pt-accent: #143a75;
  --pt-kinetic: #2b6eda;      /* the single bright accent — marks + text-on-light (4.8:1) */
  --pt-kinetic-text: #6699ee; /* the accent AS TEXT on navy — 5.9:1, WCAG AA for small text */
  --pt-surface: #f8f9fa;
  --pt-surface-2: #e9ecef;
  --pt-ink: #1a1a1a;

  /* Text on navy */
  --ink-on-navy: #f0f3f8;
  --muted-on-navy: #93a1bd;
  --rule-on-navy: #24365e;

  /* Text on paper */
  --muted-on-light: #5a6478;
  --rule-on-light: #d8dde6;

  /* STATUS — functional only, always paired with a text label */
  --pt-live: #10b981;
  --pt-stale: #d97706;
  --pt-down: #64748b;      /* deliberately GREY: a broken feed is not a threat */

  /* INFOCON — the ONLY place red is permitted on this site */
  --pt-infocon-green: #10b981;
  --pt-infocon-yellow: #eab308;
  --pt-infocon-orange: #f97316;
  --pt-infocon-red: #dc2626;

  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { font-size: 16px; }

body {
  font-family: var(--font-sans);
  color: var(--pt-ink);
  background: var(--pt-base);
  line-height: 1.55;
}

.wrap { max-width: 60rem; margin: 0 auto; padding: 0 1.25rem; }

/* ── Bands: full-width sections in sequence (no bento). Alternation is set
   explicitly per band; every band carries the faint blueprint grid — an SVG
   data-URI tile of two hairlines (NOT a repeating-gradient, so "no gradients
   anywhere" stays literally true), permitted by img-src 'self' data:. Each
   band scopes the text tokens its components consume, so one component set
   serves navy and paper grounds alike. ──────────────────────────────────── */
.band {
  padding: 3rem 0;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='32'%20height='32'%3E%3Cpath%20d='M0%20.5H32M.5%200V32'%20fill='none'%20stroke='%23ffffff'%20stroke-opacity='.045'/%3E%3C/svg%3E");
  background-size: 32px 32px;
  color: var(--band-ink);
}
.band-navy, .band-dark {
  --band-ink: var(--ink-on-navy);
  --band-muted: var(--muted-on-navy);
  --band-rule: var(--rule-on-navy);
  --band-accent-text: var(--pt-kinetic-text);
}
.band-navy { background-color: var(--pt-base); }
.band-dark { background-color: var(--pt-dark); }
.band-light {
  --band-ink: var(--pt-ink);
  --band-muted: var(--muted-on-light);
  --band-rule: var(--rule-on-light);
  --band-accent-text: var(--pt-kinetic); /* 4.8:1 on paper — AA for small text */
  background-color: var(--pt-surface);
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='32'%20height='32'%3E%3Cpath%20d='M0%20.5H32M.5%200V32'%20fill='none'%20stroke='%230a1a3c'%20stroke-opacity='.05'/%3E%3C/svg%3E");
}

.band-hero { padding: 3.5rem 0 2.5rem; border-bottom: 1px solid var(--rule-on-navy); }

.brand {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.18em;
  color: var(--band-muted);
}
.brand-sub { letter-spacing: 0.06em; text-transform: none; }

h1 { font-size: 2.4rem; font-weight: 700; margin: 0.5rem 0 0.75rem; letter-spacing: -0.01em; }
h2 { font-size: 1.5rem; font-weight: 650; margin: 0.35rem 0 1.25rem; }
h3.subhead {
  font-size: 0.95rem; font-weight: 600; letter-spacing: 0.04em;
  margin: 2rem 0 0.75rem; color: var(--band-ink);
}
.unit { color: var(--band-muted); font-weight: 400; }

.thesis { max-width: 44rem; color: var(--band-muted); }

/* Eyebrow — the parent site's section pattern; the ONE accent does the zoning */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--band-accent-text);
  border-left: 2px solid var(--pt-kinetic);
  padding-left: 0.6rem;
}

/* ── Readings: value + label + provenance, always on the face ──────────── */
.stat-row, .reading-row { display: flex; flex-wrap: wrap; gap: 2.5rem; margin: 1.5rem 0 0.5rem; }
.reading-row { gap: 2rem; align-items: flex-start; }
.reading { max-width: 20rem; }
.reading-value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 2rem;
  font-weight: 600;
  line-height: 1.15;
}
.reading-label { color: var(--band-muted); font-size: 0.9rem; max-width: 18rem; }
.reading-down .reading-value { color: var(--band-muted); }
/* Trend arrow — INK, never red: a rising ransomware count is reported calmly
   (red is reserved for the Infocon scale). Direction + aria-label carry the
   meaning, so it is never colour-alone. */
.trend { color: var(--band-ink); font-size: 0.6em; vertical-align: 0.15em; }

.stat-value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 2.6rem;
  font-weight: 600;
  line-height: 1.1;
}
.stat-label { color: var(--band-muted); font-size: 0.9rem; }

/* ── The one orchestrated moment (ADR 010 §5): headline figures count up
   once on load, then the page is still. Zero JavaScript — a registered
   integer custom property animates 0 → the value read from data-count via
   typed attr(), rendered through counter(). Layered fallbacks:
     · unsupported browsers: the @supports gate fails → the formatted
       .stat-text span renders immediately (the ADR's required fallback)
     · prefers-reduced-motion: the global animation kill leaves the counter
       pseudo at its base visibility:hidden and the span visible —
       final value, no motion
     · after the run: the counter hides and the comma-formatted text takes
       over (the number "locks in") ─────────────────────────────────────── */
@property --nv {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

@supports (width: attr(data-w type(<length>), 0px)) {
  .stat-value { position: relative; }
  /* visibility (not display) gates the two layers: a display:none pseudo
     never starts its animations — a deadlock — while hidden boxes animate
     fine. The counter overlays the concealed span absolutely, so the layout
     is reserved by the final formatted value and nothing shifts. */
  .stat-value::before {
    --nv: attr(data-count type(<integer>), 0);
    counter-reset: nv calc(var(--nv));
    content: counter(nv);
    position: absolute;
    left: 0;
    top: 0;
    visibility: hidden; /* base: hidden (no-support/reduced-motion/after-run) */
    animation:
      nv-run 1.2s cubic-bezier(0.16, 1, 0.3, 1),
      nv-visible 1.2s steps(1, end);
  }
  .stat-value .stat-text {
    animation: nv-concealed 1.2s steps(1, end);
  }
}
@keyframes nv-run { from { --nv: 0; } }
@keyframes nv-visible { from, to { visibility: visible; } }
@keyframes nv-concealed { from, to { visibility: hidden; } }

.provenance {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--band-muted);
  border-top: 1px solid var(--band-rule);
  padding-top: 0.75rem;
  margin-top: 1.25rem;
}
.provenance a { color: var(--band-accent-text); }

.status { white-space: nowrap; }
.dot {
  display: inline-block; width: 0.55em; height: 0.55em; border-radius: 50%;
  margin-right: 0.35em; vertical-align: baseline;
}
.dot-live { background: var(--pt-live); }
.dot-stale { background: var(--pt-stale); }
.dot-down { background: var(--pt-down); }

.stale-note, .down-msg { color: var(--band-muted); max-width: 44rem; }
.reading-down { padding: 0.5rem 0 0; }

/* ── Infocon: a four-step categorical scale, never a needle. The level
   colours ARE the scale — and this is the only red on the site. ─────────── */
.infocon { margin: 1rem 0 2rem; }
.infocon-scale {
  list-style: none;
  display: flex;
  gap: 0.5rem;
  max-width: 36rem;
}
.infocon-step {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  color: var(--band-muted);
  border-top: 4px solid var(--band-rule);
  padding-top: 0.5rem;
  position: relative;
}
.infocon-step.step-green { border-top-color: var(--pt-infocon-green); }
.infocon-step.step-yellow { border-top-color: var(--pt-infocon-yellow); }
.infocon-step.step-orange { border-top-color: var(--pt-infocon-orange); }
.infocon-step.step-red { border-top-color: var(--pt-infocon-red); }
.infocon-step.on { color: var(--band-ink); font-weight: 700; }
.infocon-marker { position: absolute; top: -0.35rem; left: 45%; font-size: 0.7rem; color: var(--band-ink); }
.infocon-days {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--band-muted);
  font-size: 0.85rem;
  margin-top: 0.5rem;
}

/* ── Mono table (networks) ─────────────────────────────────────────────── */
.mono-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.9rem;
}
.mono-table caption.sr-only { position: absolute; clip: rect(0 0 0 0); }
.mono-table th, .mono-table td {
  text-align: left; padding: 0.45rem 0.75rem 0.45rem 0;
  border-bottom: 1px solid var(--band-rule);
}
.mono-table thead th {
  font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--band-muted); font-weight: 600;
}
.mono-table tbody th { font-weight: 400; }
.mono-table .n { text-align: right; }
.conc { color: var(--band-accent-text); }
.note { color: var(--band-muted); font-size: 0.82rem; margin-top: 0.6rem; max-width: 44rem; }

/* ── KEV: a REAL ranked sequence, so the 01–05 numbering is earned ──────── */
.kev-list { list-style: none; max-width: 44rem; margin-top: 1rem; }
.kev-list li {
  display: grid;
  grid-template-columns: 2rem 1fr auto auto;
  gap: 0.75rem;
  align-items: baseline;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--band-rule);
  font-size: 0.95rem;
}
.kev-n {
  font-family: var(--font-mono);
  color: var(--band-accent-text);
  font-size: 0.85rem;
}
.kev-what { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kev-cve, .kev-added {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  color: var(--band-muted);
  white-space: nowrap;
}

/* ── FTC + the pull-quote tip (parent-site blockquote pattern) ──────────── */
.ftc-title { font-size: 1.15rem; font-weight: 600; max-width: 36rem; }
.ftc-title a { color: var(--band-ink); text-decoration-color: var(--pt-kinetic); }
.tip {
  border-left: 3px solid var(--pt-kinetic);
  padding-left: 1rem;
  margin-top: 2rem;
  max-width: 40rem;
  color: var(--band-ink);
}
.tip p { margin: 0.35rem 0; }
.tip p[lang="es"] { color: var(--band-muted); }

/* ── Ranked lists (categories, countries, auth adoption) ───────────────── */
.rank-list { list-style: none; max-width: 36rem; }
.rank-list li {
  display: grid;
  grid-template-columns: 12rem 1fr 4.5rem;
  align-items: center;
  gap: 0.75rem;
  padding: 0.3rem 0;
}
.rank-key {
  font-family: var(--font-mono); font-size: 0.85rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rank-bar { width: 100%; height: 6px; display: block; }
.rank-val {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 0.85rem; text-align: right;
}

/* ── Charts (SVG classes; geometry is attributes, colour is here) ──────── */
.bar { fill: var(--pt-kinetic); }
.bar-zero { fill: var(--band-rule); }
.bar-label {
  fill: var(--band-ink);
  font-family: var(--font-mono); font-size: 16px;
  font-variant-numeric: tabular-nums;
}
.axis-line { stroke: var(--band-rule); stroke-width: 1; }
.hour-bars { width: 100%; height: auto; max-width: 46rem; display: block; margin-top: 0.5rem; }
/* Hour ticks are HTML, not SVG text, so they never scale below legibility on
   small screens (SVG text shrinks with the viewBox; 10px at desktop is ~5px on
   a phone). */
.hour-axis {
  display: flex; justify-content: space-between;
  max-width: 46rem;
  font-family: var(--font-mono); font-size: 0.75rem;
  color: var(--band-muted);
  padding-top: 0.25rem;
}

.methodology {
  color: var(--band-muted); font-size: 0.82rem;
  max-width: 44rem; margin-top: 1.5rem;
}

/* ── Footer ────────────────────────────────────────────────────────────── */
.band-footer { border-top: 1px solid var(--rule-on-navy); padding: 2.5rem 0; }
.band-footer section { margin-bottom: 1.5rem; max-width: 44rem; }
.band-footer p { color: var(--band-muted); font-size: 0.9rem; }
.band-footer code { font-family: var(--font-mono); color: var(--band-ink); }
.band-footer a { color: var(--band-accent-text); }
.fineprint { font-size: 0.78rem; margin-top: 1rem; }

/* ── Motion: the count-up above is the page's ONE moment; everything else
   is still (ADR 010 §5: restraint is the rule). ─────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

@media (max-width: 540px) {
  h1 { font-size: 1.8rem; }
  .stat-value { font-size: 2rem; }
  .reading-value { font-size: 1.6rem; }
  .rank-list li { grid-template-columns: 8rem 1fr 3.5rem; }
  .kev-list li { grid-template-columns: 2rem 1fr; }
  .kev-cve, .kev-added { grid-column: 2; }
}
