:root {
  --fg: #1c2430;
  --muted: #5b6675;
  --bg: #f7f8fa;
  --surface: #ffffff;
  --accent: #2f6fed;
  --accent-strong: #1d4ed8;
  --border: #e4e7ec;
  --code-bg: #f0f2f5;
  --warn-bg: #fff8e1;
  --warn-border: #f0c000;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.04);
  --shadow-md: 0 4px 12px rgba(16, 24, 40, 0.08), 0 2px 4px rgba(16, 24, 40, 0.04);
  --max-width: 820px;
  --row1-h: 54px;
  --row2-h: 44px;
  --header-h: var(--row1-h);
}

/* Pages with a secondary nav row have a taller sticky header. */
.page-new-gas, .page-runtime, .page-glue { --header-h: calc(var(--row1-h) + var(--row2-h)); }

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 16.5px;
  color: var(--fg);
  background: var(--bg);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Header / nav: a sticky two-tier top bar (primary sections + per-group sub-pages) */
.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  border-bottom: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
}
.topbar-primary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
  min-height: var(--row1-h);
  padding: 0.4rem 1.5rem;
}
.topbar-secondary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem;
  min-height: var(--row2-h);
  padding: 0.3rem 1.5rem;
  border-top: 1px solid var(--border);
  background: rgba(16, 24, 40, 0.025);
}
.site-title {
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: -0.01em;
  color: var(--fg);
  text-decoration: none;
}
.site-nav { display: flex; flex-wrap: wrap; gap: 1.25rem; }
.site-nav a, .topbar-secondary a {
  color: var(--muted);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.site-nav a:hover, .topbar-secondary a:hover { color: var(--accent); }
.site-nav a.active, .topbar-secondary a.active { color: var(--fg); font-weight: 600; border-bottom-color: var(--accent); }
.topbar-secondary a { font-size: 0.95rem; }

/* Content */
.content {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 2.5rem 1.5rem 4rem;
}
.content h1 {
  font-size: 2rem;
  letter-spacing: -0.02em;
  margin-top: 0;
  margin-bottom: 1rem;
}
.content h2 {
  font-size: 1.35rem;
  letter-spacing: -0.01em;
  margin-top: 2.75rem;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.35rem;
}
.content h3 { font-size: 1.1rem; }
.content a { color: var(--accent); text-decoration-color: rgba(47, 111, 237, 0.35); text-underline-offset: 2px; }
.content a:hover { color: var(--accent-strong); text-decoration-color: currentColor; }

/* Takeaway callout */
.takeaway {
  background: linear-gradient(0deg, rgba(47, 111, 237, 0.05), rgba(47, 111, 237, 0.05)), var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 8px;
  padding: 1rem 1.25rem;
  margin: 1.5rem 0;
  box-shadow: var(--shadow-sm);
}
.takeaway > :first-child { margin-top: 0; }
.takeaway > :last-child { margin-bottom: 0; }
.takeaway ol, .takeaway ul { padding-left: 1.25rem; }
.takeaway li + li { margin-top: 0.4rem; }

/* Tables */
table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  margin: 1.5rem 0;
  font-size: 0.92rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow-sm);
}
th, td { border-bottom: 1px solid var(--border); padding: 0.5rem 0.7rem; text-align: right; }
tr:last-child td { border-bottom: none; }
th {
  background: var(--code-bg);
  position: sticky;
  top: var(--header-h);
  z-index: 2;
  font-weight: 600;
  /* Multi-word headers (e.g. "Second-worst client") wrap rather than force the
     table wider than the content column; short single-word headers never wrap. */
  white-space: normal;
  box-shadow: inset 0 -1px 0 var(--border);
}
/* Round outer corners without overflow:hidden (which would break sticky th) */
thead tr:first-child th:first-child { border-top-left-radius: 8px; }
thead tr:first-child th:last-child { border-top-right-radius: 8px; }
tbody tr:last-child td:first-child { border-bottom-left-radius: 8px; }
tbody tr:last-child td:last-child { border-bottom-right-radius: 8px; }
tbody tr { transition: background 0.1s ease; }
tbody tr:nth-child(even) { background: rgba(16, 24, 40, 0.018); }
tbody tr:hover { background: rgba(47, 111, 237, 0.06); }
td:first-child, th:first-child { text-align: left; }
.worst-case { background: #fdecea; font-weight: 600; }
tbody tr:hover .worst-case { background: #fbdcd6; }

/* Parameter → model map (methodology): text/code cells, left-aligned, with the
   parameter column held narrow so the wider provenance columns get the room. */
table.param-map th, table.param-map td { text-align: left; vertical-align: top; }
table.param-map td:first-child { white-space: nowrap; }
table.param-map code { background: none; padding: 0; }

/* Code / preformatted fit summaries */
code {
  background: var(--code-bg);
  padding: 0.12em 0.35em;
  border-radius: 4px;
  font-size: 0.85em;
}
pre {
  background: var(--code-bg);
  padding: 1rem 1.25rem;
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.82rem;
  line-height: 1.5;
}
pre code { background: none; padding: 0; }

/* Figures */
/* Bare markdown images (e.g. the new-gas heatmap/provenance plots) aren't wrapped
   in <figure>, so cap every content image to the column width. */
.content img { max-width: 100%; height: auto; }
figure { margin: 1.75rem 0; text-align: center; }
figure img {
  max-width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow-sm);
}
figcaption { color: var(--muted); font-size: 0.85rem; margin-top: 0.5rem; }

/* Proposed-gas heatmap: per-client proposed gas, cells tinted by
   log2(proposed/current) (green = cheaper, red = pricier). Replaces the
   matplotlib heatmap.png with a theme-native, dark-mode-aware table. */
table.heatmap { border-spacing: 3px; border-collapse: separate; }
table.heatmap th,
table.heatmap td { border-bottom: none; text-align: center; padding: 0.55rem 0.4rem; }
/* Data columns share the space evenly; the row-header column sizes to its
   (nowrap) parameter name so long names don't bleed into the first client. */
table.heatmap thead th[scope="col"] { width: 8rem; }
table.heatmap thead th { position: static; background: var(--code-bg); font-size: 0.84rem; }
table.heatmap th[scope="row"] {
  position: static;
  background: var(--code-bg);
  text-align: right;
  font-weight: 500;
  font-size: 0.82rem;
  white-space: nowrap;
}
table.heatmap td {
  font-variant-numeric: tabular-nums;
  border-radius: 5px;
  font-size: 0.86rem;
}
table.heatmap td.empty { color: var(--muted); background: none; }
/* Cells own their tint, so the row stripe/hover must not paint over them. */
table.heatmap tbody tr:nth-child(even),
table.heatmap tbody tr:hover { background: none; }
/* Provenance heatmap: the cell the worst-case selector picked. Outline (not
   border) so it sits inside the cell without nudging the grid; tabular numbers
   stay aligned. Theme-aware via --fg, readable over any tint. */
table.heatmap td.sel {
  outline: 2px solid var(--fg);
  outline-offset: -2px;
  font-weight: 700;
}
/* Provenance rows are model combos, not param names — descriptive (no-legend)
   labels can be long, so let them wrap instead of forcing the column wide. */
table.heatmap.provenance th[scope="row"] { white-space: normal; }

/* Cards (landing page) */
.cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; margin: 2rem 0; }
@media (max-width: 640px) { .cards { grid-template-columns: 1fr; } }

/* Plot grid (fit/glue pages): 2 plots per row; a lone trailing plot spans both columns */
.plot-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; margin: 2rem 0; }
.plot-grid > figure:last-child:nth-child(odd) { grid-column: 1 / -1; }
@media (max-width: 640px) { .plot-grid { grid-template-columns: 1fr; } }
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.4rem;
  text-decoration: none;
  color: var(--fg);
  box-shadow: var(--shadow-sm);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.card:hover {
  border-color: var(--accent);
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}
.card h3 { margin: 0 0 0.5rem; color: var(--accent); }
.card p { margin: 0; color: var(--muted); font-size: 0.9rem; }

/* Multi-link card (not itself clickable); spans the full grid width */
.card-links { grid-column: 1 / -1; }
.card-links:hover { border-color: var(--border); transform: none; box-shadow: none; }
.card-links ul { margin: 0; padding: 0; list-style: none; }
.card-links li { margin: 0.4rem 0; color: var(--muted); font-size: 0.9rem; }
.card-links li a { color: var(--accent); text-decoration: none; }
.card-links li a:hover { text-decoration: underline; }

/* Warnings */
.warning {
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-left: 4px solid var(--warn-border);
  border-radius: 8px;
  padding: 0.85rem 1.1rem;
  margin: 1.25rem 0;
}

/* Filter controls (runtime / glue pages) */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  margin: 1.5rem 0;
  padding: 1rem 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow-sm);
}
.filters label { font-size: 0.9rem; font-weight: 600; }
.filters select {
  padding: 0.4rem 0.6rem;
  font-size: 0.9rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  color: var(--fg);
}
.fit-section { margin: 2rem 0; padding-top: 1.25rem; border-top: 1px solid var(--border); }
.fit-section h3 { margin-top: 0; }
.stat-grid { display: flex; flex-wrap: wrap; gap: 1.5rem; margin: 0.75rem 0; font-size: 0.9rem; }
.stat-grid .stat { color: var(--muted); }
.stat-grid .stat strong { color: var(--fg); }

/* Footer */
.site-footer { border-top: 1px solid var(--border); padding: 1.5rem; color: var(--muted); font-size: 0.8rem; }
.site-footer .repro { max-width: var(--max-width); margin: 0 auto; }
.site-footer code { font-size: 0.95em; }

/* Dark mode */
@media (prefers-color-scheme: dark) {
  :root {
    --fg: #e6e9ef;
    --muted: #9aa4b2;
    --bg: #0f1218;
    --surface: #181c24;
    --accent: #6ea0ff;
    --accent-strong: #93b8ff;
    --border: #2a313d;
    --code-bg: #1f2530;
    --warn-bg: #2e2a16;
    --warn-border: #b89400;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.5);
  }
  .site-header { background: rgba(15, 18, 24, 0.78); }
  .content a { text-decoration-color: rgba(110, 160, 255, 0.4); }
  tbody tr:nth-child(even) { background: rgba(255, 255, 255, 0.025); }
  tbody tr:hover { background: rgba(110, 160, 255, 0.1); }
  .worst-case { background: #4a2420; color: #ffd9d2; }
  tbody tr:hover .worst-case { background: #5a2c27; }
  figure img { filter: brightness(0.92); }
  /* The older-run amber text is a fixed light-mode color; lift it for dark bg. */
  .run-bar-older .run-bar-meta { color: var(--warn-border); }
}

/* ---- Run selector (previous-runs dropdown) ---- */
/* A strip at the top of .content for switching between pre-rendered run pages.
   The dropdown is a custom button + listbox (styled in run_selector.js) so the
   popup font matches the page instead of the OS chrome font. */
.run-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.85rem;
  max-width: var(--max-width);
  margin: 0 auto 1.75rem;
  padding: 0.6rem 0.95rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow-sm);
  font-size: 0.9rem;
}
.run-bar-label {
  color: var(--muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.75rem;
}
.run-bar-single { font-weight: 600; color: var(--fg); }
.run-bar-meta { margin-left: auto; color: var(--muted); }
/* Viewing an older (non-latest) run: amber accent to flag it. */
.run-bar-older { border-color: var(--warn-border); background: var(--warn-bg); }
.run-bar-older .run-bar-meta { color: #8a6d00; font-weight: 600; }

.run-dropdown { position: relative; display: inline-block; }
.run-dropdown-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--fg);
  background: var(--code-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.35rem 0.7rem;
  line-height: 1.3;
  cursor: pointer;
}
.run-dropdown-toggle:hover { border-color: var(--accent); }
.run-dropdown-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* CSS-drawn chevron; uses a var color so it adapts to light/dark for free. */
.run-dropdown-chevron {
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--muted);
  transition: transform 0.15s ease;
}
.run-dropdown-toggle[aria-expanded="true"] .run-dropdown-chevron { transform: rotate(180deg); }

.run-dropdown-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 20;
  min-width: 100%;
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow-md);
  white-space: nowrap;
}
.run-dropdown-list[hidden] { display: none; }
.run-dropdown-option {
  display: block;
  padding: 0.35rem 0.6rem;
  border-radius: 5px;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--fg);
  text-decoration: none;
}
.run-dropdown-option:hover { background: rgba(47, 111, 237, 0.08); text-decoration: none; }
.run-dropdown-option:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.run-dropdown-option.is-current { color: var(--accent-strong); font-weight: 600; }
.run-dropdown-noscript a { margin-right: 0.6rem; }

/* ---- Trends page ---- */
.muted { color: var(--muted); }

/* Filter bar: client checkboxes + metric radios live in borderless fieldsets. */
.toggle-set { border: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.85rem; }
.toggle-set legend {
  float: left;
  margin-right: 0.6rem;
  padding: 0;
  font-size: 0.9rem;
  font-weight: 600;
}
.toggle { font-size: 0.9rem; font-weight: 500; display: inline-flex; align-items: center; gap: 0.3rem; }
.toggle input { margin: 0; }

/* Delta table color coding: down = faster/lower = good; up = regression.
   mid = a moderate increase (0% < Δ% ≤ 100%), tinted yellow/amber. */
.delta-down { color: #2b8a3e; font-weight: 600; }
.delta-mid { color: #b8860b; font-weight: 600; }
.delta-up { color: #c92a2a; font-weight: 600; }
.combo-badge {
  position: relative;
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05em 0.45em;
  font-size: 0.72rem;
  font-weight: 600;
  color: #8a6d00;
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: 999px;
  cursor: help;
  white-space: nowrap;
}
/* Reliable styled tooltip (the native title attribute is slow and renders
   multi-line text inconsistently). Shows the prev → latest fit on hover/focus. */
.combo-badge:hover::after,
.combo-badge:focus::after {
  content: attr(data-tip);
  position: absolute;
  left: 0;
  bottom: calc(100% + 6px);
  z-index: 30;
  width: max-content;
  max-width: 320px;
  padding: 0.5rem 0.65rem;
  white-space: pre-line;
  text-align: left;
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow-md);
}
.combo-badge:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Low-confidence marker: a "*" on values whose fit evm-gasfit flagged as poor. */
.poor-flag { color: #c2410c; font-weight: 700; cursor: help; margin-left: 1px; }

/* Binding (worst-case) row: the client that sets the proposed gas for a param. */
#delta-table tbody tr.binding-row { background: rgba(47, 111, 237, 0.07); }
#delta-table tbody tr.binding-row:hover { background: rgba(47, 111, 237, 0.13); }
#delta-table tbody tr.binding-row td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.binding-tag {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05em 0.5em;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--accent-strong);
  background: rgba(47, 111, 237, 0.12);
  border: 1px solid var(--accent);
  border-radius: 999px;
  vertical-align: middle;
}

/* Charts: Chart.js needs a sized, position:relative wrapper. The Δ% bar chart
   sets its own height inline (it grows with the row count). */
.chart-wrap { position: relative; height: 320px; margin: 1.5rem 0; }
.chart-wrap canvas { max-width: 100%; }
.trend-chart { margin: 2.25rem 0; padding-top: 1rem; border-top: 1px solid var(--border); }
.trend-chart h3 { margin: 0 0 0.25rem; }
.trend-chart[hidden] { display: none; }

/* Goals page: pass = clears the target (green), fail = needs optimization (red),
   nodata = no fit for that client (muted). Same green/red as the heatmap tints. */
.goal-pass { background: rgba(43, 138, 62, 0.82); color: #fff; font-weight: 600; }
.goal-fail { background: rgba(201, 42, 42, 0.82); color: #fff; font-weight: 600; }
.goal-mid { background: rgba(184, 134, 11, 0.85); color: #fff; font-weight: 600; }
.goal-pass .variant-label, .goal-fail .variant-label,
.goal-pass .variant-sep, .goal-fail .variant-sep { color: inherit; opacity: 0.7; }
.goal-nodata { color: var(--muted); }
.goal-chip {
  display: inline-block;
  padding: 0.02em 0.4em;
  border-radius: 4px;
  font-weight: 600;
}
.variant-label { font-size: 0.72rem; font-weight: 600; color: var(--muted); }
.variant-sep { color: var(--muted); }
/* Per-client detail cells link to their combo detail page; keep the cell's own
   pass/fail color, just hint interactivity on hover. */
.goal-cell-link,
.goal-cell-link:link,
.goal-cell-link:visited { color: #fff; text-decoration: none; display: block; }
.goal-cell-link:hover { text-decoration: underline; }
/* Combo detail pages: left-aligned combo description + highlighted winner row. */
.combo-cell { text-align: left; }
/* Combos whose value doesn't clear the goal (after the access subtraction):
   yellow font when over by up to 100%, red when more than 100% over. */
.over-goal { color: #c92a2a; font-weight: 600; }
.over-goal-mid { color: #b8860b; font-weight: 600; }
.over-goal-tag {
  display: inline-block;
  margin-left: 0.4em;
  padding: 0.02em 0.45em;
  font-size: 0.7rem;
  font-weight: 600;
  color: inherit;
  border: 1px solid currentColor;
  border-radius: 999px;
}
/* Anchor jumps (from a Goals cell) land below the sticky header so the client
   name stays visible above its table. */
h2[id] { scroll-margin-top: calc(var(--header-h) + 1rem); }
tr.winner-row td { background: rgba(47, 111, 237, 0.08); }
tr.winner-row td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

@media (prefers-color-scheme: dark) {
  .delta-down { color: #69db7c; }
  .delta-mid { color: #ffd43b; }
  .delta-up { color: #ff8787; }
  .combo-badge { color: var(--warn-border); }
  #delta-table tbody tr.binding-row { background: rgba(110, 160, 255, 0.13); }
  #delta-table tbody tr.binding-row:hover { background: rgba(110, 160, 255, 0.2); }
  .poor-flag { color: #fdba74; }
  .goal-pass { background: rgba(43, 138, 62, 0.70); color: #fff; }
  .goal-fail { background: rgba(201, 42, 42, 0.70); color: #fff; }
  .goal-mid { background: rgba(184, 134, 11, 0.72); color: #fff; }
  .over-goal { color: #ff8787; }
  .over-goal-mid { color: #ffd43b; }
}
