/* Meridian baseline stylesheet.
 *
 * Design goals:
 *   - Works with JavaScript disabled (progressive enhancement only)
 *   - No third-party fonts, no remote resources, no CDN dependencies
 *   - WCAG 2.2 AA color contrast in both light and dark
 *   - Colorblind-safe palettes (Okabe-Ito categorical; viridis sequential for heatmaps)
 *   - Prints cleanly for journalists and researchers
 */

/* ---------- Custom properties: palettes ---------- */
:root {
  color-scheme: light dark;

  /* Neutrals (light mode) */
  --bg: #fbfbf9;
  --bg-subtle: #f2f1ec;
  --fg: #1a1a1a;
  --fg-muted: #555552;
  --border: #d8d7d2;
  --link: #0b4a82;
  --link-visited: #5a3a8a;
  --link-hover: #073566;
  --accent: #b03a2e;

  /* Okabe-Ito categorical palette (colorblind-safe) */
  --cat-0: #000000;
  --cat-1: #e69f00;
  --cat-2: #56b4e9;
  --cat-3: #009e73;
  --cat-4: #f0e442;
  --cat-5: #0072b2;
  --cat-6: #d55e00;
  --cat-7: #cc79a7;

  /* Viridis 5-step sequential (for heatmaps) */
  --seq-0: #440154;
  --seq-1: #3b528b;
  --seq-2: #21918c;
  --seq-3: #5ec962;
  --seq-4: #fde725;

  /* Typography stack. Inter and IBM Plex Mono are self-hosted WOFF2
     files (see static/fonts/). System fonts remain as the fallback for
     any connection where the variable font hasn't loaded yet. */
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;

  --measure: 68ch;
  --step: 1rem;
  --radius: 4px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #111214;
    --bg-subtle: #1a1c1f;
    --fg: #ededed;
    --fg-muted: #a8a8a5;
    --border: #2a2c30;
    --link: #7ab8ff;
    --link-visited: #bfa4ff;
    --link-hover: #b3d4ff;
    --accent: #ff7a6b;
  }
}

/* ---------- Self-hosted fonts ----------
   Variable Inter covers every weight in one file. IBM Plex Mono ships
   per-weight files; we only bundle Regular + Bold since nothing in the
   templates asks for italics or other weights on the mono face.
   font-display:swap lets text render immediately in a system fallback
   rather than waiting on font download — important on low-bandwidth
   connections and for progressive-enhancement. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/fonts/InterVariable.woff2") format("woff2-variations"),
       url("/static/fonts/InterVariable.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/fonts/InterVariable-Italic.woff2") format("woff2-variations"),
       url("/static/fonts/InterVariable-Italic.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/IBMPlexMono-Bold.woff2") format("woff2");
}

/* ---------- Reset ---------- */
*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.55;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

img,
svg { max-width: 100%; height: auto; }

code,
kbd,
pre,
samp { font-family: var(--font-mono); font-size: 0.93em; }

pre { overflow-x: auto; padding: 0.8em 1em; background: var(--bg-subtle); border-radius: var(--radius); }

/* ---------- Typography ---------- */
h1, h2, h3, h4 { line-height: 1.2; letter-spacing: -0.01em; }
h1 { font-size: 2.25rem; margin: 0 0 0.4em; }
h2 { font-size: 1.5rem; margin: 2em 0 0.5em; }
h3 { font-size: 1.2rem; margin: 1.5em 0 0.4em; }

p, ul, ol, dl { margin: 0 0 1em; max-width: var(--measure); }

a { color: var(--link); text-decoration-thickness: from-font; text-underline-offset: 0.18em; }
a:visited { color: var(--link-visited); }
a:hover { color: var(--link-hover); }
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }

.muted { color: var(--fg-muted); font-size: 0.92em; }
.lede  { font-size: 1.15em; color: var(--fg); max-width: var(--measure); }

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--fg);
  color: var(--bg);
  padding: 0.6em 1em;
  z-index: 100;
}
.skip-link:focus-visible {
  left: 0;
}

/* ---------- Layout primitives ---------- */
.wrap {
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* ---------- Site chrome ---------- */
.site-header {
  border-bottom: 1px solid var(--border);
  background: var(--bg-subtle);
}
.site-header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 1rem 1.5rem;
  padding-top: 0.9rem;
  padding-bottom: 0.9rem;
}
.site-logo { color: var(--fg); text-decoration: none; font-size: 1.15rem; }
.site-nav { display: flex; flex-wrap: wrap; gap: 0 1.1rem; }
.site-nav a { color: var(--fg); text-decoration: none; }
.site-nav a:hover,
.site-nav a:focus-visible { text-decoration: underline; }

.site-main { padding: 2.5rem 0 3rem; }

.site-footer {
  border-top: 1px solid var(--border);
  background: var(--bg-subtle);
  color: var(--fg-muted);
  padding: 1.8rem 0;
  font-size: 0.9rem;
}
.site-footer p { max-width: none; margin: 0 0 0.4em; }
.site-footer a { color: var(--fg-muted); }
.footer-note a { text-decoration: underline; }
.build-prov code { background: transparent; }

/* ---------- Components ---------- */
.hero h1 { max-width: 24ch; }
.hero .lede { max-width: var(--measure); }

.axes-list,
.models-list {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.6rem;
}
.axes-list a,
.models-list a {
  display: block;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--fg);
  background: var(--bg-subtle);
}
.axes-list a:hover,
.axes-list a:focus-visible,
.models-list a:hover,
.models-list a:focus-visible {
  border-color: var(--link);
  background: var(--bg);
}
.axes-list strong,
.models-list strong { display: block; }

/* Per-model tile spelling out the refusal-rate sparkline below the
 * provider/version line. Visual scoreboard treatment for /. */
.models-list .model-tile-sparkline {
  display: block;
  margin-top: 0.4em;
  color: var(--fg-muted);
}
.models-list .model-tile-sparkline svg {
  width: 100%;
  max-width: 160px;
  height: 24px;
}
.models-list .model-tile-no-data {
  display: block;
  margin-top: 0.4em;
  font-size: 0.78rem;
  font-style: italic;
  /* Don't use the muted colour here. .muted gives ~7:1 contrast on
   * its own, but on a small italic font axe scrutinises it harder
   * and we don't need the muted treatment — the bracketed wording
   * is already an unambiguous "this is metadata" signal. */
  color: var(--fg);
}
/* Carry-forward (available=false) tiles get a dashed border instead
 * of an opacity dim. Opacity below ~0.85 drops .muted contrast under
 * the AA floor on Chrome's compositor, which axe correctly flags. */
.models-list .model-tile-dim a {
  border-style: dashed;
}

/* Notable-shift callout cards on /. Three cards in a row at desktop,
 * stacking to one column on mobile. Each card carries the headline
 * delta in large numerals, then the prompt link + small-print context. */
.notable-cards {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.8rem;
  margin: 0.6rem 0 1.4rem;
}
.notable-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.8em 1em;
  background: var(--bg-subtle);
}
.notable-card p { margin: 0 0 0.4em; max-width: none; }
.notable-card .notable-metric {
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.78rem;
  color: var(--fg-muted);
  font-weight: 600;
}
.notable-card .notable-delta {
  font-size: 1.1rem;
  font-variant-numeric: tabular-nums;
}
.notable-card .notable-arrow {
  font-weight: 600;
  margin-left: 0.4em;
}
.notable-card .notable-prompt a {
  font-weight: 600;
}
.notable-card .notable-context { font-size: 0.85rem; }

/* Drift heatmap table on /. Different layout from the .heatmap grid
 * (which is used inside per-axis pages); this one is a real <table>
 * for axis × model so screen readers announce headers correctly. */
.heatmap-table {
  border-collapse: separate;
  border-spacing: 2px;
  width: auto;
  margin: 1em 0;
}
.heatmap-table th,
.heatmap-table td { padding: 0.4em 0.6em; }
.heatmap-table thead th {
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
  border-bottom: none;
}
.heatmap-table tbody th[scope="row"] {
  text-align: left;
  font-weight: 500;
  white-space: nowrap;
  border-bottom: none;
  background: var(--bg-subtle);
}
.heatmap-table tbody th[scope="row"] a {
  color: var(--fg);
  text-decoration: none;
}
.heatmap-table tbody th[scope="row"] a:hover { text-decoration: underline; }
.heatmap-table .heatmap-cell {
  text-align: center;
  min-width: 4rem;
  border-bottom: none;
}
.heatmap-table .heatmap-cell a {
  color: inherit;
  text-decoration: none;
  display: block;
}
.heatmap-table .heatmap-cell a:hover .cell-score,
.heatmap-table .heatmap-cell a:focus-visible .cell-score {
  text-decoration: underline;
}
.heatmap-table .heatmap-empty {
  background: var(--bg-subtle);
  color: var(--fg-muted);
  text-align: center;
}
.cell-score { font-variant-numeric: tabular-nums; font-weight: 600; }
.cell-as-of {
  display: block;
  margin-top: 0.1em;
  font-size: 0.7rem;
  font-weight: 400;
  letter-spacing: 0.04em;
  /* Inherit colour from the cell's inline `color:` so the as-of
   * label tracks the bg/fg pair (white on dark cells, dark on light).
   * Avoids the contrast cliff a hardcoded muted colour would re-create.
   * Opacity stays at 1.0: the size + weight differential vs. the score
   * already de-emphasizes this label, and any opacity reduction drops
   * dark-text-on-mid-viridis (e.g. #111 on #21918c teal) under WCAG AA.
   * The previous 0.85 worked when stale cells only landed on dark
   * backgrounds; per-row colour normalization can land them anywhere. */
}

/* Heatmap cells (CSS grid). Colors set inline via style="background:var(--seq-N)" */
.heatmap {
  display: grid;
  gap: 2px;
  background: var(--border);
  padding: 2px;
  border-radius: var(--radius);
  overflow-x: auto;
}
/* Scope to .heatmap (the CSS grid container on per-axis pages). Without
 * this scoping, `display: flex` strips table-cell behavior from the
 * homepage <td class="heatmap-cell"> elements, collapsing all three
 * model columns into one stacked column. */
.heatmap .heatmap-cell {
  min-width: 2.2rem;
  min-height: 2.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  color: var(--bg);
  background: var(--seq-2);
  text-decoration: none;
}
.heatmap .heatmap-cell:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* GitHub link in the header. Inline SVG, no remote dependency.
 * Selector is `a.site-github` (specificity 0,1,1) so it wins against
 * any future `header a { color: ... }` rule the way `a.bmc-button`
 * does in the footer. */
a.site-github {
  color: var(--fg);
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  line-height: 0;
  padding: 0.2em;
  border-radius: var(--radius);
}
a.site-github:hover,
a.site-github:focus-visible {
  color: var(--link-hover);
  text-decoration: none;
}
a.site-github:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Search */
.site-search { margin-left: auto; position: relative; }
.site-search input[type="search"] {
  padding: 0.35em 0.6em;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--fg);
  font: inherit;
  min-width: 18ch;
}
.search-results {
  list-style: none;
  padding: 0.3em;
  margin: 0;
  position: absolute;
  top: 2.4em;
  right: 0;
  width: 28ch;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 4px 14px rgba(0,0,0,0.12);
  z-index: 20;
}
.search-results:empty { display: none; }
.search-results li { padding: 0.3em 0.5em; display: flex; gap: 0.5em; align-items: center; }
.search-results a { text-decoration: none; color: var(--fg); flex: 1; }
.search-results a:hover,
.search-results a:focus-visible { text-decoration: underline; }

/* Filter chips */
.filter-chips {
  display: flex; flex-wrap: wrap; gap: 0.3em; margin: 0.4em 0;
}
.chip,
.tag {
  padding: 0.15em 0.5em;
  font-size: 0.78rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-subtle);
  color: var(--fg-muted);
  text-decoration: none;
  cursor: pointer;
  font: inherit;
  line-height: 1.4;
}
.tag { cursor: default; padding: 0.1em 0.45em; font-size: 0.72rem; }
.chip[aria-pressed="true"] { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* "Buy me a coffee" button. Self-styled (no remote image) to honor the
 * site's no-third-party-resources rule. The red tones are darker than
 * BMC's stock pink so white-on-red clears WCAG AA (4.5:1). Fixed
 * colors — not theme variables — so contrast holds under both light
 * and dark schemes.
 *
 * Selector uses `a.bmc-button` (specificity 0,1,1) so it beats
 * `.site-footer a` when the button lives in the footer. Without the
 * `a` qualifier, the muted-link color wins by specificity and drops
 * contrast to ~2.5:1. */
a.bmc-button {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.55em 1.1em;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.95rem;
  color: #fff;
  background: #b03a2e;  /* 5.9:1 on #fff */
  border: 1px solid #8e2d24;
  border-radius: 999px;
  text-decoration: none;
  line-height: 1.2;
  transition: transform 120ms ease, background 120ms ease;
}
a.bmc-button:visited { color: #fff; }
a.bmc-button:hover,
a.bmc-button:focus-visible {
  background: #8e2d24;  /* 8.3:1 on #fff */
  color: #fff;
  text-decoration: none;
  transform: translateY(-1px);
}
a.bmc-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
a.bmc-button .cup { font-size: 1.2em; line-height: 1; }

/* Citation entries. Wraps <details> + injected .copy-btn so the button
 * is a sibling of <summary>, not nested inside it (nested interactive
 * elements fail WCAG; see _citation.html and citations.js). */
.citation-entry {
  position: relative;
  margin-bottom: 0.8em;
}
.citation-entry .copy-btn {
  position: absolute;
  top: 0.2em;
  right: 0.2em;
}

.copy-btn {
  font: inherit;
  font-size: 0.8rem;
  padding: 0.1em 0.55em;
  border: 1px solid var(--border);
  background: var(--bg-subtle);
  color: var(--fg);
  border-radius: var(--radius);
  cursor: pointer;
}
.copy-btn:hover { background: var(--bg); }

/* Visually-hidden but still announced to screen readers. */
.visually-hidden {
  position: absolute; clip: rect(0 0 0 0); clip-path: inset(50%);
  width: 1px; height: 1px; overflow: hidden; white-space: nowrap;
}

/* Data table defaults */
table {
  border-collapse: collapse;
  width: 100%;
  margin: 1em 0;
}
th, td {
  text-align: left;
  padding: 0.4em 0.7em;
  border-bottom: 1px solid var(--border);
}
caption { text-align: left; color: var(--fg-muted); margin-bottom: 0.3em; }

/* ---------- Stance badges ---------- */
.stance {
  display: inline-block;
  padding: 0.1em 0.55em;
  border-radius: 3px;
  font-size: 0.88em;
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid var(--border);
  background: var(--bg-subtle);
  color: var(--fg);
}
.stance-pro      { background: #1a4d2e; color: #e8f4eb; border-color: #2d7346; }
.stance-anti     { background: #5c1f1f; color: #f7e5e5; border-color: #8a3636; }
.stance-neutral  { background: var(--bg-subtle); color: var(--fg); }

/* ---------- Severity badges (silent-update warnings) ---------- */
.severity {
  display: inline-block;
  padding: 0.1em 0.55em;
  border-radius: 3px;
  font-size: 0.88em;
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid var(--border);
  text-transform: uppercase;
}
.severity-low    { background: var(--bg-subtle); color: var(--fg-muted); }
.severity-medium { background: #7a5c1f; color: #faf0db; border-color: #a68132; }
.severity-high   { background: #5c1f1f; color: #f7e5e5; border-color: #8a3636; }

/* "What's measured this week" status badges on /methodology/. Same
 * visual grammar as .severity / .stance — rounded inline-block with
 * a colour that codes the metric's pipeline state. */
[class^="status-"] {
  display: inline-block;
  padding: 0.1em 0.55em;
  border-radius: 3px;
  font-size: 0.88em;
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid var(--border);
}
.status-live              { background: #1a4d2e; color: #e8f4eb; border-color: #2d7346; }
.status-live-no-flags-this-week { background: var(--bg-subtle); color: var(--fg-muted); }
.status-data-gated        { background: #7a5c1f; color: #faf0db; border-color: #a68132; }
.status-off               { background: #5c1f1f; color: #f7e5e5; border-color: #8a3636; }

/* ---------- Semantic-drift cell ---------- */
.semantic-drift-cell { font-variant-numeric: tabular-nums; }
.semantic-drift-cell .magnitude { font-weight: 600; }
.semantic-drift-cell .hint { color: var(--fg-muted); font-size: 0.85em; }

/* ---------- Print ---------- */
@media print {
  :root { --bg: #fff; --fg: #000; --fg-muted: #333; --border: #999; }
  body { background: #fff; color: #000; font-size: 11pt; line-height: 1.4; }
  .site-header, .site-nav, .site-footer .footer-note a { background: #fff; color: #000; }
  .skip-link { display: none; }
  /* Donation widget + repo link have no place on printed reports. */
  .footer-support, a.bmc-button, a.site-github { display: none; }
  a { color: #000; text-decoration: underline; }
  a[href]::after { content: " (" attr(href) ")"; font-size: 85%; color: #333; }
  .build-prov { border-top: 1px solid #999; padding-top: 0.5em; }
  main { padding: 0; }
  h1, h2, h3 { page-break-after: avoid; }
  table, figure, pre { page-break-inside: avoid; }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
