/* One stylesheet, no framework, no build step, like every page on peterparker.ca.

   Copied from project 04's site, which took 12's, which grew from 08's, which took 01 and
   02's: the palette, the type and the 3px rule over the page are peterparker.ca's, because
   this page is part of that site even though the demonstration's own host serves it. The two
   fonts are copied into this folder rather than linked: the page makes no off-origin request,
   and a font is a request. Both are SIL Open Font License; fonts/LICENSE.txt says where they
   came from. The rules the other projects need and this one does not are kept, so the file
   stays a copy anybody can diff. What this site adds is at the end, after project 04's
   additions.

   Colours live here and never in app.js, so one palette follows the page into dark mode. */

@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url(fonts/newsreader-latin.woff2) format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(fonts/inter-latin.woff2) format("woff2");
}

:root {
  color-scheme: light dark;
  --paper: #f5f3ee;
  --paper-soft: #fdfcf9;
  --ink: #16181d;
  --ink-soft: #3c4048;
  --ink-faint: #6b7079;
  --line: #e3dfd6;
  --line-2: #cfc9bd;
  --line-soft: #eeebe4;
  --accent: #0f5c6e;
  --accent-ink: #0b4653;
  --accent-soft: #e4eff1;
  --warn: #c0392b;
  --good: #1e7a4c;
  --alt: #6d3f9e;
  --shift: rgba(192, 57, 43, 0.09);
  /* The three levels of the hierarchy are an ordered set, so they are one hue in three
     steps rather than three colours: darkest is the city, lightest the dispatch areas. */
  --lv0: #0b4653;
  --lv1: #2f8294;
  --lv2: #7bb3c0;
  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  --sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;
  --radius: 10px;
  --shadow: 0 6px 24px -18px rgba(0, 0, 0, 0.35);
  --column: 66rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #0e1013;
    --paper-soft: #15181d;
    --ink: #ece9e2;
    --ink-soft: #c9c6bf;
    --ink-faint: #969ba5;
    --line: #262a31;
    --line-2: #363b44;
    --line-soft: #1c2026;
    --accent: #7cc7d6;
    --accent-ink: #a9dde7;
    --accent-soft: #14262b;
    --warn: #f0736a;
    --good: #58c286;
    --alt: #b191e0;
    --shift: rgba(240, 115, 106, 0.13);
    --lv0: #cbeaf2;
    --lv1: #7cc7d6;
    --lv2: #3d8ea1;
    --shadow: 0 6px 24px -14px rgba(0, 0, 0, 0.6);
  }
}

* { box-sizing: border-box; }

html { font-size: 18px; -webkit-text-size-adjust: 100%; }

body {
  overflow-x: clip;
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.72;
  border-top: 3px solid var(--accent);
  font-feature-settings: "cv11", "ss01";
}

main {
  max-width: var(--column);
  margin: 0 auto;
  padding: 0 1.5rem 5rem;
}

h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 500;
  letter-spacing: -0.012em;
}

h1 { font-size: clamp(2.1rem, 4.6vw, 3rem); line-height: 1.1; margin: 0 0 1rem; }
h2 { font-size: clamp(1.55rem, 2.6vw, 2rem); line-height: 1.2; margin: 0 0 0.7rem; }
h3 { font-size: 1.2rem; line-height: 1.25; margin: 0 0 0.45rem; }
p { margin: 0 0 0.85rem; }

a { color: var(--accent); text-decoration: none; text-underline-offset: 0.15em; }
a:hover, a:focus-visible { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

code { font-family: var(--mono); font-size: 0.9em; }

strong { font-weight: 600; }

/* ---------------------------------------------------------------- the way back */

.top { border-bottom: 1px solid var(--line); background: var(--paper); }

.top-inner {
  max-width: var(--column);
  margin: 0 auto;
  padding: 0 1.5rem;
  height: 4rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  color: var(--ink);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.brand:hover { text-decoration: none; color: var(--accent-ink); }

.mono-mark {
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 6px;
  background: var(--accent);
  color: #fdfcf9;
  font-family: var(--serif);
  font-weight: 500;
  font-size: 1.15rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

@media (prefers-color-scheme: dark) { .mono-mark { color: #0e1013; } }

.top-nav { font-size: 0.92rem; color: var(--ink-soft); text-align: right; margin: 0; }
.top-nav a { color: var(--ink-soft); }
.top-nav a:hover { color: var(--accent-ink); }

/* ---------------------------------------------------------------- the menu */

/* The site's pages, as pills, as on the other project pages (01, 02, 03). The proxy's
   /demo and /dashboard carry the same menu through boundary.server.chrome. */
.tabs { border-bottom: 1px solid var(--line); background: var(--paper-soft); }

.tabs-inner {
  max-width: var(--column);
  margin: 0 auto;
  padding: 0.55rem 1.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.tabs a {
  font-size: 0.85rem;
  padding: 0.2rem 0.75rem;
  border-radius: 999px;
  border: 1px solid transparent;
  color: var(--ink-soft);
}

.tabs a:hover { text-decoration: none; border-color: var(--line-2); color: var(--accent-ink); }

.tabs a[aria-current] {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--ink);
  font-weight: 600;
}

@media (max-width: 46rem) {
  /* One row that scrolls sideways, rather than rows of pills above the page. */
  .tabs-inner { padding: 0.5rem 1.1rem; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .tabs a { flex: none; }
}

/* ---------------------------------------------------------------- the architecture page */

/* The diagrams are white-ground SVGs generated from a specification, so they sit on their own
   card in both themes, and each opens full size for narrow screens. */
.arch-figure { margin: 1.1rem 0 1.4rem; }
.arch-figure a { display: block; }
.arch-figure img {
  display: block;
  width: 100%;
  height: auto;
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.prose .where { font-size: 0.86rem; color: var(--ink-faint); }
.arch-back { margin: 0; font-size: 0.95rem; }

/* ---------------------------------------------------------------- hero */

.hero { position: relative; padding: 1.5rem 0 2.25rem; border-bottom: 1px solid var(--line); }

/* A wash of the accent behind the first screen, full width, fading into the page, as on the
   release gate's site (03): the one place colour is used for its own sake. */
.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 100vw;
  margin-left: -50vw;
  background:
    radial-gradient(60rem 22rem at 85% 0%, color-mix(in srgb, var(--alt) 14%, transparent), transparent 70%),
    linear-gradient(180deg, var(--accent-soft), var(--paper) 85%);
}
.hero h1 .hl { color: var(--accent); }
.hero .eyebrow { color: var(--accent-ink); }
.hero .point { border-top: 3px solid var(--accent); box-shadow: var(--shadow); }
.hero .point.good { border-top-color: var(--good); }
.hero .point.violet { border-top-color: var(--alt); }

.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--ink-faint);
  margin: 0 0 0.6rem;
}

.lead { font-size: 1.05rem; color: var(--ink-soft); }

.hero-points {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 0.9rem;
  margin: 1.75rem 0 1.1rem;
}

.point {
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
}

.point-figure {
  display: block;
  font-family: var(--serif);
  font-size: 1.9rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--ink);
}

.point .point-figure { color: var(--accent-ink); }
.point.good .point-figure { color: var(--good); }
.point.violet .point-figure { color: var(--alt); }

.point-unit {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--ink-soft);
  line-height: 1.35;
}

.point-label {
  display: block;
  margin-top: 0.4rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--line);
  font-size: 0.82rem;
  color: var(--ink-faint);
  line-height: 1.4;
}

.point-extra {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.8rem;
  color: var(--ink-faint);
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}

.hero-models {
  position: relative;
  font-size: 0.86rem;
  color: var(--ink-soft);
  margin: 0 0 0.6rem;
}

/* A model's name that explains itself. The bubble hangs from the paragraph rather than
   from the word, because the paragraph is the one box that is always inside the page: a
   bubble anchored to a name at the end of a line would run off the right edge. It opens on
   focus as well as hover, so a keyboard reaches it and a tap on a phone opens it. */
.term {
  border-bottom: 1px dotted var(--ink-faint);
  cursor: help;
}

.term:hover, .term:focus { color: var(--accent-ink); border-bottom-color: var(--accent); }

.term::after {
  content: attr(data-note);
  position: absolute;
  left: 0;
  top: calc(100% + 0.4rem);
  width: min(32rem, 100%);
  padding: 0.7rem 0.85rem;
  background: var(--paper-soft);
  color: var(--ink-soft);
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  font-size: 0.84rem;
  font-weight: 400;
  line-height: 1.5;
  z-index: 10;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease;
}

.term:hover::after, .term:focus::after { opacity: 1; visibility: visible; }

/* Read by a screen reader, drawn for nobody: the notes the bubbles show, as descriptions. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.hero-note { font-size: 0.88rem; color: var(--ink-faint); margin: 0; }

/* The headline error, broken out by race length, right under the figures it belongs to. Five
   minutes means something different over 5 km and over a marathon, so the strip carries both the
   minutes and the share of a finish time, and the share is what makes the row comparable. It
   wraps on a phone rather than scrolling sideways. */
/* The picker over the hero strip. Narrow, because it governs six small cards rather than the
   page, and left-aligned with them. */
.hero-slicer {
  max-width: 22rem;
  margin: 1.5rem 0 0;
}

.hero-slicer label { display: block; font-weight: 600; font-size: 0.9rem; }

.hero-strip-label {
  font-size: 0.84rem;
  color: var(--ink-faint);
  margin: 0.9rem 0 0.5rem;
  line-height: 1.45;
}

.hero-distances {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1.1rem;
}

.hero-distance {
  flex: 1 1 7.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.55rem 0.7rem;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.hd-race {
  font-size: 0.76rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
}

.hd-min {
  font-family: var(--serif);
  font-size: 1.25rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  color: var(--good);
}

.hd-pct {
  font-size: 0.8rem;
  line-height: 1.3;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* The second line of a two-line sentence closes the column gap, so "avg miss," and
   "3.8% of the time" read as one thing and not as two facts. */
.hd-pct + .hd-pct,
.hd-spread + .hd-spread { margin-top: -0.1rem; }

/* What the average does not say: where the middle of the misses is, and where the tail
   ends. Quieter than the figure above it, because it is the sentence that stops a reader
   believing every prediction is out by the headline number. */
.hd-spread {
  font-size: 0.75rem;
  color: var(--ink-faint);
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}

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

.section { padding: 2.75rem 0; border-bottom: 1px solid var(--line); }
.section:last-of-type { border-bottom: 0; }
.section-lead { color: var(--ink-soft); }
.note { font-size: 0.86rem; color: var(--ink-faint); }
/* A note that explains the table above it, rather than the one below. */
.table-wrap + .note { margin-top: 1.1rem; }

.warning {
  max-width: var(--column);
  margin: 1.25rem auto;
  padding: 0.9rem 1.1rem;
  border-left: 3px solid var(--warn);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: color-mix(in srgb, var(--warn) 9%, transparent);
}

/* The callout a section's finding goes in, and the one an assumption goes in. Same shape,
   different weight: a finding is the point of the section, an assumption is the fine print
   that stops the finding being overread. */
.verdict {
  margin: 1.1rem 0 1.6rem;
  padding: 1rem 1.1rem;
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  font-size: 0.98rem;
}

.verdict p:last-child { margin-bottom: 0; }

.assumption {
  margin: 1.1rem 0 0;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-2);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--paper-soft);
  font-size: 0.88rem;
  color: var(--ink-soft);
}

.assumption p:last-child { margin-bottom: 0; }

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

.controls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1rem;
  margin: 1.25rem 0;
  padding: 1rem;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.control { display: flex; flex-direction: column; gap: 0.4rem; min-width: 0; }
.control.wide { grid-column: 1 / -1; }

label { font-size: 0.85rem; font-weight: 600; color: var(--ink-soft); }

.hint {
  display: block;
  font-weight: 400;
  font-size: 0.78rem;
  color: var(--ink-faint);
  margin-top: 0.1rem;
}

select, input[type="range"] { width: 100%; font: inherit; accent-color: var(--accent); }

select {
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  background: var(--paper-soft);
  color: var(--ink);
  font-size: 0.9rem;
}

input[type="range"] { height: 1.6rem; }

output { font-variant-numeric: tabular-nums; color: var(--accent-ink); font-weight: 600; }

/* ---------------------------------------------------------------- charts */

.chart-figure { margin: 1.1rem 0; }
.chart { width: 100%; }
.chart svg { width: 100%; height: auto; display: block; touch-action: pan-y; }

/* A chart whose labels are words rather than ticks cannot be shrunk to a phone's width and
   still be read, so it keeps its size and scrolls sideways instead. */
.wide-chart { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.wide-chart svg { min-width: 40rem; }

figcaption { font-size: 0.83rem; color: var(--ink-faint); margin-top: 0.5rem; }

.gridline { stroke: var(--line); stroke-width: 1; }
.axis-line { stroke: var(--line-2); stroke-width: 1; }
.tick { fill: var(--ink-faint); font-size: 11px; }
.axis-title { fill: var(--ink-faint); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.series { fill: none; stroke-linejoin: round; stroke-linecap: round; stroke-width: 1.5; }
.band { fill: var(--accent); stroke: none; }

/* The three conformal methods, and the swatch that names each one. Set here rather than on
   the element so that both follow the palette into dark mode. */
.m0 { stroke: var(--accent); }
.m1 { stroke: var(--warn); }
.m2 { stroke: var(--alt); }
.sw0 { background: var(--accent); }
.sw1 { background: var(--warn); }
.sw2 { background: var(--alt); }
.sw-ink { background: var(--ink); }
.sw-accent { background: var(--accent); }
.sw-band { background: var(--accent); }
.sw-warn { background: var(--warn); color: var(--warn); }
.sw-faint { background: var(--ink-faint); color: var(--ink-faint); }
.nominal { stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 5 4; fill: none; }
.actual-line { fill: none; stroke: var(--ink); stroke-width: 1.5; stroke-linejoin: round; }
.median { fill: none; stroke: var(--accent); stroke-width: 1.75; stroke-linejoin: round; }
/* Over 911 origins a 1.5px line is a solid block; these are the same lines, drawn for a
   view that has ten times as many points in the same width. */
.actual-line.thin, .median.thin { stroke-width: 0.8; }

.service { fill: none; stroke: var(--warn); stroke-width: 1.5; stroke-dasharray: 6 4; }
.shift-span { fill: var(--shift); }
.shift-label { fill: var(--ink-faint); font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; }
.cursor { stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 3 3; }
.dot { stroke: var(--paper-soft); stroke-width: 1.5; fill: var(--ink); }
.dot.median { fill: var(--accent); }
.dot.m0 { fill: var(--accent); }
.dot.m1 { fill: var(--warn); }
.dot.m2 { fill: var(--alt); }
.catcher { cursor: crosshair; }

/* The models panel. A bar is a length, so it gets a fill and no outline; the interval is
   a hairline through it, in ink rather than in the series colour, because it is not a
   fourth series. */
.bar { stroke: none; }
.bar.lv0 { fill: var(--lv0); }
.bar.lv1 { fill: var(--lv1); }
.bar.lv2 { fill: var(--lv2); }
.bar.own { fill-opacity: 0.7; stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 3 2; }
.sw-lv0 { background: var(--lv0); }
.sw-lv1 { background: var(--lv1); }
.sw-lv2 { background: var(--lv2); }
.whisker { stroke: var(--ink-soft); stroke-width: 1; }
.zero { stroke: var(--ink-faint); stroke-width: 1.25; }
.zero-label { fill: var(--ink-faint); font-size: 10.5px; }
.bar-value { fill: var(--ink-soft); font-size: 11px; font-variant-numeric: tabular-nums; }
.row-label { fill: var(--ink); font-size: 12px; font-weight: 600; }
.row-label.faint { fill: var(--ink-soft); font-weight: 500; }
.row-note { fill: var(--ink-faint); font-size: 10.5px; }
.divider { stroke: var(--line-2); stroke-width: 1; stroke-dasharray: 4 3; }
.divider-label { fill: var(--ink-faint); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; }

.legend { display: flex; flex-wrap: wrap; gap: 0.45rem; margin: 0.25rem 0 0.5rem; }

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.82rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: var(--paper-soft);
  color: var(--ink-soft);
}

.swatch { width: 14px; height: 3px; border-radius: 2px; display: inline-block; flex: none; }
.swatch.dashed { background: repeating-linear-gradient(90deg, currentColor 0 4px, transparent 4px 7px); }
.swatch.block { height: 11px; border-radius: 3px; opacity: 0.3; }
/* A bar's swatch is the bar's colour at full strength: it names a series, not a band. */
.swatch.solid { height: 11px; border-radius: 3px; }

/* The hover readout. One row per series, values right-aligned so they line up as a column. */
.readout {
  min-height: 1.6rem;
  margin: 0.3rem 0 0;
  font-size: 0.84rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.readout .when { font-weight: 600; color: var(--ink); margin-right: 0.6rem; }
.readout .pair { margin-right: 0.9rem; white-space: nowrap; }
.readout .key { color: var(--ink-faint); }

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

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }

th, td {
  text-align: left;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

th {
  font-weight: 600;
  color: var(--ink);
  font-size: 0.82rem;
  background: var(--line-soft);
  border-bottom-color: var(--line-2);
  vertical-align: bottom;
}

tbody th { background: transparent; font-size: 0.9rem; }
/* A row label that carries its window as well as its name is the one cell allowed to wrap,
   so that one long label does not push the whole table out of its column. */
tbody th.wrap { white-space: normal; max-width: 14rem; }

td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* Seven columns of estimate and interval is a table that only just fits the column this
   page is set in, so it is given narrower gutters rather than a scrollbar it does not
   need. It still scrolls on a narrow screen, like every other table here. */
.tight th, .tight td { padding-left: 0.55rem; padding-right: 0.55rem; }

caption { caption-side: bottom; text-align: left; color: var(--ink-faint); font-size: 0.83rem; padding-top: 0.6rem; }

tbody tr.reference { background: var(--accent-soft); }

.interval { color: var(--ink-faint); font-size: 0.82em; }

.better { color: var(--good); font-weight: 600; }
.worse { color: var(--warn); font-weight: 600; }

/* ---------------------------------------------------------------- headline stats */

.headline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.9rem;
  margin: 1.25rem 0;
}

.stat {
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
}

.figure {
  display: block;
  font-family: var(--serif);
  font-size: 1.75rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.stat.up .figure { color: var(--good); }
.stat.down .figure { color: var(--warn); }

.caption { display: block; margin-top: 0.3rem; font-size: 0.82rem; color: var(--ink-faint); line-height: 1.4; }

.range { display: block; font-size: 0.78rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- disclosure */

.disclose {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0 1.1rem;
  margin: 1.1rem 0;
  background: var(--paper-soft);
}

.disclose summary {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  cursor: pointer;
  padding: 0.8rem 0 0.8rem 0.25rem;
  font-weight: 600;
  font-size: 0.94rem;
  list-style: none;
}

.disclose summary::-webkit-details-marker { display: none; }

.disclose summary::before {
  content: "\203A";
  flex: none;
  width: 0.6em;
  text-align: center;
  font-size: 1.2em;
  line-height: 1;
  color: var(--ink-faint);
  transform: rotate(90deg);
  transition: transform 0.12s ease;
}

.disclose[open] summary::before { transform: rotate(270deg); }
.disclose summary:hover { color: var(--accent-ink); }
.disclose[open] summary { border-bottom: 1px solid var(--line); margin-bottom: 0.75rem; }
.disclose > *:last-child { margin-bottom: 0.85rem; }

@media (prefers-reduced-motion: reduce) {
  .disclose summary::before { transition: none; }
  .term::after { transition: none; }
}

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

.foot {
  border-top: 1px solid var(--line);
  background: var(--paper-soft);
  margin-top: 2rem;
}

.foot-inner {
  max-width: var(--column);
  margin: 0 auto;
  padding: 2rem 1.5rem 2.5rem;
  font-size: 0.88rem;
  color: var(--ink-faint);
}

.foot-inner p { margin: 0 0 0.5rem; }

.foot-inner ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; }

@media (max-width: 34rem) {
  html { font-size: 17px; }
  main { padding: 0 1rem 3rem; }
  .top-inner { padding: 0 1rem; height: auto; min-height: 4rem; flex-wrap: wrap; gap: 0.25rem 1rem; padding-top: 0.6rem; padding-bottom: 0.6rem; }
  .top-nav { text-align: left; }
  .controls { padding: 0.85rem; }
  .foot-inner { padding: 1.5rem 1rem 2rem; }
}

/* ====================================== The Whole Field, Called Before the Gun */

/* Four methods, five race lengths and five kinds of history, and the colours the charts name
   them by. What the site publishes is the accent; the three baselines are neutral steps,
   because they are the backdrop it is measured against. The published prediction averages the
   Bayesian model and the challenger, so those two carry lighter shades of the accent and the
   alternate, near their average but never mistaken for it. */
:root {
  --m-cf: #8a8f98;
  --m-vdot: #b5a58a;
  --m-median: #d6d1c6;
  --m-hier: #5f9fae;
  --d4: #0b4653;
  --d2: #2f8294;
  --d1: #7bb3c0;
  --d0: #e0b35a;
  --dx: #c9c4ba;
  --w0: #7bb3c0;
  --w1: #2f8294;
  --w2: #0b4653;
  --w3: #c0392b;
  --w4: #6d3f9e;
  --hit: #1e7a4c;
  --miss: #c0392b;
}

@media (prefers-color-scheme: dark) {
  :root {
    --m-cf: #7d838d;
    --m-vdot: #8f8166;
    --m-median: #4a4f58;
    --m-hier: #40798a;
    --d4: #cbeaf2;
    --d2: #7cc7d6;
    --d1: #3d8ea1;
    --d0: #d9a441;
    --dx: #4a4f58;
    --w0: #3d8ea1;
    --w1: #7cc7d6;
    --w2: #cbeaf2;
    --w3: #f0736a;
    --w4: #b191e0;
    --hit: #58c286;
    --miss: #f0736a;
  }
}

/* ------------------------------------------------------------- on this page */

.toc { padding: 1.5rem 0 1.75rem; border-bottom: 1px solid var(--line); }
.toc ol {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: toc;
  columns: 2 16rem;
  column-gap: 2rem;
}
.toc li { counter-increment: toc; margin: 0 0 0.3rem; break-inside: avoid; font-size: 0.93rem; }
.toc li::before {
  content: counter(toc, decimal-leading-zero);
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
  font-size: 0.78rem;
  margin-right: 0.6rem;
}

.part { padding: 3.5rem 0 0.5rem; }
.part-title { font-size: clamp(1.75rem, 3.4vw, 2.4rem); line-height: 1.15; margin-bottom: 0.9rem; }

.two-col { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1.25rem 2rem; margin: 1rem 0; }

/* ------------------------------------------------------------- the picture */

.pipeline {
  list-style: none;
  margin: 1.5rem 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.6rem;
}
@media (max-width: 60rem) { .pipeline { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); } }
.pipeline li {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.8rem 0.75rem 0.9rem;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 0.82rem;
  color: var(--ink-soft);
  line-height: 1.45;
}
.pipeline li strong { font-family: var(--serif); font-size: 1.15rem; font-weight: 500; color: var(--ink); }
.pipeline li:nth-child(6) { border-color: var(--accent); background: var(--accent-soft); }
.step {
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--accent);
  color: var(--paper-soft);
  font-size: 0.8rem;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.2rem;
}

/* ------------------------------------------------------------- the race */

.race-card {
  margin: 1.25rem 0 1rem;
  padding: 1.25rem 1.3rem;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.race-head h3 { font-size: 1.6rem; margin: 0; }
.race-when { margin: 0.1rem 0 0.35rem; color: var(--ink-soft); }
.race-status {
  display: inline-block;
  margin: 0 0 1rem;
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  font-size: 0.84rem;
  font-weight: 600;
  background: var(--accent-soft);
  color: var(--accent-ink);
}
.race-status.stage-final, .race-status.stage-scored {
  background: color-mix(in srgb, var(--good) 14%, transparent);
  color: var(--good);
}
.race-status.stage-retrospect, .race-status.stage-calendar {
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  color: var(--warn);
}

/* The banner on a race that ran before this project published anything. It sits above the
   race name rather than beside the status chip, because the one thing a reader must not
   carry away from this card is that these numbers were published before the gun. */
.race-warning {
  margin: -0.25rem 0 1.1rem;
  padding: 0.9rem 1.1rem;
  border-left: 3px solid var(--warn);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: color-mix(in srgb, var(--warn) 9%, transparent);
}
.race-warning strong { display: block; color: var(--warn); margin-bottom: 0.35rem; }
.race-warning p { font-size: 0.86rem; line-height: 1.55; margin: 0 0 0.5rem; }
.race-warning p:last-child { margin-bottom: 0; }

/* A miss where the finish landed inside that runner's published range. The one promise this
   project makes about a single runner, marked on the miss because that is the number being
   read, and the same green the scatter above the table uses for the same thing. */
td.close { color: var(--good); }

/* A finisher with no prediction. The row is real and stays in place; what it cannot say is
   greyed, and the range column says so in words where the range would have been. */
tr.unpredicted td { color: var(--ink-faint); }
td.why { font-size: 0.82rem; font-style: italic; white-space: nowrap; }

/* The tag after a name the archive would not commit to, and anything else carrying a note
   behind it. The dotted underline is the only thing on the page that says a tooltip is
   there; without it nobody hovers. The note is also written out under the table, because a
   touch screen has no hover at all. */
/* Not `.tag`, which is the pill used elsewhere on the page and would draw a box round it. */
.name-tag, #everyone td[title] { cursor: help; }
.name-tag {
  font-size: 0.82rem;
  font-style: italic;
  border-bottom: 1px dotted currentColor;
}
#everyone td[title] { border-bottom: 1px dotted var(--line); }

/* A note whose opening words are the thing a reader must not miss: the tag in the table
   above it, and where two of its columns came from. Bold alone is not enough in a colour
   this faint. */
.note strong { color: var(--ink); }

.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 0.9rem 1.25rem; margin-bottom: 1rem; }
.fact { display: flex; flex-direction: column; min-width: 0; }
.fact-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-faint); font-weight: 600; }
.fact-value { font-family: var(--serif); font-size: 1.25rem; line-height: 1.3; }
.fact-note { font-size: 0.8rem; color: var(--ink-faint); line-height: 1.4; }

.field { margin-top: 0.5rem; }
.field-title { font-size: 0.88rem; color: var(--ink-soft); margin-bottom: 0.4rem; }
.field svg { width: 100%; height: auto; display: block; }
.seg.d4, .sw-d4 { fill: var(--d4); background: var(--d4); }
.seg.d2, .sw-d2 { fill: var(--d2); background: var(--d2); }
.seg.d1, .sw-d1 { fill: var(--d1); background: var(--d1); }
.seg.d0, .sw-d0 { fill: var(--d0); background: var(--d0); }
.seg.dx, .sw-dx { fill: var(--dx); background: var(--dx); }
.seg-label { fill: var(--paper-soft); font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }

.week { margin: 0 0 1.5rem; }
.week-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
}
.week-steps li {
  display: flex;
  flex-direction: column;
  padding: 0.65rem 0.8rem;
  border-top: 3px solid var(--line-2);
  font-size: 0.82rem;
  color: var(--ink-faint);
}
.week-steps li strong { color: var(--ink-soft); font-size: 0.9rem; }
.week-steps li.done { border-top-color: var(--good); }
.week-steps li.now { border-top-color: var(--accent); background: var(--accent-soft); }
.week-steps li.now strong { color: var(--accent-ink); }

.table-wrap.tall { max-height: 34rem; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.table-wrap.tall thead th { position: sticky; top: 0; z-index: 1; }
/* The runner table, which a race already run gives nine columns: a place, a name, the two
   the association's other pages printed, and the prediction against the finish. All of it
   has to be on screen at an ordinary desktop width rather than behind a horizontal scroll
   nobody knows is there, so the padding comes in. The live prediction table shares this id
   and is a little tighter for it, which costs nothing. */
#everyone th, #everyone td { padding-left: 0.5rem; padding-right: 0.5rem; }
/* The last column reads against the edge of the scroll box otherwise, and it is the one
   column a reader stops on. */
#everyone th:last-child, #everyone td:last-child { padding-right: 1.2rem; }
#everyone tbody tr { cursor: pointer; }
#everyone tbody tr:hover { background: var(--accent-soft); }
.muted-cell { color: var(--ink-faint); font-size: 0.8rem; }
.hash { font-family: var(--mono); font-size: 0.74rem; color: var(--ink-faint); }
tr.unseen td { color: var(--ink-faint); font-style: italic; }

input[type="search"] {
  width: 100%;
  font: inherit;
  font-size: 0.9rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  background: var(--paper-soft);
  color: var(--ink);
}
input[type="search"]:disabled { opacity: 0.55; }

/* ------------------------------------------------------------- chart marks */

.catcher { fill: transparent; cursor: crosshair; }
.catcher:hover, .catcher:focus { fill: var(--line-soft); fill-opacity: 0.6; outline: none; }
.chart [tabindex]:focus { outline: none; stroke: var(--ink); stroke-width: 2; }

.chosen-band { fill: var(--warn); fill-opacity: 0.14; }
.chosen-line { stroke: var(--warn); stroke-width: 2; }
.diagonal { stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 5 4; }
.pt { fill-opacity: 0.55; stroke: none; }
.pt-hit { fill: var(--hit); }
.pt-miss { fill: var(--miss); fill-opacity: 0.75; }
.pt-none { fill: var(--ink-faint); }
.gap-label { fill: var(--ink-faint); font-size: 10px; letter-spacing: 0.04em; }

.median-line { stroke: var(--accent); stroke-width: 2; fill: none; }
.fastest-line { stroke: var(--warn); stroke-width: 1.5; fill: none; stroke-dasharray: 4 3; }
.dot.median-dot { fill: var(--accent); }
.dot.fastest-dot { fill: var(--warn); }

.course-dot { fill: var(--ink-faint); stroke: var(--paper-soft); stroke-width: 1; }
.course-dot.live { fill: var(--warn); }
.course-dot.named { fill: var(--ink-soft); }
.whisker.live { stroke: var(--warn); stroke-width: 1.5; }
.whisker.faint { stroke: var(--ink-faint); stroke-dasharray: 2 2; }

.cool-zone { fill: var(--accent-soft); }
.series.heat { stroke-width: 2.25; }
.series.w0 { stroke: var(--w0); }
.series.w1 { stroke: var(--w1); }
.series.w2 { stroke: var(--w2); }
.series.w3 { stroke: var(--w3); }
.series.w4 { stroke: var(--w4); }
.heat-dot.w0, .heat-label.w0 { fill: var(--w0); }
.heat-dot.w1, .heat-label.w1 { fill: var(--w1); }
.heat-dot.w2, .heat-label.w2 { fill: var(--w2); }
.heat-dot.w3, .heat-label.w3 { fill: var(--w3); }
.heat-dot.w4, .heat-label.w4 { fill: var(--w4); }

.group-band { fill: var(--accent-soft); }
.past-dot { fill: var(--paper-soft); stroke: var(--ink-soft); stroke-width: 1.5; }
.pred-dot { fill: var(--accent); stroke: var(--paper-soft); stroke-width: 1.5; }
.pred-range { stroke: var(--accent); stroke-width: 3; stroke-linecap: round; }

.cov-raw { fill: var(--paper-soft); stroke: var(--ink-soft); stroke-width: 2; }
.cov-cal { fill: var(--accent); stroke: var(--paper-soft); stroke-width: 1.5; }

.bar.m-cf { fill: var(--m-cf); }
.bar.m-vdot { fill: var(--m-vdot); }
.bar.m-median { fill: var(--m-median); }
.bar.m-hier { fill: var(--m-hier); }
.bar.m-gbm { fill: var(--alt); }
.bar.m-model { fill: var(--accent); }

/* Legend swatches for the marks above. */
.swatch.dot { width: 10px; height: 10px; border-radius: 50%; }
.pt-hit-sw { background: var(--hit); }
.pt-miss-sw { background: var(--miss); }
.course-sw { background: var(--ink-faint); }
.live-sw { background: var(--warn); }
.named-sw { background: var(--ink-soft); }
.past-sw { background: var(--paper-soft); border: 1.5px solid var(--ink-soft); }
.pred-sw { background: var(--accent); }
.raw-sw { background: var(--paper-soft); border: 2px solid var(--ink-soft); }
.cal-sw { background: var(--accent); }
.sw-range { background: var(--accent); }
.sw-group { background: var(--accent); }
.sw-median-line { background: var(--accent); }
.sw-fastest-line { background: repeating-linear-gradient(90deg, var(--warn) 0 4px, transparent 4px 7px); }
.sw-cf { background: var(--m-cf); }
.sw-vdot { background: var(--m-vdot); }
.sw-median { background: var(--m-median); }
.sw-hier { background: var(--m-hier); }
.sw-gbm { background: var(--alt); }
.sw-model { background: var(--accent); }

/* ------------------------------------------------------------- how it works */

.baselines { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 0.75rem; margin: 1.25rem 0; }
.baselines > div { padding: 0.8rem 0.95rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper-soft); }
.baselines dt { font-weight: 600; display: flex; align-items: center; gap: 0.5rem; }
.baselines dd { margin: 0.25rem 0 0; font-size: 0.86rem; color: var(--ink-soft); line-height: 1.5; }

table.example { margin-top: 0.5rem; }
.tag { display: inline-block; padding: 0.1rem 0.55rem; border-radius: 999px; font-size: 0.8rem; font-weight: 600; }
.tag-a { background: var(--accent-soft); color: var(--accent-ink); }
.tag-b { background: color-mix(in srgb, var(--alt) 15%, transparent); color: var(--alt); }
.tag-x { background: var(--line-soft); color: var(--ink-faint); }

pre.formula {
  font-family: var(--mono);
  font-size: 0.8rem;
  line-height: 1.55;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.9rem 1rem;
  overflow-x: auto;
  margin: 0.4rem 0 0.9rem;
}

.timeline { list-style: none; margin: 1.25rem 0; padding: 0 0 0 1.5rem; border-left: 2px solid var(--line-2); }
.timeline li { position: relative; margin: 0 0 1rem; display: flex; flex-direction: column; }
.timeline li::before {
  content: "";
  position: absolute;
  left: calc(-1.5rem - 7px);
  top: 0.45rem;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--paper-soft);
  border: 2px solid var(--accent);
}
.timeline li:nth-child(3)::before { background: var(--accent); }
.timeline li span { color: var(--ink-soft); font-size: 0.93rem; }

.cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.9rem; margin: 1.25rem 0; }
@media (max-width: 50rem) { .cards { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); } }
.halo { paint-order: stroke; stroke: var(--paper); stroke-width: 4px; stroke-linejoin: round; }
.card-note { padding: 1rem 1.1rem; background: var(--paper-soft); border: 1px solid var(--line); border-top: 3px solid var(--warn); border-radius: var(--radius); }
.card-note h3 { font-size: 1.08rem; }
.card-note p { font-size: 0.9rem; color: var(--ink-soft); margin: 0; }

.checks { list-style: none; padding: 0; margin: 1rem 0; display: grid; gap: 0.7rem; }
.checks li { padding-left: 1.7rem; position: relative; }
.checks li::before { content: "\2713"; position: absolute; left: 0; top: 0; color: var(--good); font-weight: 700; }

.chips { list-style: none; padding: 0; margin: 1.25rem 0; display: flex; flex-wrap: wrap; gap: 0.45rem; }
.chips li { padding: 0.25rem 0.75rem; border: 1px solid var(--line-2); border-radius: 999px; font-size: 0.82rem; background: var(--paper-soft); color: var(--ink-soft); }

.glossary { margin: 0 0 0.9rem; }
.glossary dt { font-weight: 600; margin-top: 0.7rem; }
.glossary dd { margin: 0.15rem 0 0; color: var(--ink-soft); font-size: 0.92rem; }

.disclose ul { padding-left: 1.2rem; }
.disclose li { margin-bottom: 0.5rem; }

@media (max-width: 34rem) {
  .week-steps { grid-template-columns: repeat(2, 1fr); }
  .race-card { padding: 1rem; }
  .toc ol { columns: 1; }
}

#predictions h3, #preview h3, #races > h3 { margin-top: 2rem; }


/* ================================================================ project 04's additions */

.cta { display: flex; flex-wrap: wrap; gap: 0.7rem; margin: 1.6rem 0 0.4rem; }
.button {
  display: inline-block; padding: 0.6rem 1.1rem; border-radius: 999px; font-weight: 600;
  font-size: 0.95rem; text-decoration: none; background: var(--accent); color: var(--paper-soft);
  border: 1px solid var(--accent);
}
.button:hover, .button:focus-visible { background: var(--accent-ink); color: var(--paper-soft); }
.button.ghost { background: transparent; color: var(--accent); }
.button.ghost:hover, .button.ghost:focus-visible { background: var(--accent-soft); color: var(--accent-ink); }
.live { font-size: 0.92rem; color: var(--ink-soft); margin: 0.8rem 0 0; min-height: 1.5em; }

td.wrap { white-space: normal; }

.pipeline.eight { grid-template-columns: repeat(8, minmax(0, 1fr)); }
@media (max-width: 66rem) { .pipeline.eight { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); } }

/* The redaction example: four panes, the vendor's two shaded, every placeholder marked. */
.flow { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.8rem; margin: 1.4rem 0 0.6rem; }
@media (max-width: 60rem) { .flow { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); } }
.pane {
  margin: 0; padding: 0.9rem 1rem; background: var(--paper-soft); border: 1px solid var(--line);
  border-radius: var(--radius); font-size: 0.92rem;
}
.pane p { margin: 0.5rem 0 0; }
.pane figcaption { font-size: 0.8rem; font-weight: 600; color: var(--ink-faint); letter-spacing: 0.02em; }
.pane.vendor { background: var(--accent-soft); border-color: var(--accent); }
.pane-step {
  display: inline-flex; align-items: center; justify-content: center; width: 1.3rem; height: 1.3rem;
  margin-right: 0.4rem; border-radius: 50%; background: var(--accent); color: var(--paper-soft);
  font-size: 0.72rem;
}
.ph {
  font-family: var(--mono); font-size: 0.82em; padding: 0.05rem 0.3rem; border-radius: 4px;
  background: var(--paper); border: 1px solid var(--line-2); color: var(--accent-ink); white-space: nowrap;
}

/* The residency grid. */
table.grid thead th:not(:first-child) { text-align: center; }
table.grid td { text-align: center; font-size: 0.85rem; font-weight: 600; }
table.grid td.go { color: var(--good); }
table.grid td.stop { color: var(--warn); }
table.grid tbody th .where { display: block; font-weight: 400; font-size: 0.78rem; color: var(--ink-faint); }

/* The load test chart: one line per layer. */
.l0 { stroke: var(--accent); fill: var(--accent); }
.l1 { stroke: var(--alt); fill: var(--alt); }
.l2 { stroke: var(--warn); fill: var(--warn); }
.l3 { stroke: var(--good); fill: var(--good); }
.series.l0, .series.l1, .series.l2, .series.l3 { fill: none; stroke-width: 2; }
.whisker.l0, .whisker.l1, .whisker.l2, .whisker.l3 { stroke-width: 2; stroke-opacity: 0.5; }
.dot.l0, .dot.l1, .dot.l2, .dot.l3 { stroke: var(--paper); stroke-width: 1.5; }
.sw-l0 { background: var(--accent); } .sw-l1 { background: var(--alt); }
.sw-l2 { background: var(--warn); } .sw-l3 { background: var(--good); }
.shed, .end-label { stroke: none; font-size: 11px; font-weight: 600; }
.shed { font-style: italic; }

/* The audit chain. */
.block { fill: var(--paper-soft); stroke: var(--line-2); stroke-width: 1.5; }
.block.head { stroke: var(--accent); stroke-width: 2.5; fill: var(--accent-soft); }
.link { stroke: var(--ink-faint); stroke-width: 2; }
.block-seq { fill: var(--ink); font-size: 14px; font-weight: 600; }
.block-hash { fill: var(--ink-faint); font-size: 10.5px; font-family: var(--mono); }
.anchor-line { stroke: var(--good); stroke-width: 2; stroke-dasharray: 3 2; }
.anchor-label { fill: var(--good); font-size: 11px; font-weight: 600; }
.head-label { fill: var(--accent); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }

/* Code to copy, on the demo page. */
pre.code {
  margin: 0.6rem 0; padding: 0.9rem 1rem; background: var(--paper-soft); border: 1px solid var(--line);
  border-radius: var(--radius); overflow-x: auto; font: 0.82rem/1.5 var(--mono); color: var(--ink);
}

/* Six figures as two rows of three, not five and an orphan. */
.headline.six { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 40rem) { .headline.six { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); } }


/* ================================================================ project 07's additions */

/* What the tool does to a span is the colour language of the whole site: red withholds, amber
   withholds and asks a person, green releases, grey is not personal information at all. The
   reviewer's screen (review.css) uses the same four. */
:root {
  --withhold: #b3261e;
  --withhold-soft: #fbe9e7;
  --escalate: #9a6200;
  --escalate-soft: #fdf1d8;
  --release: #1e7a4c;
  --release-soft: #e3f2e9;
  --none: #8a8f98;
}

@media (prefers-color-scheme: dark) {
  :root {
    --withhold: #f0736a;
    --withhold-soft: #3a1d1b;
    --escalate: #e3b45a;
    --escalate-soft: #33280f;
    --release: #58c286;
    --release-soft: #15291e;
    --none: #7d838d;
  }
}

.hero.compact { padding-bottom: 1.6rem; }

/* A category code, coloured by what it does. */
.code-chip {
  display: inline-block; min-width: 2.1rem; margin-right: 0.45rem; padding: 0.02rem 0.4rem;
  border-radius: 5px; font: 600 0.74rem/1.5 var(--mono); text-align: center;
  border: 1px solid currentColor; vertical-align: 0.08em;
}
.code-chip.withhold { color: var(--withhold); background: var(--withhold-soft); }
.code-chip.escalate { color: var(--escalate); background: var(--escalate-soft); }
.code-chip.release { color: var(--release); background: var(--release-soft); }
.code-chip.flag, .code-chip.optional { color: var(--ink-faint); background: var(--paper); border-style: dashed; }

/* ---------------------------------------------------------------- the letter */

.letter-wrap { display: grid; grid-template-columns: minmax(0, 1fr) 16rem; gap: 1.25rem; margin: 1.4rem 0 1rem; align-items: start; }
@media (max-width: 56rem) { .letter-wrap { grid-template-columns: minmax(0, 1fr); } }

/* A sheet of paper in both themes: a record is printed on white, and the highlights were
   chosen against white. */
.letter { margin: 0; background: #fffefb; color: #1d1f24; border: 1px solid var(--line-2); border-radius: 4px; box-shadow: 0 18px 40px -28px rgba(0, 0, 0, 0.45); }
.letter pre {
  margin: 0; padding: 1.6rem 1.8rem; overflow-x: auto; white-space: pre-wrap; word-break: break-word;
  font: 0.7rem/1.8 var(--mono); color: #1d1f24;
}
@media (max-width: 34rem) { .letter pre { padding: 1rem; font-size: 0.66rem; } }
.letter mark { padding: 0.06em 0.12em; border-radius: 2px; border-bottom: 2px solid; cursor: help; color: inherit; }
.letter mark:focus { outline: 2px solid #0f5c6e; outline-offset: 1px; }
.letter mark.x-withhold { background: #fbe0dd; border-color: #b3261e; }
.letter mark.x-escalate { background: #fdeec9; border-color: #b07800; }
.letter mark.x-release { background: #dcefe3; border-color: #1e7a4c; }
.letter mark.x-none { background: transparent; border-bottom: 1px dotted #9aa0a8; }

.letter-side { position: sticky; top: 1rem; display: flex; flex-direction: column; gap: 0.9rem; }
.legend-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; font-size: 0.86rem; color: var(--ink-soft); line-height: 1.4; }
.legend-list li { display: flex; gap: 0.6rem; align-items: flex-start; }
.key-chip { flex: none; width: 1.1rem; height: 1.1rem; margin-top: 0.12rem; border-radius: 3px; border-bottom: 3px solid; }
.key-chip.withhold { background: var(--withhold-soft); border-color: var(--withhold); }
.key-chip.escalate { background: var(--escalate-soft); border-color: var(--escalate); }
.key-chip.release { background: var(--release-soft); border-color: var(--release); }
.key-chip.none { background: transparent; border: 1px dotted var(--none); }

.why-box {
  padding: 0.85rem 0.95rem; background: var(--paper-soft); border: 1px solid var(--line);
  border-left: 3px solid var(--line-2); border-radius: 0 var(--radius) var(--radius) 0; font-size: 0.86rem;
  min-height: 9rem;
}
.why-box.x-withhold { border-left-color: var(--withhold); }
.why-box.x-escalate { border-left-color: var(--escalate); }
.why-box.x-release { border-left-color: var(--release); }
.why-box.x-none { border-left-color: var(--none); }
.why-title { margin: 0 0 0.35rem; font-family: var(--mono); font-size: 0.8rem; font-weight: 600; color: var(--ink); word-break: break-word; }
.why-text { margin: 0; color: var(--ink-soft); line-height: 1.5; }

ul.reasons { list-style: none; padding: 0; }
ul.reasons li { margin-bottom: 0.65rem; font-size: 0.92rem; }
ul.reasons .why { color: var(--ink-faint); }

/* ---------------------------------------------------------------- charts */

.good-zone { fill: var(--release-soft); }
.zone-label { fill: var(--release); font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.system .pt { stroke: var(--paper); stroke-width: 2; }
.system .whisker { stroke-width: 1.5; }
.system:focus { outline: none; }
.system:focus .pt { stroke: var(--ink); }
.pt-label { fill: var(--ink); font-size: 12.5px; font-weight: 600; }
.pt-sub { fill: var(--ink-faint); font-size: 11px; font-variant-numeric: tabular-nums; }
.sys-rules .pt { fill: var(--accent); }
.sys-rules .whisker { stroke: var(--accent); }
.sys-full .pt, .sys-model_only .pt { fill: var(--alt); }
.sys-full .whisker, .sys-model_only .whisker { stroke: var(--alt); }
.sys-model_only .pt { fill-opacity: 0.55; }
.sys-sentence .pt { fill: var(--ink-faint); }
.sys-sentence .whisker { stroke: var(--ink-faint); }
.sys-blunt .pt { fill: var(--warn); }
.sys-blunt .whisker { stroke: var(--warn); }

.bar.b-over, .swatch.b-over { fill: var(--accent); background: var(--accent); }
.bar.b-leak, .swatch.b-leak { fill: var(--withhold); background: var(--withhold); }
.bar.b-before, .swatch.b-before { fill: var(--line-2); background: var(--line-2); }
.bar.b-now, .swatch.b-now { fill: var(--accent); background: var(--accent); }
.bar.seg-never, .swatch.seg-never { fill: var(--ink-faint); background: var(--ink-faint); }
.bar.seg-mislabel, .swatch.seg-mislabel { fill: var(--alt); background: var(--alt); }
.bar.seg-short, .swatch.seg-short { fill: var(--escalate); background: var(--escalate); }
.bar.seg-decision, .swatch.seg-decision { fill: var(--withhold); background: var(--withhold); }
.seg-label { fill: var(--paper-soft); font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums; }
.dumbbell { stroke: var(--line-2); stroke-width: 4; stroke-linecap: round; }
.dot-unaided { fill: var(--warn); stroke: var(--paper); stroke-width: 2; }
.dot-with { fill: var(--good); stroke: var(--paper); stroke-width: 2; }
.swatch.sw-unaided { background: var(--warn); }
.swatch.sw-with { background: var(--good); }
.empty-label { fill: var(--ink-faint); font-size: 13px; }

/* The dashboard's outcomes, the same four colours as everywhere else. */
.bar.o-withhold, .swatch.o-withhold { fill: var(--withhold); background: var(--withhold); }
.bar.o-escalate, .swatch.o-escalate { fill: var(--escalate); background: var(--escalate); }
.bar.o-release, .swatch.o-release { fill: var(--release); background: var(--release); }
.bar.o-add, .swatch.o-add { fill: var(--alt); background: var(--alt); }

/* A live line starts with a dot that breathes, so it reads as live rather than as text. */
.pulse {
  display: inline-block; width: 0.55rem; height: 0.55rem; margin-right: 0.15rem; border-radius: 50%;
  background: var(--good); vertical-align: 0.06em; box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 60%, transparent);
  animation: pulse 2.4s ease-out infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 55%, transparent); }
  70% { box-shadow: 0 0 0 0.55rem transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) { .pulse { animation: none; } }

.live-tiles .figure { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- the law */

table.law th[scope="row"] { font-weight: 500; font-size: 0.9rem; }
.does { display: block; font-weight: 600; font-size: 0.86rem; }
.does.withhold { color: var(--withhold); }
.does.escalate { color: var(--escalate); }
.does.release { color: var(--release); }
.does.flag { color: var(--ink-faint); }
.cites { display: block; font-size: 0.8rem; color: var(--ink-faint); line-height: 1.4; }

/* A link into the repository while it is private: the name, not a link that 404s. */
.repo-ref { font-family: var(--mono); font-size: 0.86em; color: var(--ink-soft); }

/* ---------------------------------------------------------------- how it's built */

.arch { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.6rem; margin: 1.5rem 0 1rem; position: relative; }
.arch.narrow { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 60rem) { .arch, .arch.narrow { grid-template-columns: minmax(0, 1fr); gap: 1.4rem; } }
.lane { display: flex; flex-direction: column; gap: 0.55rem; position: relative; }
.lane:not(:last-child)::after {
  content: "\2192"; position: absolute; right: -1.2rem; top: 50%; transform: translateY(-50%);
  color: var(--ink-faint); font-size: 1.1rem;
}
@media (max-width: 60rem) { .lane:not(:last-child)::after { content: "\2193"; right: auto; left: 50%; top: auto; bottom: -1.35rem; transform: none; } }
.lane-title { margin: 0 0 0.1rem; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); }
.node {
  display: flex; flex-direction: column; gap: 0.15rem; padding: 0.65rem 0.75rem; background: var(--paper-soft);
  border: 1px solid var(--line); border-radius: var(--radius); font-size: 0.8rem; color: var(--ink-soft); line-height: 1.4;
}
.node strong { font-family: var(--serif); font-size: 1.05rem; font-weight: 500; color: var(--ink); }
.lane.engine .node { border-top: 3px solid var(--accent); }
.lane.person .node { border-top: 3px solid var(--good); background: color-mix(in srgb, var(--good) 6%, var(--paper-soft)); }
.lane.out .node { border-top: 3px solid var(--alt); }
.node.optional { border-style: dashed; border-top-style: dashed; }

ol.rules { list-style: none; counter-reset: rule; padding: 0; margin: 1.4rem 0; display: grid; gap: 0.5rem; }
ol.rules li {
  counter-increment: rule; display: grid; grid-template-columns: 2rem 3.2rem minmax(0, 1fr); column-gap: 0.4rem;
  align-items: baseline; padding: 0.6rem 0.8rem; background: var(--paper-soft); border: 1px solid var(--line); border-radius: var(--radius);
}
ol.rules li::before { content: counter(rule, decimal-leading-zero); font-size: 0.78rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
ol.rules li .code-chip { margin: 0; justify-self: start; }
ol.rules li strong { font-weight: 600; }
ol.rules li > span:last-child { grid-column: 3; color: var(--ink-soft); font-size: 0.88rem; }
ol.rules li.optional { border-style: dashed; }
@media (max-width: 34rem) { ol.rules li { grid-template-columns: 1.6rem minmax(0, 1fr); } ol.rules li .code-chip { grid-column: 2; } ol.rules li strong, ol.rules li > span:last-child { grid-column: 2; } }

ol.flowline { list-style: none; counter-reset: flow; padding: 0 0 0 1.6rem; margin: 1.4rem 0; border-left: 2px solid var(--line-2); }
ol.flowline li { counter-increment: flow; position: relative; margin: 0 0 1rem; display: flex; flex-direction: column; }
ol.flowline li::before {
  content: counter(flow); position: absolute; left: -2.45rem; top: 0.1rem; width: 1.5rem; height: 1.5rem; border-radius: 50%;
  background: var(--accent); color: var(--paper-soft); font-size: 0.75rem; font-weight: 600; display: flex; align-items: center; justify-content: center;
}
ol.flowline li span { color: var(--ink-soft); font-size: 0.93rem; }

.cards.plain .card-note { border-top-color: var(--accent); }

/* ---------------------------------------------------------------- the reviewer's front page */

ol.howto { margin: 1.2rem 0 0; padding-left: 1.3rem; display: grid; gap: 0.35rem; color: var(--ink-soft); font-size: 0.95rem; }
ol.howto strong { color: var(--ink); }
kbd { font: 600 0.74rem/1 var(--mono); border: 1px solid var(--line-2); border-bottom-width: 2px; border-radius: 4px; padding: 0.1rem 0.32rem; background: var(--paper-soft); color: var(--ink); }

.records { display: grid; grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr)); gap: 0.9rem; margin: 1.8rem 0 1.2rem; }
.record-card {
  display: flex; flex-direction: column; gap: 0.2rem; padding: 1rem 1.1rem 1.05rem; color: var(--ink);
  background: var(--paper-soft); border: 1px solid var(--line); border-top: 3px solid var(--accent);
  border-radius: var(--radius); box-shadow: var(--shadow); transition: transform 0.12s ease, border-color 0.12s ease;
}
.record-card:hover, .record-card:focus-visible { text-decoration: none; transform: translateY(-2px); border-color: var(--accent); }
.record-card.done { border-top-color: var(--good); }
.record-kind { font-family: var(--serif); font-size: 1.3rem; line-height: 1.2; }
.record-id { font: 0.76rem var(--mono); color: var(--ink-faint); }
.record-meta { font-size: 0.85rem; color: var(--ink-soft); }
.record-progress { display: block; height: 5px; margin: 0.55rem 0 0.25rem; border-radius: 3px; background: var(--line-soft); overflow: hidden; }
.record-progress span { display: block; height: 100%; background: var(--accent); }
.record-card.done .record-progress span { background: var(--good); }
.record-status { font-size: 0.8rem; font-weight: 600; color: var(--accent-ink); }
.record-card.done .record-status { color: var(--good); }
@media (prefers-reduced-motion: reduce) { .record-card { transition: none; } .record-card:hover { transform: none; } }

/* A fourth colour for a headline figure in money: the escalation amber, a dark gold on paper
   and a soft gold in the dark, so a dollar figure never reads as one more green. */
.hero .point.gold { border-top-color: var(--escalate); }
.point.gold .point-figure { color: var(--escalate); }
