/* noisebench analysis site — shared chrome and chart tokens.
   Colors follow the validated reference palette: categorical slots 1-3 only
   (the set that clears the all-pairs CVD floors), a blue<->red diverging pair
   for signed quantities, and text tokens that never take a series color. */

:root {
  color-scheme: light;

  --surface-1: #fcfcfb;
  --page: #f9f9f7;
  --text-primary: #0b0b0b;
  --text-secondary: #52514e;
  --text-muted: #898781;
  --gridline: #e1e0d9;
  --baseline: #c3c2b7;
  --border: rgba(11, 11, 11, 0.1);

  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;

  /* Diverging: signed effects read as opposite poles around a neutral zero. */
  --diverge-pos: #2a78d6;
  --diverge-neg: #d03b3b;
  --diverge-mid: #f0efec;

  --font: system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Vendor brand hues, keyed by the slug prefix of a model name. Identity is
     still carried by the label on every mark — this is a grouping cue on top of
     it, so a reader can see a lab's models cluster without reading twenty
     names. Three brand books collide when put on one chart and are nudged the
     minimum needed to separate: Xiaomi's orange sits on Mistral's, and Zhipu's
     blue sits between Google's and DeepSeek's, so Xiaomi moves toward amber and
     Zhipu toward the cyan its own branding claims. xAI and Moonshot are both
     monochrome brands; xAI inverts with the theme the way its own marque does,
     and Moonshot keeps a violet cast to its charcoal so the two never read as
     the same ink. */
  --brand-openai: #10a37f;
  --brand-anthropic: #d97757;
  --brand-google: #4285f4;
  --brand-deepseek: #4e6cff;
  --brand-qwen: #7c3aed;
  --brand-z-ai: #0e9cd9;
  --brand-x-ai: #111111;
  --brand-moonshotai: #3f3d56;
  --brand-xiaomi: #ff8a00;
  --brand-mistralai: #ff5000;
  --brand-nvidia: #76b900;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --surface-1: #1a1a19;
    --page: #0d0d0d;
    --text-primary: #ffffff;
    --text-secondary: #c3c2b7;
    --text-muted: #898781;
    --gridline: #2c2c2a;
    --baseline: #383835;
    --border: rgba(255, 255, 255, 0.1);
    --series-1: #3987e5;
    --series-2: #d95926;
    --series-3: #199e70;
    --diverge-pos: #3987e5;
    --diverge-neg: #e66767;
    --diverge-mid: #383835;

    /* Lifted off the dark surface. xAI flips to the light half of its own
       black-and-white identity rather than staying an invisible black. */
    --brand-openai: #14b892;
    --brand-anthropic: #e08a6e;
    --brand-google: #5b9bf8;
    --brand-deepseek: #6b84ff;
    --brand-qwen: #a480ff;
    --brand-z-ai: #35b4e8;
    --brand-x-ai: #ededed;
    --brand-moonshotai: #9b98c0;
    --brand-xiaomi: #ff9e2e;
    --brand-mistralai: #ff6b29;
    --brand-nvidia: #8fd119;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-1: #1a1a19;
  --page: #0d0d0d;
  --text-primary: #ffffff;
  --text-secondary: #c3c2b7;
  --text-muted: #898781;
  --gridline: #2c2c2a;
  --baseline: #383835;
  --border: rgba(255, 255, 255, 0.1);
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
  --diverge-pos: #3987e5;
  --diverge-neg: #e66767;
  --diverge-mid: #383835;

  --brand-openai: #14b892;
  --brand-anthropic: #e08a6e;
  --brand-google: #5b9bf8;
  --brand-deepseek: #6b84ff;
  --brand-qwen: #a480ff;
  --brand-z-ai: #35b4e8;
  --brand-x-ai: #ededed;
  --brand-moonshotai: #9b98c0;
  --brand-xiaomi: #ff9e2e;
  --brand-mistralai: #ff6b29;
  --brand-nvidia: #8fd119;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--page);
  color: var(--text-primary);
  font-family: var(--font);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: 1080px;
  margin: 0 auto;
  padding: 32px 24px 96px;
}

/* ---------- masthead ---------- */

header.masthead {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  /* Centered rather than baseline-aligned: the left side is a logo lockup now,
     and a flex row takes its baseline from the image's bottom edge. */
  align-items: center;
  justify-content: space-between;
  padding-bottom: 20px;
  margin-bottom: 32px;
  border-bottom: 1px solid var(--border);
}

.masthead .brand {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* The mark is a flat one-color PNG, so it ships as a black/white pair rather
   than one file that inverts. The swap follows the same rules as the color
   tokens above: an explicit theme choice wins over the OS preference. */
.brand-mark {
  display: block;
  flex: none;
  width: 35px;
  height: 32px;
}

.brand-mark.dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .brand-mark.light {
    display: none;
  }
  :root:where(:not([data-theme="light"])) .brand-mark.dark {
    display: block;
  }
}

:root[data-theme="dark"] .brand-mark.light {
  display: none;
}

:root[data-theme="dark"] .brand-mark.dark {
  display: block;
}

.masthead h1 {
  font-size: 20px;
  margin: 0;
  letter-spacing: -0.01em;
}

.masthead .sub {
  color: var(--text-secondary);
  font-size: 13px;
}

nav.tabs {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

nav.tabs a {
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 13px;
  padding: 6px 12px;
  border-radius: 6px;
  border: 1px solid transparent;
}

nav.tabs a:hover {
  background: var(--surface-1);
  color: var(--text-primary);
}

nav.tabs a[aria-current="page"] {
  background: var(--surface-1);
  border-color: var(--border);
  color: var(--text-primary);
  font-weight: 600;
}

/* ---------- sections ---------- */

section {
  margin-bottom: 44px;
}

h2 {
  font-size: 17px;
  margin: 0 0 6px;
  letter-spacing: -0.01em;
}

h3 {
  font-size: 14px;
  margin: 0 0 4px;
}

/* Prose runs the full width of its container rather than to a `ch` measure.
   `.wrap` already caps the page at 1080px, so that is the line length, and it
   is the same edge the charts and tables end on — text that stopped short of
   it read as crammed into the left of the page. */
p.lede {
  color: var(--text-secondary);
  font-size: 14px;
  margin: 0 0 20px;
}

p.note {
  color: var(--text-muted);
  font-size: 12.5px;
  margin: 10px 0 0;
}

/* Body links take a text token, not the browser default, so they sit in the
   same ink family as everything around them. */
.wrap a:not(nav a) {
  color: var(--text-primary);
  text-decoration-color: var(--baseline);
  text-underline-offset: 2px;
}

.wrap a:not(nav a):hover {
  text-decoration-color: var(--series-1);
}

code {
  font-size: 0.94em;
  background: color-mix(in srgb, var(--text-primary) 7%, transparent);
  padding: 1px 5px;
  border-radius: 4px;
}

/* ---------- stat tiles ---------- */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}

/* Tiles that carry a formula need room for it to sit on one or two lines. */
.tiles.wide {
  grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
}

.tile {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
}

.tile .label {
  font-size: 12px;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tile .value {
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 6px 0 2px;
}

.tile .hint {
  font-size: 12px;
  color: var(--text-muted);
}

.tile.accent {
  border-color: color-mix(in srgb, var(--series-1) 40%, var(--border));
}

/* ---------- numbered steps ---------- */

/* A pipeline is an ordered thing, so it takes an ordered list and the numbers
   are real list counters rather than characters typed into the prose. */
ol.steps {
  list-style: none;
  counter-reset: step;
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
}

ol.steps li {
  counter-increment: step;
  position: relative;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 15px 18px 15px 54px;
}

ol.steps li::before {
  content: counter(step);
  position: absolute;
  left: 16px;
  top: 15px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--series-1);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
  display: grid;
  place-items: center;
}

ol.steps .step-title {
  font-size: 13.5px;
  font-weight: 600;
  margin-bottom: 2px;
}

ol.steps p {
  margin: 0;
  font-size: 13px;
  color: var(--text-secondary);
}

/* ---------- definition list ---------- */

dl.defs {
  margin: 0;
}

dl.defs dt {
  font-size: 13.5px;
  font-weight: 600;
  margin-top: 16px;
}

dl.defs dt:first-of-type {
  margin-top: 0;
}

dl.defs dd {
  margin: 3px 0 0;
  font-size: 13.5px;
  color: var(--text-secondary);
}

/* ---------- figures ---------- */

figure {
  margin: 0 0 8px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 20px 14px;
}

figcaption {
  font-size: 12.5px;
  color: var(--text-secondary);
  margin-top: 10px;
}

/* A caption that is a formula rather than a sentence. `pre-wrap` keeps the
   alignment spacing and still wraps rather than overflowing on a narrow
   screen. */
figcaption > code {
  display: block;
  white-space: pre-wrap;
  font-family: ui-monospace, "Cascadia Code", "Consolas", monospace;
  font-size: 12px;
  padding: 8px 10px;
}

.chart-head {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 14px;
}

.chart-scroll {
  overflow-x: auto;
}

svg {
  display: block;
  max-width: 100%;
  height: auto;
  overflow: visible;
}

svg text {
  font-family: var(--font);
}

/* ---------- controls ---------- */

.controls {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 18px;
}

.seg {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface-1);
}

.seg button {
  font: inherit;
  font-size: 13px;
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  padding: 6px 14px;
  cursor: pointer;
}

.seg button[aria-pressed="true"] {
  background: var(--series-1);
  color: #fff;
  font-weight: 600;
}

.seg button:focus-visible {
  outline: 2px solid var(--series-1);
  outline-offset: -2px;
}

button.link {
  font: inherit;
  font-size: 12.5px;
  background: none;
  border: 0;
  color: var(--text-secondary);
  text-decoration: underline;
  cursor: pointer;
  padding: 4px 0;
}

button.link:hover {
  color: var(--text-primary);
}

/* ---------- legend ---------- */

.legend {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--text-secondary);
}

.legend span.key {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.legend i {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  display: inline-block;
}

/* ---------- tables ---------- */

.table-wrap {
  overflow-x: auto;
  margin-top: 12px;
}

table {
  border-collapse: collapse;
  font-size: 12.5px;
  width: 100%;
  min-width: 480px;
}

th,
td {
  text-align: right;
  padding: 7px 10px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

th:first-child,
td:first-child {
  text-align: left;
  white-space: normal;
}

/* Explanatory tables carry sentences, not figures — they wrap and fill the
   column rather than forcing the reader to scroll sideways through prose. */
table.prose {
  min-width: 0;
}

table.prose td,
table.prose th {
  white-space: normal;
  vertical-align: top;
}

/* The narrow columns hold a label or a percentage; leaving them unconstrained
   lets auto-layout give the prose column whatever is left. */
table.prose td.num,
table.prose th.num {
  width: 1%;
}

thead th {
  color: var(--text-secondary);
  font-weight: 600;
  border-bottom: 1px solid var(--baseline);
}

td.num {
  font-variant-numeric: tabular-nums;
}

tbody tr:hover {
  background: color-mix(in srgb, var(--series-1) 6%, transparent);
}

/* ---------- sortable headers ---------- */

thead th:has(button.sort) {
  padding: 0;
}

button.sort {
  font: inherit;
  font-weight: 600;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 7px 10px;
  width: 100%;
  text-align: inherit;
  white-space: nowrap;
}

button.sort:hover {
  color: var(--text-primary);
}

button.sort:focus-visible {
  outline: 2px solid var(--series-1);
  outline-offset: -2px;
}

/* The idle carets are a hint that the column is clickable, not information —
   they stay near the floor of legibility so a hundred rows of figures still
   own the eye. */
button.sort span.off {
  opacity: 0.28;
}

button.sort span.on {
  color: var(--series-1);
}

/* A signed distance painted onto the cell. The alpha carries the magnitude, so
   the number itself stays the primary read and the wash is the sort key made
   visible. Kept as RGB triples because the alpha is computed per row. */
:root {
  --cell-above: 27, 175, 122;
  --cell-below: 208, 59, 59;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    --cell-above: 25, 158, 112;
    --cell-below: 230, 103, 103;
  }
}

:root[data-theme="dark"] {
  --cell-above: 25, 158, 112;
  --cell-below: 230, 103, 103;
}

/* ---------- formulas ---------- */

.formula {
  font-family: ui-monospace, "Cascadia Code", "Consolas", monospace;
  font-size: 12.5px;
  color: var(--text-primary);
  background: color-mix(in srgb, var(--text-primary) 5%, transparent);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 0 0 14px;
  overflow-x: auto;
  white-space: pre;
}

.formula .unit {
  display: block;
  font-family: var(--font);
  color: var(--text-muted);
  font-size: 12px;
  margin-top: 6px;
  white-space: normal;
}

/* ---------- tooltip ---------- */

.tip {
  position: fixed;
  pointer-events: none;
  z-index: 50;
  background: var(--surface-1);
  border: 1px solid var(--border);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.16);
  border-radius: 8px;
  padding: 9px 11px;
  font-size: 12.5px;
  color: var(--text-primary);
  max-width: 300px;
  opacity: 0;
  transition: opacity 0.1s;
}

.tip.on {
  opacity: 1;
}

.tip .tip-title {
  font-weight: 600;
  margin-bottom: 4px;
}

.tip .tip-row {
  display: flex;
  gap: 12px;
  justify-content: space-between;
  color: var(--text-secondary);
}

.tip .tip-row b {
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.hidden {
  display: none !important;
}

/* `display` on an author rule beats the UA rule behind the hidden attribute,
   so anything laid out here has to opt back in. */
[hidden] {
  display: none !important;
}

@media (max-width: 640px) {
  .wrap {
    padding: 20px 14px 64px;
  }
  .tile .value {
    font-size: 25px;
  }
}
