/* Benchmarks page.

   The :root block below is a near-copy of the one in index.css, deliberately,
   for the reason already recorded in CLAUDE.md: one shared tokens file would
   couple pages that are otherwise edited independently. If these drift far
   enough to cause a real bug, that is the point to revisit it. */

:root {
  --bg: #11141a;
  --surface: #171b22;
  --surface-2: #1c212a;
  --border: #262b35;
  --text: #e9e8e4;
  --text-muted: #8b92a0;
  --text-dim: #565d6b;
  --brass: #b08d57;
  --brass-dim: #8a6f45;
  --signal: #6b93b5;
  --pass: #6f9e6f;
  --mixed: #b08d57;
  --fail: #b57a7a;
  --serif: 'Spectral', Georgia, serif;
  --sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, sans-serif;
}

/* Light mode is opt-in only, per visit, never remembered — matching the other
   two pages. No localStorage, no prefers-color-scheme. */
html[data-theme="light"] {
  --bg: #f6f4ef;
  --surface: #ffffff;
  --surface-2: #eeebe3;
  --border: #ddd7c9;
  --text: #201d19;
  --text-muted: #5b5548;
  --text-dim: #8a8375;
  --brass: #9c7a3f;
  --brass-dim: #b08d57;
  --signal: #3d6a8f;
  --pass: #4a7a4a;
  --mixed: #8a6a2f;
  --fail: #9c5555;
}

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

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: 1080px; margin: 0 auto; padding: 0 28px; }

a { color: inherit; }

/* ---------- header / footer ---------- */

header { border-bottom: 1px solid var(--border); padding: 18px 0; }
header .wrap { display: flex; align-items: center; justify-content: space-between; gap: 20px; }

.mark { font-family: var(--serif); font-size: 20px; letter-spacing: -0.01em; text-decoration: none; }
.mark span { color: var(--brass); }
/* Painted through the PNG's alpha so one file is right in both themes — see the
   long note in css/chat.css for why the artwork cannot be used as-is. */
.mark-img {
  display: block; width: 160px; height: 48px;
  background: var(--text);
  -webkit-mask: url('/img/zerowitness-mark.png') no-repeat center / contain;
  mask: url('/img/zerowitness-mark.png') no-repeat center / contain;
}

nav { display: flex; align-items: center; gap: 22px; }
nav a { color: var(--text-muted); text-decoration: none; font-size: 13.5px; }
nav a:hover { color: var(--text); }

.theme-switch {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: none; cursor: pointer; color: var(--text-dim); padding: 0;
}
.theme-switch-track {
  width: 30px; height: 16px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--border);
  position: relative; display: inline-block;
}
.theme-switch-thumb {
  position: absolute; top: 1px; left: 1px; width: 12px; height: 12px;
  border-radius: 50%; background: var(--brass); transition: transform .16s ease;
}
html[data-theme="light"] .theme-switch-thumb { transform: translateX(14px); }
.theme-icon { flex-shrink: 0; }

.footer-mark {
  /* inline-block so the link shrink-wraps the mark. Left inline it lays out as
     a full-width box and a click on empty footer navigates home from nowhere
     near the logo — the same bug the rail's brand already had. */
  display: inline-block;
  opacity: 0.75;
}
.footer-mark:hover { opacity: 1; }
.footer-mark:focus-visible { outline: 2px solid var(--brass-dim); outline-offset: 3px; border-radius: 2px; }
/* Smaller than the header's, and it inherits the same alpha-mask treatment, so
   it takes --text in both themes with no second asset. */
.footer-mark .mark-img { width: 118px; height: 35px; }

footer { border-top: 1px solid var(--border); padding: 30px 0 44px; margin-top: 60px; }
footer .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; color: var(--text-dim); font-size: 13px;
}
.footer-right { display: flex; align-items: center; gap: 24px; }
.footer-link { color: var(--text-muted); text-decoration: none; }
.footer-link:hover { color: var(--text); }

/* ---------- intro ---------- */

.intro { padding: 56px 0 34px; }
.intro h1 {
  font-family: var(--serif); font-weight: 500;
  font-size: clamp(30px, 4.4vw, 44px); line-height: 1.18;
  letter-spacing: -0.015em; margin-bottom: 18px;
}
.lede { max-width: 66ch; color: var(--text-muted); font-size: 16px; }
.standfirst {
  margin-top: 18px; color: var(--text-dim); font-size: 13px;
  font-variant-numeric: tabular-nums;
}

/* ---------- the caveats, deliberately above the table ---------- */

.caveat-band { padding: 8px 0 14px; }
.caveat-band .wrap {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 2px solid var(--brass-dim);
  border-radius: 6px; padding: 20px 26px; max-width: 1080px;
}
.caveat-band h2 {
  font-family: var(--sans); font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--brass); margin-bottom: 12px;
}
.caveat-band ul { list-style: none; display: grid; gap: 9px; }
.caveat-band li {
  color: var(--text-muted); font-size: 14px; padding-left: 16px; position: relative; max-width: 90ch;
}
.caveat-band li::before {
  content: ''; position: absolute; left: 0; top: 10px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--border);
}
.caveat-band strong { color: var(--text); font-weight: 600; }

/* ---------- results table ---------- */

.results { padding: 44px 0 10px; }

.results-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap; margin-bottom: 16px;
}
.results h2, .models h2, .probes h2, .method h2, .cta h2 {
  font-family: var(--serif); font-weight: 500; font-size: 24px; letter-spacing: -0.01em;
}

.filters { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.filters label {
  display: inline-flex; align-items: center; gap: 7px;
  color: var(--text-dim); font-size: 12px;
}
.filters select {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 6px 9px; font: 500 12.5px/1 var(--sans); cursor: pointer;
}
.filters select:focus-visible { outline: 2px solid var(--brass-dim); outline-offset: 1px; }
.shown-count { color: var(--text-dim); font-size: 12px; font-variant-numeric: tabular-nums; }

/* Matches the selects beside it rather than inventing a second control look —
   type=search so a phone offers the right keyboard and a clear affordance. */
.filters input[type="search"] {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 6px 9px; font: 500 12.5px/1 var(--sans); width: 150px;
}
.filters input[type="search"]::placeholder { color: var(--text-dim); }
.filters input[type="search"]:focus-visible { outline: 2px solid var(--brass-dim); outline-offset: 1px; }

/* The overall figure. Stars are drawn as one glyph row clipped to a percentage
   rather than five separate marks, which is what lets 4.8 look like 4.8 instead
   of rounding to a whole star — the figure and the picture must not disagree. */
.col-overall { white-space: nowrap; text-align: left; }
.stars {
  position: relative; display: inline-block; vertical-align: -2px;
  width: 62px; height: 12px;
  color: var(--border);
}
.stars::before,
.stars i::before {
  content: '★★★★★';
  position: absolute; left: 0; top: 0;
  font-size: 12px; line-height: 12px; letter-spacing: 0.5px;
}
.stars i {
  position: absolute; left: 0; top: 0; height: 100%;
  overflow: hidden; color: var(--brass);
}
.score-num { margin-left: 7px; font-weight: 600; font-variant-numeric: tabular-nums; }
/* Never dropped for space: the models sat different exams and this is the only
   thing on the row that says so. */
.score-of { margin-left: 5px; color: var(--text-dim); font-size: 11.5px; }
.score-none { color: var(--text-dim); }

.compact-overall { margin: 6px 0 2px; }

/* Sortable headers. The button fills the cell so the whole header is the target
   rather than the few pixels of its text, and it inherits the header's own type
   rather than looking like a control dropped into a table. */
.th-sort {
  display: inline-flex; align-items: center; gap: 4px;
  background: none; border: none; padding: 0; margin: 0;
  color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit;
  cursor: pointer; text-align: left;
}
.th-sort:hover { color: var(--text); }
.th-sort:focus-visible { outline: 2px solid var(--brass-dim); outline-offset: 2px; border-radius: 3px; }
.th-sort.is-on { color: var(--brass); }
/* The idle arrow is present but nearly invisible: it says "this sorts" without
   nine bright arrows competing with the one that is actually in effect. It is
   not hover-only — that would not exist on a phone, and this table has headers
   on a desktop only anyway, but the rule is the rule. */
.sort-arrow { font-size: 8px; line-height: 1; }
.sort-arrow.is-idle { opacity: 0.28; }
.th-sort:hover .sort-arrow.is-idle { opacity: 0.6; }

/* Replaces the nine per-column "?" links. Quiet, above the table, and reachable
   by keyboard like any other link — the abbreviations still need explaining, they
   just do not each need their own glyph to do it. */
.col-key { margin: 0 0 8px; font-size: 12px; }
.col-key a { color: var(--text-dim); text-decoration: none; border-bottom: 1px dotted var(--border); }
.col-key a:hover { color: var(--brass); border-bottom-color: var(--brass-dim); }
.col-key a:focus-visible { outline: 2px solid var(--brass-dim); outline-offset: 2px; }

.overall-note {
  margin-top: 14px; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface);
  color: var(--text-muted); font-size: 13px; line-height: 1.6;
}
.overall-note strong { color: var(--text); font-weight: 600; }
:target.overall-note { border-color: var(--brass-dim); }

/* Wide content scrolls inside its own container — the page body must never
   scroll sideways. */
.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--border); border-radius: 6px; background: var(--surface);
}
/* Sized so that all nine probe columns fit a laptop without scrolling, and any
   single focus group fits comfortably narrower than that. The earlier version
   used the full probe names as headers, which pushed the minimum past 1100px
   and made even a desktop scroll sideways. */
table { border-collapse: collapse; width: 100%; min-width: 720px; font-size: 13px; }
th, td {
  border-bottom: 1px solid var(--border);
  padding: 10px 8px; text-align: center; vertical-align: middle;
}
tbody tr:last-child th, tbody tr:last-child td { border-bottom: none; }
thead th {
  color: var(--text-dim); font-weight: 500; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: 0.04em;
  background: var(--surface-2);
}
thead th a { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--border); }
thead th a:hover { color: var(--text); }
.col-probe { width: 78px; }

/* The row label has to stay put while the remaining columns scroll — a grid of
   numbers whose row names have scrolled off is not readable. */
.col-model {
  position: sticky; left: 0; z-index: 1;
  min-width: 165px; text-align: left; font-weight: 500;
  background: var(--surface);
  box-shadow: 1px 0 0 var(--border);
}
thead .col-model { background: var(--surface-2); }
.model-name { color: var(--text); text-decoration: none; display: block; font-size: 13.5px; }
.model-name:hover { color: var(--brass); }
.model-sub { display: block; color: var(--text-dim); font-size: 11px; font-weight: 400; margin-top: 1px; }

.cell-score { font-variant-numeric: tabular-nums; font-weight: 600; font-size: 14px; }
.cell-score.is-good { color: var(--pass); }
.cell-score.is-mixed { color: var(--mixed); }
.cell-score.is-poor { color: var(--fail); }
/* The denominator is the same on every cell, so it is stated once in the legend
   and shown here only faintly — nine repetitions of "/5" is most of the ink in
   the table and none of the information. */
.cell-of { color: var(--text-dim); font-weight: 400; font-size: 10.5px; }
.cell-none { color: var(--text-dim); font-size: 13px; }
.cell-untested { color: var(--text-dim); font-size: 12.5px; font-style: italic; }

.col-try { text-align: right; white-space: nowrap; width: 60px; }
.try-link {
  color: var(--brass); text-decoration: none; font-size: 12px; font-weight: 600;
  border: 1px solid var(--border); border-radius: 4px; padding: 4px 9px;
  display: inline-block;
}
.try-link:hover { border-color: var(--brass-dim); background: var(--surface-2); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---------- narrow-screen replacement for the table ---------- */

/* Hidden on wide screens; the media query at the foot of this file swaps which
   of the two is displayed. */
.compact-list { display: none; }
.compact-row {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 6px; padding: 13px 15px; margin-bottom: 8px;
}
.compact-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.compact-head .model-name { font-size: 15px; }
.compact-probes { list-style: none; display: grid; gap: 4px; margin-top: 10px; }
.compact-probes li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  font-size: 12.5px; color: var(--text-muted);
  border-bottom: 1px dotted var(--border); padding-bottom: 3px;
}
.compact-untested { color: var(--text-dim); font-size: 12.5px; font-style: italic; margin-top: 8px; }

.table-legend, .empty-note {
  color: var(--text-dim); font-size: 12.5px; margin-top: 12px;
}
.legend-n { font-variant-numeric: tabular-nums; }

/* ---------- model cards ---------- */

.models { padding: 46px 0 0; }
.model-cards {
  display: grid; gap: 16px; margin-top: 20px;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 6px; padding: 20px 22px;
  scroll-margin-top: 20px;
}
.card-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.card-head h3 { font-family: var(--serif); font-weight: 500; font-size: 18px; }
.chip {
  font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  padding: 3px 7px; border-radius: 3px; border: 1px solid var(--border);
}
.chip-default { color: var(--brass); border-color: var(--brass-dim); }
.chip-untested { color: var(--text-dim); }
.card-meta { color: var(--text-dim); font-size: 12px; margin-bottom: 10px; }
.card-summary { color: var(--text-muted); font-size: 14px; margin-bottom: 14px; }

.card-probes { list-style: none; display: grid; gap: 5px; margin-bottom: 8px; }
.card-probes li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  font-size: 13px; color: var(--text-muted);
  border-bottom: 1px dotted var(--border); padding-bottom: 4px;
}
.card-coverage { color: var(--text-dim); font-size: 11.5px; margin-bottom: 12px; }

.card-notes { list-style: none; display: grid; gap: 7px; margin-bottom: 16px; }
.card-notes li {
  color: var(--text-muted); font-size: 13px; padding-left: 14px; position: relative;
}
.card-notes li::before {
  content: ''; position: absolute; left: 0; top: 9px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--brass-dim);
}
.card-try { color: var(--brass); text-decoration: none; font-size: 13px; font-weight: 600; }
.card-try:hover { text-decoration: underline; }

/* ---------- probes ---------- */

.probes { padding: 46px 0 0; }
.probes-lede { color: var(--text-muted); font-size: 14.5px; max-width: 70ch; margin: 10px 0 20px; }
.probe-list { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.probe {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 6px; padding: 18px 20px; scroll-margin-top: 20px;
}
.probe h3 { font-size: 14.5px; font-weight: 600; margin-bottom: 10px; }
.probe p { color: var(--text-muted); font-size: 13px; }
.probe-turns {
  list-style: none; counter-reset: turn;
  background: var(--surface-2); border-radius: 5px;
  padding: 10px 12px; margin-bottom: 11px; display: grid; gap: 5px;
}
.probe-turns li {
  color: var(--text-muted); font-size: 12.5px; font-style: italic;
  padding-left: 16px; position: relative;
}
.probe-turns li::before {
  counter-increment: turn; content: counter(turn);
  position: absolute; left: 0; font-style: normal;
  color: var(--text-dim); font-size: 11px; font-variant-numeric: tabular-nums;
}

/* ---------- method + cta ---------- */

.method { padding: 46px 0 0; }
.method p { color: var(--text-muted); font-size: 14.5px; max-width: 76ch; margin-top: 12px; }
.method em { color: var(--text); font-style: italic; }

.cta { padding: 46px 0 0; }
.cta p { color: var(--text-muted); font-size: 14.5px; max-width: 66ch; margin: 10px 0 18px; }
.cta-btn {
  display: inline-block; background: var(--brass); color: #14161b;
  text-decoration: none; font-weight: 600; font-size: 14px;
  padding: 11px 20px; border-radius: 4px;
}
.cta-btn:hover { background: var(--brass-dim); }

/* ---------- responsive ---------- */

/* The swap. Below this the table would be a sideways scroll through a grid
   whose row labels have gone off screen; the stacked list says the same thing
   one model at a time, driven by the same filters. */
@media (max-width: 880px) {
  .table-scroll { display: none; }
  .compact-list { display: block; }
}

@media (max-width: 720px) {
  /* The lockup is 160px here and the nav beside it is ~197px, which overflows a
     375px screen by 20px — the page body scrolling sideways, which this repo
     does not allow. index.css got this rule when the wordmark went in and this
     file did not; same fix, same scoping to .mark-img. */
  .mark-img { width: 104px; height: 31px; }
  .wrap { padding: 0 18px; }
  .intro { padding: 38px 0 24px; }
  .caveat-band .wrap { padding: 16px 18px; }
  .results-head { align-items: flex-start; }
  .filters { gap: 10px; }
  footer .wrap { flex-direction: column; align-items: flex-start; gap: 12px; }
  .footer-right { flex-direction: column; align-items: flex-start; gap: 8px; }
  nav { gap: 14px; }
  nav a { font-size: 12.5px; }
}

/* ── Accessibility utilities ─────────────────────────────────────────────
   Added 9 Sep 2026 with the <main> landmarks and chat.html's h1.

   EVERY COLOUR HERE CARRIES A var() FALLBACK ON PURPOSE. These same two rules
   go into three stylesheets that deliberately do not share a :root, and this
   repo has already paid for that once: --brass-dim existed in index.css and not
   chat.css, and an undefined custom property invalidates the whole declaration
   rather than falling back, so a button computed to transparent and every focus
   ring went invisible. A literal fallback cannot fail that way. */

/* The first focusable thing in the document, and off-screen until it is
   focused — so it costs a sighted visitor nothing and saves a keyboard one a
   full pass through the navigation on every load. Not display:none, which
   would take it out of the focus order and defeat the point entirely. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
}
.skip-link:focus {
  left: 10px;
  top: 10px;
  padding: 10px 14px;
  background: var(--surface, #16181d);
  color: var(--text, #e9e8e4);
  border: 1px solid var(--brass, #b08d57);
  border-radius: 8px;
  font: 500 14px/1.2 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
  text-decoration: none;
}

/* Announced, never drawn. clip-path is the modern half and clip the legacy one;
   both are kept because dropping either loses a browser somebody still uses. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
