/* Vannaris — a public instrument, not a HUD and not a paper mock.
 *
 * Dark field, Geist for words, Geist Mono for readouts. Identity is infrared
 * red used as a signal (mark, current nav, primary button, leader outline,
 * finding rule). Quantity rides an ice-to-heat ramp so the identity colour
 * never has to mean "series 2".
 *
 * No page makes an external request. Motion is additive: the default state
 * is the finished state, and prefers-reduced-motion skips the performance.
 * The one entrance is the hero matrix lighting, cell by cell.
 */

/* ------------------------------------------------------------------- fonts */
@font-face {
  font-family: "Geist";
  src: url("fonts/geist.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("fonts/geistmono.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

/* ------------------------------------------------------------------ tokens */
:root {
  color-scheme: dark;

  --page:        #07080c;
  --page-2:      #0a0c12;
  --card:        #10131a;
  --card-2:      #161a24;
  --card-3:      #1e2430;

  --ink:         #eef2f7;
  --ink-2:       #a8b0bd;
  --ink-3:       #6e7686;

  --line:        rgba(238, 242, 247, 0.10);
  --line-strong: rgba(238, 242, 247, 0.18);

  --accent:      #ff2a4a;
  --accent-deep: #c91032;
  --accent-text: #ff6b82;
  --accent-wash: rgba(255, 42, 74, 0.12);
  --accent-ink:  #ffffff;
  --signal:      var(--accent);

  /* The score ramp: one hue, luminance rising monotonically from 0.008 to
   * 0.333. It ran blue → light blue → pink → accent red before, which is a
   * diverging scale, and a diverging scale asserts a midpoint. Quality here is
   * 0-10 with no meaningful middle, so the old ramp painted two cells either
   * side of an invented centre as opposites. Every step carries either #eef2f7
   * or #07080c at 4.5:1 or better — see inkFor() in site.js for the crossover. */
  --d100: #1a1420; --d200: #3a1526; --d300: #5c1a2e;
  --d400: #851f37; --d500: #b32540; --d600: #e02f4c; --d700: #ff6b7e;
  --muted-mark:  #2a3140;

  --surface:     var(--card);
  --surface-2:   var(--card-2);
  --surface-3:   var(--card-3);
  --text:        var(--ink);
  --text-2:      var(--ink-2);
  --text-3:      var(--ink-3);

  --sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
          Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, Consolas,
          "Liberation Mono", monospace;

  --shell: 1280px;
  --prose: 68ch;

  --r-sm: 0;
  --r-md: 0;
  --r-lg: 0;
  --r-xl: 0;
  --r-pill: 0;

  --z-nav: 200;
  --z-tooltip: 400;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --mast: 64px;
}

/* --------------------------------------------------------------- base type */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--mast);
  overflow-x: clip;
  overflow-y: auto;
  background: var(--page);
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--page);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  font-feature-settings: "ss01" 1, "cv11" 1;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { max-width: 100%; display: block; }
button, input, select { font: inherit; }
a { color: inherit; text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--accent-text); }
strong { font-weight: 640; color: var(--text); }
h1, h2, h3 { font-weight: 620; letter-spacing: -0.045em; line-height: 1.1; text-wrap: balance; }
h1 { font-size: clamp(2.05rem, 1.15rem + 2.6vw, 3.4rem); }
h2 { font-size: clamp(1.4rem, 1.1rem + 1vw, 1.95rem); }
h3 { font-size: 1.05rem; letter-spacing: -0.03em; }

::selection { background: rgb(255 42 74 / 0.32); color: var(--ink); }
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.shell { width: min(100% - 2.4rem, var(--shell)); margin-inline: auto; }
.mono, .num, code {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.note { font-size: 0.86rem; color: var(--text-3); line-height: 1.55; }
.lead { font-size: clamp(1.02rem, 0.95rem + 0.35vw, 1.18rem); color: var(--text-2); max-width: 62ch; }
.inert { opacity: 0.45; cursor: default; }

.eyebrow {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--text-3);
}
.eyebrow--accent { color: var(--text-3); }

.prose { max-width: var(--prose); color: var(--text-2); }
.prose p { margin: 0 0 1em; }
.prose ul, .prose ol { padding-left: 1.15em; margin: 0 0 1em; }
.prose li { margin-bottom: 0.45em; }
.prose h3 { margin: 1.9em 0 0.5em; color: var(--text); }
.prose h3:first-child { margin-top: 0; }
.prose a { color: var(--text); }
.prose strong { color: var(--text); }

code {
  font-size: 0.82em;
  background: var(--card-2);
  padding: 0.12em 0.38em;
}
pre.code {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  background: var(--card);
  box-shadow: inset 0 0 0 1px var(--line);
  padding: 1.15rem 1.25rem;
  font-size: 0.78rem;
  line-height: 1.75;
  overflow-x: auto;
  margin: 0;
  color: var(--text-2);
}

.section-head { margin: 0 0 1.5rem; max-width: 62ch; }
.section-head h2 { margin: 0; }
.section-head p { margin: 0.7rem 0 0; color: var(--text-2); font-size: 1.02rem; max-width: 56ch; }
.section-head--wide { max-width: none; }
.section-lede {
  margin: -0.35rem 0 1.4rem;
  max-width: 46ch;
  font-size: 0.9rem;
  color: var(--text-3);
  line-height: 1.5;
}

.band { background: var(--page-2); }
.seam { padding-block: clamp(3.6rem, 7vw, 5.8rem); }

.grid-2 {
  display: grid;
  gap: 1.6rem;
}
@media (min-width: 860px) {
  .grid-2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* ---------------------------------------------------------------- masthead */
.masthead {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  height: var(--mast);
  background: var(--page);
  border-bottom: 1px solid var(--line);
}
.masthead__inner {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  height: var(--mast);
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.62rem;
  text-decoration: none;
  font-weight: 660;
  letter-spacing: -0.05em;
  font-size: 1.02rem;
  color: var(--text);
}
.brand:hover { color: var(--text); }
.brand__mark {
  display: grid;
  place-items: center;
  width: 1.4rem;
  height: 1.4rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 760;
  font-size: 0.78rem;
  letter-spacing: -0.08em;
  line-height: 1;
}
.nav {
  display: flex;
  align-items: center;
  gap: 0.1rem;
  margin-left: auto;
}
.nav a {
  padding: 0.38rem 0.72rem;
  color: var(--text-2);
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 520;
  letter-spacing: -0.02em;
}
.nav a:hover { color: var(--text); }
.nav a[aria-current="page"] {
  color: var(--text);
  box-shadow: inset 0 -2px 0 var(--accent);
}

.nav-toggle {
  display: none;
  width: 2.4rem;
  height: 2.4rem;
  margin-left: auto;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  padding: 0;
}
.nav-toggle span,
.nav-toggle span::before,
.nav-toggle span::after {
  display: block;
  width: 14px;
  height: 1.5px;
  background: currentColor;
  margin: 0 auto;
  position: relative;
}
.nav-toggle span::before,
.nav-toggle span::after {
  content: "";
  position: absolute;
  left: 0;
}
.nav-toggle span::before { top: -5px; }
.nav-toggle span::after { top: 5px; }

.progress {
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--accent);
  transform-origin: 0 50%;
  transform: scaleX(0);
  pointer-events: none;
}
@supports (animation-timeline: scroll()) {
  .progress {
    animation: sb-progress linear both;
    animation-timeline: scroll(root);
  }
}
@keyframes sb-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@media (max-width: 760px) {
  .nav-toggle { display: grid; place-items: center; }
  .nav {
    display: none;
    position: absolute;
    top: var(--mast);
    left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0.6rem 1.2rem 1rem;
    background: var(--page);
    border-bottom: 1px solid var(--line);
  }
  .navbar[data-menu="open"] .nav { display: flex; }
}

/* ----------------------------------------------------------------- buttons */
.btn {
  --fill: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.82rem 1.2rem;
  border: 0;
  background: var(--fill);
  color: var(--accent-ink);
  text-decoration: none;
  font-weight: 650;
  letter-spacing: -0.03em;
  font-size: 0.95rem;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 160ms var(--ease), background 160ms var(--ease);
}
.btn:hover, .btn:focus-visible {
  color: var(--accent-ink);
  background: var(--accent-deep);
  transform: translateY(-1px);
}
.btn:active { transform: scale(0.98); }
.btn .arrow { display: inline-block; transition: transform 160ms var(--ease); }
.btn:hover .arrow { transform: translateX(3px); }

.btn--ghost {
  background: transparent;
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--line-strong);
}
.btn--ghost:hover, .btn--ghost:focus-visible {
  color: var(--text);
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--accent);
}

.cta-row { display: flex; flex-wrap: wrap; gap: 0.7rem; align-items: center; }
.link-arrow {
  display: inline-flex; align-items: center; gap: 0.4rem;
  color: var(--text); text-decoration: none; font-weight: 560;
}
.link-arrow:hover { color: var(--accent-text); }

/* -------------------------------------------------------------------- hero */
.hero {
  position: relative;
  padding: 1.8rem 0 2.2rem;
}
.hero > .shell {
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: min(100% - 2.4rem, var(--shell));
}
.hero__grid {
  display: grid;
  gap: 1.8rem;
  align-items: center;
  grid-template-columns: minmax(0, 1fr);
}
.hero h1 {
  margin: 0.5rem 0 0;
  max-width: 11ch;
  font-size: clamp(2.35rem, 1.2rem + 3.2vw, 4.05rem);
  line-height: 1.06;
  letter-spacing: -0.058em;
  font-weight: 620;
  padding-bottom: 0.08em;
}
.hero h1 em {
  font-style: italic;
  font-weight: 540;
  color: inherit;
  padding: 0 0.02em 0.12em;
}
.hero__sub {
  margin: 0.85rem 0 0;
  max-width: 34ch;
  font-size: 1.02rem;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.018em;
  color: var(--text-2);
}
.hero .cta-row { margin-top: 1.2rem; }

@media (min-width: 980px) {
  .hero { padding: 2.4rem 0 2.8rem; }
  .hero__grid {
    gap: 0 3.2rem;
    align-items: center;
    grid-template-columns: minmax(18rem, 22.5rem) minmax(0, 1fr);
  }
}

.run-line {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--text-3);
}
.run-line b { color: var(--text); font-weight: 600; }
.run-line__sep { margin: 0 0.55em; opacity: 0.4; }

/* The finding is the only infrared object on the first scroll. A wash box
 * turns the sentence into a toast. A rule and larger type is the sentence. */
.finding {
  margin: 0;
  max-width: 44rem;
  padding: 0 0 0 1.05rem;
  border-left: 2px solid var(--accent);
  color: var(--text);
  font-size: clamp(1.12rem, 0.98rem + 0.55vw, 1.48rem);
  line-height: 1.35;
  letter-spacing: -0.025em;
  font-weight: 520;
}
.finding b { font-family: var(--mono); font-weight: 620; font-size: 0.92em; }
.signal-strip {
  padding: 2rem 0 2.2rem;
  border-block: 1px solid var(--line);
}
.signal-strip .finding { margin: 0; }

.audit-stamp {
  display: block;
  margin-top: 0.85rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--text-3);
}

.page-hero {
  padding-top: 2.4rem;
  padding-bottom: clamp(1.6rem, 3vw, 2.6rem);
}
.page-hero h1 { margin: 0; max-width: 18ch; }
.page-hero .lead { margin-top: 0.85rem; }
.page-hero .cta-row { margin-top: 1.35rem; }
.page-hero .stamp { margin-top: 1.4rem; }

/* -------------------------------------------------------------- plate
 * The hero used to be a WebGL stack of cubes, then a postage-stamp widget
 * next to a slogan. The product is vendors × categories. This is that
 * matrix, same cells as the results heatmap, run-relative ice→heat. */
.plate {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.plate__board {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
/* Narrow screens cut the last categories off the right edge with no sign that
   anything is there. The fade is applied only when site.js has measured real
   overflow, and lifts at the end of the scroll so it never implies more table
   than exists. */
.plate__board.is-scrollable {
  -webkit-mask-image: linear-gradient(to right, #000 82%, rgba(0, 0, 0, 0.25) 100%);
          mask-image: linear-gradient(to right, #000 82%, rgba(0, 0, 0, 0.25) 100%);
}
.plate__board.is-scrollable.is-scrolled-end {
  -webkit-mask-image: none;
          mask-image: none;
}
.plate__table {
  display: grid;
  grid-template-columns: 7rem repeat(var(--cols, 6), minmax(3.35rem, 1fr));
  grid-template-rows: auto repeat(var(--rows, 5), minmax(2.9rem, 3.35rem));
  gap: 2px;
  width: 100%;
  min-width: 34rem;
}
.plate__table thead,
.plate__table tbody,
.plate__table tr {
  display: contents;
}
.plate__table thead th {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--text-3);
  text-align: center;
  padding: 0 0.15rem 0.5rem;
  align-self: end;
}
.plate__table thead th:first-child,
.plate__table tbody th {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--page);
}
.plate__table tbody th {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 0.7rem 0 0;
  font-size: 0.82rem;
  font-weight: 560;
  letter-spacing: -0.03em;
  white-space: nowrap;
}
.plate__vendor {
  color: var(--text-2);
  text-decoration: none;
}
.plate__vendor:hover { color: var(--ink); }
.plate__cell {
  position: relative;
  display: flex;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.84rem;
  font-weight: 560;
  letter-spacing: -0.02em;
  padding: 0;
}
.plate__cell a {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  color: inherit;
  text-decoration: none;
}
/* The category leader. An accent-red ring was legible while the ramp was blue
   and is invisible now that the ramp is red end to end; the marker has to sit
   outside the scale it marks, so it is drawn in ink. */
.plate__cell.is-lead {
  box-shadow: inset 0 0 0 1px var(--ink);
}
.plate__cell.is-empty {
  align-items: center;
  justify-content: center;
  background: var(--card-2);
  color: var(--text-3);
  box-shadow: inset 0 0 0 1px dashed var(--line);
}
.plate__cell:hover,
.plate__cell:focus-within {
  filter: brightness(1.12);
  z-index: 2;
}
.plate__hud {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem 0.85rem;
  margin: 0.65rem 0 0;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--text-3);
}
.plate__hud b { color: var(--text); font-weight: 600; }
.plate__legend {
  display: inline-flex;
  width: 5.4rem;
  height: 0.45rem;
  flex: 0 0 auto;
}
.plate__legend i { flex: 1; display: block; }
.plate__legend i:nth-child(1) { background: var(--d100); }
.plate__legend i:nth-child(2) { background: var(--d200); }
.plate__legend i:nth-child(3) { background: var(--d300); }
.plate__legend i:nth-child(4) { background: var(--d400); }
.plate__legend i:nth-child(5) { background: var(--d500); }
.plate__legend i:nth-child(6) { background: var(--d600); }
.plate__legend i:nth-child(7) { background: var(--d700); }
.plate__domain { min-width: 0; }
.plate__read {
  margin-left: auto;
  color: var(--accent-text);
  min-height: 1em;
}

/* ----------------------------------------------------------------- roster */
.roster { display: grid; gap: 0; border-top: 1px solid var(--line); }
.roster__row {
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr) auto;
  gap: 0.7rem 0.9rem;
  align-items: baseline;
  padding: 0.95rem 0;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
  transition: color 160ms var(--ease);
}
.roster__row:hover { color: inherit; }
.roster__row:hover .roster__name { color: var(--accent-text); }
.roster__n {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--text-3);
}
.roster__name { font-weight: 640; letter-spacing: -0.03em; }
.roster__score {
  font-family: var(--mono);
  font-size: 1.2rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.04em;
  text-align: right;
}
.roster__meta {
  grid-column: 2 / -1;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--text-3);
}
/* Every row goes to that vendor's page, and nothing but the cursor said so
   while the standings sat above a second list of the same five vendors that
   read as the navigational one. The second list is gone; this is what it was
   for. */
.roster__go {
  display: none;
  font-family: var(--mono);
  color: var(--text-3);
  justify-self: end;
  transition: transform 160ms var(--ease), color 160ms var(--ease);
}
.roster__row:hover .roster__go,
.roster__row:focus-visible .roster__go {
  color: var(--accent-text);
  transform: translateX(3px);
}
@media (min-width: 700px) {
  .roster__row {
    grid-template-columns: 2.6rem minmax(0, 1fr) 4.4rem auto 1.4rem;
    align-items: center;
  }
  .roster__meta { grid-column: auto; text-align: right; }
  /* Only where there is a pointer to follow it. On a phone the row is a tap
     target and the arrow is one more thing crowding a two-line row. */
  .roster__go { display: block; }
}
@media (prefers-reduced-motion: reduce) {
  .roster__row:hover .roster__go { transform: none; }
}

/* ----------------------------------------------------------------- cards */
.card, .panel, .module {
  background: var(--card);
  box-shadow: inset 0 0 0 1px var(--line);
}
.card--pad { padding: 1.15rem 1.2rem; }
.panel { margin: 0; }
.panel + .panel { margin-top: 1.2rem; }
.panel__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.8rem;
  padding: 0.85rem 1rem 0.7rem;
  border-bottom: 1px solid var(--line);
}
.panel__head h3 { margin: 0; }
.panel__body { padding: 0.9rem 1rem 1.05rem; }
.panel--flush .panel__body { padding: 0; }
.panel__foot {
  padding: 0.7rem 1rem 0.9rem;
  border-top: 1px solid var(--line);
  font-size: 0.82rem;
  color: var(--text-3);
  line-height: 1.5;
}
.label {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--text-3);
}

/* ---------------------------------------------------------------- metrics */
.metrics {
  display: grid;
  gap: 0;
  margin-top: 1.8rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--line);
}
@media (min-width: 860px) {
  .metrics { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.metric {
  padding: 1.15rem 1.3rem 1.2rem 0;
  border-bottom: 1px solid var(--line);
}
.metric__label { display: block; margin-bottom: 0.45rem; }
.metric__value {
  font-size: clamp(1.55rem, 1.1rem + 1.3vw, 2.15rem);
  font-weight: 640;
  letter-spacing: -0.05em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.metric__value .unit { font-size: 0.48em; font-weight: 520; color: var(--text-2); }
.metric__note { font-size: 0.76rem; color: var(--text-3); margin-top: 0.5rem; line-height: 1.4; }

.stamp {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem 1.1rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--text-3);
}
.stamp b { font-weight: 600; color: var(--text-2); }
.stamp [data-priority="low"] { opacity: 0.7; }

.callout {
  padding: 0.2rem 0 0.2rem 1.05rem;
  border-left: 2px solid var(--accent);
  background: transparent;
  box-shadow: none;
}
.callout p { margin: 0; font-size: 0.95rem; color: var(--text-2); }
.callout .eyebrow { color: var(--accent-text); padding-top: 0.15em; display: block; margin-bottom: 0.35rem; }

/* ----------------------------------------------------------------- tables */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
caption {
  text-align: left;
  padding: 0.9rem 1rem 0.7rem;
  font-size: 0.86rem;
  color: var(--text-3);
  line-height: 1.5;
}
th, td { padding: 0.62rem 0.85rem; text-align: left; vertical-align: top; }
th {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--text-3);
  border-bottom: 1px solid var(--line-strong);
}
td { border-bottom: 1px solid var(--line); }
.num { text-align: right; }
.rank {
  display: inline-block;
  min-width: 1.8em;
  margin-right: 0.55em;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--text-3);
}
a.vendor-name { text-decoration: none; font-weight: 600; }
a.vendor-name:hover { color: var(--accent-text); }
.best { color: var(--accent-text); font-weight: 640; }
.meter { position: relative; }
.meter::before {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  height: 2px;
  width: calc(var(--pct, 50) * 1%);
  background: var(--d400);
}
.meter.best::before { background: var(--accent); }

.tag {
  display: inline-block;
  padding: 0.12em 0.45em;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--text-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.tag--accent {
  color: var(--accent-text);
  background: var(--accent-wash);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent);
}

.controls {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 1.15rem;
  font-size: 0.85rem;
  color: var(--text-2);
}
select, input[type="search"] {
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--line-strong);
  background: var(--page);
  color: var(--text);
  min-width: 0;
}
select:hover, input[type="search"]:hover { border-color: var(--text-3); }
select:focus-visible, input[type="search"]:focus-visible { border-color: var(--accent); }
input[type="search"] { min-width: 230px; }
input[type="search"]::placeholder { color: var(--text-3); }
.empty {
  padding: 2.4rem 1rem;
  text-align: center;
  color: var(--text-3);
  box-shadow: inset 0 0 0 1px dashed var(--line);
}

.view-toggle {
  display: inline-flex;
  margin-left: auto;
  box-shadow: inset 0 0 0 1px var(--line);
}
.view-toggle button {
  padding: 0.38em 0.7em;
  background: transparent;
  color: var(--text-3);
  border: 0;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
}
.view-toggle button:hover { color: var(--text); }
.view-toggle button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }

[hidden] { display: none !important; }

.deflist { display: grid; margin: 0; }
.deflist > div {
  display: grid;
  gap: 0.35rem 2rem;
  padding: 1.15rem 0;
  border-bottom: 1px solid var(--line);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 760px) {
  .deflist > div { grid-template-columns: 250px minmax(0, 1fr); }
}
.deflist dt { margin: 0; font-weight: 620; color: var(--text); }
.deflist dd { margin: 0; color: var(--text-2); font-size: 0.94rem; }
.deflist > div:first-child { border-top: 1px solid var(--line); }

/* A real sequence. Numbers carry order, not decoration, and the four
 * stages are a list rather than a row of identical cards. */
.steps {
  counter-reset: step;
  display: grid;
  gap: 0;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--line);
}
.steps > li {
  list-style: none;
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr);
  gap: 1rem;
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--line);
}
.steps > li::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--text-3);
  padding-top: 0.28rem;
}
.steps h3 { margin: 0 0 0.3rem; }
.steps p { margin: 0; color: var(--text-2); font-size: 0.9rem; }

.numcard {
  padding: 1rem 0;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
  display: block;
}
.numcard:hover { color: inherit; }
.numcard__n { font-size: 1.4rem; font-weight: 640; letter-spacing: -0.04em; }
.numcard:hover .numcard__n { color: var(--accent-text); }
.numcard__meta { display: block; margin-top: 0.3rem; font-size: 0.82rem; color: var(--text-3); line-height: 1.45; }

.contact__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }
.contact__list li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.7rem;
  font-size: 0.92rem;
  color: var(--text-2);
  align-items: start;
}
.contact__list .tick-mark {
  width: 18px;
  height: 18px;
  margin-top: 0.15em;
  display: inline-grid;
  place-items: center;
  background: var(--accent-wash);
  color: var(--accent-text);
  font-size: 0.6rem;
  font-weight: 700;
}
.mail {
  display: inline-flex;
  padding: 0.7rem 0.95rem;
  box-shadow: inset 0 0 0 1px var(--line-strong);
  color: var(--text);
  text-decoration: none;
  font-family: var(--mono);
  font-size: 0.9rem;
  word-break: break-all;
}
.mail:hover { box-shadow: inset 0 0 0 1px var(--accent); color: var(--accent-text); }

/* ------------------------------------------------------------------ charts */
.chart { position: relative; overflow-x: auto; overflow-y: hidden; }
.chart svg { display: block; width: 100%; min-width: 520px; height: auto; overflow: visible; }
.chart text { font-family: var(--sans); }
.chart .tick {
  font-family: var(--mono); font-size: 10px; fill: var(--text-3);
}
.chart .axis-title {
  font-family: var(--mono); font-size: 9.5px; fill: var(--text-3);
}
.chart .mark-name { font-size: 12px; fill: var(--text-2); font-weight: 540; }
.chart .mark-label {
  font-family: var(--mono); font-size: 11px; fill: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.chart .mark-label--strong { fill: var(--text); font-weight: 620; }
.chart .grid-line { stroke: var(--line); stroke-width: 1; }
.chart .cell-label {
  font-family: var(--mono); font-size: 11.5px; font-variant-numeric: tabular-nums;
  font-weight: 500;
}
.chart .hit { fill: transparent; cursor: default; }

.legend {
  display: flex; gap: 1.1rem; flex-wrap: wrap; align-items: center;
  font-size: 0.76rem; color: var(--text-2); margin-top: 1rem;
}
.legend__item { display: inline-flex; align-items: center; gap: 0.45em; }
.legend__swatch { width: 11px; height: 11px; flex: none; }
.legend__ramp { display: inline-flex; gap: 2px; }
.legend__ramp i { width: 18px; height: 11px; display: block; }

/* ---------------------------------------------------------------- tooltip */
.tooltip {
  position: fixed;
  z-index: var(--z-tooltip);
  max-width: 18rem;
  padding: 0.7rem 0.8rem;
  background: #12151c;
  color: #eef2f7;
  box-shadow: 0 12px 40px rgb(0 0 0 / 0.45), inset 0 0 0 1px var(--line);
  font-size: 0.78rem;
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 140ms var(--ease), transform 140ms var(--ease);
}
.tooltip[data-show] { opacity: 1; transform: none; }
.tooltip b { display: block; margin-bottom: 0.4rem; color: #eef2f7; }
.tooltip .t-row { display: flex; justify-content: space-between; gap: 1.3rem; color: #a8b0bd; }
.tooltip .t-row span:last-child { font-family: var(--mono); font-variant-numeric: tabular-nums; color: #eef2f7; }

/* ------------------------------------------------------------------ footer */
.foot {
  padding: 2.6rem 0 3rem;
  border-top: 1px solid var(--line);
}
.foot__row {
  display: grid;
  gap: 1.6rem;
}
@media (min-width: 760px) {
  .foot__row { grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.8fr); align-items: start; }
}
.foot__tagline { margin: 0.7rem 0 0; max-width: 42ch; font-size: 0.9rem; color: var(--text-3); }
.foot a { color: var(--text-2); text-decoration: none; }
.foot a:hover { color: var(--accent-text); text-decoration: underline; }
.foot__eval { margin: 0.7rem 0 0; max-width: 48ch; color: var(--text-3); }
.foot__eval a { color: var(--text-2); }
.foot__links { display: flex; flex-wrap: wrap; gap: 0.55rem 1rem; margin: 0; }

/* ----------------------------------------------------------------- motion */
/* Default state is the finished state. .js only adds an entrance. A stalled
 * frame loop stamps data-done and this block removes the animation so a
 * delayed cell cannot sit at opacity 0. */
[data-reveal], .reveal { opacity: 1; transform: none; }

.js [data-done],
.js [data-done]::before,
.js [data-done] > *,
.js [data-done] .cell-in,
.js [data-done] .bar-in,
.js .plate[data-done] .plate__cell {
  animation: none !important;
  opacity: 1 !important;
  transform: none !important;
  filter: none !important;
}

@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal="rise"][data-shown] {
    animation: sb-rise 640ms var(--ease-out) both;
  }
  .js [data-reveal="rows"][data-shown] > * {
    animation: sb-rise 540ms var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 45ms);
  }
  .js .plate__cell {
    animation: sb-ignite 640ms var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 16ms);
  }
  .js .chart[data-animate][data-shown] .cell-in {
    animation: sb-ignite 420ms var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 14ms);
  }
  .js .chart[data-animate][data-shown] .bar-in {
    animation: sb-bar 560ms var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 55ms);
    transform-origin: left center;
    transform-box: fill-box;
  }
}
@keyframes sb-rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
@keyframes sb-ignite {
  from { filter: brightness(0.45); }
  to { filter: none; }
}
@keyframes sb-bar {
  from { transform: scaleX(0.12); }
  to { transform: scaleX(1); }
}

.counting { font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ----------------------------------------------------------------- print */
@media print {
  .masthead, .progress, .nav-toggle { display: none !important; }
  body, .band, .card, .panel { background: #fff !important; color: #000 !important; box-shadow: none !important; }
  a { color: inherit; }
}
