:root {
/* TOKENS:BEGIN */
  /* GENERATED by tools/palette.mjs. Do not hand-edit. */
  --deep: #0E1406;
  --ground2: #161D0B;
  --ground: #1E2612;
  --plate: #28311B;
  --plate2: #333C25;

  --ink: #FAFCF6;
  --ink2: #E7EAE3;
  --ink3: #C7CAC4;
  --faint: #A6AAA2;

  --husk: #E69022;
  --husk-mark: #F29A33;
  --husk-wash: #2F1C09;
  --vent: #79A1FF;
  --vent-mark: #85ADFF;
  --vent-wash: #172035;
  --oxide: #E88A84;
  --oxide-mark: #F2938D;
  --oxide-wash: #301A19;

  /* One name for the primary, so a swap is one line. */
  --accent: var(--husk);
  --accent-mark: var(--husk-mark);
  --accent-wash: var(--husk-wash);
/* TOKENS:END */
}

/* ==========================================================================
   base.css — tokens, reset, type, layout primitives.

   THE DOCUMENT GENRE IS A STRUCTURAL DESIGN CODE: the kind of paper that
   tells an engineer what load to assume for a silo and, beside every number,
   where the number came from. That is not decoration here. A code numbers
   its clauses so a claim can be cited; it prints a symbol table so a letter
   means one thing; it gives every value a class so you know whether it was
   measured, derived or assumed. This site makes claims about other people's
   numbers, so it had better carry all three.

   Hairline rules, tabular figures, dotted leaders, clause numbers in the
   gutter. No rounded cards, no glow, no gradient that is not a material.

   EVERY COLOUR IS GENERATED, from the Kubelka–Munk model in js/powder.js via
   tools/palette.mjs. A hex anywhere else in css/ or js/ fails the build.
   ========================================================================== */

:root {
  --font-display: 'Archivo', ui-sans-serif, system-ui, sans-serif;
  --font-text: 'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --wrap: 1180px;
  --measure: 66ch;
  --gut: clamp(20px, 5vw, 56px);
  --clause: 5.5rem;          /* the left gutter clause numbers live in */
  --rule: 1px;

  --r-sm: 2px;
  --r: 3px;

  --step: clamp(60px, 9vw, 118px);
  --ease: cubic-bezier(.22, .61, .36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink2);
  font-family: var(--font-text);
  font-size: 16.5px;
  line-height: 1.62;
  font-feature-settings: 'kern' 1, 'liga' 1;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Figures are compared down columns all over this site. */
table, .fig, .num, dd, .spec, .stat, tbody, .mono { font-variant-numeric: tabular-nums; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink);
  font-weight: 600;
  letter-spacing: -0.017em;
  line-height: 1.1;
  margin: 0 0 .5em;
  text-wrap: balance;
}
h1 { font-size: clamp(38px, 6.2vw, 62px); letter-spacing: -0.028em; }
h2 { font-size: clamp(27px, 3.5vw, 39px); letter-spacing: -0.022em; }
h3 { font-size: clamp(19px, 2vw, 23px); }
h4 { font-size: 15px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink3); font-weight: 600; }

p { margin: 0 0 1.1em; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

b, strong { color: var(--ink); font-weight: 600; }

code, kbd, samp { font-family: var(--font-mono); font-size: .88em; }
code { color: var(--ink); background: var(--plate); padding: .1em .35em; border-radius: var(--r-sm); }

hr { border: 0; border-top: var(--rule) solid var(--plate2); margin: var(--step) 0; }

::selection { background: var(--accent-mark); color: var(--deep); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--accent-mark); color: var(--deep);
  padding: 10px 16px; z-index: 100; font-weight: 600;
}
.skip:focus { left: 12px; top: 12px; }

/* ---- layout -------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gut);
}

section { padding-block: var(--step); }
section + section { border-top: var(--rule) solid var(--plate); }

/* THE CLAUSE GRID. A numbered gutter on the left, the document on the right.
   Below the breakpoint it collapses to one column and the number sits inline
   above its heading, which is what a printed code does in a narrow measure. */
.clause {
  display: grid;
  grid-template-columns: var(--clause) minmax(0, 1fr);
  gap: 0 clamp(16px, 3vw, 40px);
  align-items: start;
}
.clause > .n {
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: .06em;
  color: var(--faint);
  padding-top: .55em;
  white-space: nowrap;
}
.clause > .body { min-width: 0; }
@media (max-width: 860px) {
  .clause { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .clause > .n { padding-top: 0; margin-bottom: .5em; }
}

.lede {
  font-size: clamp(17.5px, 1.9vw, 21px);
  line-height: 1.52;
  color: var(--ink2);
  max-width: 58ch;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1.1em;
  display: block;
}

.cols {
  display: grid;
  gap: clamp(22px, 3vw, 40px);
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
}
.cols > * { min-width: 0; }

/* ---- rules and panels ---------------------------------------------------- */
.panel {
  background: var(--plate);
  border: var(--rule) solid var(--plate2);
  border-radius: var(--r);
  padding: clamp(18px, 2.4vw, 28px);
  min-width: 0;
}
.panel.flush { background: transparent; }

/* A hairline with tape ticks, the way a section is drawn on a survey sheet. */
.tick {
  height: 9px;
  border-top: var(--rule) solid var(--plate2);
  background-image: linear-gradient(to right, var(--plate2) var(--rule), transparent var(--rule));
  background-size: 12px 100%;
  background-repeat: repeat-x;
  opacity: .85;
  margin: 0 0 clamp(20px, 3vw, 34px);
}

/* ---- spec list, with dotted leaders -------------------------------------- */
/* NOT a grid or a flex container on the row itself. A grid row splits inline
   markup into anonymous items — a sibling site turned every <li> containing
   <b> and <code> into four overlapping boxes that way, and a flex container
   discards whitespace-only text nodes, which rendered a button label as
   "Thefifteenrules". The leader is a background, so the row stays inline. */
.spec { margin: 0; padding: 0; }
.spec > div {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: .42em 0;
  border-bottom: var(--rule) dotted var(--plate2);
}
.spec dt {
  color: var(--ink3);
  font-size: 14.5px;
  flex: 0 1 auto;
}
.spec .lead { flex: 1 1 auto; min-width: 12px; }
.spec dd {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 14px;
  text-align: right;
  flex: 0 0 auto;
}

/* ---- confidence classes -------------------------------------------------- */
/* Every published figure carries one. The letter is the whole point, so it is
   legible rather than decorative: solved to 4.5:1 as text. */
.cls {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .08em;
  padding: .15em .4em;
  border: var(--rule) solid currentColor;
  border-radius: var(--r-sm);
  vertical-align: .18em;
  margin-left: .35em;
  white-space: nowrap;
  opacity: .9;
}
.c1 { color: var(--vent); }
.c2 { color: var(--husk); }
.c3 { color: var(--faint); }

/* ---- figures in prose ---------------------------------------------------- */
.fig {
  font-family: var(--font-mono);
  color: var(--ink);
  font-weight: 500;
  font-size: .97em;
}

/* ---- buttons ------------------------------------------------------------- */
.btn {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -.005em;
  padding: 11px 20px;
  border-radius: var(--r);
  border: var(--rule) solid var(--plate2);
  color: var(--ink);
  background: var(--plate);
  cursor: pointer;
  transition: background .16s var(--ease), border-color .16s var(--ease);
}
.btn:hover { background: var(--plate2); text-decoration: none; }
.btn.primary {
  background: var(--accent-mark);
  border-color: var(--accent-mark);
  color: var(--deep);
}
.btn.primary:hover { filter: brightness(1.08); }

.btnrow { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

/* ---- tables -------------------------------------------------------------- */
/* Wide tables scroll INSIDE their own container. min-width:0 is required on
   the scroller: overflow-x:auto still has a non-zero min-content contribution,
   so without it the page itself widens and the browser zooms out rather than
   showing a scrollbar. */
.scroller { overflow-x: auto; min-width: 0; max-width: 100%; }
table { border-collapse: collapse; width: 100%; font-size: 14.5px; }
th, td {
  text-align: left;
  padding: .55em .8em .55em 0;
  border-bottom: var(--rule) solid var(--plate2);
  vertical-align: baseline;
}
th {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink3);
  font-weight: 500;
  white-space: nowrap;
}
td.num, th.num { text-align: right; font-family: var(--font-mono); }
tbody tr:last-child td { border-bottom: 0; }

/* ---- reveal on scroll ---------------------------------------------------- */
/* SCOPED TO .js, which an inline script in <head> sets before any stylesheet
   is applied. Unscoped, this rule hides the entire page from anyone without
   JavaScript — a sibling site shipped 37 elements stuck at opacity 0. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.js [data-reveal].seen { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; transition: none; }
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
