/* Redline dashboard.
 *
 * One stylesheet, no framework, no CDN. A dashboard for a page-speed product
 * that shipped a slow front-end would be an argument against the product.
 *
 * Status is never carried by colour alone -- every dot is paired with a word,
 * because roughly one man in twelve cannot tell the green one from the red.
 */

:root {
  color-scheme: light dark;

  --bg: #fff;
  --bg-subtle: #fafafa;
  --bg-raised: #fff;
  --fg: #0a0a0a;
  --fg-muted: #666;
  --fg-faint: #767676;   /* 4.54:1 on #fff */
  --line: #ebebeb;
  --line-strong: #d4d4d4;

  --ok: #0a7f43;
  --ok-bg: #e8f6ee;
  --warn: #a35c00;
  --warn-bg: #fdf3e3;
  --bad: #c62828;
  --bad-bg: #fdecec;
  --info: #0060df;
  --info-bg: #e8f1fd;

  --add-bg: #e6ffec;
  --add-fg: #04502a;
  --del-bg: #ffebe9;
  --del-fg: #7a1c17;

  --radius: 8px;
  --radius-lg: 12px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 3px rgba(0, 0, 0, .06);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000;
    --bg-subtle: #0a0a0a;
    --bg-raised: #101010;
    --fg: #ededed;
    --fg-muted: #a1a1a1;
    --fg-faint: #7a7a7a;   /* 4.73:1 on #000 */
    --line: #1f1f1f;
    --line-strong: #333;

    --ok: #3fcf72;
    --ok-bg: #0d2a18;
    --warn: #f5a524;
    --warn-bg: #2b1e05;
    --bad: #ff6369;
    --bad-bg: #2d1113;
    --info: #52a8ff;
    --info-bg: #0b1e33;

    --add-bg: #0d2a18;
    --add-fg: #7ee2a8;
    --del-bg: #2d1113;
    --del-fg: #ffabab;

    --shadow: 0 1px 2px rgba(0, 0, 0, .5);
  }
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font: 400 14px/1.6 var(--sans);
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -.015em; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.0625rem; }
h3 { font-size: .9375rem; }

code, .mono { font-family: var(--mono); font-size: .8125rem; }

/* -- chrome ------------------------------------------------------------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: .75rem;
  height: 56px;
  padding: 0 1.5rem;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-weight: 600;
  letter-spacing: -.02em;
}
.brand:hover { text-decoration: none; }
.brand .mark {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: linear-gradient(135deg, var(--bad) 0%, var(--warn) 100%);
}

.crumbs { display: flex; align-items: center; gap: .5rem; min-width: 0; }
.crumbs .sep { color: var(--fg-faint); }
.crumbs a, .crumbs span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.spacer { flex: 1; }

.who { color: var(--fg-muted); font-size: .8125rem; display: flex; gap: .625rem; align-items: center; }

main { max-width: 68rem; margin: 0 auto; padding: 2rem 1.5rem 6rem; }

.page-head { margin-bottom: 1.75rem; }
.page-head .lede { color: var(--fg-muted); margin: .375rem 0 0; }

/* -- tabs --------------------------------------------------------------- */

.tabs {
  display: flex;
  gap: 1.25rem;
  border-bottom: 1px solid var(--line);
  margin: 0 0 1.5rem;
  overflow-x: auto;
}
.tabs a {
  padding: .625rem .125rem;
  color: var(--fg-muted);
  font-size: .875rem;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
}
.tabs a:hover { color: var(--fg); text-decoration: none; }
.tabs a[aria-current="page"] { color: var(--fg); border-bottom-color: var(--fg); font-weight: 500; }

/* -- status ------------------------------------------------------------- */

.status { display: inline-flex; align-items: center; gap: .4375rem; white-space: nowrap; }
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--fg-faint); flex: none; }
.s-ok   .dot { background: var(--ok); }
.s-warn .dot { background: var(--warn); }
.s-bad  .dot { background: var(--bad); }
.s-live .dot { background: var(--info); animation: pulse 1.4s ease-in-out infinite; }
.s-ok { color: var(--ok); } .s-warn { color: var(--warn); }
.s-bad { color: var(--bad); } .s-live { color: var(--info); }

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .s-live .dot { animation: none; } }

.pill {
  display: inline-block;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .01em;
  padding: .125rem .4375rem;
  border-radius: 999px;
  border: 1px solid currentColor;
  white-space: nowrap;
}
.pill.ok { color: var(--ok); background: var(--ok-bg); }
.pill.warn { color: var(--warn); background: var(--warn-bg); }
.pill.bad { color: var(--bad); background: var(--bad-bg); }
.pill.info { color: var(--info); background: var(--info-bg); }
.pill.plain { color: var(--fg-muted); border-color: var(--line-strong); }

/* -- surfaces ----------------------------------------------------------- */

.card {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.125rem 1.25rem;
}

.grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); }

.repo-card { display: flex; flex-direction: column; gap: .75rem; }
.repo-card:hover { border-color: var(--line-strong); text-decoration: none; }
.repo-card .name { font-weight: 600; display: flex; align-items: center; gap: .5rem; }
.repo-card .meta { color: var(--fg-muted); font-size: .8125rem; display: flex; gap: .75rem; flex-wrap: wrap; }

.stats { display: flex; gap: 2rem; flex-wrap: wrap; margin: 0 0 1.5rem; }
.stat .n { font-size: 1.75rem; font-weight: 600; letter-spacing: -.03em; line-height: 1.1; }
.stat .k { color: var(--fg-muted); font-size: .8125rem; }

/* -- tables ------------------------------------------------------------- */

.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius-lg); }
table { width: 100%; border-collapse: collapse; font-size: .875rem; }
thead th {
  text-align: left;
  font-size: .6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--fg-muted);
  background: var(--bg-subtle);
  padding: .625rem .875rem;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
tbody td { padding: .75rem .875rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--bg-subtle); }
td.num { text-align: right; font-variant-numeric: tabular-nums; }

.delta-better { color: var(--ok); font-variant-numeric: tabular-nums; }
.delta-worse  { color: var(--bad); font-variant-numeric: tabular-nums; }
.delta-same   { color: var(--fg-faint); font-variant-numeric: tabular-nums; }

/* -- buttons ------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  background: var(--fg);
  color: var(--bg);
  padding: .5rem .875rem;
  border-radius: var(--radius);
  font-size: .875rem;
  font-weight: 500;
  border: 1px solid var(--fg);
}
.btn:hover { text-decoration: none; opacity: .88; }
.btn.ghost { background: transparent; color: var(--fg); border-color: var(--line-strong); }
.btn.ghost:hover { background: var(--bg-subtle); opacity: 1; }
.btn.sm { padding: .3125rem .625rem; font-size: .8125rem; }

/* -- empty states ------------------------------------------------------- */

.empty {
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  padding: 3rem 1.5rem;
  text-align: center;
  color: var(--fg-muted);
}
.empty h3 { color: var(--fg); margin-bottom: .375rem; }
.empty p { margin: 0 auto 1.25rem; max-width: 32rem; }

/* -- findings ----------------------------------------------------------- */

.finding { border: 1px solid var(--line); border-radius: var(--radius-lg); margin-bottom: 1rem; overflow: hidden; }
.finding > header {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .875rem 1.125rem;
  background: var(--bg-subtle);
  border-bottom: 1px solid var(--line);
}
.finding > header .route { font-family: var(--mono); font-weight: 600; }
.finding-body { padding: 1.125rem; }

.kv { display: grid; grid-template-columns: max-content 1fr; gap: .375rem 1rem; font-size: .875rem; margin: 0; }
.kv dt { color: var(--fg-muted); }
.kv dd { margin: 0; }

.chips { display: flex; gap: .375rem; flex-wrap: wrap; }
.chip {
  font-family: var(--mono);
  font-size: .75rem;
  padding: .125rem .4375rem;
  border-radius: 5px;
  background: var(--bg-subtle);
  border: 1px solid var(--line);
  color: var(--fg-muted);
}

.attempt { border-top: 1px solid var(--line); padding: .875rem 1.125rem; }
.attempt-head { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.attempt .why {
  margin: .625rem 0 0;
  padding: .625rem .75rem;
  background: var(--warn-bg);
  border-left: 3px solid var(--warn);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: .8125rem;
}
.attempt .why.good { background: var(--ok-bg); border-left-color: var(--ok); }

/* -- diffs -------------------------------------------------------------- */

details.diff { border: 1px solid var(--line); border-radius: var(--radius); margin-top: .75rem; }
details.diff > summary {
  cursor: pointer;
  padding: .5rem .75rem;
  font-size: .8125rem;
  color: var(--fg-muted);
  list-style: none;
  display: flex;
  align-items: center;
  gap: .5rem;
}
details.diff > summary::-webkit-details-marker { display: none; }
details.diff > summary::before { content: "\25B8"; font-size: .625rem; }
details.diff[open] > summary::before { content: "\25BE"; }
details.diff > summary:hover { color: var(--fg); }

pre.diff {
  margin: 0;
  padding: 0;
  overflow-x: auto;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: .75rem;
  line-height: 1.55;
  tab-size: 2;
}
pre.diff .ln { display: block; padding: 0 .75rem; white-space: pre; }
pre.diff .ln.add { background: var(--add-bg); color: var(--add-fg); }
pre.diff .ln.del { background: var(--del-bg); color: var(--del-fg); }
pre.diff .ln.hunk { color: var(--info); background: var(--info-bg); }
pre.diff .ln.file { color: var(--fg); font-weight: 600; background: var(--bg-subtle); }

.shots { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.shots figure { margin: 0; }
.shots img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-subtle);
}
.shots figcaption { color: var(--fg-muted); font-size: .8125rem; margin-top: .375rem; }

/* -- timeline ----------------------------------------------------------- */

.timeline { list-style: none; margin: 0; padding: 0 0 0 1.25rem; border-left: 2px solid var(--line); }
.timeline li { position: relative; padding: 0 0 1rem 1rem; }
.timeline li::before {
  content: "";
  position: absolute;
  left: -1.4375rem;
  top: .5rem;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--line-strong);
  border: 2px solid var(--bg);
}
.timeline li.lv-warn::before { background: var(--warn); }
.timeline li.lv-error::before { background: var(--bad); }
.timeline .stage {
  font-family: var(--mono);
  font-size: .6875rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--fg-faint);
}
.timeline .msg { display: block; }
.timeline .at { color: var(--fg-faint); font-size: .75rem; font-variant-numeric: tabular-nums; }

/* -- charts ------------------------------------------------------------- */

.chart { width: 100%; height: auto; overflow: visible; }
.chart .axis { stroke: var(--line); stroke-width: 1; }
.chart .line { fill: none; stroke: var(--info); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart .area { fill: var(--info); opacity: .08; }
.chart .pt { fill: var(--bg); stroke: var(--info); stroke-width: 2; }
.chart .budget { stroke: var(--bad); stroke-width: 1; stroke-dasharray: 4 3; }
.chart text { fill: var(--fg-muted); font-family: var(--sans); font-size: 10px; }

.spark { vertical-align: middle; }
.spark path { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }

/* -- misc --------------------------------------------------------------- */

.muted { color: var(--fg-muted); }
.faint { color: var(--fg-faint); }
.nowrap { white-space: nowrap; }
.section { margin: 2rem 0 0; }
.section > h2 { margin-bottom: .75rem; }
.hr { height: 1px; background: var(--line); border: 0; margin: 2rem 0; }

.note {
  border: 1px solid var(--line);
  border-left: 3px solid var(--info);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--bg-subtle);
  padding: .75rem 1rem;
  font-size: .875rem;
  color: var(--fg-muted);
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

@media (max-width: 640px) {
  main { padding: 1.5rem 1rem 4rem; }
  .topbar { padding: 0 1rem; }
  .stats { gap: 1.25rem; }
  .who .login { display: none; }
}

/* -- focus ---------------------------------------------------------------
 *
 * There were none. Every interactive element fell back to the browser
 * default ring, whose colour comes from the OS accent and is unrelated to
 * these tokens -- and on a near-black button in dark mode it is invisible.
 * The three scroll containers clipped it entirely, because a scroller cuts
 * outlines at its padding box.
 */

:focus-visible {
  outline: 2px solid var(--info);
  outline-offset: 2px;
  border-radius: var(--radius);
}
.btn:focus-visible { outline-color: var(--fg); outline-offset: 3px; }
.tabs { padding-top: 3px; }                        /* room inside the scroller */
.tabs a:focus-visible { outline-offset: -2px; }
.table-wrap:focus-visible,
pre.diff:focus-visible { outline-offset: -2px; }

/* Scrollable regions are focusable now, so they need to look scrollable. */
.table-wrap, pre.diff, .tabs { scrollbar-width: thin; }

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--bg);
  color: var(--fg);
  padding: .625rem 1rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  z-index: 100;
}
.skip:focus { left: .5rem; top: .5rem; }

/* -- a finding's headline ------------------------------------------------
 *
 * The number that MAKES it a finding used to be a 14px muted span, quieter
 * than the severity pill beside it. A page four times over budget should
 * read as one at a glance.
 */

.finding > header { align-items: baseline; }
.finding > header .route { font-family: var(--mono); font-size: .9375rem; }
.finding > header .outcome { margin-left: auto; }

.headline {
  display: flex;
  align-items: baseline;
  gap: .625rem;
  flex-wrap: wrap;
  padding: 1rem 1.125rem .25rem;
}
.headline .observed {
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: -.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--bad);
}
.headline .against { color: var(--fg-muted); font-size: .8125rem; }

h1 .sha { font-size: 1.375rem; font-weight: 600; }
h1 { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }

.note.bad { border-left-color: var(--bad); color: var(--fg); }

pre.diff.standalone {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: .5rem 0;
}

/* Direction is stated in words as well as colour -- the rule this file's own
 * header sets out, and the one place that broke it. */
.delta-better::before,
.delta-worse::before { font-size: .75rem; margin-right: .25rem; }
.delta-better::before { content: "\2193"; }
.delta-worse::before { content: "\2191"; }

/* -- measure --------------------------------------------------------------
 *
 * main is 68rem wide, which constrains the LAYOUT and not the LINE. Prose
 * was running to about 140 characters, roughly double what is comfortable —
 * worst of all on the "what was withdrawn" explainer, which is the most
 * important paragraph in the product.
 */

.lede,
.note,
.empty p,
.attempt .why,
.section > p.muted { max-width: 68ch; }

/* -- repository trend ----------------------------------------------------- */

.repo-card .trend { align-items: center; gap: .5rem; color: var(--fg-muted); }
.repo-card .trend svg { color: var(--fg-muted); flex: none; }

/* -- charts, continued ---------------------------------------------------- */

.chart .axis { stroke: var(--line-strong); stroke-width: 1; opacity: .6; }
.chart .pt { cursor: default; }
.chart text { font-size: 11px; }

@media (max-width: 640px) {
  /* At 375px a 720-wide viewBox scales to 52%, taking 11px axis text down to
   * about 6px. Taller box, bigger text, fewer labels. */
  .chart text { font-size: 15px; }
}

/* -- diff line numbers ---------------------------------------------------
 *
 * The hunk header was the only positional cue in the whole panel, so a
 * reviewer comparing a patch against the file in another tab had to count.
 */

pre.diff .ln { display: flex; padding: 0; }
pre.diff .ln .no {
  flex: none;
  width: 3rem;
  padding: 0 .5rem;
  text-align: right;
  color: var(--fg-faint);
  background: var(--bg-subtle);
  border-right: 1px solid var(--line);
  user-select: none;
  -webkit-user-select: none;
}
pre.diff .ln .tx { padding: 0 .75rem; white-space: pre; flex: 1; }
pre.diff .ln.file .no,
pre.diff .ln.hunk .no { background: transparent; }

.diff-head {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .5rem .75rem;
  border-bottom: 1px solid var(--line);
  font-size: .8125rem;
  color: var(--fg-muted);
}
.copy {
  margin-left: auto;
  font: inherit;
  font-size: .75rem;
  background: transparent;
  color: var(--fg-muted);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: .1875rem .5rem;
  cursor: pointer;
}
.copy:hover { color: var(--fg); background: var(--bg-subtle); }

/* -- landing --------------------------------------------------------------
 *
 * The one page a visitor sees before deciding whether to trust this with
 * write access to their repository. It leads with what a run produced,
 * including the run that produced nothing, because the withdrawals are the
 * part that makes the successes believable.
 */

.hero { max-width: 44rem; margin: 4rem 0 3.5rem; }
.hero h1 {
  font-size: clamp(2rem, 5vw, 2.75rem);
  line-height: 1.1;
  letter-spacing: -.03em;
  max-width: 20ch;
}
.hero .lede { font-size: 1.0625rem; margin-top: 1.125rem; }
.hero .cta { margin: 1.75rem 0 .75rem; display: flex; gap: .625rem; flex-wrap: wrap; }
.hero .faint { font-size: .875rem; margin: 0; }

.proof-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  margin-top: 1rem;
}
.proof-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.125rem 1.25rem;
  background: var(--bg-raised);
}
.proof-card .route {
  font-family: var(--mono);
  font-size: .8125rem;
  color: var(--fg-muted);
  margin-bottom: .625rem;
}
.proof-card .pair {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  font-variant-numeric: tabular-nums;
}
.proof-card .was {
  font-size: 1.125rem;
  color: var(--fg-muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.proof-card .arrow { color: var(--fg-faint); }
.proof-card .now {
  font-size: 1.875rem;
  font-weight: 600;
  letter-spacing: -.03em;
  color: var(--ok);
  line-height: 1;
}
.proof-card .refused {
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--warn);
}
.proof-card .what { color: var(--fg-muted); font-size: .8125rem; margin-top: .625rem; }
.proof-card.withdrawn { border-style: dashed; }

.steps {
  margin: 1rem 0 1.75rem;
  padding-left: 1.25rem;
  max-width: 60ch;
  color: var(--fg-muted);
}
.steps li { margin-bottom: .5rem; }
.steps strong { color: var(--fg); font-weight: 600; }

.closing { border-top: 1px solid var(--line); padding-top: 2rem; margin-top: 3rem; }

.pr-card {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  margin-bottom: .75rem;
}
.pr-card:hover { border-color: var(--line-strong); text-decoration: none; }
.pr-card .title { font-weight: 500; }
.pr-card .meta { display: flex; align-items: center; gap: .625rem; color: var(--fg-muted); font-size: .8125rem; }

/* -- filter --------------------------------------------------------------- */

.filter { display: flex; align-items: center; gap: .75rem; margin: 0 0 1rem; }
.filter input {
  font: inherit;
  font-size: .875rem;
  padding: .4375rem .75rem;
  min-width: min(22rem, 100%);
  color: var(--fg);
  background: var(--bg-raised);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
}
.filter input::placeholder { color: var(--fg-faint); }
.filter .count { color: var(--fg-muted); font-size: .8125rem; }

/* -- plain lists ---------------------------------------------------------- */

.plain-list { margin: 0; padding-left: 1.125rem; color: var(--fg-muted); }
.plain-list li { margin-bottom: .4375rem; }
.plain-list strong { color: var(--fg); font-weight: 600; }

.card h3 { margin-bottom: .625rem; }
.card .kv { font-size: .8125rem; }
.card .kv dt { font-weight: 600; color: var(--fg); }

/* The insights gridlines were 1.66:1 in dark mode — invisible, and they are
 * what makes the y-axis labels mean anything. Non-text graphics need 3:1. */
.chart .axis { stroke: var(--fg-faint); stroke-width: 1; opacity: .45; }

/* A skip link that leaves the heading under the sticky bar has not skipped
 * anywhere the reader can tell. */
html { scroll-padding-top: 72px; }
main:focus { outline: none; }
main:focus-visible { outline: 2px solid var(--info); outline-offset: 4px; }

/* -- footer ---------------------------------------------------------------
 *
 * There was no contentinfo landmark anywhere, and /security, /privacy and
 * /status were all 404 — so somebody deciding whether to grant write access
 * had no route, in-product or out, to the answers.
 */

.siteinfo {
  border-top: 1px solid var(--line);
  margin-top: 4rem;
  padding: 1.5rem 0 3rem;
  font-size: .8125rem;
  color: var(--fg-muted);
}
.siteinfo .inner {
  max-width: 68rem;
  margin: 0 auto;
  padding: 0 1.5rem;
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
  align-items: center;
}
.siteinfo nav { display: flex; gap: 1.25rem; margin-left: auto; }

.repo-card h2.name { font-size: .9375rem; font-weight: 600; }

@media (max-width: 640px) {
  .siteinfo .inner { padding: 0 1rem; }
  .siteinfo nav { margin-left: 0; }
}

/* -- mobile ---------------------------------------------------------------
 *
 * Measured at 375x812, not guessed. Nothing overflowed the document; every
 * failure was inside a scroll container, which is the kind that hides.
 */

@media (max-width: 640px) {
  /* The tab strip was 452px in a 343px box, so "Accessibility" started at
   * x=370 — entirely off screen, with no fade to suggest it was there. It
   * wraps now: two short rows beat one row you cannot see the end of. */
  .tabs {
    flex-wrap: wrap;
    overflow-x: visible;
    gap: .875rem 1rem;
    padding-bottom: .25rem;
  }
  .tabs a { padding: .5rem .125rem; }

  /* 28% of a 341px viewport was line-number gutters, leaving about thirty
   * monospace characters for the patch itself. One gutter, narrower. */
  pre.diff .ln .no:first-child { display: none; }
  pre.diff .ln .no { width: 2.25rem; padding: 0 .375rem; }
  pre.diff .ln .tx { padding: 0 .5rem; }

  /* "62% faster" — the proof — was cut off by 13px inside .table-wrap. */
  .table-wrap table { font-size: .8125rem; }
  tbody td, thead th { padding: .625rem .5rem; }

  /* A 720-wide viewBox scaled to 343px renders 15px text at about 7px. */
  .chart { min-height: 220px; }
  .chart text { font-size: 20px; }

  .stats { gap: 1rem 1.75rem; }
  .stat .n { font-size: 1.5rem; }
  .headline .observed { font-size: 1.5rem; }
}

/* -- insight charts ------------------------------------------------------ */
/* Small multiples. One full-width chart per route per metric meant reading a
   three-route site took nine screens; these fit nine on one. */

.route-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .6rem;
}

.route-head code { font-weight: 400; font-size: .8em; }

.chart-grid {
  display: grid;
  gap: .75rem;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.chart-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: .9rem 1rem 1rem;
}

.chart-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .5rem;
}

.chart-head .metric {
  font: 600 .6875rem/1 var(--mono);
  letter-spacing: .08em;
  color: var(--fg-muted);
}

.chart-head .value {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

.chart-sub {
  display: flex;
  flex-wrap: wrap;
  gap: .15rem .6rem;
  margin: .1rem 0 .5rem;
  font-size: .75rem;
}

/* The verdict is a word, so the colour below is reinforcement and never the
   only thing carrying the state. */
.chart-card.is-over .verdict { color: var(--bad); font-weight: 600; }
.chart-card.is-under .verdict { color: var(--ok); font-weight: 600; }
.chart-card.is-none .verdict { color: var(--fg-faint); }

.chart-foot {
  margin: .4rem 0 0;
  font-size: .75rem;
  color: var(--fg-muted);
}

.chart.is-over .line { stroke: var(--bad); }
.chart.is-over .area { fill: var(--bad); }
.chart.is-over .pt { stroke: var(--bad); }
.chart.is-under .line { stroke: var(--ok); }
.chart.is-under .area { fill: var(--ok); }
.chart.is-under .pt { stroke: var(--ok); }
.chart .pt.is-last { stroke-width: 3; }
.chart .budget-label { fill: var(--fg-faint); font-size: 9px; }
.chart .xlab { font-family: var(--mono); font-size: 9px; }


/* The waiting-for-approval notice. Longer than a one-line note because it has
   to answer three questions at once: why nothing is happening, whether the
   reader needs to act, and who to ask. */
/* `.note` carries no margin of its own -- everywhere else it sits inside a
   .section, which supplies the spacing. This one is a direct child of the
   page, so it needs its own or it ends flush against the row of stats. */
.note.pending { padding: 1.1rem 1.25rem; margin: 0 0 2rem; }
.note.pending h2 { margin: 0 0 .5rem; font-size: 1.0625rem; }
.note.pending p { margin: 0 0 .6rem; }
.note.pending p:last-child { margin-bottom: 0; }
