/* ==========================================================================
   AURORA — Canada's UAP record
   Design language: a calm, dark, single-accent reading surface. No motion
   theatre, no fake live telemetry, no decorative gradients doing the work
   that typography should do.
   ========================================================================== */

:root {
  /* One accent. Ice-cyan reads as archival/technical; the greens and indigos
     this palette used to carry read as science-fiction set dressing. */
  --accent: #5fd4e8;
  --accent-dim: #3aa9bd;
  --accent-ink: #04222a;
  --accent-wash: rgba(95, 212, 232, 0.11);
  --accent-line: rgba(95, 212, 232, 0.34);

  --bg-0: #04060c;
  --bg-1: #0a1020;
  --glass: rgba(14, 21, 38, 0.52);
  --glass-strong: rgba(10, 16, 30, 0.86);
  --line: rgba(148, 176, 214, 0.16);
  --line-bright: rgba(180, 210, 245, 0.32);
  --text: #e8eef7;
  --text-soft: #b9c7da;
  --muted: #8497ae;
  --faint: #7286a0;   /* 5.4:1 on the page, 5.1:1 on a card -- it carries 10-12px
                    table headers, column labels and counts, so it has to clear
                    AA for body text rather than only for large text */
  --red: #e11d48;
  --red-soft: rgba(225, 29, 72, 0.16);
  --amber: #f59e0b;

  /* The sourcing-confidence scale, used by the map dots, the case cards and
   * the legend. Primary is the accent; the other two exist only here, so a
   * colour can be changed in one place and picked up everywhere. */
  --conf-primary: #5fd4e8;
  --conf-reported: #8fa6f7;
  --conf-partial: #f59e0b;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI",
          Roboto, "Helvetica Neue", Arial, system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, "Cascadia Mono",
          "Segoe UI Mono", Consolas, "Liberation Mono", monospace;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --r: 18px;
  --r-sm: 12px;
  --max: 1240px;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  /* Sticky header height; keeps scroll-padding and the mobile nav honest. */
  --head-h: 59px;
}

* { box-sizing: border-box; }

:root { color-scheme: dark; }   /* --head-h lives with the other tokens above */

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--head-h) + 18px); -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg-0);
  color: var(--text);
  font: 16px/1.65 var(--sans);
  font-feature-settings: "kern" 1, "liga" 1, "tnum" 1;
  overflow-x: hidden;
}

/* aurora field: fixed, behind everything, GPU-friendly */
.aurora-field {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(62vw 48vh at 10% -8%, rgba(95, 212, 232, 0.13), transparent 64%),
    radial-gradient(56vw 46vh at 92% 0%, rgba(110, 168, 255, 0.10), transparent 62%),
    linear-gradient(180deg, var(--bg-1) 0%, var(--bg-0) 52%, #03050a 100%);
}

.shell { position: relative; z-index: 1; }

/* ------------------------------------------------------------------ header */
.site-head {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 12px clamp(16px, 4vw, 40px);
  background: color-mix(in srgb, var(--bg-0) 78%, transparent);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  border-bottom: 1px solid var(--line);
  min-height: var(--head-h);
}
.brand { display: flex; align-items: center; gap: 11px; text-decoration: none; color: var(--text); }
.brand-mark {
  width: 34px; height: 34px; border-radius: 10px; flex: 0 0 auto;
  background: var(--accent);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.14) inset, 0 6px 18px rgba(95, 212, 232, 0.2);
  position: relative;
}
.brand-mark::after {
  content: ""; position: absolute; inset: 9px; border-radius: 3px;
  background: var(--bg-0); opacity: 0.86;
}
.brand-name { font: 600 16px/1 var(--sans); letter-spacing: 0.14em; }
.brand-sub { display: block; font: 400 10px/1.5 var(--mono); letter-spacing: 0.1em; color: var(--faint); text-transform: uppercase; margin-top: 3px; }

.nav { margin-left: auto; display: flex; gap: 4px; align-items: center; flex-wrap: wrap; }
.nav a {
  color: var(--text-soft); text-decoration: none; font: 500 13.5px/1 var(--sans);
  padding: 9px 12px; border-radius: 999px; border: 1px solid transparent; white-space: nowrap;
  transition: color .18s var(--ease), background .18s var(--ease), border-color .18s var(--ease);
}
.nav a:hover { color: var(--text); background: rgba(148, 176, 214, 0.10); border-color: var(--line); }
.nav a[aria-current="page"] { color: #fff; background: var(--accent-wash); border-color: var(--accent-line); }
.nav-toggle { display: none; }

/* --------------------------------------------------------------------- hero */
.hero { position: relative; padding: clamp(56px, 9vw, 108px) clamp(16px, 4vw, 40px) clamp(40px, 6vw, 72px); }
.hero-inner { max-width: var(--max); margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1.32fr) minmax(0, 0.68fr); gap: clamp(28px, 4vw, 56px); align-items: center; }
/* A hero with no side panel. The 940px query below already collapses to one
   column on narrow screens, so this only has to handle the wide case -- which
   is why it was previously an inline style repeated across every page. */
.hero-1col { grid-template-columns: minmax(0, 1fr); }
.kicker {
  display: block; margin: 0 0 22px;
  font: 500 11.5px/1.5 var(--mono); letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent);
}

.hero h1 {
  margin: 0;
  font: 700 clamp(44px, 8vw, 96px)/0.96 var(--sans);
  letter-spacing: -0.04em;
  color: #fff;
}
.hero .tagline { margin: 14px 0 0; max-width: 34ch; font: 400 clamp(17px, 2.1vw, 21px)/1.5 var(--serif); color: var(--text-soft); }
.hero-lede { margin: 22px 0 0; max-width: 64ch; color: var(--muted); font-size: 15.5px; }
.hero-lede strong { color: var(--text-soft); font-weight: 600; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 30px; }
.hero-tight { padding-bottom: 8px; }
.hero-h1-sm { font-size: clamp(34px, 5.6vw, 64px); }
.hero-h1-md { font-size: clamp(36px, 6vw, 70px); }
.hero-h1-lg { font-size: clamp(38px, 6.4vw, 74px); }

/* Vertical rhythm, one 2px step per step. These were repeated inline
   margin-top declarations in every page and in the case-page template. */
.mt-1 { margin-top: 10px; }
.mt-2 { margin-top: 12px; }
.mt-3 { margin-top: 14px; }
.mt-4 { margin-top: 16px; }
.mt-8 { margin-top: 24px; }
.mb-4 { margin-bottom: 18px; }
.sec-title-sm { font-size: 26px; margin-bottom: 18px; }
.card-note { padding: 18px 20px; margin-top: 26px; }
.grid-top { align-items: start; }
.note { color: var(--muted); font-size: 13.6px; }
.faint { color: var(--faint); font-size: 12.5px; }
.inherit { color: inherit; }
.chip-row { display: flex; gap: 10px; flex-wrap: wrap; }
.flush { list-style: none; padding: 0; }
/* These four were inline styles in the JS renderers. A static page with
 * JavaScript off never had them, so a card rendered by aurora.js and the same
 * card in the markup did not look alike. */
.card-sub { color: var(--muted); font-size: 12.5px; margin: 0 0 10px; }
.prose-note { color: var(--muted); font-size: 13.6px; max-width: 72ch; margin: 10px 0 0; }
.search-note { color: var(--muted); margin: 0 0 12px; }
.figure-cap { margin-top: 10px; }
.readout-num { font-size: 44px; margin-top: 8px; }

.btn {
  display: inline-flex; align-items: center; gap: 9px; text-decoration: none; cursor: pointer;
  font: 600 14px/1 var(--sans); padding: 13px 20px; border-radius: 999px;
  border: 1px solid var(--line-bright); color: var(--text); background: rgba(148, 176, 214, 0.08);
  transition: transform .16s var(--ease), background .16s var(--ease), border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.btn:hover { transform: translateY(-2px); background: rgba(148, 176, 214, 0.15); box-shadow: 0 10px 26px rgba(2, 6, 23, 0.5); }
.btn:active { transform: translateY(0); }
.btn-primary { color: var(--accent-ink); border-color: transparent; background: var(--accent); }
.btn-primary:hover { background: #7ee0f1; box-shadow: 0 12px 28px rgba(95, 212, 232, 0.22); }

/* hero readout panel */
.readout { display: grid; gap: 12px; }
.readout .panel {
  padding: 20px 22px; border-radius: var(--r);
  background: var(--glass);
  box-shadow: 0 18px 44px rgba(2, 6, 23, 0.4);
  backdrop-filter: blur(18px) saturate(130%);
  -webkit-backdrop-filter: blur(18px) saturate(130%);
  border: 1px solid var(--line);
}
.startlist { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 2px; }
.startlist a {
  display: block; padding: 9px 10px; margin: 0 -10px; border-radius: var(--r-sm);
  text-decoration: none; color: var(--text-soft);
  transition: background .16s var(--ease), color .16s var(--ease);
}
.startlist a:hover { background: var(--accent-wash); color: #fff; }
.startlist b { display: block; font: 600 14.5px/1.3 var(--sans); color: var(--text); }
.startlist a:hover b { color: var(--accent); }
.startlist span { display: block; font-size: 12.6px; color: var(--muted); margin-top: 2px; }
.readout-label { font: 500 10.5px/1 var(--mono); letter-spacing: 0.15em; text-transform: uppercase; color: var(--faint); }
.figure { font: 500 clamp(32px, 4.6vw, 46px)/1 var(--sans); letter-spacing: -0.035em; color: #fff; font-variant-numeric: tabular-nums; margin-top: 10px; }
.stat-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
/* The survey readout under the survey cards. It carried an inline
   margin-top:16px until the pass that removed inline styles turned the
   surrounding tag into class="stat-pair id="survey-stats"" -- see
   assert_clean_markup in generate_pages.py, which now fails the build on that
   shape. */
.survey-stats { margin-top: 16px; }
.stat { padding: 15px 16px; border-radius: var(--r-sm); background: rgba(148, 176, 214, 0.06); border: 1px solid var(--line); }
.stat b { display: block; font: 600 25px/1.1 var(--sans); letter-spacing: -0.02em; color: #fff; }
.stat span { display: block; font: 400 11.5px/1.45 var(--sans); color: var(--muted); margin-top: 5px; }

/* ------------------------------------------------------------------ section */
main { max-width: var(--max); margin: 0 auto; padding: 0 clamp(16px, 4vw, 40px) 96px; }
section { padding: clamp(48px, 7vw, 88px) 0; border-top: 1px solid var(--line); }
section:first-of-type { border-top: 0; }
.sec-head {
  display: grid;
  grid-template-columns: minmax(2.4rem, auto) minmax(0, 1fr);
  gap: 4px 16px;
  align-items: start;
  margin-bottom: 30px;
}
.sec-num {
  font: 500 11px/1.9 var(--mono);
  letter-spacing: 0.18em;
  color: var(--accent);
  border-top: 1px solid var(--accent-line);
  padding-top: 9px;
  text-align: right;
}
.sec-head-col { min-width: 0; }
.sec-title { margin: 0; font: 700 clamp(25px, 3.6vw, 38px)/1.14 var(--sans); letter-spacing: -0.028em; }
.sec-dek { margin: 12px 0 0; max-width: 68ch; color: var(--muted); font-size: 15px; }

.grid { display: grid; gap: 18px; }
.g-2 { grid-template-columns: repeat(auto-fit, minmax(310px, 1fr)); }
.g-3 { grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); }
.g-4 { grid-template-columns: repeat(auto-fit, minmax(206px, 1fr)); }
/* Exactly two columns, for an even number of cards -- auto-fit would pack
   three and leave the last one stranded. */
.g-2up { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* -------------------------------------------------------------------- cards */
.card {
  position: relative; padding: 22px; border-radius: var(--r); overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--glass);
  border: 1px solid var(--line);
  box-shadow: 0 14px 34px rgba(2, 6, 23, 0.3);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.card:hover { border-color: var(--line-bright); background: rgba(20, 30, 50, 0.6); }
.card h3 { margin: 0 0 8px; font: 650 18.5px/1.3 var(--sans); letter-spacing: -0.015em; }
.card p { margin: 0; color: var(--muted); font-size: 14.4px; }
.card .meta { margin-top: auto; padding-top: 14px; }


/* Chip row on a case card. Was an inline margin on every instance. */
.card-chips { margin-bottom: 12px; }

.tranches { margin: 0; padding: 0; list-style: none; display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.tranche {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; gap: 20px; align-items: start;
  padding: 20px 22px; background: var(--bg-1);
  transition: background .18s var(--ease);
}
.tranche:hover { background: rgba(20, 30, 50, 0.55); }
.tranche-n {
  font: 600 24px/1 var(--mono); letter-spacing: -0.02em; color: var(--accent);
  font-variant-numeric: tabular-nums; padding-top: 2px;
}
.tranche-body h3 { margin: 0 0 5px; font: 650 17.5px/1.3 var(--sans); letter-spacing: -0.015em; }
.tranche-body p { margin: 0; color: var(--muted); font-size: 14.2px; max-width: 78ch; }
.tranche-go { align-self: center; white-space: nowrap; }
@media (max-width: 760px) {
  .tranche { grid-template-columns: 44px minmax(0, 1fr); gap: 14px; padding: 18px 16px; }
  .tranche-go { grid-column: 2; justify-self: start; margin-top: 4px; }
}

.chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border-radius: 999px;
  font: 500 11px/1 var(--mono); letter-spacing: 0.04em; color: var(--text-soft);
  background: rgba(148, 176, 214, 0.1); border: 1px solid var(--line);
}
.chip-a { color: #a8e9f7; background: var(--accent-wash); border-color: var(--accent-line); }
.chip-amb { color: #fde0a8; background: rgba(245, 158, 11, 0.12); border-color: rgba(245, 158, 11, 0.3); }
.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip a { color: inherit; text-decoration: none; }
.chip a:hover { text-decoration: underline; text-underline-offset: 2px; }

.card-media { position: relative; margin: -22px -22px 18px; aspect-ratio: 16/9; background: #05080f; }
.card-media iframe, .card-media img { width: 100%; height: 100%; border: 0; display: block; }
.card-media.poster .poster-link { position: absolute; inset: 0; z-index: 2; }
.card-media.poster:has(.poster-link):hover { border-bottom-color: var(--accent-line); }
.card-media.poster {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 20px; text-align: center;
  background: radial-gradient(80% 120% at 50% 0%, rgba(95, 212, 232, 0.10), transparent 64%), #05080f;
  border-bottom: 1px solid var(--line);
}
.card-media.poster .pm { font: 600 11.5px/1.4 var(--mono); color: var(--text-soft); letter-spacing: 0.02em; }
.card-media.poster .pb {
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255, 255, 255, 0.08); border: 1px solid var(--line-bright);
  transition: background .18s var(--ease), transform .18s var(--ease);
}
.card-media.poster .pb::after { content: "▶"; font-size: 14px; margin-left: 3px; color: #fff; }
.card:hover .card-media.poster .pb { background: var(--accent-wash); }

/* doc cards */
.doc-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(272px, 1fr)); }
.doc {
  display: flex; flex-direction: column; padding: 0; overflow: hidden; text-decoration: none; color: inherit;
  border-radius: var(--r); border: 1px solid var(--line); background: var(--glass);
  box-shadow: 0 14px 32px rgba(2, 6, 23, 0.28); transition: border-color .18s var(--ease), background .18s var(--ease);
}
.doc:hover { border-color: var(--accent-line); background: rgba(20, 30, 50, 0.6); }
.doc-thumb { position: relative; aspect-ratio: 4/3; background: #0a1120; border-bottom: 1px solid var(--line); overflow: hidden; }
.doc-thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top center; filter: contrast(1.06) saturate(0.92); display: block; }
.doc-thumb .ph { position: absolute; inset: 0; display: grid; place-items: center; font: 600 10.5px/1.5 var(--mono); color: var(--faint); letter-spacing: 0.1em; background: repeating-linear-gradient(45deg, rgba(148,176,214,0.05) 0 8px, transparent 8px 16px); }
.doc-body { padding: 16px 17px 18px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.doc-id { font: 500 10.5px/1 var(--mono); letter-spacing: 0.12em; color: var(--accent); }
.doc-body h3 { margin: 0; font: 650 15.5px/1.34 var(--sans); letter-spacing: -0.012em; }
.doc-body p { margin: 0; font-size: 13px; color: var(--muted); }
.doc-foot { margin-top: auto; display: flex; flex-wrap: wrap; gap: 6px; }

/* filters */
.filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 22px; }
.search {
  flex: 1 1 250px; min-width: 0; display: flex; align-items: center; gap: 9px;
  padding: 0 15px; border-radius: 999px; border: 1px solid var(--line); background: rgba(148, 176, 214, 0.07);
  backdrop-filter: blur(10px);
}
.search input { flex: 1; min-width: 0; background: none; border: 0; color: var(--text); font: 400 14px var(--sans); padding: 12px 0; }
/* No outline:0 here -- :focus-visible below supplies the ring, and removing the
   UA default outright costs keyboard users the focus indicator in any engine
   that does not support it. */
.search input::placeholder { color: var(--faint); }
.search svg { flex: 0 0 auto; opacity: .5; }
.seg { display: flex; gap: 4px; padding: 4px; border-radius: 999px; border: 1px solid var(--line); background: rgba(148, 176, 214, 0.06); overflow-x: auto; max-width: 100%; }
.seg button {
  border: 0; cursor: pointer; white-space: nowrap; border-radius: 999px; padding: 8px 13px;
  background: transparent; color: var(--muted); font: 500 12.5px/1 var(--sans); transition: all .16s var(--ease);
}
.seg button:hover:not(:disabled) { color: var(--text); background: rgba(148, 176, 214, 0.1); }
.seg button[aria-pressed="true"] { color: var(--accent-ink); background: var(--accent); }
.seg button:disabled, .btn:disabled, .seg button[aria-disabled="true"] {
  opacity: .38; cursor: not-allowed; pointer-events: none;
}
.count-note { font: 400 12.5px/1 var(--mono); color: var(--faint); margin-left: auto; }

/* The filter <select>s hide the native control so they can match .chip; without
   a caret of their own they then read as static text. */
select.select-chip { padding: 11px 14px; }
select.chip, select.select-chip {
  appearance: none; -webkit-appearance: none; cursor: pointer; color: var(--text-soft);
  padding-right: 32px !important;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: right 16px center, right 11px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
select.chip:hover { border-color: var(--accent-line); color: var(--text); }
select.chip option { background: var(--bg-1); color: var(--text); }

/* --------------------------------------------------------------------- map */
.map-shell {
  position: relative; border-radius: var(--r); overflow: hidden; border: 1px solid var(--line);
  background: var(--glass-strong); box-shadow: 0 24px 60px rgba(2, 6, 23, 0.5);
}
#map { height: clamp(400px, 56vh, 620px); width: 100%; background: #060a12; }
/* Where map.js puts a visible note when part of the map fails. Empty and
   zero-height until something goes wrong, so it costs nothing normally. */
.map-warn:empty { display: none; }
.map-warn .error-note { margin: 0 0 12px; }
.map-side { display: flex; }
.map-side > * { width: 100%; }

/* The case list sits beside the map, never on top of it.
 *
 * It used to be an absolutely positioned panel over the map's top-left, on the
 * theory that a floating legend was tidier. It is not: the panel covered
 * British Columbia and the Yukon, which is where the Yukon shootdown and Prince
 * George are, so a legend was hiding two of the eighteen cases. The fix was
 * applied at min-width 1081px only, which left 761-1080px still on the overlay —
 * and at 900px the Yukon dots were under the panel again, verified in a browser.
 *
 * So there are now two layouts and no overlay. Above 860px it is a two-column
 * grid; below that it stacks. The 860px line is where a 302px panel plus a map
 * stops being worth having side by side. */
@media (min-width: 861px) {
  /* The map keeps the height it wants. At 1440x1000 the panel is 738px and the
     eighteen rows come to 681, so the list does not scroll here. It does scroll
     in the stacked layout below, where .map-side is capped at 42vh, so the
     scroller keeps a visible scrollbar. A bottom fade was tried first and had to
     come back out: it painted over the last row whether or not anything was cut,
     and since the rows are transparent a background-coloured gradient could not
     have done the job anyway. */
  .map-shell { display: grid; grid-template-columns: 1fr 302px; align-items: stretch; }
  #map { height: clamp(520px, 64vh, 700px); }
  .map-side {
    position: static; width: auto; max-height: none; z-index: auto;
    border-left: 1px solid var(--line);
  }
  /* .map-panel is the flex column; .map-scroll inside it does the scrolling.
     This rule used to make the panel itself the scroller. */
  .map-side > * { border: 0; border-radius: 0; background: transparent; backdrop-filter: none; height: 100%; overflow: hidden; }
  /* The source credit spans the bottom of the whole shell, under the map and the
     case list. It is absolutely positioned against .map-shell, which is as tall
     as the taller of the two columns, so it always clears both. Moving it into
     the map's own grid cell was tried and abandoned: a media query adds no
     specificity, so it had to be written as .map-shell .map-hint to win against
     the bare rule further down, and the resulting placement overflowed the shell
     to the left at both widths tested. A full-width credit bar is the ordinary
     pattern and reads fine. */
  .map-hint { left: 14px; right: 14px; text-align: center; }
}

/* One declaration each. .map-panel and .map-list were both declared twice --
   once here for layout and once further down for the glass and the rows -- and
   the second pair silently won on the properties they shared. */
.map-list { list-style: none; margin: 0; padding: 6px 0; display: grid; gap: 2px; flex: 0 0 auto; }
.map-panel {
  position: relative; overflow: hidden;
  padding: 14px 15px; background: var(--glass-strong); border: 1px solid var(--line);
  border-radius: 14px; backdrop-filter: blur(14px);
  display: flex; flex-direction: column; gap: 10px;
}
.map-panel > .readout-label { flex: 0 0 auto; }
/* The list is a scroller so the readout label above it stays put when the panel
   is shorter than eighteen rows. At 1440x1000 the panel is 738px and the list
   needs 681, so it does not scroll there; in the stacked layout it does.

   The column flex on .map-scroll is not cosmetic: without it the grid list is a
   plain block child and gets squashed to the scroller's height, and rows that
   no longer fit paint outside it while scrollHeight keeps reporting the squashed
   box. flex: 0 0 auto on the list keeps it at its natural height so there is
   something to scroll. */
.map-scroll { min-height: 0; overflow-y: scroll; overscroll-behavior: contain;
              display: flex; flex-direction: column;
              scrollbar-width: thin; scrollbar-color: var(--line-bright) transparent; }
.map-scroll::-webkit-scrollbar { width: 8px; }
.map-scroll::-webkit-scrollbar-track { background: transparent; }
.map-scroll::-webkit-scrollbar-thumb { background: var(--line-bright); border-radius: 99px; }
.map-scroll::-webkit-scrollbar-thumb:hover { background: var(--accent-line); }
.map-list button {
  width: 100%; text-align: left; cursor: pointer; border: 1px solid transparent; border-radius: var(--r-sm);
  background: transparent; color: var(--text-soft); padding: 8px 10px; font: 500 12.6px/1.4 var(--sans);
  display: flex; gap: 9px; align-items: baseline; transition: all .15s var(--ease);
}
.map-list button:hover { background: rgba(148, 176, 214, 0.1); color: var(--text); }
.map-list button[aria-current="true"] { background: var(--accent-wash); border-color: var(--accent-line); color: #fff; }
.map-list .yr { font: 500 10.5px/1 var(--mono); color: var(--accent); flex: 0 0 auto; }
.map-list .nm { display: flex; align-items: baseline; gap: 6px; min-width: 0; flex: 1 1 auto; }
.map-list .nm b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.map-list .pv { font: 500 10.5px/1 var(--mono); color: var(--faint); flex: 0 0 auto; }
.map-list .dot { width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto; margin-left: auto; }
.map-list button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
#map-legend { display: grid; gap: 9px; }
#map-legend li { display: flex; align-items: center; gap: 10px; font-size: 13.4px; color: var(--text-soft); }
#map-legend .swatch {
  width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.06);
}
/* Colour is data, so it was being written into a style attribute from a JS
 * table. The keys match cases.json's `conf` field, which is a fixed three-value
 * enum, so classes are enough and base.css stays the only place a colour is
 * spelled. */
.conf-primary { --conf: var(--conf-primary); }
.conf-reported { --conf: var(--conf-reported); }
.conf-partial { --conf: var(--conf-partial); }
.swatch, .map-list .dot { background: var(--conf, var(--conf-partial)); }
.pp .label { color: var(--conf, var(--conf-partial)); }
.map-hint {
  position: absolute; right: 14px; bottom: 14px; z-index: 500; padding: 8px 12px; border-radius: 999px;
  font: 400 11.5px/1 var(--mono); color: var(--text-soft); background: rgba(6, 10, 18, 0.82);
  border: 1px solid var(--line); backdrop-filter: blur(10px);
}

/* MapLibre. The vendor stylesheet does the layout; these rules restyle its
   chrome to match the rest of the site. There is no tile-pane filter any more:
   the basemap ships as a real dark vector style, so nothing is inverted. */
#map { font-family: var(--sans); }
.maplibregl-map { font-family: var(--sans); }
.maplibregl-ctrl-group {
  background: rgba(10, 16, 30, 0.92) !important;
  border: 1px solid var(--line) !important;
  border-radius: 10px !important;
  box-shadow: 0 8px 22px rgba(2, 6, 23, 0.5) !important;
}
.maplibregl-ctrl-group button + button { border-top: 1px solid var(--line) !important; }
.maplibregl-ctrl-group button .maplibregl-ctrl-icon { filter: invert(1) brightness(1.5); }
.maplibregl-ctrl-group button:hover { background: var(--accent-wash) !important; }
.maplibregl-ctrl-attrib {
  background: rgba(6, 10, 18, 0.82) !important;
  border-radius: 8px 0 0 0 !important;
  font: 400 10px/1.5 var(--sans) !important;
}
.maplibregl-ctrl-attrib a { color: var(--text-soft) !important; }
.maplibregl-popup-content-wrapper {
  background: var(--glass-strong); color: var(--text);
  border: 1px solid var(--line-bright); border-radius: 14px; padding: 0;
  backdrop-filter: blur(14px); box-shadow: 0 20px 46px rgba(2, 6, 23, .6);
}
.maplibregl-popup-content { margin: 13px 15px; font-size: 13.4px; line-height: 1.55; }
.maplibregl-popup-content h4 { margin: 0 0 6px; font: 650 14.5px/1.3 var(--sans); }
.maplibregl-popup-content .pp { margin: 0 0 9px; color: var(--muted); font-size: 12.6px; }
.maplibregl-popup-tip { border-top-color: var(--line-bright) !important; border-bottom-color: var(--line-bright) !important; }
.maplibregl-popup-close-button {
  color: var(--muted) !important; font-size: 17px !important; padding: 6px 8px 0 0 !important;
}
.maplibregl-popup-close-button:hover { color: var(--text) !important; background: transparent !important; }
.maplibregl-canvas:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ---------------------------------------------------------------- timeline */
.tl { position: relative; margin: 0; padding: 0 0 0 30px; list-style: none; }
.tl::before { content: ""; position: absolute; left: 7px; top: 6px; bottom: 6px; width: 1px; background: linear-gradient(180deg, transparent, var(--line-bright) 8%, var(--line-bright) 92%, transparent); }
.tl li { position: relative; padding: 0 0 30px; }
.tl li::before {
  content: ""; position: absolute; left: -30px; top: 7px; width: 15px; height: 15px; border-radius: 50%;
  background: var(--bg-0); border: 1.5px solid var(--accent-dim); box-shadow: 0 0 0 4px var(--accent-wash);
}
.tl li.now::before { border-color: var(--red); box-shadow: 0 0 0 4px rgba(225, 29, 72, 0.14); }
.tl .yr { font: 500 11.5px/1 var(--mono); letter-spacing: 0.1em; color: var(--accent); }
.tl li.now .yr { color: #ff8fa3; }
.tl h3 { margin: 7px 0 6px; font: 650 18px/1.3 var(--sans); letter-spacing: -0.015em; }
.tl p { margin: 0; color: var(--muted); font-size: 14.4px; max-width: 74ch; }

/* Nineteen entries down one rail came to just over 3,000px, which made the
   overview page longer than every page it links to put together. Two columns
   hold the reading order (multi-column fills the first column before the
   second) and halve the height. The rail moves onto each item so both columns
   get their own line. */
@media (min-width: 981px) {
  .tl { column-count: 2; column-gap: 48px; padding-left: 0; }
  .tl::before { display: none; }
  .tl li { break-inside: avoid; padding: 0 0 30px 28px; border-left: 1px solid var(--line-bright); }
  .tl li::before { left: -7px; }
}

/* ------------------------------------------------------------------- table */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); background: var(--glass); box-shadow: 0 18px 44px rgba(2, 6, 23, 0.34); }
table { width: 100%; border-collapse: collapse; font-size: 13.6px; }
th, td { text-align: left; padding: 12px 15px; border-bottom: 1px solid var(--line); vertical-align: top; }
th { position: sticky; top: 0; z-index: 2; background: rgba(10, 16, 30, 0.94); backdrop-filter: blur(10px); font: 500 11px/1.4 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); white-space: nowrap; }
th button { background: none; border: 0; padding: 0; cursor: pointer; color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; }
th button:hover, th button[aria-sort] { color: var(--accent); }
tbody tr { transition: background .14s var(--ease); }
tbody tr:hover { background: var(--accent-wash); }
tbody tr:last-child td { border-bottom: 0; }
td .rid { font: 500 11.5px/1.3 var(--mono); color: var(--accent); }
td a { color: var(--text); text-decoration-color: var(--accent-line); text-underline-offset: 3px; }
td a:hover { text-decoration-color: var(--accent); }
td .none { color: var(--faint); font-style: italic; }

/* ------------------------------------------------------------------- lists */
.linklist { list-style: none; margin: 0; padding: 0; display: grid; gap: 11px; }
.linklist li { display: flex; gap: 13px; align-items: flex-start; }
.linklist .bullet { flex: 0 0 auto; margin-top: 6px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent-dim); }
.linklist a { color: var(--text); font-weight: 600; text-decoration: none; }
.linklist a:hover { text-decoration: underline; text-underline-offset: 3px; }
.linklist .desc { color: var(--muted); font-size: 13.4px; margin-top: 3px; }
.linklist code, code { font: 400 12.4px/1.5 var(--mono); color: #a8e9f7; background: var(--accent-wash); padding: 2px 6px; border-radius: 5px; overflow-wrap: anywhere; }

/* Recommendation / bullet groups: a hairline marker, not a numbered <ol>
   the source report does not number. */
.ticks { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 11px; }
.ticks li { position: relative; padding-left: 18px; color: var(--muted); font-size: 14.2px; line-height: 1.55; }
.ticks li::before {
  content: ""; position: absolute; left: 0; top: 8px; width: 5px; height: 5px;
  border-radius: 50%; background: var(--accent-dim);
}
.ticks strong { color: var(--text); font-weight: 600; }

.qa { display: grid; gap: 0; }
.qa details { border-bottom: 1px solid var(--line); }
.qa summary { cursor: pointer; list-style: none; padding: 19px 40px 19px 0; position: relative; font: 600 16.5px/1.45 var(--sans); }
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after { content: "+"; position: absolute; right: 8px; top: 19px; font: 400 22px/1 var(--mono); color: var(--accent); }
.qa details[open] summary::after { content: "\2013"; }
.qa summary:hover { color: #fff; }
.qa .a { padding: 0 0 20px; color: var(--text-soft); font-size: 14.6px; max-width: 78ch; }
.qa .a p { margin: 0 0 10px; }

.quote { margin: 0; padding: 26px 30px; border-radius: var(--r); border: 1px solid var(--line); background: rgba(148, 176, 214, 0.055); }
.quote blockquote { margin: 0; font: 400 clamp(17px, 2.2vw, 21px)/1.6 var(--serif); color: var(--text); }
.quote cite { display: block; margin-top: 14px; font: 500 12px/1.5 var(--mono); letter-spacing: 0.06em; color: var(--faint); font-style: normal; }

.prose { max-width: 74ch; color: var(--text-soft); }
.prose p { margin: 0 0 15px; }
.prose a { color: #a8e9f7; }
.prose strong { color: var(--text); }

/* ----------------------------------------------------------------- footer */
footer { border-top: 1px solid var(--line); padding: 46px clamp(16px, 4vw, 40px) 60px; }
.foot-inner { max-width: var(--max); margin: 0 auto; display: grid; gap: 28px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.foot-inner h2 { margin: 0 0 12px; font: 500 11px/1 var(--mono); letter-spacing: 0.15em; text-transform: uppercase; color: var(--faint); }
.foot-inner ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.foot-inner a { color: var(--text-soft); text-decoration: none; font-size: 14px; }
.foot-inner a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.disclaimer {
  max-width: var(--max); margin: 34px auto 0; padding: 20px 22px; border-radius: var(--r);
  border: 1px solid rgba(245, 158, 11, 0.28); background: rgba(245, 158, 11, 0.06); color: #f6ddb4; font-size: 13.4px;
}
.disclaimer b { color: #ffe9c2; }

/* ------------------------------------------------------------- utilities */
.skip { position: absolute; left: -9999px; top: 0; z-index: 999; padding: 12px 18px; background: var(--bg-1); color: #fff; border-radius: 0 0 10px 0; }
.skip:focus { left: 0; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
/* Visually hidden, still read by a screen reader. Existed twice under two
   names with identical declarations -- .sr in two hand-written pages and
   .sr-only in the release-row renderer. One name now, and it is the one the
   JavaScript emits. */
.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;
}
.noscript-note {
  margin-top: 16px; padding: 16px 18px; border-radius: var(--r-sm);
  border: 1px solid var(--amber); border-left-width: 3px;
  background: rgba(245, 158, 11, 0.07); color: #f6ddb4; font-size: 13.6px;
}
.noscript-note p { margin: 0; }
.noscript-note b { color: #ffe9c2; }
.noscript-note a { color: #ffd894; }
.spinner { padding: 40px; text-align: center; font: 400 13px var(--mono); color: var(--faint); }
/* Without JS these are never replaced, and they read as a page stuck loading
   right above the note that says so. core.js sets .js when it runs. */
html:not(.js) .spinner { display: none; }
.error-note { padding: 18px 20px; border-radius: var(--r-sm); border: 1px solid rgba(225,29,72,.3); background: var(--red-soft); color: #ffc4d0; font-size: 13.4px; }

/* ----------------------------------------------------------- responsive */
@media (max-width: 940px) {
  .hero-inner { grid-template-columns: 1fr; }
  .hero .tagline { max-width: 26ch; }
  .readout { order: 2; }
}
@media (max-width: 760px) {
  /* .site-head is position:sticky, so it is already the containing block for
     an absolutely positioned child — no magic offset to keep in sync. */
  .nav {
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 2px;
    margin: 0; padding: 14px clamp(16px, 4vw, 40px) 20px;
    background: var(--bg-0); border-bottom: 1px solid var(--line);
    max-height: calc(100vh - var(--head-h)); overflow-y: auto; display: none;
  }
  .nav.open { display: flex; }
  .nav a { padding: 12px 14px; border-radius: 10px; }
  .nav-toggle {
    display: inline-grid; place-items: center; margin-left: auto; width: 40px; height: 38px; cursor: pointer;
    border-radius: 10px; border: 1px solid var(--line); background: rgba(148, 176, 214, 0.08); color: var(--text);
  }
  .sec-head { grid-template-columns: 1fr; gap: 8px; }
  .sec-num { text-align: left; border-top: 0; padding-top: 0; }
  .count-note { margin-left: 0; width: 100%; }
  .stat-pair { grid-template-columns: 1fr; }
  .g-2up { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}

/* The map stacks below 861px — the companion to the two-column grid above. It is
   here rather than in the 760px block because the case list stops being worth
   having beside the map at 860px, not at the nav's 760px breakpoint. The two are
   unrelated limits that happened to share a media query. */
@media (max-width: 860px) {
  .map-shell { display: flex; flex-direction: column; }
  /* Order matters and the hint was left out of it. .map-hint is the source credit
     for the boundaries, and with no order it defaulted to 0, so in the stacked
     layout it rendered *above* the map it credits. It belongs under the map and
     above the case list. */
  #map { order: 1; height: clamp(320px, 52vh, 460px); }
  .map-hint { order: 2; position: static; display: inline-block; margin: 0 12px 12px; }
  .map-side { order: 3; position: static; width: auto; margin: 0; max-height: 42vh; }
  .map-panel { backdrop-filter: none; }
}
@media print {
  .aurora-field, .nav, .hero-cta, .map-shell { display: none; }
  body { background: #fff; color: #000; }
  .card, .doc, .table-wrap { border: 1px solid #999; box-shadow: none; background: none; }
}
