/* yah264 docs site.
   Type and figure style follow the direction chosen in site/samples: IBM Plex
   Serif for reading, Plex Sans for labels, Plex Mono for code, Caveat for the
   hand-drawn figure annotations. One accent, and four semantic chips that only
   ever classify a redundancy. Body text is 19px on purpose: these pages are
   long and technical, and 16px reads as a form rather than as a document. */

:root {
  color-scheme: light dark;
  --serif: "IBM Plex Serif", Georgia, serif;
  --sans: "IBM Plex Sans", system-ui, -apple-system, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --hand: "Caveat", cursive;

  --paper: #f8f9fa;
  --surface: #ffffff;
  --ink: #212529;
  --ink-2: #495057;
  --ink-3: #6b7178;
  --hairline: #dee2e6;
  --code-bg: #fff4e6;
  --code-ink: #8f310c;

  --accent: #6741d9;
  --accent-lt: #845ef7;
  --accent-soft: #e5dbff;
  --orange: #e8590c;
  --teal: #0b7285;

  --spatial: #cfeefc;    --spatial-d: #276184;
  --temporal: #e6fccf;   --temporal-d: #4b7a22;
  --statistical: #fcf3cf;--statistical-d: #8a7415;
  --perceptual: #fccfcf; --perceptual-d: #8f3d3d;
}

/* The dark palette re-points the same tokens, so every rule below is written
   once. Values match the two hand-written explainers' own dark themes after
   build_site.py retunes their accent, which is what keeps the nav from taking
   a reader between two different dark pages.

   The four redundancy chips keep their light pastels in both modes. They
   classify rather than decorate, one colour per redundancy across five pages,
   and a pastel on a dark ground still reads as a highlight. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #131517;
    --surface: #1a1a19;
    --ink: #e9ecee;
    --ink-2: #b6bcc1;
    --ink-3: #7d8388;
    --hairline: #2b2e31;
    --code-bg: #22252a;
    --code-ink: #ffbf94;

    --accent: #845ef7;
    --accent-lt: #9775fa;
    --accent-soft: #33285c;
    --orange: #ff922b;
    --teal: #4dabc7;
  }
  /* Live figures keep the light palette they were drawn against. Their canvas
     heat maps and their inline SVG axes carry fixed colours that no token
     reaches, so flipping the card around them would leave a light cost map on
     a dark plate. The card becomes a light plate on a dark page instead, and
     the tokens are re-declared on it so everything inside resolves the way it
     does in light mode. */
  .fig {
    --paper: #f8f9fa;
    --surface: #ffffff;
    --ink: #212529;
    --ink-2: #495057;
    --ink-3: #6b7178;
    --hairline: #dee2e6;
    --code-bg: #fff4e6;
    --code-ink: #8f310c;
    --accent: #6741d9;
    --accent-lt: #845ef7;
    --accent-soft: #e5dbff;
    --orange: #e8590c;
    --teal: #0b7285;
    background: var(--surface);
    color: var(--ink);
  }
  .fig a { color: var(--accent); }
  /* The masthead bars are a broadcast test pattern at 75%, so they are the one
     thing on the page that must not be retuned. Knocked back instead. */
  .smpte { opacity: 0.72; }
}

* { box-sizing: border-box; }
/* rem resolves against the ROOT element, so this has to live on html. Setting
   19px on body instead leaves every rem in this file computing against the
   browser's 16px default, which shrinks the whole page by about a sixth. */
html { font-size: 19px; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1rem;
  line-height: 1.75;
  margin: 0;
}

.wrap { max-width: 44rem; margin: 0 auto; padding: 0 1.5rem; }

h1, h2, h3, h4 { font-family: var(--serif); }
h1 { font-size: 2.9rem; font-weight: 700; letter-spacing: -0.022em; line-height: 1.16; margin: 0.35em 0 0.25em; text-wrap: balance; }
h2 { font-size: 1.8rem; font-weight: 700; letter-spacing: -0.015em; line-height: 1.35; margin: 4rem 0 0; text-wrap: balance; }
h3 { font-family: var(--sans); font-size: 1rem; font-weight: 600; color: var(--ink); margin: 34px 0 0; }
p { margin: 20px 0; }
a { color: var(--accent); text-decoration: none; box-shadow: inset 0 -0.11em 0 var(--accent-soft); }
a:hover { background: var(--accent-soft); }
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
strong { font-weight: 700; }
ul, ol { padding-left: 1.2rem; margin: 20px 0; }
li { margin: 9px 0; }
hr { border: 0; border-top: 1px solid var(--hairline); margin: 2.6rem 0; }

/* SMPTE colour bars under the page title. The seven-bar broadcast test pattern
   at 75%, which is the right motif for a video encoder and was already on the
   two hand-written explainers; it goes under every h1 so the site carries one
   masthead rather than two. Decorative, hence aria-hidden at the markup. */
.smpte {
  display: flex; height: 6px; border-radius: 3px; overflow: hidden;
  margin: 1.75rem 0 0; opacity: 0.85;
}
.smpte span { flex: 1; }

blockquote {
  margin: 1.6rem 0;
  padding: 0.6rem 1.3rem;
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--accent-lt);
  background: var(--surface);
  font-size: 0.96em;
}
blockquote p:last-child { margin-bottom: 0; }

code {
  font-family: var(--mono);
  font-size: 0.8em;
  background: var(--code-bg);
  color: var(--code-ink);
  padding: 1px 4px;
  border-radius: 2px;
}
pre {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 5px;
  padding: 1rem 1.1rem;
  overflow-x: auto;
  font-size: 0.86rem;
  line-height: 1.55;
}
pre code { background: none; padding: 0; color: var(--ink); font-size: 0.86rem; }

/* Wide content scrolls inside its own box; the page body never does. */
.table-scroll { display: block; overflow-x: auto; max-width: 100%; }
table {
  border-collapse: collapse;
  width: 100%;
  max-width: 100%;
  font-family: var(--sans);
  font-size: 0.93rem;
  margin: 1.5rem 0;
}
th, td {
  padding: 0.53rem 0.63rem 0.53rem 0;
  border-bottom: 1px solid var(--hairline);
  text-align: left;
  vertical-align: top;
}
th {
  font-weight: 600; color: var(--ink-3); font-size: 0.7rem;
  letter-spacing: 0.09em; text-transform: uppercase;
  border-bottom: 2px solid var(--ink);
}
tbody tr:last-child td { border-bottom: none; }

.eyebrow {
  font-family: var(--sans);
  font-size: 0.76rem; font-weight: 600; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--accent); margin: 0;
}
.smpte { display: flex; height: 6px; border-radius: 3px; overflow: hidden; margin: 1.5rem 0 0; opacity: 0.85; }
.smpte span { flex: 1; }

/* the four redundancies keep one colour across every page */
.t { font-family: var(--sans); font-size: 0.82em; font-weight: 600; padding: 0.12em 0.45em; border-radius: 3px; white-space: nowrap; }
.t-sp { background: var(--spatial); color: var(--spatial-d); }
.t-tp { background: var(--temporal); color: var(--temporal-d); }
.t-st { background: var(--statistical); color: var(--statistical-d); }
.t-pc { background: var(--perceptual); color: var(--perceptual-d); }

/* masthead + nav */
header.site {
  border-bottom: 1px solid var(--hairline);
  background: var(--surface);
  position: sticky; top: 0; z-index: 10;
}
header.site .bar {
  max-width: 1220px; margin: 0 auto; padding: 14px 28px;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem 1.3rem;
  font-family: var(--sans);
}
header.site .brand { font-weight: 600; font-size: 1.05rem; color: var(--ink); box-shadow: none; letter-spacing: -0.01em; }
header.site .brand span { color: var(--accent); }
header.site .brand:hover { background: none; }
header.site nav { display: flex; flex-wrap: wrap; gap: 0.2rem 1.25rem; font-size: 0.84rem; margin-left: auto; }
header.site nav a { color: var(--ink-2); box-shadow: none; }
header.site nav a:hover { color: var(--accent); background: none; }
header.site nav a[aria-current="page"] { color: var(--accent); font-weight: 600; }

main { padding: 2.8rem 0 5rem; }

footer.site .wrap { display: block; max-width: 66rem; }
footer.site {
  border-top: 1px solid var(--hairline);
  color: var(--ink-3);
  font-family: var(--sans);
  font-size: 0.82rem;
  padding: 1.6rem 0 3rem;
}
footer.site a { color: var(--ink-3); box-shadow: none; text-decoration: underline; }

.draft {
  border: 1px dashed var(--hairline);
  border-radius: 5px;
  background: var(--surface);
  padding: 0.8rem 1.1rem;
  color: var(--ink-3);
  font-family: var(--sans);
  font-size: 0.85rem;
  margin: 0 0 2rem;
}

/* ---------- asides ---------- */
.aside {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--accent-lt);
  padding: 18px 24px;
  margin: 34px 0;
  font-size: 0.96rem;
}
.aside .aside-title, .aside h4 {
  font-family: var(--sans); font-size: 0.74rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 8px; font-weight: 700;
}
.aside p { margin: 8px 0; }

.footnote {
  margin: 20px 0; font-family: var(--sans); font-size: 0.82rem; color: var(--ink-3);
  border-left: 2px solid var(--hairline); padding-left: 14px; line-height: 1.6;
}

/* ---------- hand-drawn figures ---------- */
figure { margin: 44px 0; }
figure.bleed { margin-left: -3.5rem; margin-right: -6rem; }
@media (max-width: 62rem) { figure.bleed { margin-left: 0; margin-right: 0; } }
figcaption { font-family: var(--sans); font-size: 0.83rem; color: var(--ink-3); line-height: 1.6; margin-top: 12px; }
.hand { font-family: var(--hand); font-size: 19px; fill: var(--ink-2); }
.hand-lg { font-family: var(--hand); font-size: 23px; fill: var(--ink); }

/* Hand-drawn geometry is generated as jittered paths, not a displacement
   filter. feDisplacementMap tears a 2px stroke: it shifts patches of the
   stroke further than the stroke is wide, which leaves gaps and detached
   fragments. Paths cannot tear. */
.sketch-fill { fill: var(--surface); stroke: none; }
.sketch { fill: none; stroke: var(--ink-2); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.stage .box { fill: var(--surface); stroke: var(--ink); stroke-width: 2; stroke-linejoin: round; transition: fill .18s; }
.stage .box-sketch { fill: none; stroke: var(--ink); stroke-width: 1.4; stroke-linejoin: round; opacity: .55; }
.stage.lit .box { fill: var(--accent-soft); stroke: var(--accent); }
.stage.lit .box-sketch { stroke: var(--accent); }
.conn { stroke-linecap: round; }


/* ---------- live figures ---------- */
.fig {
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: 5px; margin: 46px 0; overflow: hidden;
}
.fig > header { padding: 14px 20px; border-bottom: 1px solid var(--hairline); background: #fcfcfd; }
.fig h4 { font-family: var(--sans); font-size: 0.95rem; font-weight: 600; margin: 0; }
.fig .look { font-family: var(--sans); font-size: 0.8rem; color: var(--ink-3); margin: 2px 0 0; }
.fig .bd { padding: 20px; }
.ctrls {
  display: flex; gap: 16px; align-items: center; flex-wrap: wrap;
  font-family: var(--sans); font-size: 0.82rem; color: var(--ink-2); margin-top: 16px;
}
button {
  font-family: var(--sans); font-size: 0.82rem; padding: 5px 14px;
  border: 1px solid var(--hairline); background: var(--surface);
  border-radius: 3px; cursor: pointer; color: var(--ink);
}
button:hover { border-color: var(--accent); color: var(--accent); }
input[type=range] { accent-color: var(--accent); vertical-align: middle; }
label.sw { display: inline-flex; gap: 0.4rem; align-items: center; cursor: pointer; }

.stage { cursor: pointer; }

.stage text { font-family: var(--sans); font-size: 12.5px; fill: var(--ink); }

.stage.lit text { fill: var(--accent); font-weight: 600; }
[data-path=return] { stroke: var(--ink-3); transition: stroke .18s, fill .18s; }
[data-path=return].lit { stroke: var(--accent); }
[data-path=return].arrow { fill: var(--ink-3); stroke: none; }
[data-path=return].arrow.lit { fill: var(--accent); }
.dots { display: flex; gap: 7px; }
.dots button { width: 11px; height: 11px; padding: 0; border-radius: 50%; background: var(--hairline); border: none; }
.dots button.on { background: var(--accent); }
.stagecap { margin: 14px 0 20px; font-size: 0.98rem; min-height: 5.2em; }
.stagecap b {
  font-family: var(--sans); font-size: 0.72rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent); display: block; margin-bottom: 4px;
}

.me { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
.me-small { display: grid; grid-template-columns: 240px 240px 1fr; gap: 20px; align-items: start; margin-top: 20px; }
.me h5, .me-small h5 {
  font-family: var(--sans); font-size: 0.68rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink-3); margin: 0 0 0.4rem; font-weight: 600;
}
.me canvas { width: 100%; image-rendering: pixelated; border: 1px solid var(--hairline); display: block; background: #000; }
.me-small canvas { width: 100%; height: auto; background: var(--paper); border: 1px solid var(--hairline); display: block; }
.me-small #meres { background: var(--surface); }
.me .cap, .me-small .cap { font-family: var(--sans); font-size: 0.76rem; color: var(--ink-3); line-height: 1.55; margin: 0.5rem 0 0; }
.me-small .cap b { color: var(--ink); font-family: var(--serif); font-size: 1rem; }
.me-hint { font-family: var(--sans); font-size: 0.78rem; color: var(--ink-3); line-height: 1.6; align-self: center; }
.phase {
  font-family: var(--sans); font-size: 0.86rem; color: var(--ink);
  background: var(--accent-soft); padding: 9px 14px; border-radius: 3px; margin: 16px 0 0;
}
@media (max-width: 52rem) { .me, .me-small { grid-template-columns: 1fr; } }

.nums { display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); gap: 14px; margin-top: 16px; font-family: var(--sans); }
.nums div { border-top: 2px solid var(--accent-soft); padding-top: 7px; }
.nums span { display: block; font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.nums b { font-family: var(--serif); font-size: 1.2rem; font-weight: 600; }

.quant { display: grid; grid-template-columns: 1fr 260px; gap: 18px; align-items: start; }
@media (max-width: 52rem) { .quant { grid-template-columns: 1fr; } }
.quant canvas { width: 100%; display: block; border: 1px solid var(--hairline); }
.quant #qzoom { image-rendering: pixelated; }
.credit { font-family: var(--sans); font-size: 0.74rem; color: var(--ink-3); line-height: 1.55; margin: 8px 0 0; }
.credit code { font-size: 0.9em; }

.rc-modes { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.rc-modes button.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.verdict {
  font-size: 0.98rem; margin: 16px 0 0; padding-left: 14px;
  border-left: 3px solid var(--accent-lt); color: var(--ink-2); min-height: 3.2em;
}

.rd-row {
  display: grid; grid-template-columns: 1fr 1.5fr repeat(3, auto); gap: 14px;
  align-items: baseline; padding: 10px 12px; border: 1px solid transparent;
  border-radius: 4px; font-family: var(--sans); font-size: 0.84rem;
}
.rd-row.win { background: var(--accent-soft); border-color: var(--accent-lt); }
.rd-k { font-weight: 600; color: var(--ink); }
.rd-tag { font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); margin-left: 0.5rem; }
.rd-why { color: var(--ink-3); }
.rd-n { font-family: var(--mono); font-size: 0.8rem; text-align: right; min-width: 5.5em; }
.rd-n span { display: block; font-family: var(--sans); font-size: 0.58rem; letter-spacing: 0.1em; text-transform: none; color: var(--ink-3); }
.rd-c { font-weight: 600; color: var(--accent); }
@media (max-width: 52rem) { .rd-row { grid-template-columns: 1fr; gap: 0.2rem; } }

/* ---------- document layout: section rail beside the article ----------
   Ported from site/samples/a2-longform.html, which is the approved shape. */
.wrap {
  max-width: 1220px;
  margin: 0 auto;
  padding: 0 28px;
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 54px;
}
/* A board table has more columns than a phone has room for. On desktop it
   wraps (nothing clipped); below this it becomes its own scroll region, so the
   table pans instead of the page. */
@media (max-width: 62rem) {
  table { display: block; overflow-x: auto; max-width: 100%; }
}
@media (max-width: 62rem) {
  .wrap { grid-template-columns: minmax(0, 1fr); gap: 0; }
  aside.toc { display: none; }
}
aside.toc {
  position: sticky; top: 0; align-self: start; max-height: 100vh; overflow-y: auto;
  padding: 52px 0; font-family: var(--sans); font-size: 0.8rem;
}
aside.toc { grid-column: 1; }
aside.toc:empty { visibility: hidden; }
aside.toc .lbl {
  text-transform: uppercase; letter-spacing: 0.09em; font-size: 0.66rem;
  color: var(--ink-3); margin-bottom: 12px;
}
aside.toc ol { list-style: none; margin: 0; padding: 0; border-left: 2px solid var(--hairline); }
aside.toc li { margin: 9px 0; }
aside.toc a {
  display: block; padding: 5px 0 5px 14px; margin-left: -2px;
  border-left: 2px solid transparent; color: var(--ink-2); box-shadow: none;
}
aside.toc a:hover { color: var(--accent); border-left-color: var(--accent-lt); background: none; }
aside.toc a.on { color: var(--ink); font-weight: 600; border-left-color: var(--accent); }

main { padding: 0; grid-column: 2; }
@media (max-width: 62rem) { main, aside.toc { grid-column: 1; } }
article { padding: 52px 0 24px; max-width: 44rem; }

/* the sample page's opening: kicker, standfirst, byline */
.kicker, p.eyebrow {
  font-family: var(--sans); font-size: 0.76rem; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--accent); font-weight: 600; margin: 0;
}
.standfirst { font-size: 1.28rem; color: var(--ink-2); line-height: 1.6; margin: 0; }
.byline {
  font-family: var(--sans); font-size: 0.8rem; color: var(--ink-3);
  border-top: 1px solid var(--hairline); padding-top: 14px; margin: 24px 0 0; line-height: 1.6;
}

/* The home page's h1 is the banner wordmark rather than the word. The README
   carries it as a <picture> with a dark and a light source, and build_site.py
   keeps it instead of stripping it, so the first screen has an image on it. */
h1.brandmark { margin: 0.35em 0 0; line-height: 0; }
h1.brandmark img, h1.brandmark picture { max-width: min(100%, 24rem); height: auto; display: block; }

/* Eight nav items are three lines of chrome on a 400px screen. They stay on
   one or two by dropping the type and closing the gaps, which is cheaper for a
   reader than a button that hides the site's own map behind a tap. */
@media (max-width: 34rem) {
  header.site .bar { padding: 11px 18px; gap: 0.3rem 0.9rem; }
  header.site nav { font-size: 0.78rem; gap: 0.1rem 0.85rem; margin-left: 0; width: 100%; }
}

/* Below 62rem the rail has nowhere to sit beside the article, and results.md
   is 3,600 words with no way to jump. It becomes a wrapping strip above the
   prose instead of disappearing. */
@media (max-width: 62rem) {
  aside.toc {
    display: block; position: static; max-height: none; overflow: visible;
    padding: 28px 0 0; border-bottom: 1px solid var(--hairline); margin-bottom: 8px;
  }
  aside.toc:empty { display: none; }
  aside.toc ol { display: flex; flex-wrap: wrap; gap: 0 0.2rem; border-left: 0; }
  aside.toc li { margin: 0; }
  aside.toc a { padding: 4px 10px 4px 0; border-left: 0; margin-left: 0; }
  aside.toc a:hover { border-left-color: transparent; }
  aside.toc a.on { border-left-color: transparent; }
}


/* The rail lists every page in reading order and nests this page's sections
   under the current one. The pager under the article carries the same order,
   so a reader never has to go back to the top bar to find the next page. */
aside.toc ol.pages { border-left: 0; }
aside.toc ol.pages > li { margin: 6px 0; }
aside.toc ol.pages > li > a { padding-left: 0; margin-left: 0; border-left: 0; }
aside.toc ol.pages > li.here > a { color: var(--ink); font-weight: 600; }
aside.toc ol.sections, aside.toc ul.sections { margin: 8px 0 14px 4px; padding: 0;
  border-left: 2px solid var(--hairline); list-style: none; }
aside.toc ol.sections li, aside.toc ul.sections li { margin: 7px 0; }
aside.toc ol.sections a, aside.toc ul.sections a { font-size: 0.76rem; }
nav.pager { display: flex; justify-content: space-between; gap: 1rem;
  margin: 2.5rem 0 3.5rem; padding-top: 1.4rem; border-top: 1px solid var(--hairline);
  font-family: "IBM Plex Sans", system-ui, sans-serif; }
nav.pager a { display: block; box-shadow: none; text-decoration: none;
  color: var(--ink); font-weight: 600; font-size: 1rem; }
nav.pager a span { display: block; font-size: 0.66rem; text-transform: uppercase;
  letter-spacing: 0.09em; color: var(--ink-3); font-weight: 400; margin-bottom: 4px; }
nav.pager a.next { text-align: right; margin-left: auto; }
nav.pager a:hover { color: var(--accent); background: none; }
@media (max-width: 62rem) {
  aside.toc .lbl, aside.toc ol.pages > li:not(.here) > a, aside.toc ol.pages > li.here > a { display: none; }
  aside.toc ol.pages { display: block; }
  aside.toc ol.sections, aside.toc ul.sections { display: flex; flex-wrap: wrap;
    gap: 0 0.2rem; border-left: 0; margin: 0; }
}

/* ---------- blog charts ---------- */
/* the charts are drawn on a light plate, like the live figures */
figure.chart { margin: 32px 0; }
figure.chart img { display: block; width: 100%; height: auto; border-radius: 8px; }
