/* Display face — Newsreader 600 (SIL OFL 1.1, see assets/fonts/OFL.txt), self-hosted
   and subsetted (latin + latin-ext) because this site makes no external requests.
   Body text stays system-ui; the display face carries the wordmark and titles only. */
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("./assets/fonts/newsreader-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("./assets/fonts/newsreader-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg: #0f1115;
  --panel: #181b22;
  --panel-2: #1f232c;
  --text: #e7e9ee;
  --muted: #9aa3b0;
  --line: #2a2f3a;
  --accent: #6ea8fe;
  --accent-soft: rgba(110, 168, 254, 0.55); /* hover borders */
  --green: #3fb950;
  --amber: #d29922;
  --red: #f85149;
  --grey: #6e7681;
  --font-display: "Newsreader", Georgia, "Times New Roman", serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  /* Belt-and-braces against any stray wide element causing page-level horizontal
     scroll on phones (clip, not hidden: no new scroll container). */
  overflow-x: clip;
}

/* One consistent link treatment everywhere (tabs opt out below). Without a base
   rule, links outside the styled components fell back to UA default #0000EE —
   near-invisible on this dark background. */
a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
a:hover { text-decoration-thickness: 2px; }
/* iOS auto-detected "links" (dates, phone-number-looking IDs) must not restyle
   card text with the UA's blue. */
a[x-apple-data-detectors] { color: inherit !important; text-decoration: inherit !important; }
a:focus-visible, button:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

.site-header, main, .site-footer {
  max-width: 920px;
  margin: 0 auto;
  padding: 0 20px;
}

/* Masthead: mark + wordmark and a two-link nav (code, author); the tagline lives on About. */
.masthead { padding-top: 32px; padding-bottom: 4px; }
.brand { min-width: 0; }
.brand-name {
  display: flex; align-items: center; gap: 12px; margin: 0;
  font-family: var(--font-display); font-weight: 600; font-size: 1.9rem; line-height: 1.1; letter-spacing: -0.015em;
}
.mark { width: 30px; height: 30px; flex: none; color: var(--accent); }
.wordmark { min-width: 0; overflow-wrap: break-word; }
.freshness { color: var(--muted); font-size: 0.85rem; margin: 6px 0 0; }
.freshness-stale { color: var(--amber); font-weight: 600; }

.loading { color: var(--muted); }

/* Hash-routed tab bar: #pulse / #threats / #history. */
.tabs {
  max-width: 920px; margin: 20px auto 0; padding: 0 20px;
  display: flex; flex-wrap: wrap; gap: 4px;
  border-bottom: 2px solid var(--line);
}
.tabs a {
  color: var(--muted); text-decoration: none; font-weight: 600; font-size: 0.95rem;
  padding: 10px 14px; border-bottom: 2px solid transparent; margin-bottom: -2px;
  white-space: nowrap;
}
.tabs a:hover { color: var(--text); }
.tabs a.active { color: var(--accent); border-bottom-color: var(--accent); }

/* One pane per tab: World Pulse, Existential Threats, Historical Archive. */
.pane { margin-top: 28px; }
.pane[hidden] { display: none; }
.pane-head { border-bottom: 2px solid var(--line); padding-bottom: 12px; margin-bottom: 18px; }
/* The active tab is the pane's visible title; the h2 stays for the outline only. */
.pane-title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.pane-sub { color: var(--muted); margin: 0; }

/* Sort/filter toolbars (threats + history panes); hidden until data arrives. */
.toolbar { display: flex; flex-wrap: wrap; gap: 10px 16px; margin-top: 12px; }
.toolbar-field { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 0.85rem; }
.toolbar select, .toolbar input[type="search"] {
  background: var(--panel-2); color: var(--text); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 10px; font: inherit; font-size: 0.9rem;
}
.toolbar input[type="search"] { min-width: 12ch; width: 22ch; max-width: 100%; }
.toolbar input[type="search"]::placeholder { color: var(--muted); opacity: 0.8; }

/* World Pulse map (map.js): self-contained NASA Blue Marble basemap + impact markers. */
.map-wrap { margin: 0 0 20px; }
#map {
  position: relative; overflow: hidden; height: clamp(220px, 40vh, 340px);
  border: 1px solid var(--line); border-radius: 10px;
  /* pan-y (not none): a one-finger vertical swipe scrolls the page instead of
     being trapped panning the map; horizontal drags and two-finger gestures
     still reach map.js's pointer handlers. */
  background: #06070a; touch-action: pan-y; cursor: grab;
}
#map.dragging { cursor: grabbing; }
.map-world { position: absolute; top: 0; left: 0; transform-origin: 0 0; will-change: transform; }
.map-world img { display: block; width: 100%; height: 100%; user-select: none; -webkit-user-drag: none; }
.map-marker {
  position: absolute; padding: 0; border-radius: 50%;
  border: 2px solid rgba(15, 17, 21, 0.85); cursor: pointer;
  transform: translate(-50%, -50%);
}
/* Markers are 12-24px; give them an invisible tap area closer to finger-sized. */
.map-marker::after { content: ""; position: absolute; inset: -10px; border-radius: 50%; }
.map-marker:focus-visible { outline: 2px solid var(--text); outline-offset: 1px; }
.map-marker.r1 { background: var(--grey); }
.map-marker.r2 { background: var(--accent); }
.map-marker.r3 { background: var(--amber); }
.map-marker.r4 { background: var(--red); }
.map-tip {
  position: absolute; z-index: 2; max-width: 260px; pointer-events: none;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 10px; font-size: 0.8rem; color: var(--text);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
}
.map-tip strong { display: block; margin-bottom: 2px; }
.map-tip span { color: var(--muted); }
.map-attrib { color: var(--muted); font-size: 0.8rem; margin: 6px 2px 0; }

/* Flash the card a map marker jumps to. */
@keyframes card-flash-fade { from { outline-color: var(--accent); } to { outline-color: transparent; } }
.card-flash { outline: 2px solid transparent; outline-offset: 2px; animation: card-flash-fade 2s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .card-flash { animation: none; outline-color: var(--accent); }
}

.category { margin: 24px 0 8px; }
.category-title {
  font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600;
  color: var(--muted); border-bottom: 1px solid var(--line); padding-bottom: 6px; margin: 0 0 14px;
}

/* --- Cards: dateline · title · teaser — one anatomy for all three tabs ----- */
/* The whole card is the link: .card-title-link::after stretches the title anchor
   over the article, so the accessible name stays the title, Tab lands on one
   link per card, and the article id stays the map's jump target. Hover lifts,
   :active settles, and the keyboard ring is drawn on the card via :has(). */
.card {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px 18px 16px;
  margin: 0 0 14px;
  cursor: pointer;
  transition: transform 160ms ease-out, border-color 160ms ease-out, box-shadow 160ms ease-out;
}
.card:hover { transform: translateY(-2px); border-color: var(--accent-soft); box-shadow: 0 10px 26px rgba(0, 0, 0, 0.38); }
.card:active { transform: translateY(0); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3); }
.card:has(.card-title-link:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.card-title-link:focus-visible { outline: none; }
/* The arrow closes the dateline row: a stroked SVG (not a text glyph, which sits
   below the capitals' optical centre), centred by the signal group's flex. */
.card-arrow {
  width: 14px; height: 14px; flex: none; display: block; color: var(--muted);
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
  transition: transform 160ms ease-out, color 160ms ease-out;
}
.card:hover .card-arrow { transform: translateX(3px); color: var(--accent); }

/* Dateline: short structured facts on the left (category | country | date), the
   live signal on the right (event status with a dot, plus a pill only when the
   record is the exception — partial / under review — never when verified). */
.card-dateline {
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 2px 16px;
  margin: 0; font-size: 0.78rem; line-height: 1.6; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); min-width: 0;
}
/* Facts shrink and wrap inside their own box, so the signal stays on the first
   row instead of being pushed under a long dateline. */
.card-facts { flex: 1 1 0; min-width: 0; overflow-wrap: anywhere; }
.card-sep { margin: 0 0.55em; opacity: 0.45; font-weight: 400; }
.card-signal { display: flex; align-items: center; gap: 12px; margin-left: auto; white-space: nowrap; }
/* Event status is a word with a dot — never a pill, and never green. */
.card-status::before {
  content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  margin: 0 6px 2px 0; vertical-align: middle; background: var(--grey);
}
.status-ongoing::before { background: var(--red); }
.status-contained::before { background: var(--amber); }
.status-resolved::before { background: var(--grey); }
.card-trust { text-transform: none; letter-spacing: 0; }

.card-title {
  margin: 6px 0 4px; font-family: var(--font-display); font-weight: 600; font-size: 1.3rem;
  line-height: 1.25; letter-spacing: -0.01em; min-width: 0; overflow-wrap: break-word;
}
.card-title-link { color: inherit; text-decoration: none; }
.card-title-link::after { content: ""; position: absolute; inset: 0; }
/* The teaser is the first sentence of the description, complete — no clamp. */
.card-teaser { margin: 0; color: var(--text); overflow-wrap: break-word; }


.badge {
  display: inline-block; font-size: 0.78rem; font-weight: 600;
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line);
  color: var(--text); background: var(--panel-2);
  /* Chips must never widen the page: wrap and break rather than overflow. */
  max-width: 100%; white-space: normal; overflow-wrap: anywhere;
}
.badge-verified { color: #0f1115; background: var(--green); border-color: var(--green); }
.badge-partial  { color: #0f1115; background: var(--amber); border-color: var(--amber); }
.badge-unverified { color: var(--text); background: var(--panel-2); border-color: var(--grey); }
.badge-disputed { color: #0f1115; background: var(--red); border-color: var(--red); }
.badge-review   { color: #0f1115; background: var(--amber); border-color: var(--amber); }

/* Narrow screens: the trust mark takes its own row (right-aligned) instead of
   squeezing the facts into a three-line column beside it. */
@media (max-width: 480px) {
  .card-facts { flex-basis: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .card, .card-arrow { transition: none; }
  .card:hover, .card:active { transform: none; }
  .card:hover .card-arrow { transform: none; }
}

.claim { padding: 10px 0; border-bottom: 1px solid var(--line); }
.claim:last-child { border-bottom: none; }
.claim-text { margin: 0 0 6px; overflow-wrap: break-word; }
.claim-src { font-size: 0.85rem; color: var(--muted); display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* A claim with no source_name falls back to the raw URL as link text. */
.claim-src a { min-width: 0; overflow-wrap: anywhere; }

/* --- Record detail view (#<tab>/<record-id>) -------------------------------- */
.detail-back { margin: 0 0 16px; font-size: 0.9rem; }
.detail h2 {
  margin: 6px 0 0; font-family: var(--font-display); font-weight: 600; font-size: 1.75rem;
  line-height: 1.2; letter-spacing: -0.015em; min-width: 0; overflow-wrap: break-word;
}
/* Facts block under the detail head: full location (text colour), scale, the
   live-source link, last-updated, and the gate's verdict in words. */
.detail-facts { margin-top: 12px; }
.fact { margin: 0 0 4px; font-size: 0.85rem; color: var(--muted); overflow-wrap: break-word; }
.fact-where { color: var(--text); font-weight: 500; }
.detail-prose { max-width: 74ch; overflow-wrap: break-word; }
.detail-section { margin-top: 28px; }
.detail-section h3 {
  font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600;
  color: var(--muted); border-bottom: 1px solid var(--line); padding-bottom: 6px; margin: 0 0 14px;
}
.figure { margin: 4px 0; }
.figures-summary { margin-top: 12px; }
.update { display: flex; gap: 12px; border-bottom: 1px solid var(--line); padding: 8px 0; }
.update:last-child { border-bottom: none; }
.update-date { color: var(--muted); white-space: nowrap; }
.update-text { overflow-wrap: break-word; min-width: 0; }
.detail.under-review { border-left: 3px solid var(--amber); padding-left: 16px; }

.review-section { margin-top: 40px; }
.review-banner {
  background: rgba(210, 153, 34, 0.12);
  border: 1px solid var(--amber);
  border-radius: 10px;
  padding: 12px 16px;
  color: var(--amber);
  font-size: 0.9rem;
  margin-bottom: 14px;
}
.review-section .card { border-left: 3px solid var(--amber); }

.site-footer {
  margin-top: 48px; padding-top: 20px; padding-bottom: 40px;
  border-top: 1px solid var(--line); color: var(--muted); font-size: 0.85rem;
}
.site-footer p { margin: 0; }

/* About pane: static panels with the cards' surface, one per topic; the hidden
   h2 keeps the outline, so the first panel needs the pane's top spacing itself. */
.about .panel:first-of-type { margin-top: 0; }
.panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 14px 18px 16px; margin: 0 0 14px;
}
.panel-title {
  margin: 0 0 8px; font-size: 0.78rem; line-height: 1.6; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
}
.panel p { margin: 0 0 12px; overflow-wrap: break-word; }
.panel p:last-child { margin-bottom: 0; }
.error { color: var(--red); }
