/* One stylesheet, no framework, no build step.

   The palette, the type and the 3px rule over the page are peterparker.ca's, shared with the
   other project pages, because this page is part of that site even though a separate 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. */

@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);
  /* An ordered set in one hue, darkest first: the three percentiles. */
  --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 {
  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); }

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

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

.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-figure.up { color: var(--good); }
.point-figure.down { color: var(--warn); }

.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 term 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; }

/* ---------------------------------------------------------------- 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); }

.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 0;
  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, .label-text { 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; }

/* Series colours and their swatches, 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; }
/* Thinner lines, for a view with 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; }

/* A bar is a length, so it gets a fill and no outline; its interval is a hairline in ink,
   because it is not another 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-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 long row label is the one cell allowed to wrap, so that it 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; }

/* Narrower gutters for a table that only just fits the column. */
.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; }
}

.cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 0.75rem;
  margin: 0 0 2.25rem;
}

.button {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.62rem 1.1rem;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  background: var(--paper-soft);
  color: var(--ink);
  font-weight: 600;
  font-size: 0.93rem;
  line-height: 1.2;
}

.button:hover, .button:focus-visible { text-decoration: none; border-color: var(--accent); color: var(--accent-ink); }

.button.primary { background: var(--accent); border-color: var(--accent); color: #fdfcf9; }
.button.primary::after { content: "\2197"; font-weight: 400; }
.button.primary:hover, .button.primary:focus-visible { background: var(--accent-ink); border-color: var(--accent-ink); color: #fdfcf9; }

@media (prefers-color-scheme: dark) {
  .button.primary, .button.primary:hover, .button.primary:focus-visible { color: #0e1013; }
}

.cta-note { font-size: 0.84rem; color: var(--ink-faint); }

/* ---------------------------------------------------------------- this page's own */

.subhead { margin-top: 2rem; }

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

input[type="number"]:focus-visible, select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* The calculator: the inputs, then what they come to, then the month drawn. */
.answer {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 0.9rem;
  margin: 1.1rem 0 0.4rem;
}

.answer .stat.lead-stat { border-color: var(--accent); background: var(--accent-soft); }
.answer .stat.lead-stat .figure { color: var(--accent-ink); }
.answer .figure.never { color: var(--warn); }

.button-row { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.chip {
  font: inherit;
  font-size: 0.8rem;
  padding: 0.28rem 0.7rem;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: var(--paper-soft);
  color: var(--ink-soft);
  cursor: pointer;
}

.chip:hover { border-color: var(--accent); color: var(--accent-ink); }
.chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: #fdfcf9; }
@media (prefers-color-scheme: dark) { .chip[aria-pressed="true"] { color: #0e1013; } }

/* The Pareto chart and the month chart, drawn by app.js. Frontier runs are circles and
   self-hosted ones diamonds, so the shape carries the identity as well as the colour. */
.frontier-mark { fill: var(--alt); stroke: var(--paper-soft); stroke-width: 1.5; }
.hosted-mark { fill: var(--accent); stroke: var(--paper-soft); stroke-width: 1.5; }
.frontier-mark.on, .hosted-mark.on { stroke: var(--ink); stroke-width: 2; }
.mark-label { fill: var(--ink-soft); font-size: 11px; }
.mark-label.strong { fill: var(--ink); font-weight: 600; }
.sw-frontier { background: var(--alt); }
.sw-hosted { background: var(--accent); }
.api-line { fill: none; stroke: var(--alt); stroke-width: 2; }
.own-line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: miter; }
.even-mark { stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 4 3; }
.even-label { fill: var(--ink); font-size: 11px; font-weight: 600; }
.you-mark { stroke: var(--good); stroke-width: 1.5; }
.you-label { fill: var(--good); font-size: 11px; font-weight: 600; }
.sw-api { background: var(--alt); }
.sw-own { background: var(--accent); }
.sw-you { background: var(--good); }

td.never { color: var(--warn); }
td.verdict-pass { color: var(--good); font-weight: 600; }
td.verdict-block { color: var(--warn); font-weight: 600; }
td.fields { white-space: normal; min-width: 12rem; }

.task-sample {
  font-family: var(--mono);
  font-size: 0.8rem;
  line-height: 1.55;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
  overflow-x: auto;
  white-space: pre;
  color: var(--ink-soft);
}

.two-up { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1.25rem; align-items: start; }

@media (max-width: 52rem) {
  .two-up { grid-template-columns: minmax(0, 1fr); }
}

.noscript { padding: 0.9rem 1.1rem; border-left: 3px solid var(--warn); background: var(--paper-soft); }

/* The three recipes, one card each. */
.recipes { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 0.9rem; margin: 1.25rem 0 0.5rem; }
.recipe { background: var(--paper-soft); border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem 1.1rem 0.9rem; display: flex; flex-direction: column; gap: 0.5rem; min-width: 0; }
.recipe h3 { margin: 0; }
.recipe .maker { font-size: 0.82rem; color: var(--ink-faint); margin: -0.35rem 0 0; }
.recipe .lift { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; font-variant-numeric: tabular-nums; }
.recipe .lift .from { font-family: var(--serif); font-size: 1.35rem; color: var(--ink-faint); }
.recipe .lift .arrow { color: var(--ink-faint); }
.recipe .lift .to { font-family: var(--serif); font-size: 1.75rem; color: var(--good); }
.recipe .lift-note { font-size: 0.8rem; color: var(--ink-faint); line-height: 1.4; margin: -0.3rem 0 0.2rem; }
.recipe dl { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.25rem 0.8rem; margin: 0; font-size: 0.84rem; }
.recipe dt { color: var(--ink-faint); }
.recipe dd { margin: 0; color: var(--ink-soft); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.recipe .links { font-size: 0.84rem; margin-top: auto; padding-top: 0.4rem; border-top: 1px solid var(--line); }
td.chosen { color: var(--good); font-weight: 600; }
td.chosen::after { content: " \2713"; }
tbody tr.group-start th, tbody tr.group-start td { border-top: 1px solid var(--line-2); }
.steps li > span:last-child { min-width: 0; }
.steps { list-style: none; margin: 0.75rem 0 1rem; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 0.7rem; }

.steps li {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.8rem 0.95rem;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.step-n {
  flex: none;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: 600;
  font-size: 0.8rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.steps li:last-child .step-n { background: var(--accent); color: #fdfcf9; }
@media (prefers-color-scheme: dark) { .steps li:last-child .step-n { color: #0e1013; } }

/* ---------------------------------------------------------------- the first screen, as project 03's */

/* A wash of the accent behind the first screen, full width, fading into the page: the one
   place colour is used for its own sake, so the opening is not black on white alone. The
   same treatment as gate.peterparker.ca, so the project pages read as one site. */
body { overflow-x: clip; }
.hero { position: relative; }
.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); }
.hero .point .point-figure { color: var(--accent-ink); }
.hero .point.good .point-figure { color: var(--good); }
.hero .point.violet .point-figure { color: var(--alt); }

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

/* The page's sections and the architecture page, as pills, as on the other project pages. */
.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.2rem;
}

.tabs a {
  font-size: 0.83rem;
  padding: 0.2rem 0.55rem;
  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; }

/* ================================================================ project 16's own */

/* One colour per kind of reader, used for its marks, its lines and its legend on every
   chart. The fine-tune is the accent, because it is this project's; the frontier models
   the shared violet; Azure an amber, apart from both; the OCR pipelines and the untuned
   bases recede in greys and a pale accent. */
:root {
  --k-finetuned: var(--accent);
  --k-frontier: var(--alt);
  --k-managed: #b0661a;
  --k-ocr-llm: #7a7f88;
  --k-ocr-rules: #a8acb3;
  --k-untuned: #7bb3c0;
  --k-opus: #3f1f66;
  --box-ok: #1e7a4c;
  --box-bad: #c0392b;
  --box-hot: #d99a00;
}

@media (prefers-color-scheme: dark) {
  :root {
    --k-managed: #e9a25a;
    --k-ocr-llm: #8d929b;
    --k-ocr-rules: #5d626b;
    --k-untuned: #3d8ea1;
    --k-opus: #dccbf5;
    --box-ok: #58c286;
    --box-bad: #f0736a;
  }
}

.hero .point.warn { border-top-color: var(--warn); }
.hero .point.warn .point-figure { color: var(--warn); }

/* ---------------------------------------------------------------- findings */

.findings {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: 0.9rem;
  margin: 1.25rem 0 0.5rem;
}

.finding {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-top: 3px solid var(--ink-faint);
  border-radius: var(--radius);
  padding: 1rem 1.1rem 0.9rem;
  box-shadow: var(--shadow);
  min-width: 0;
}

.finding.good { border-top-color: var(--good); }
.finding.violet { border-top-color: var(--alt); }
.finding.warn { border-top-color: var(--warn); }
.finding h3 { margin: 0; font-size: 1.08rem; }
.finding p { margin: 0; font-size: 0.9rem; color: var(--ink-soft); line-height: 1.55; }
.finding > a { margin-top: auto; padding-top: 0.45rem; font-size: 0.84rem; font-weight: 600; }
.finding > a::after { content: " \2193"; }

.finding .finding-figure {
  font-family: var(--serif);
  font-size: 1.85rem;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.finding.good .finding-figure { color: var(--good); }
.finding.violet .finding-figure { color: var(--alt); }
.finding.warn .finding-figure { color: var(--warn); }

.ticks, .limits { margin: 0.6rem 0 0; padding-left: 1.2rem; }
.ticks li, .limits li { margin-bottom: 0.5rem; color: var(--ink-soft); }
.ticks li strong, .limits li strong { color: var(--ink); }

.cards-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
  gap: 0.9rem;
  margin: 1.75rem 0 0.5rem;
}

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

.card h3 { margin: 0 0 0.4rem; font-size: 1.08rem; }
.card p { font-size: 0.9rem; color: var(--ink-soft); }

/* The four corpora, one card each, under the landscape chart. */
.corpora {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: 0.7rem;
  margin: 1.25rem 0 0;
}

.corpus-card {
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.8rem 0.95rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
  line-height: 1.5;
}

.corpus-card h3 { font-size: 1rem; margin: 0 0 0.25rem; }
.corpus-card p { margin: 0; }
.corpus-card .meta { font-size: 0.78rem; color: var(--ink-faint); margin: 0.35rem 0 0; }

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

.k-fill-finetuned { fill: var(--k-finetuned); }
.k-fill-frontier { fill: var(--k-frontier); }
.k-fill-managed { fill: var(--k-managed); }
.k-fill-ocr-llm { fill: var(--k-ocr-llm); }
.k-fill-ocr-rules { fill: var(--k-ocr-rules); }
.k-fill-untuned { fill: var(--k-untuned); }
.k-fill-opus { fill: var(--k-opus); }
.k-stroke-finetuned { stroke: var(--k-finetuned); }
.k-stroke-frontier { stroke: var(--k-frontier); }
.k-stroke-managed { stroke: var(--k-managed); }
.k-stroke-ocr-llm { stroke: var(--k-ocr-llm); }
.k-stroke-ocr-rules { stroke: var(--k-ocr-rules); }
.k-stroke-untuned { stroke: var(--k-untuned); }
.k-stroke-opus { stroke: var(--k-opus); }
.sw-finetuned { background: var(--k-finetuned); }
.sw-frontier { background: var(--k-frontier); }
.sw-managed { background: var(--k-managed); }
.sw-ocr-llm { background: var(--k-ocr-llm); }
.sw-ocr-rules { background: var(--k-ocr-rules); }
.sw-untuned { background: var(--k-untuned); }
.sw-opus { background: var(--k-opus); }

.mark { stroke: var(--paper-soft); stroke-width: 1.5; }
.mark.on { stroke: var(--ink); stroke-width: 2; }
.dim { opacity: 0.22; }
.mark-label { fill: var(--ink-soft); font-size: 11px; }
.mark-label.strong { fill: var(--ink); font-weight: 600; }
.pareto-line { fill: none; stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 4 3; }
.ci-line { stroke-width: 1.25; stroke-linecap: round; }
.panel-title { fill: var(--ink-faint); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.corpus-label { fill: var(--ink); font-size: 13px; font-weight: 600; }
.corpus-note { fill: var(--ink-faint); font-size: 10.5px; }
.value-label { fill: var(--ink-soft); font-size: 10.5px; font-variant-numeric: tabular-nums; }
.value-label.strong { fill: var(--ink); font-weight: 600; }
.row-band { fill: var(--line-soft); }
.lift-arrow { stroke: var(--ink-faint); stroke-width: 1.5; fill: none; }
.lift-gain { fill: var(--good); font-size: 11px; font-weight: 600; }
.lift-loss { fill: var(--warn); font-size: 11px; font-weight: 600; }
.curve-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.curve-band { opacity: 0.12; stroke: none; }
.curve-dot { stroke: var(--paper-soft); stroke-width: 1.5; }
.bar-fill { stroke: none; }
.bar-fill.light { opacity: 0.5; }
.arm-row { cursor: pointer; }
.arm-row:hover .row-band, .arm-row.sel .row-band { fill: var(--accent-soft); }
.arm-row:focus { outline: none; }
.arm-row:focus-visible .row-band { stroke: var(--accent); stroke-width: 1.5; }

/* A legend chip that switches a series on and off. */
button.legend-item { font: inherit; font-size: 0.82rem; cursor: pointer; }
button.legend-item[aria-pressed="false"] { opacity: 0.45; text-decoration: line-through; }

/* ---------------------------------------------------------------- chart or table */

/* Every chart can be read as a table: a small switch under it, and the table drawn from the
   same numbers. The chart is the default. */
.view-switch { display: flex; justify-content: flex-end; margin: 0.25rem 0 0; }

.view-switch button {
  font: inherit;
  font-size: 0.78rem;
  padding: 0.18rem 0.65rem;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: var(--paper-soft);
  color: var(--ink-faint);
  cursor: pointer;
}

.view-switch button:hover { color: var(--accent-ink); border-color: var(--accent); }
.view-switch button[aria-pressed="true"] { color: var(--accent-ink); border-color: var(--accent); background: var(--accent-soft); }
.chart-table { margin-top: 0.5rem; }
[hidden] { display: none !important; }

/* ---------------------------------------------------------------- the page viewer */

.viewer-controls { align-items: end; }
.control.checks { gap: 0.25rem; }
.check { display: flex; align-items: center; gap: 0.45rem; font-weight: 400; font-size: 0.84rem; color: var(--ink-soft); }
.check input { accent-color: var(--accent); }

.viewer { display: grid; grid-template-columns: minmax(0, 3fr) minmax(17rem, 2fr); gap: 1.1rem; align-items: start; }
@media (max-width: 52rem) { .viewer { grid-template-columns: minmax(0, 1fr); } }

.page-figure { margin: 0; }
.sheet { position: relative; margin-bottom: 0.75rem; border: 1px solid var(--line-2); border-radius: 6px; overflow: hidden; background: #fff; line-height: 0; box-shadow: var(--shadow); }
.sheet img { width: 100%; height: auto; display: block; }
.sheet svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.sheet .pageno { position: absolute; right: 0; bottom: 0; line-height: 1.5; font-size: 0.75rem; padding: 0.1rem 0.5rem; color: #3c4048; background: rgba(253, 252, 249, 0.92); border-top-left-radius: 6px; }

.box { fill: none; stroke-width: 3; vector-effect: non-scaling-stroke; }
.box.ok { stroke: #1e7a4c; fill: rgba(30, 122, 76, 0.1); }
.box.bad { stroke: #c0392b; fill: rgba(192, 57, 43, 0.12); stroke-dasharray: 6 3; }
.box.hot { stroke-width: 5; stroke: #d99a00; }
.tag rect { fill: rgba(253, 252, 249, 0.95); stroke: #c0392b; stroke-width: 1; vector-effect: non-scaling-stroke; }
.tag text { fill: #16181d; font-family: var(--sans); }

.fields {
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
  position: sticky;
  top: 0.75rem;
  max-height: calc(100vh - 1.5rem);
  overflow: auto;
}

.fields h3 { margin: 0 0 0.3rem; }
.fields h4 { margin: 1rem 0 0.2rem; font-size: 0.95rem; }
.fields .summary { font-size: 0.9rem; color: var(--ink); font-weight: 600; margin-bottom: 0.4rem; }
.keys { font-size: 0.8rem; margin: 0 0 0.5rem; }
.key { display: inline-block; padding: 0 0.4rem; border-radius: 4px; font-weight: 600; margin-right: 0.3rem; }
.key.ok { color: var(--box-ok); background: color-mix(in srgb, var(--box-ok) 12%, transparent); }
.key.bad { color: var(--box-bad); background: color-mix(in srgb, var(--box-bad) 12%, transparent); }
.key.ok::before { content: "\2713  "; }
.key.bad::before { content: "\2717  "; }

.field-list { list-style: none; margin: 0.35rem 0 0; padding: 0; font-size: 0.82rem; line-height: 1.45; }
.field-list li { padding: 0.4rem 0.55rem; border-left: 3px solid var(--line-2); margin-bottom: 0.3rem; border-radius: 0 6px 6px 0; }
.field-list li.ok { border-left-color: var(--box-ok); background: color-mix(in srgb, var(--box-ok) 8%, transparent); }
.field-list li.bad { border-left-color: var(--box-bad); background: color-mix(in srgb, var(--box-bad) 9%, transparent); }
.field-list li.hot { outline: 2px solid var(--box-hot); }
.field-list .name { font-weight: 600; color: var(--ink); font-family: var(--mono); font-size: 0.78rem; }
.field-list .desc { color: var(--ink-faint); display: block; font-size: 0.76rem; }
.field-list .vals { display: grid; grid-template-columns: 3.4em minmax(0, 1fr); gap: 0 0.4rem; margin: 0.15rem 0 0; overflow-wrap: anywhere; }
.field-list .vals dt { color: var(--ink-faint); }
.field-list .vals dd { margin: 0; color: var(--ink); }
.field-list .outcome { font-weight: 600; float: right; font-size: 0.76rem; }
.field-list li.ok .outcome { color: var(--box-ok); }
.field-list li.bad .outcome { color: var(--box-bad); }

/* A label drawn over lines keeps a rim of the page's colour, so a gridline or the frontier's
   line never runs through its letters. */
.halo { paint-order: stroke; stroke: var(--paper); stroke-width: 3px; stroke-linejoin: round; }
.swatch.light { opacity: 0.5; }
