/* CurveNumber, public pages.

   The application is a tool: dense, scanned, operated. These pages are read,
   once, by somebody deciding whether to trust the thing. So the palette, the
   type and the three theme states are the application's, unchanged, and the
   proportions are not: a wider measure, a serif for the argument, and room
   around the artefacts.

   The one idea in this stylesheet is the specimen. Anything shown here is a
   real thing out of the product, framed and labelled with where it came
   from, in the same way the product labels its own figures. Nothing on these
   pages is an illustration of a feature. */

/* ---------- tokens: the application's, verbatim ---------- */
:root {
  --ground: #f5f4f0;
  --surface: #ffffff;
  --sunk: #efeee8;
  --line: #dfdcd3;
  --line-strong: #c6c2b6;
  --ink: #1e2320;
  --ink-mid: #5a5f58;
  --ink-soft: #636860;
  --accent: #26696c;
  --accent-soft: #e2edec;
  --accent-line: #9dc2c1;
  --ochre: #8a5324;
  --ochre-soft: #f3e7db;
  --ochre-line: #d6ac83;
  --red: #9b3226;
  --red-soft: #f7e4e1;
  --shadow: 0 1px 2px rgba(30,35,32,.05), 0 4px 14px rgba(30,35,32,.05);
  --sans: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --serif: "Source Serif 4", Georgia, serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* A screenshot is a photograph of something that happened, so it does not
     invert with the theme. The mat behind it does: in light it is a shade of
     paper, in dark it is the panel surface, so a white specimen reads as a
     printed page laid on the page rather than as a hole burned in it. */
  --paper: #fbfaf7;
  --paper-line: #d9d5cb;
  --measure: 34rem;
}

/* --ink-soft is now 5.2 to 1 on the light ground (it was 3.4 to 1), the same
   value the application uses, so both pass WCAG AA. These pages set whole sentences at 10 and 11 px, so everything that
   is read rather than glanced at takes --ink-mid, at 5.9 to 1, and --ink-soft
   is left to the one place it still belongs: the DEFAULTED chip, where the
   word is deliberately the quietest of the three provenance states. */
:root {
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #151917; --surface: #1d2220; --sunk: #262b28;
    --line: #333935; --line-strong: #4a514c;
    --ink: #e9e7e0; --ink-mid: #a8ada4; --ink-soft: #9aa096;
    --accent: #5fafb0; --accent-soft: #1e3234; --accent-line: #356f71;
    --ochre: #d3924f; --ochre-soft: #33261a; --ochre-line: #7a5730;
    --red: #d98276; --red-soft: #331e1b;
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 4px 14px rgba(0,0,0,.25);
    --paper: #1d2220; --paper-line: #3f4642;
  }
}
:root[data-theme="dark"] {
  --ground: #151917; --surface: #1d2220; --sunk: #262b28;
  --line: #333935; --line-strong: #4a514c;
  --ink: #e9e7e0; --ink-mid: #a8ada4; --ink-soft: #9aa096;
  --accent: #5fafb0; --accent-soft: #1e3234; --accent-line: #356f71;
  --ochre: #d3924f; --ochre-soft: #33261a; --ochre-line: #7a5730;
  --red: #d98276; --red-soft: #331e1b;
  --shadow: 0 1px 2px rgba(0,0,0,.3), 0 4px 14px rgba(0,0,0,.25);
  --paper: #1d2220; --paper-line: #3f4642;
}

/* ---------- base ---------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--ground); color: var(--ink);
  font-family: var(--sans); font-size: 16px; line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}
[hidden] { display: none !important; }
img { max-width: 100%; height: auto; display: block; }

a { color: var(--accent); text-decoration: none; border-bottom: 1px solid var(--accent-line); }
a:hover { border-bottom-color: var(--accent); }
a:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

h1, h2, h3 { font-family: var(--serif); font-weight: 600; letter-spacing: -.012em; }
h1 { font-size: clamp(2rem, 1.35rem + 2.6vw, 3.1rem); line-height: 1.1; margin: 0 0 1rem; }
h2 { font-size: clamp(1.4rem, 1.15rem + 1vw, 1.85rem); line-height: 1.2; margin: 0 0 .75rem; }
h3 { font-size: 1.12rem; line-height: 1.3; margin: 0 0 .4rem; }
p { margin: 0 0 1rem; }
ul, ol { margin: 0 0 1rem; padding-left: 1.25rem; }
li { margin-bottom: .45rem; }
strong { font-weight: 600; }
code, .mono { font-family: var(--mono); font-size: .875em; }

/* ---------- shell ---------- */
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 1.5rem; }
.col { max-width: var(--measure); }
.col-wide { max-width: 46rem; }

.site-header {
  border-bottom: 1px solid var(--line); background: var(--surface);
}
.site-header .wrap {
  display: flex; align-items: center; gap: 1.25rem; padding-top: .9rem; padding-bottom: .9rem;
}
/* The testing notice under the header on every page. One quiet line in the
   accent's soft tint, so it is seen without competing with the headline. */
.test-notice {
  background: var(--accent-soft); border-bottom: 1px solid var(--accent-line);
  font-size: .85rem; line-height: 1.5; color: var(--ink);
}
.test-notice p { margin: 0; padding: .45rem 0; }
.test-notice a { color: var(--accent); font-weight: 500; }
.brand {
  font-family: var(--serif); font-weight: 700; font-size: 1.2rem;
  letter-spacing: -.015em; color: var(--ink); border: 0;
}
.brand span { color: var(--accent); }
.brand.sm { font-size: 1.05rem; }

/* ---------- the mark ---------- */

/* The monogram, beside the word, in the one place a reader looks for the
   name of the thing they are using.

   WHY IT IS A BACKGROUND AND NOT AN `img` OR AN INLINE `svg`. It has to
   change with the theme, because the mark is a navy that disappears on the
   dark ground. An `img` cannot take `currentColor`. An inline `svg` can, but
   it would be three kilobytes repeated in every one of the pages that carry
   this header, edited by hand in each of them the next time the mark moves. A
   CSS mask would take `currentColor` from one file, and then the mark would
   be whatever colour the surrounding text is, which is a thing a brand mark
   is not. So: two files, and the theme picks one, in exactly the three rules
   the tokens above already use for every other colour in this stylesheet.

   THE SIZE IS IN `em`. The mark is set from the brand type rather than in
   pixels, so the header, the footer's smaller `brand sm`, and any future
   place that sets this class at another size all get a mark in proportion to
   the word beside it, and there is one number to change rather than three.
   1.672 is the mark's own aspect ratio, 512 by 306.3, and is not a choice.

   AND IT IS AN `inline-block` AND NOT A FLEX ITEM. `display: inline-flex` on
   the anchor was tried first and it put a gap inside the word: the markup is
   `Curve<span>Number</span>`, so a flex container makes the text node and the
   span two items and `gap` separates them. The name is one word. */
:root { --mark: url("/brand/cn-mark.svg"); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --mark: url("/brand/cn-mark-dark.svg"); }
}
:root[data-theme="dark"] { --mark: url("/brand/cn-mark-dark.svg"); }

.brand::before {
  content: ""; display: inline-block; --mark-h: 1.25em;
  height: var(--mark-h); width: calc(var(--mark-h) * 1.672);
  vertical-align: -.28em; margin-right: .44em;
  background: var(--mark) no-repeat center / contain;
}
/* A sans heading inside a reading column, one step below the section head. */
.h-sub { font-family: var(--serif); font-size: 1.15rem; }
.site-nav { display: flex; align-items: center; gap: .2rem; margin-left: auto; flex-wrap: wrap; }
.site-nav a {
  font-size: 13.5px; color: var(--ink-mid); border: 1px solid transparent;
  padding: .35rem .65rem; border-radius: 2px;
}
.site-nav a:hover { background: var(--sunk); color: var(--ink); }
.site-nav a[aria-current="page"] {
  background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line);
}
.theme-toggle {
  font-family: var(--mono); font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-mid); background: none; border: 1px solid var(--line); border-radius: 2px;
  padding: .35rem .55rem; cursor: pointer; flex: 0 0 auto;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--line-strong); }
/* The mark the toggle shows in place of the word it used to print.
   `.theme-toggle` sets the control in uppercase, so rendering the state as
   text put the word AUTO in the header of every page, above the headline and
   before the product had said what it was. The state is now the button's
   accessible name and its tooltip, which is where a control's state belongs;
   `site.js` records the reasoning and the alternative that was rejected. */
.theme-mark { font-size: 12px; line-height: 1; letter-spacing: 0; }

main { display: block; }
section { padding: 3.4rem 0; border-top: 1px solid var(--line); }
section:first-of-type { border-top: 0; }
.section-tight { padding: 2.4rem 0; }

.eyebrow {
  font-family: var(--mono); font-size: 11px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-mid); margin: 0 0 .9rem;
}
.eyebrow.accent { color: var(--accent); }
.eyebrow.warn { color: var(--ochre); }
.lede { font-size: 1.14rem; line-height: 1.58; color: var(--ink-mid); }
.lede strong { color: var(--ink); font-weight: 600; }
.note { font-size: .875rem; line-height: 1.6; color: var(--ink-mid); }
.muted { color: var(--ink-soft); }

/* ---------- provenance line: where a claim on this page came from ---------- */
/* The product's whole argument is that a figure without a source is not a
   figure. A page making that argument cites itself. */
.from {
  font-family: var(--mono); font-size: 11px; line-height: 1.5; color: var(--ink-mid);
  border-left: 2px solid var(--line-strong); padding-left: .55rem; margin: -.3rem 0 1.25rem;
  word-break: break-word;
}

/* ---------- hero ---------- */
.hero { padding: 3.6rem 0 3.2rem; }
.hero-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  gap: 3rem; align-items: start;
}
.hero h1 { max-width: 13ch; }
.hero .lede { max-width: 32rem; }
.actions { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; margin-top: 1.6rem; }
.btn {
  font-family: var(--sans); font-size: 14.5px; font-weight: 500; padding: .6rem 1.1rem;
  border-radius: 2px; cursor: pointer; display: inline-block; border: 1px solid var(--accent);
}
.btn.primary { background: var(--accent); color: #fff; }
:root[data-theme="dark"] .btn.primary { color: #10201f; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn.primary { color: #10201f; }
}
.btn.primary:hover { filter: brightness(1.08); }
.btn.ghost { background: transparent; color: var(--ink-mid); border-color: var(--line-strong); }
.btn.ghost:hover { color: var(--accent); border-color: var(--accent); }
.price-line { font-size: .9rem; color: var(--ink-mid); margin-top: .9rem; }

/* ---------- specimen: a real artefact, framed and labelled ---------- */
.spec { margin: 0; }
.spec-frame {
  background: var(--paper); border: 1px solid var(--paper-line); box-shadow: var(--shadow);
  padding: .5rem; border-radius: 2px;
}
.spec-frame img { border: 1px solid rgba(30,35,32,.07); }
.spec-cap {
  font-family: var(--mono); font-size: 11px; line-height: 1.55; color: var(--ink-mid);
  margin-top: .55rem; letter-spacing: .01em;
}
.spec-cap b { color: var(--ink); font-weight: 500; }

/* ---------- three mechanics ---------- */
.tri { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; margin-top: 2rem; }
.mech {
  border-top: 3px solid var(--accent); background: var(--surface);
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  border-left: 1px solid var(--line); padding: 1.1rem; box-shadow: var(--shadow);
}
.mech.defaulted { border-top-color: var(--line-strong); }
.mech.overridden { border-top-color: var(--ochre); }
.mech .origin { margin-bottom: .6rem; }
.mech h3 { font-family: var(--sans); font-size: .98rem; font-weight: 600; }
.mech p { font-size: .9rem; color: var(--ink-mid); margin-bottom: .7rem; }
.mech .sample {
  font-family: var(--mono); font-size: 11.5px; line-height: 1.6; color: var(--ink);
  background: var(--sunk); border: 1px solid var(--line); padding: .55rem .6rem;
  word-break: break-word;
}

.origin {
  display: inline-block; font-family: var(--mono); font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; padding: 2px 6px; border-radius: 2px; border: 1px solid;
}
.origin.derived { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }
.origin.defaulted { color: var(--ink-soft); border-color: var(--line-strong); background: transparent; }
.origin.overridden { color: var(--ochre); border-color: var(--ochre-line); background: var(--ochre-soft); }

/* ---------- verbatim: text lifted out of the codebase ---------- */
.verbatim {
  border-left: 3px solid var(--red); background: var(--red-soft);
  padding: .9rem 1.1rem; margin: 0 0 1.2rem;
}
.verbatim.warn { border-left-color: var(--ochre); background: var(--ochre-soft); }
.verbatim.quiet { border-left-color: var(--line-strong); background: var(--sunk); }
.verbatim .head {
  font-family: var(--mono); font-size: 11px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--red); margin-bottom: .45rem;
}
.verbatim.warn .head { color: var(--ochre); }
.verbatim.quiet .head { color: var(--ink-mid); }
.verbatim p { font-size: .93rem; line-height: 1.6; color: var(--ink-mid); margin-bottom: .6rem; }
.verbatim p:last-child { margin-bottom: 0; }

/* ---------- split layouts ---------- */
.split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 3rem; align-items: start;
}
.split.narrow-left { grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); }
.split.wide-left { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); }

/* ---------- data list ---------- */
.rows { border-top: 1px solid var(--line-strong); margin-top: 1.4rem; }
.row-item {
  display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 1.5rem;
  padding: .95rem 0; border-bottom: 1px solid var(--line); align-items: baseline;
}
.row-item .k { font-weight: 600; font-size: .95rem; }
.row-item .k span {
  display: block; font-family: var(--mono); font-size: 11px; font-weight: 400;
  color: var(--ink-mid); margin-top: .15rem; letter-spacing: .02em; word-break: break-word;
}
.row-item .v { font-size: .93rem; color: var(--ink-mid); }

/* ---------- figures ---------- */
.figs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; margin: 1.8rem 0 0; }
.fig-card { border-top: 1px solid var(--line-strong); padding-top: .8rem; }
.fig-n {
  font-family: var(--mono); font-size: 1.85rem; font-weight: 600; line-height: 1;
  letter-spacing: -.03em; color: var(--accent); font-variant-numeric: tabular-nums;
}
.fig-n small { font-size: .95rem; font-weight: 400; color: var(--ink-mid); letter-spacing: 0; }
.fig-l { font-size: .875rem; color: var(--ink-mid); margin-top: .5rem; }

/* ---------- pricing ---------- */
.plans { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.5rem; margin-top: 2rem; }
/* Three price cards in a row (pricing page). Stacks with the others below 900px. */
.plans.three { grid-template-columns: repeat(3, 1fr); gap: 1.1rem; }
.plans.three .plan { padding: 1.25rem; }
.plans.three .plan .amount { font-size: 1.85rem; }
.plans.three .plan .amount small { display: block; margin-top: .3rem; }
.plan {
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow);
  padding: 1.5rem;
}
.plan.lead { border-top: 3px solid var(--accent); }
.plan .amount {
  font-family: var(--mono); font-size: 2.3rem; font-weight: 600; letter-spacing: -.035em;
  color: var(--accent); line-height: 1; font-variant-numeric: tabular-nums;
}
.plan .amount small { font-size: .9rem; font-weight: 400; color: var(--ink-mid); letter-spacing: 0; }
.plan h2, .plan h3 { font-family: var(--sans); font-size: .95rem; font-weight: 600; line-height: 1.3; margin: 0 0 .8rem; }
.plan p { font-size: .9rem; color: var(--ink-mid); margin: .9rem 0 0; }

/* ---------- legal documents ---------- */
.doc { padding: 2.6rem 0 3.4rem; }
.doc h1 { font-size: 2.1rem; }
.doc .col-wide { max-width: 43rem; }
.draft-banner {
  border: 1px solid var(--ochre-line); border-left: 3px solid var(--ochre);
  background: var(--ochre-soft); padding: 1rem 1.15rem; margin-bottom: 2.2rem;
}
.draft-banner .head {
  font-family: var(--mono); font-size: 11px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--ochre); margin-bottom: .45rem;
}
.draft-banner p { font-size: .93rem; color: var(--ink-mid); margin-bottom: .6rem; }
.draft-banner p:last-child { margin-bottom: 0; }

.doc h2.first { border-top: 0; padding-top: 0; margin-top: 2.4rem; }
.doc h2 {
  font-size: 1.3rem; margin-top: 2.6rem; padding-top: 1.1rem; border-top: 1px solid var(--line);
  display: flex; gap: .8rem; align-items: baseline;
}
.doc h2 .n {
  font-family: var(--mono); font-size: .82rem; font-weight: 400; color: var(--ink-mid);
  flex: 0 0 auto; padding-top: .15rem;
}
.doc h3 { margin-top: 1.6rem; font-family: var(--sans); font-size: 1rem; font-weight: 600; }
.doc p, .doc li { font-size: .97rem; }
.doc .meta {
  font-family: var(--mono); font-size: 11px; color: var(--ink-mid); letter-spacing: .02em;
  margin-bottom: 1.6rem;
}
.toc {
  background: var(--sunk); border: 1px solid var(--line); padding: 1rem 1.15rem;
  margin-bottom: 2rem;
}
.toc ol { margin: 0; padding-left: 1.3rem; column-count: 2; column-gap: 2rem; }
.toc li { margin-bottom: .3rem; font-size: .9rem; }
@media (max-width: 640px) { .toc ol { column-count: 1; } }

/* A placeholder wraps like any other text. An early draft held it on one line
   so it would read as a single token, and a long instruction to the lawyer
   then pushed the page four times wider than the viewport. */
.ph {
  font-family: var(--mono); font-size: .84em; letter-spacing: .02em; line-height: 1.5;
  color: var(--ochre); background: var(--ochre-soft);
  border: 1px dashed var(--ochre-line); border-radius: 2px; padding: 1px 5px;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
.ph-list { border: 1px solid var(--ochre-line); background: var(--ochre-soft); padding: 1.1rem 1.25rem; }
/* Inside the ochre box the chips would otherwise sit on their own fill and
   disappear, so they take the surface instead. */
.ph-list .ph { background: var(--surface); }
.ph-list ul { margin-bottom: 0; }
.ph-list li { font-size: .92rem; }

/* ---------- footer ---------- */
.site-footer {
  border-top: 1px solid var(--line); background: var(--surface); padding: 2.2rem 0 2.8rem;
  margin-top: 0;
}
.foot-grid { display: flex; gap: 2.5rem; flex-wrap: wrap; align-items: flex-start; }
.foot-links { display: flex; gap: 1.2rem; flex-wrap: wrap; margin-left: auto; }
.foot-links a { font-size: .88rem; color: var(--ink-mid); border-bottom-color: var(--line-strong); }
.foot-links a:hover { color: var(--accent); border-bottom-color: var(--accent); }
.disclaimer {
  font-size: .8rem; color: var(--ink-mid); line-height: 1.65; max-width: 46rem;
  margin-top: 1.4rem; padding-top: 1rem; border-top: 1px solid var(--line);
}

/* ---------- responsive ---------- */
@media (max-width: 900px) {
  .hero-grid, .split, .split.narrow-left, .split.wide-left { grid-template-columns: 1fr; gap: 2.2rem; }
  .tri, .figs, .plans, .plans.three { grid-template-columns: 1fr; gap: 1.2rem; }
  .row-item { grid-template-columns: 1fr; gap: .3rem; }
  .hero h1 { max-width: none; }
}
@media (max-width: 560px) {
  body { font-size: 15.5px; }
  .wrap { padding: 0 1.1rem; }
  section { padding: 2.6rem 0; }
  .hero { padding: 2.4rem 0; }
  .site-header .wrap { flex-wrap: wrap; gap: .6rem; }
  .site-nav { margin-left: 0; width: 100%; order: 3; }
  .theme-toggle { margin-left: auto; }
  .foot-links { margin-left: 0; width: 100%; }
}

/* ---------- front page, 12 September 2026: one column, two points, five steps ----------
   Appended for the short front page. Everything above is untouched. The page
   is a single column, so the split hero's narrow headline measure does not
   apply, and it needs two things the sheet did not have: a pair of plain
   cards for the two points, and a numbered row for the workflow. Both use the
   existing tokens, so they follow the theme. */

/* The split hero holds a short headline beside a specimen. This one holds a
   long headline on its own, so it takes a wider measure. */
.hero.hero-one h1 { max-width: 24ch; }

/* two points, as two quiet cards */
.points {
  list-style: none; margin: 2.8rem 0 0; padding: 0; max-width: 46rem;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem;
}
.points li {
  margin: 0; padding: 1.1rem 1.2rem; font-size: 1rem; line-height: 1.5; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-top: 3px solid var(--accent);
  box-shadow: var(--shadow);
}

/* five steps, as a numbered row */
.steps {
  list-style: none; counter-reset: step; margin: 1.6rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1.25rem;
  border-top: 1px solid var(--line-strong);
}
.steps li {
  counter-increment: step; margin: 0; padding-top: .9rem;
  font-size: .95rem; font-weight: 500; line-height: 1.4; color: var(--ink);
}
.steps li::before {
  content: counter(step, decimal-leading-zero); display: block; margin-bottom: .35rem;
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; color: var(--accent);
}
.steps + .note { margin: 1.4rem 0 0; }

/* Narrower than 900px the row becomes a list, number beside each step. */
@media (max-width: 900px) {
  .steps { grid-template-columns: 1fr; gap: 0; }
  .steps li {
    display: flex; align-items: baseline; gap: .9rem;
    padding: .7rem 0; border-bottom: 1px solid var(--line);
  }
  .steps li::before { display: inline-block; margin: 0; min-width: 2ch; }
}
/* At phone width the two cards stack, inside the existing gutters. */
@media (max-width: 560px) {
  .points { grid-template-columns: 1fr; gap: .9rem; margin-top: 2.2rem; }
}

/* ---------- how-it-works screenshots, 12 September 2026 ----------
   Four of the five steps get a real screenshot; "Modify BMPs" stays
   text-only above because no screenshot matches it yet. Each card is a
   plain surface with the image on top and a caption underneath, using the
   same tokens as .points so it reads as one family. */
.shots {
  list-style: none; margin: 2.4rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem;
}
.shots li {
  margin: 0; background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow);
}
.shots img {
  display: block; width: 100%; height: auto; border-bottom: 1px solid var(--line);
}
.shots .shot-label {
  margin: 0; padding: .9rem 1.1rem 0; font-family: var(--sans); font-weight: 600;
  font-size: .92rem; color: var(--ink);
}
.shots .shot-label span {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; color: var(--accent);
  margin-right: .5rem;
}
.shots .shot-cap { margin: .3rem 0 0; padding: 0 1.1rem 1rem; font-size: .82rem; color: var(--ink-mid); }

@media (max-width: 700px) {
  .shots { grid-template-columns: 1fr; }
}

/* ---------- homepage, 20 September 2026: fewer words, shorter lines ----------
   The overview page had grown to 11,800 pixels of dense serif prose and read
   as a wall. The long material moved to features.html and about.html; what
   stayed needed room to breathe rather than more argument. Scoped to
   body.home so terms, privacy, pricing and about are untouched: those are
   documents and a 46rem measure is right for them.

   Three changes only. A shorter measure, because 46rem of Source Serif at
   this size runs past the line length a reader tracks comfortably. More
   vertical space between sections, because the borders were doing all the
   separating. And a card grid for the nine capabilities, which were nine
   paragraphs and are now nine names with a line under each. */

.home section { padding: 4.8rem 0; }
.home .col-wide { max-width: 40rem; }
.home .hero .lede { max-width: 34rem; }
.home .lede { line-height: 1.6; }
.home .split { gap: 3rem; }
.home h2 { margin-bottom: 1rem; }

/* The nine capabilities. A name and one line: anybody who wants the paragraph
   follows the link under the grid. Three columns at desk width, two at
   tablet, one on a phone, because a 3-up grid of prose at 390px is a column
   of single words. */
.home .cards {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.7rem 2rem; margin-top: 2.2rem;
}
.home .card { border-top: 1px solid var(--line-strong); padding-top: .85rem; }
.home .card h3 {
  font-family: var(--sans); font-size: .95rem; font-weight: 600;
  line-height: 1.35; margin: 0 0 .4rem;
}
.home .card p { font-size: .875rem; color: var(--ink-mid); margin: 0; line-height: 1.55; }

@media (max-width: 900px) {
  .home .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .home section { padding: 3.6rem 0; }
  .home .split { gap: 2rem; }
}
@media (max-width: 560px) {
  .home .cards { grid-template-columns: 1fr; gap: 1.4rem; }
}

/* ---------- tables, 20 September 2026 ----------
   Added for the white paper, which is the first page on this site to carry
   real tabular data. The other document pages use .rows, a definition list in
   two columns, which is right for "term, then explanation" and wrong for
   "four columns of counts". Styled to match .rows rather than to look like a
   spreadsheet: one rule under the head, one hairline between rows, figures in
   the mono face so columns of numbers line up. */

.doc table {
  width: 100%; border-collapse: collapse; margin: 1.4rem 0;
  font-size: .9rem; line-height: 1.55;
}
.doc table th {
  text-align: left; vertical-align: bottom;
  font-family: var(--sans); font-size: .68rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft);
  border-bottom: 1px solid var(--line-strong); padding: 0 1rem .5rem 0;
}
.doc table td {
  vertical-align: top; color: var(--ink-mid);
  border-bottom: 1px solid var(--line); padding: .7rem 1rem .7rem 0;
}
.doc table td:first-child { color: var(--ink); font-weight: 500; }
.doc table th:last-child, .doc table td:last-child { padding-right: 0; }
/* Second column of a three or four column table is nearly always a count. */
.doc table td:nth-child(2) { font-family: var(--mono); font-size: .84rem; }
.doc table:not(.wide) td:nth-child(2) { white-space: nowrap; }
.doc table.prose td:nth-child(2) {
  font-family: var(--serif); font-size: .9rem; white-space: normal;
}

@media (max-width: 620px) {
  .doc table, .doc table tbody, .doc table tr, .doc table td { display: block; width: 100%; }
  .doc table thead { display: none; }
  .doc table tr { border-bottom: 1px solid var(--line-strong); padding: .8rem 0; }
  .doc table td { border: 0; padding: .15rem 0; }
  .doc table td:first-child { font-weight: 600; color: var(--ink); }
  .doc table td:nth-child(2) { white-space: normal; }
}

/* ---------- print, 20 September 2026 ----------
   Added for the white paper, which is the first page here anybody would
   reasonably print or save as a PDF. The navigation, the theme toggle and
   the footer link list are screen furniture and are dropped; the disclaimer
   is not, because it is the sentence that has to travel with the document.
   Headings do not end a page alone and a table row does not split across
   one, which is the difference between a document and a web page somebody
   printed. */

/* ---------- the access form ----------
   The only form on this website, and the first one. Everything else here is
   a document, so there was no input styling at all and a form dropped in
   would have rendered in the browser's own default face beside prose set in
   Source Serif. That reads as a third-party widget bolted on, which is the
   wrong impression for the one page where a visitor is deciding whether to
   trust the people behind it.

   Deliberately small. A control needs a readable face, a visible edge, a
   focus ring somebody can see, and enough width to hold what it asks for.
   Anything past that is a design system this site does not have and does not
   need for five fields. */
.access-form { max-width: 34rem; margin-top: 1.4rem; }
.access-form p { margin: 0 0 1.1rem; }
.access-form label {
  display: block; font-family: var(--sans); font-size: 14.5px; font-weight: 500;
  color: var(--ink); margin-bottom: .3rem;
}
.access-form label .note { display: block; font-weight: 400; margin: .1rem 0 0; }
.access-form input, .access-form textarea {
  width: 100%; box-sizing: border-box; font-family: var(--sans); font-size: 15px;
  line-height: 1.5; color: var(--ink); background: var(--paper);
  border: 1px solid var(--line-strong); border-radius: 2px; padding: .55rem .65rem;
}
.access-form textarea { resize: vertical; min-height: 5.5rem; }
.access-form .field-msg { display: block; min-height: 1.2em; margin-top: .3rem; font-size: .9rem; color: var(--red); }
.access-form .field-msg:empty { min-height: 0; margin: 0; }
.access-form input:focus-visible, .access-form textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
/* `.btn` was written for an anchor, so a button needs the two properties an
   anchor gets for nothing. */
button.btn { font: inherit; font-family: var(--sans); font-size: 14.5px; font-weight: 500; }

@media print {
  .site-header, .theme-toggle, .foot-links, .toc, .actions { display: none !important; }
  html, body { background: #fff !important; }
  .doc .wrap { max-width: none; padding: 0; }
  .doc .col-wide { max-width: none; }
  .site-footer { border-top: 1px solid var(--line-strong); margin-top: 1.5rem; }
  .site-footer .foot-grid { display: block; }
  h1, h2, h3 { break-after: avoid-page; page-break-after: avoid; }
  table, figure, .verbatim, .row-item { break-inside: avoid-page; page-break-inside: avoid; }
  .doc table tr { break-inside: avoid-page; page-break-inside: avoid; }
  a { text-decoration: none; }
}

/* Skip link: the first thing a keyboard user reaches on every page (WCAG
   2.4.1). Same look as the application's. */
.skip-link { position: absolute; left: .5rem; top: -4rem; z-index: 1000; background: var(--accent);
             color: var(--surface); padding: .7rem 1rem; font-weight: 600; border-radius: 3px;
             text-decoration: none; }
.skip-link:focus { top: .5rem; outline: 3px solid var(--accent); outline-offset: 2px; }
main:focus { outline: none; }

/* ------------------------------------------------------------------------
   Round 1 review: legibility, touch targets and print (E-18, E-39).
   Kept together at the end so the earlier rules read as they did.
   ------------------------------------------------------------------------ */

/* The muted ink was 3.4:1 on the page ground; this is about 5.7:1. Dark mode
   keeps its own value (its selectors are more specific than this one). */
:root { --ink-soft: #5f6359; }

.origin { font-size: 12px; }
.doc table th { font-size: 12px; color: var(--ink-mid); }
.verbatim .head, .draft-banner .head { font-size: 12px; }
.access-form input { min-height: 44px; }

@media (max-width: 480px) {
  .site-nav a, .theme-toggle {
    min-height: 44px; min-width: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }
}

/* Printing in dark mode used to put near-white text on white paper: the
   background was reset and the ink was not. Every page prints in the light
   palette, and the testing notice bar is left off the paper. */
@media print {
  :root, :root[data-theme="dark"], :root:not([data-theme="light"]) {
    --ground: #ffffff; --surface: #ffffff; --sunk: #f2f2f2;
    --line: #999999; --line-strong: #777777;
    --ink: #1a1a1a; --ink-mid: #444444; --ink-soft: #444444;
    --accent: #1f5a5c; --accent-soft: #eef4f4; --accent-line: #7aa6a5;
    --ochre: #7a4a1f; --ochre-soft: #f6eee6; --ochre-line: #b88b62;
    --red: #8a2b20; --red-soft: #f7e9e7;
    --paper: #ffffff; --paper-line: #999999;
  }
  body { color: #1a1a1a !important; }
  .test-notice { display: none !important; }
}

/* Round 2 (Q4, RB-62): footer links are a finger wide on a phone. */
@media (max-width: 480px) {
  .foot-links a { display: inline-flex; align-items: center; min-height: 44px; }
}

/* Round 2 (Q4, RB-67): on a phone the navigation is one row that scrolls
   sideways, as in the app, and the hero leads with its one action, so "Ask
   for access" is above the fold at 390 x 844. */
@media (max-width: 560px) {
  .site-nav { display: flex; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
              scrollbar-width: none; gap: .9rem; }
  .site-nav::-webkit-scrollbar { display: none; }
  .site-nav a { flex: none; }
  .hero { padding: 1.4rem 0 2rem; }
  .hero-grid > div:first-child { display: flex; flex-direction: column; }
  .hero-grid > div:first-child > .actions { order: 3; margin: .4rem 0 1.4rem; }
  .hero-grid > div:first-child > .eyebrow { order: 0; }
  .hero-grid > div:first-child > h1 { order: 1; }
  .hero-grid > div:first-child > .hero-what { order: 2; }
  .hero-grid > div:first-child > .lede,
  .hero-grid > div:first-child > .note,
  .hero-grid > div:first-child > .price-line { order: 4; }
}

/* Round 2 (Q4, RB-63): a wide table scrolls in its own box on a phone. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-wrap table { min-width: 560px; }
/* Where a page's table stacks into blocks on a phone (above), the blocks fit
   the screen and nothing is left to scroll to. */
@media (max-width: 620px) { .doc .table-wrap table { min-width: 0; } }

/* ---------- worked examples, 26 September 2026 ----------
   The Examples index and one page per example. Each example is a run
   through the real product, so its screenshots are specimens in the sense
   this sheet already uses: framed in .spec-frame, captioned in .spec-cap.
   What is new is the step: a numbered block of text beside the screenshots
   it describes, stacking to one column below 900px. Everything takes the
   existing tokens, so both themes follow. */

/* The example pages are not the Examples link's own page, so the link says
   "true" rather than "page"; it is drawn the same. */
.site-nav a[aria-current="true"] {
  background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line);
}

.ex-hero h1 { max-width: 24ch; }
.ex-crumb {
  font-family: var(--mono); font-size: 12px; color: var(--ink-mid); margin: 0 0 1.4rem;
  letter-spacing: .02em;
}
.ex-crumb a { color: var(--ink-mid); border-bottom-color: var(--line-strong); }
.ex-crumb a:hover { color: var(--accent); border-bottom-color: var(--accent); }
.ex-intro {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  gap: 3rem; align-items: start; margin-top: .6rem;
}
.ex-shows {
  background: var(--surface); border: 1px solid var(--line); border-top: 3px solid var(--accent);
  box-shadow: var(--shadow); padding: 1.1rem 1.25rem .4rem;
}
.ex-shows-h {
  font-family: var(--mono); font-size: 12px; font-weight: 500; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 .8rem;
}
.ex-shows li { font-size: .93rem; line-height: 1.5; color: var(--ink); margin-bottom: .55rem; }
.ex-note {
  border-left: 3px solid var(--line-strong); background: var(--sunk);
  padding: .8rem 1rem; margin: 1.4rem 0 0;
}
.ex-note .head {
  font-family: var(--mono); font-size: 12px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--ink-mid); margin: 0 0 .35rem;
}
.ex-note p { font-size: .9rem; line-height: 1.6; color: var(--ink-mid); margin: 0; }
.ex-parts { display: flex; flex-direction: column; gap: .45rem; margin: 0; }
.ex-parts a { font-size: .95rem; align-self: flex-start; }

/* one part of a two-part example */
.ex-part { max-width: 46rem; margin-bottom: 2.4rem; }

/* a step: text on the left, its screenshots on the right */
.ex-step {
  display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: 3rem; align-items: start; padding: 2.6rem 0; border-top: 1px solid var(--line);
}
.ex-body .wrap > .ex-step:first-child { border-top: 0; padding-top: 0; }
.ex-step.solo { grid-template-columns: minmax(0, 46rem); }
.ex-text h2, .ex-text h3 {
  font-size: clamp(1.25rem, 1.1rem + .6vw, 1.5rem); line-height: 1.25; margin: 0 0 .8rem;
}
.ex-text .n {
  display: block; margin-bottom: .45rem; font-family: var(--mono); font-size: 12px;
  font-weight: 500; letter-spacing: .1em; color: var(--accent);
}
.ex-text p, .ex-text li { font-size: .98rem; }
.ex-text li { margin-bottom: .5rem; }
.ex-figs { display: grid; gap: 1.8rem; }
/* Beside a tall column of screenshots the text stays in view. */
@media (min-width: 901px) {
  .ex-step:not(.solo) .ex-text { position: sticky; top: 1.5rem; }
}

/* a screenshot that opens full size */
.zoom { display: block; position: relative; cursor: zoom-in; transition: border-color .15s; }
.zoom:hover { border-color: var(--accent-line); }
.zoom::after {
  content: "Enlarge"; position: absolute; top: .9rem; right: .9rem;
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: #fff; background: rgba(30,35,32,.78); padding: 3px 8px; border-radius: 2px;
  opacity: 0; transition: opacity .15s;
}
.zoom:hover::after, .zoom:focus-visible::after { opacity: 1; }

/* The tables are small, so they stay tables on a phone and scroll in their
   own box if they have to. */
.ex-table { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 1.3rem 0 1.4rem; }
.ex-table table {
  width: 100%; border-collapse: collapse; font-size: .9rem; line-height: 1.45;
  font-variant-numeric: tabular-nums;
}
.ex-table thead th {
  font-family: var(--sans); font-size: 12px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-mid); text-align: right; vertical-align: bottom;
  border-bottom: 1px solid var(--line-strong); padding: 0 0 .5rem .9rem;
}
.ex-table thead th:first-child { text-align: left; padding-left: 0; }
.ex-table tbody th {
  text-align: left; font-weight: 500; color: var(--ink); padding: .6rem 0;
  border-bottom: 1px solid var(--line);
}
.ex-table td {
  font-family: var(--mono); font-size: .84rem; color: var(--ink); text-align: right;
  white-space: nowrap; padding: .6rem 0 .6rem .9rem; border-bottom: 1px solid var(--line);
}

/* the published link, at the end of every example */
.ex-published {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.5rem; align-items: center;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-left: 3px solid var(--accent); padding: 1.3rem 1.4rem; margin: 2.4rem 0 .6rem;
}
.ex-published .head {
  font-family: var(--mono); font-size: 12px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 .35rem;
}
.ex-published p { font-size: .95rem; color: var(--ink); margin: 0 0 .5rem; }
.ex-published .from { margin: .2rem 0 0; border-left-color: var(--accent-line); word-break: break-all; }
.ex-published .btn { white-space: nowrap; }

/* previous and next */
.ex-pager {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem;
  margin-top: 2.6rem; padding-top: 2rem; border-top: 1px solid var(--line-strong);
}
.ex-pager-link {
  display: block; background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow); padding: 1rem 1.2rem; color: var(--ink);
  font-family: var(--serif); font-size: 1.08rem; font-weight: 600; line-height: 1.3;
}
.ex-pager-link:hover { border-color: var(--accent); color: var(--accent); }
.ex-pager-link.next { text-align: right; }
.ex-pager-link.empty { background: none; border: 0; box-shadow: none; padding: 0; }
.ex-pager-link .lab {
  display: block; margin-bottom: .3rem; font-family: var(--mono); font-size: 11px;
  font-weight: 400; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-mid);
}
.ex-pager-all { text-align: center; margin: 1.3rem 0 0; font-size: .92rem; }

/* the index: one card per example */
.ex-cards {
  list-style: none; margin: 2.6rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.6rem;
}
.ex-card {
  position: relative; margin: 0; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow);
  transition: border-color .15s;
}
.ex-card:hover { border-color: var(--accent-line); }
.ex-card:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.ex-card-img { background: var(--paper); border-bottom: 1px solid var(--line); overflow: hidden; }
.ex-card-img img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: top left; }
.ex-card-body { padding: 1.1rem 1.25rem 1.25rem; display: flex; flex-direction: column; flex: 1; }
.ex-card-body .eyebrow { margin-bottom: .5rem; }
.ex-card h2 { font-size: 1.2rem; line-height: 1.3; margin: 0 0 .35rem; }
.ex-card h2 a { color: var(--ink); border: 0; }
.ex-card h2 a::after { content: ""; position: absolute; inset: 0; }
.ex-card h2 a:focus-visible { outline: none; }
.ex-card:hover h2 a { color: var(--accent); }
.ex-card-place { font-family: var(--mono); font-size: 12px; color: var(--ink-mid); margin: 0 0 .7rem; }
.ex-card-line { font-size: .92rem; color: var(--ink-mid); margin: 0 0 1rem; }
.ex-card-go { margin-top: auto; font-size: .9rem; font-weight: 500; color: var(--accent); }

/* getting started: the five steps, each with a line under it */
.ex-five li div > strong { display: block; font-weight: 600; }
.ex-five li div > span {
  display: block; margin-top: .3rem; font-size: .875rem; font-weight: 400;
  line-height: 1.5; color: var(--ink-mid);
}
.ex-start { margin-top: 2.6rem; }
.ex-start .spec { margin-top: 1.2rem; }

/* the home page's pointer to the examples */
.ex-mini { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line-strong); }
.ex-mini li { margin: 0; border-bottom: 1px solid var(--line); }
.ex-mini a {
  display: grid; grid-template-columns: 2.4rem minmax(0, 1fr); gap: .2rem .8rem;
  padding: .9rem 0; border: 0; color: var(--ink);
}
.ex-mini a:hover .t { color: var(--accent); }
.ex-mini .k {
  grid-row: span 2; font-family: var(--mono); font-size: 12px; letter-spacing: .1em;
  color: var(--accent); padding-top: .2rem;
}
.ex-mini .t { font-weight: 600; font-size: .98rem; line-height: 1.35; }
.ex-mini .p { font-family: var(--mono); font-size: 12px; color: var(--ink-mid); }

/* the full-size view a screenshot opens into */
.lightbox {
  padding: 0; border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink);
  max-width: min(1600px, 96vw); max-height: 94vh; width: fit-content; overflow: auto;
  box-shadow: 0 10px 40px rgba(0,0,0,.35);
}
.lightbox::backdrop { background: rgba(12,15,13,.82); }
.lightbox-bar {
  position: sticky; top: 0; z-index: 1; display: flex; gap: 1rem; align-items: center;
  justify-content: space-between; background: var(--surface); border-bottom: 1px solid var(--line);
  padding: .55rem .6rem .55rem 1rem;
  /* The image sets the dialog's width; the caption wraps inside it. */
  width: 0; min-width: 100%; box-sizing: border-box;
}
.lightbox-cap { font-family: var(--mono); font-size: 12px; color: var(--ink-mid); margin: 0; }
.lightbox-cap b { color: var(--ink); font-weight: 500; }
.lightbox-close {
  flex: 0 0 auto; font-family: var(--sans); font-size: 14px; font-weight: 500; cursor: pointer;
  color: var(--ink); background: var(--sunk); border: 1px solid var(--line-strong);
  border-radius: 2px; padding: .4rem .8rem; min-height: 36px;
}
.lightbox-close:hover { border-color: var(--accent); color: var(--accent); }
.lightbox img { display: block; max-width: 100%; width: auto; height: auto; margin: 0 auto; }

@media (max-width: 900px) {
  .ex-intro, .ex-step, .ex-step.solo { grid-template-columns: minmax(0, 1fr); gap: 1.8rem; }
  .ex-cards { grid-template-columns: minmax(0, 1fr); }
  .ex-published { grid-template-columns: minmax(0, 1fr); }
  .ex-published .btn { justify-self: start; }
}
@media (max-width: 560px) {
  .ex-step { padding: 2rem 0; }
  .ex-pager { grid-template-columns: minmax(0, 1fr); gap: .8rem; }
  .ex-pager-link.next { text-align: left; }
  .ex-pager-link.empty { display: none; }
  .ex-table table { font-size: .84rem; }
  .ex-table td { font-size: .78rem; padding-left: .6rem; }
  .ex-table thead th { font-size: 11px; padding-left: .6rem; letter-spacing: .04em; }
  .ex-published .btn { white-space: normal; }
  .zoom::after { display: none; }
  /* On a phone the full-size view is the real full size, scrolled in both
     directions, because fitted to 390px it is no larger than the page. */
  .lightbox { width: 96vw; }
  .lightbox img { max-width: none; margin: 0; }
  .lightbox-bar { left: 0; width: 96vw; min-width: 0; }
}
@media print {
  .ex-pager, .ex-pager-all, .zoom::after { display: none !important; }
  .ex-step { break-inside: avoid-page; }
}
