/* ==========================================================================
   GENERATED — do not edit, and do not restate any of it by hand.

   Emitted by site/sheetspec.py from
     paper-session/references/design.md  (sha256 aed260888cb0)

   design.md is the single source of visual truth for every sheet this
   project prints. A CSS restatement of it would be a second spec with no
   gate, and two specs drift; that is what this block prevents. Every
   number below is the number in design.md, and the pt->px arithmetic is
   written out rather than pre-multiplied so it can be checked by eye.

   The page that consumes these tokens is rendered to PDF and run through
   paper-session/scripts/verify_layout.py on every build. If you need a
   number that is not here, add an extractor to site/sheetspec.py.
   ========================================================================== */

/* The eight faces design.md §1 registers by exact name, self-hosted from
   paper-session/assets/fonts/ so the printed sheet is measured on the
   metrics of the files the spec names rather than on a CDN substitute or
   a fallback the gate would never notice. */
@font-face {
  font-family: "Paper Session Sans"; /* Sans · IBM Plex Sans */
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("fonts/IBMPlexSans-Regular.ttf") format("truetype");
}
@font-face {
  font-family: "Paper Session Sans"; /* SansSB · IBM Plex Sans */
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("fonts/IBMPlexSans-SemiBold.ttf") format("truetype");
}
@font-face {
  font-family: "Paper Session Sans"; /* SansB · IBM Plex Sans */
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("fonts/IBMPlexSans-Bold.ttf") format("truetype");
}
@font-face {
  font-family: "Paper Session Serif"; /* Serif · IBM Plex Serif */
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("fonts/IBMPlexSerif-Regular.ttf") format("truetype");
}
@font-face {
  font-family: "Paper Session Serif"; /* SerifSB · IBM Plex Serif */
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("fonts/IBMPlexSerif-SemiBold.ttf") format("truetype");
}
@font-face {
  font-family: "Paper Session Serif"; /* SerifI · IBM Plex Serif */
  font-style: italic;
  font-weight: 400;
  font-display: block;
  src: url("fonts/IBMPlexSerif-Italic.ttf") format("truetype");
}
@font-face {
  font-family: "Paper Session Mono"; /* Mono · IBM Plex Mono */
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("fonts/IBMPlexMono-Regular.ttf") format("truetype");
}
@font-face {
  font-family: "Paper Session Mono"; /* MonoM · IBM Plex Mono */
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("fonts/IBMPlexMono-Medium.ttf") format("truetype");
}

/* The paper. Margin zero on purpose: design.md §0 puts the footer BELOW
   the margin box at baseline y=30, which a @page margin cannot express,
   so the sheet element carries the 54pt margins itself. */
@page { size: 612pt 792pt; margin: 0; }

:root,
.ps-sheet {
  /* One printer's point, at the CSS-fixed 96 px per inch. */
  --ps-pt-px: calc(96 / 72 * 1px);
  /* Every length below is expressed in --ps-pt. A screen-rendered sheet
     rebinds this to a fraction of its own width and the whole object
     scales; print rebinds it to a true point. */
  --ps-pt: var(--ps-pt-px);

  /* §0 Non-negotiables — the page box and the two gray limits. */
  /* The bare numbers too: a ratio and a divisor cannot take a unit,
     and style.css derives the screen scale by dividing the sheet's own
     width into 612 points. */
  --ps-page-width-pt: 612;
  --ps-page-height-pt: 792;
  --ps-margin-pt: 54;
  --ps-page-width: calc(612 * var(--ps-pt));
  --ps-page-height: calc(792 * var(--ps-pt));
  --ps-margin: calc(54 * var(--ps-pt));
  --ps-text-width: calc((612 - 2 * 54) * var(--ps-pt));
  --ps-text-height: calc((792 - 2 * 54) * var(--ps-pt));
  --ps-footer-baseline: calc(30 * var(--ps-pt));
  --ps-meaning-floor-gray: 0.5;
  --ps-guide-ceiling-gray: 0.6;
  --ps-pen-share: 50%;

  /* Font metrics, read from the hhea table of the files §1 registers.
     design.md places type by baseline; CSS places boxes. At line-height 1
     the baseline sits this far below a line box's top edge, and this far
     above its bottom, so a spec baseline becomes a box offset. */
  --ps-font-ascent: 1.025;
  --ps-font-descent: 0.275;
  --ps-baseline-from-top: calc((1 - (var(--ps-font-ascent) + var(--ps-font-descent))) / 2 + var(--ps-font-ascent));
  --ps-baseline-from-bottom: calc((1 - (var(--ps-font-ascent) + var(--ps-font-descent))) / 2 + var(--ps-font-descent));

  /* §4 Header anatomy — baselines as drops from the top margin. */
  --ps-header-top: calc(738 * var(--ps-pt));
  --ps-header-title-drop: calc(22 * var(--ps-pt));
  --ps-header-date-drop: calc(36 * var(--ps-pt));
  --ps-header-intent-drop: calc(52 * var(--ps-pt));
  --ps-header-body-drop: calc(74 * var(--ps-pt));

  /* §6 Molecules — the open-territory floors, the constraint box. */
  --ps-open-territory-light: calc(96 * var(--ps-pt));
  --ps-open-territory-deep: calc(108 * var(--ps-pt));
  --ps-constraint-prompt-size: calc(13 * var(--ps-pt));
  --ps-react-gutter: calc(24 * var(--ps-pt));

  /* Gray values, verbatim from §2 and §3. design.md counts them the way
     reportlab does: 0 is black, 1 is white, so value v is v x 100% white.
     Nothing that carries meaning goes above 0.5;
     writing guides may reach 0.6 because they carry none. */
  --ps-gray-0: rgb(calc(0 * 100%) calc(0 * 100%) calc(0 * 100%));
  --ps-gray-12: rgb(calc(0.12 * 100%) calc(0.12 * 100%) calc(0.12 * 100%));
  --ps-gray-15: rgb(calc(0.15 * 100%) calc(0.15 * 100%) calc(0.15 * 100%));
  --ps-gray-20: rgb(calc(0.2 * 100%) calc(0.2 * 100%) calc(0.2 * 100%));
  --ps-gray-30: rgb(calc(0.3 * 100%) calc(0.3 * 100%) calc(0.3 * 100%));
  --ps-gray-35: rgb(calc(0.35 * 100%) calc(0.35 * 100%) calc(0.35 * 100%));
  --ps-gray-40: rgb(calc(0.4 * 100%) calc(0.4 * 100%) calc(0.4 * 100%));
  --ps-gray-42: rgb(calc(0.42 * 100%) calc(0.42 * 100%) calc(0.42 * 100%));
  --ps-gray-45: rgb(calc(0.45 * 100%) calc(0.45 * 100%) calc(0.45 * 100%));
  --ps-gray-50: rgb(calc(0.5 * 100%) calc(0.5 * 100%) calc(0.5 * 100%));
  --ps-gray-55: rgb(calc(0.55 * 100%) calc(0.55 * 100%) calc(0.55 * 100%));
  --ps-gray-60: rgb(calc(0.6 * 100%) calc(0.6 * 100%) calc(0.6 * 100%));

  /* §1 Font registers. Never blend the voices: Serif asks, Mono is the
     machine, tracked Sans caps is furniture. */
  --ps-face-sans: "Paper Session Sans";
  --ps-face-sans-weight: 400;
  --ps-face-sans-style: normal;
  --ps-face-sanssb: "Paper Session Sans";
  --ps-face-sanssb-weight: 600;
  --ps-face-sanssb-style: normal;
  --ps-face-sansb: "Paper Session Sans";
  --ps-face-sansb-weight: 700;
  --ps-face-sansb-style: normal;
  --ps-face-serif: "Paper Session Serif";
  --ps-face-serif-weight: 400;
  --ps-face-serif-style: normal;
  --ps-face-serifsb: "Paper Session Serif";
  --ps-face-serifsb-weight: 600;
  --ps-face-serifsb-style: normal;
  --ps-face-serifi: "Paper Session Serif";
  --ps-face-serifi-weight: 400;
  --ps-face-serifi-style: italic;
  --ps-face-mono: "Paper Session Mono";
  --ps-face-mono-weight: 400;
  --ps-face-mono-style: normal;
  --ps-face-monom: "Paper Session Mono";
  --ps-face-monom-weight: 500;
  --ps-face-monom-style: normal;

  /* §2 Type scale. One group per row of the table. */
  /* Sheet title */
  --ps-sheet-title-family: var(--ps-face-sansb);
  --ps-sheet-title-weight: var(--ps-face-sansb-weight);
  --ps-sheet-title-style: var(--ps-face-sansb-style);
  --ps-sheet-title-size: calc(16 * var(--ps-pt));
  --ps-sheet-title-leading: normal;
  --ps-sheet-title-color: var(--ps-gray-0);
  --ps-sheet-title-track: calc(0 * var(--ps-pt));
  --ps-sheet-title-transform: none;
  /* Voice captions (I PROPOSE / YOU DECIDE) */
  --ps-voice-captions-family: var(--ps-face-sansb);
  --ps-voice-captions-weight: var(--ps-face-sansb-weight);
  --ps-voice-captions-style: var(--ps-face-sansb-style);
  --ps-voice-captions-size: calc(8 * var(--ps-pt));
  --ps-voice-captions-leading: normal;
  --ps-voice-captions-color: var(--ps-gray-20);
  --ps-voice-captions-track: calc(1.2 * var(--ps-pt));
  --ps-voice-captions-transform: none;
  /* Section labels, open-territory label */
  --ps-section-labels-open-territory-label-family: var(--ps-face-sanssb);
  --ps-section-labels-open-territory-label-weight: var(--ps-face-sanssb-weight);
  --ps-section-labels-open-territory-label-style: var(--ps-face-sanssb-style);
  --ps-section-labels-open-territory-label-size: calc(6.8 * var(--ps-pt));
  --ps-section-labels-open-territory-label-leading: normal;
  --ps-section-labels-open-territory-label-color: var(--ps-gray-40);
  --ps-section-labels-open-territory-label-track: calc(1.4 * var(--ps-pt));
  --ps-section-labels-open-territory-label-transform: none;
  /* Metadata (date line) */
  --ps-metadata-family: var(--ps-face-sans);
  --ps-metadata-weight: var(--ps-face-sans-weight);
  --ps-metadata-style: var(--ps-face-sans-style);
  --ps-metadata-size: calc(6.8 * var(--ps-pt));
  --ps-metadata-leading: normal;
  --ps-metadata-color: var(--ps-gray-40);
  --ps-metadata-track: calc(0.8 * var(--ps-pt));
  --ps-metadata-transform: uppercase;
  /* `HAND:` label (group round sheets) */
  --ps-hand-label-family: var(--ps-face-sanssb);
  --ps-hand-label-weight: var(--ps-face-sanssb-weight);
  --ps-hand-label-style: var(--ps-face-sanssb-style);
  --ps-hand-label-size: calc(6.5 * var(--ps-pt));
  --ps-hand-label-leading: normal;
  --ps-hand-label-color: var(--ps-gray-45);
  --ps-hand-label-track: calc(1.4 * var(--ps-pt));
  --ps-hand-label-transform: uppercase;
  /* Intent line */
  --ps-intent-line-family: var(--ps-face-serifi);
  --ps-intent-line-weight: var(--ps-face-serifi-weight);
  --ps-intent-line-style: var(--ps-face-serifi-style);
  --ps-intent-line-size: calc(9.5 * var(--ps-pt));
  --ps-intent-line-leading: normal;
  --ps-intent-line-color: var(--ps-gray-30);
  --ps-intent-line-track: calc(0 * var(--ps-pt));
  --ps-intent-line-transform: none;
  /* Provocation, standard */
  --ps-provocation-standard-family: var(--ps-face-serif);
  --ps-provocation-standard-weight: var(--ps-face-serif-weight);
  --ps-provocation-standard-style: var(--ps-face-serif-style);
  --ps-provocation-standard-size: calc(21 * var(--ps-pt));
  --ps-provocation-standard-leading: calc(28 * var(--ps-pt));
  --ps-provocation-standard-color: var(--ps-gray-0);
  --ps-provocation-standard-track: calc(0 * var(--ps-pt));
  --ps-provocation-standard-transform: none;
  /* Provocation, Light sheets */
  --ps-provocation-light-sheets-family: var(--ps-face-serif);
  --ps-provocation-light-sheets-weight: var(--ps-face-serif-weight);
  --ps-provocation-light-sheets-style: var(--ps-face-serif-style);
  --ps-provocation-light-sheets-size: calc(15 * var(--ps-pt));
  --ps-provocation-light-sheets-leading: calc(20 * var(--ps-pt));
  --ps-provocation-light-sheets-color: var(--ps-gray-0);
  --ps-provocation-light-sheets-track: calc(0 * var(--ps-pt));
  --ps-provocation-light-sheets-transform: none;
  /* Provocation subline */
  --ps-provocation-subline-family: var(--ps-face-serifi);
  --ps-provocation-subline-weight: var(--ps-face-serifi-weight);
  --ps-provocation-subline-style: var(--ps-face-serifi-style);
  --ps-provocation-subline-size: calc(10 * var(--ps-pt));
  --ps-provocation-subline-leading: normal;
  --ps-provocation-subline-color: var(--ps-gray-40);
  --ps-provocation-subline-track: calc(0 * var(--ps-pt));
  --ps-provocation-subline-transform: none;
  /* AI item, primary */
  --ps-ai-item-primary-family: var(--ps-face-monom);
  --ps-ai-item-primary-weight: var(--ps-face-monom-weight);
  --ps-ai-item-primary-style: var(--ps-face-monom-style);
  --ps-ai-item-primary-size: calc(9.2 * var(--ps-pt));
  --ps-ai-item-primary-leading: normal;
  --ps-ai-item-primary-color: var(--ps-gray-12);
  --ps-ai-item-primary-track: calc(0 * var(--ps-pt));
  --ps-ai-item-primary-transform: none;
  /* AI item, secondary/promise */
  --ps-ai-item-secondary-promise-family: var(--ps-face-mono);
  --ps-ai-item-secondary-promise-weight: var(--ps-face-mono-weight);
  --ps-ai-item-secondary-promise-style: var(--ps-face-mono-style);
  --ps-ai-item-secondary-promise-size: calc(7.6 * var(--ps-pt));
  --ps-ai-item-secondary-promise-leading: calc(9 * var(--ps-pt));
  --ps-ai-item-secondary-promise-color: var(--ps-gray-42);
  --ps-ai-item-secondary-promise-track: calc(0 * var(--ps-pt));
  --ps-ai-item-secondary-promise-transform: none;
  /* House rule / aside */
  --ps-house-rule-aside-family: var(--ps-face-serifi);
  --ps-house-rule-aside-weight: var(--ps-face-serifi-weight);
  --ps-house-rule-aside-style: var(--ps-face-serifi-style);
  --ps-house-rule-aside-size: calc(8.5 * var(--ps-pt));
  --ps-house-rule-aside-leading: normal;
  --ps-house-rule-aside-color: var(--ps-gray-35);
  --ps-house-rule-aside-track: calc(0 * var(--ps-pt));
  --ps-house-rule-aside-transform: none;
  /* Footer */
  --ps-footer-family: var(--ps-face-sanssb);
  --ps-footer-weight: var(--ps-face-sanssb-weight);
  --ps-footer-style: var(--ps-face-sanssb-style);
  --ps-footer-size: calc(6.8 * var(--ps-pt));
  --ps-footer-leading: normal;
  --ps-footer-color: var(--ps-gray-45);
  --ps-footer-track: calc(1.2 * var(--ps-pt));
  --ps-footer-transform: uppercase;
  /* Slot numbers */
  --ps-slot-numbers-family: var(--ps-face-sans);
  --ps-slot-numbers-weight: var(--ps-face-sans-weight);
  --ps-slot-numbers-style: var(--ps-face-sans-style);
  --ps-slot-numbers-size: calc(8 * var(--ps-pt));
  --ps-slot-numbers-leading: normal;
  --ps-slot-numbers-color: var(--ps-gray-50);
  --ps-slot-numbers-track: calc(0 * var(--ps-pt));
  --ps-slot-numbers-transform: none;

  /* §3 Rules and guides. */
  /* Datum rule (top of every page, full text width) */
  --ps-datum-rule-weight: calc(2 * var(--ps-pt));
  --ps-datum-rule-color: var(--ps-gray-0);
  /* Voice caption underline */
  --ps-voice-caption-underline-weight: calc(1.6 * var(--ps-pt));
  --ps-voice-caption-underline-color: var(--ps-gray-0);
  /* Open territory rule */
  --ps-open-territory-rule-weight: calc(1.6 * var(--ps-pt));
  --ps-open-territory-rule-color: var(--ps-gray-0);
  /* Structural hairline */
  --ps-structural-hairline-weight: calc(0.5 * var(--ps-pt));
  --ps-structural-hairline-color: var(--ps-gray-55);
  /* Writing guide (ruled line) */
  --ps-writing-guide-weight: calc(0.5 * var(--ps-pt));
  --ps-writing-guide-color: var(--ps-gray-55);
  --ps-writing-guide-leading: calc(16 * var(--ps-pt));
  /* Answer frame (rank box) */
  --ps-answer-frame-weight: calc(1 * var(--ps-pt));
  --ps-answer-frame-color: var(--ps-gray-15);
  /* Keep/kill circle */
  --ps-keep-kill-circle-weight: calc(0.9 * var(--ps-pt));
  --ps-keep-kill-circle-color: var(--ps-gray-20);
  --ps-keep-kill-circle-radius: calc(8 * var(--ps-pt));
  /* Dot grid (optional zone type) */
  --ps-dot-grid-color: var(--ps-gray-60);
  --ps-dot-grid-radius-min: calc(0.5 * var(--ps-pt));
  --ps-dot-grid-radius-max: calc(0.6 * var(--ps-pt));
  --ps-dot-grid-pitch-min: calc(12 * var(--ps-pt));
  --ps-dot-grid-pitch-max: calc(16 * var(--ps-pt));
  /* Cut line (card kits only) */
  --ps-cut-line-weight: calc(0.6 * var(--ps-pt));
  --ps-cut-line-color: var(--ps-gray-30);
  --ps-cut-line-dash: calc(3 * var(--ps-pt)) calc(2.5 * var(--ps-pt));
}

/* =========================================================================
   paper-session — site design system
   -------------------------------------------------------------------------
   This is the printed system translated to screen, not a second identity.
   Screen-side, the translation is by hand and by ratio:

     print 2pt datum rule      -> --rule-datum: 3px   (2pt = 2.67px @96dpi)
     print 1.6pt closing rule  -> --rule-close: 2px
     print 0.5pt hairline      -> --rule-hair:  1px
     print gray value 0.NN     -> --g-NN

   THE SHEET IS NOT TRANSLATED. It is the spec, at the spec's own numbers, and
   NOTHING in this file may restate one of them. build.py prefixes the served
   stylesheet with a block generated by site/sheetspec.py straight out of
   paper-session/references/design.md; §21 below consumes those --ps-* tokens
   and never types a point size, a rule weight, a gray value or a margin of its
   own. Direction A was killed for hand-writing that spec a second time in CSS.
   Any page declaring `sheet: true` is printed to PDF and put through
   paper-session/scripts/verify_layout.py on every build, so this is checked
   rather than promised. Need a number that is not tokenised? Add an extractor
   to sheetspec.py.

   Three voices, never blended:
     Serif  asks    — running prose, provocations, intent lines
     Mono   reports — every word quoted verbatim out of the repo
     Sans   caps    — infrastructure: nav, labels, buttons, footers
   Nothing on this site imitates handwriting.

   Colour law: grayscale carries the page. Colour appears only where it
   encodes pen intent (red review / green go / blue do / black notes) and
   never alone — every coloured thing is also named in words or shape
   (WCAG 1.4.1; ~1 in 12 men have red-green CVD).
   ========================================================================= */

/* ---- 1. Tokens: complete light palette on bare :root -------------------- */

:root {
  color-scheme: light;

  /* Neutrals. Ink is a cool graphite; paper carries a faint warm bias.
     Deliberately not pure mid-grey, deliberately not cream. */
  --g-00: #191c1e;
  --g-12: #24282a;
  --g-20: #33383a;
  --g-30: #4a5052;
  --g-40: #5c6264;
  --g-45: #656b6d; /* 4.75:1 on --paper — the small-caps label floor */
  --g-50: #7b8183; /* 3.5:1 — decoration and rules only, never body text */
  --g-55: #a0a5a3;
  --g-60: #c3c6c2;

  --paper: #f1f0ec;
  --surface: #f8f7f4;
  --surface-2: #eceae5;

  --ink: var(--g-00);
  --ink-2: var(--g-30);
  --ink-quiet: var(--g-45);
  --ink-faint: var(--g-50); /* nothing meaningful goes lighter than this */
  --guide: var(--g-60); /* rules and hairlines only, never type */

  /* Pen channels. Meaning is always also carried by words or marks. */
  --pen-black: var(--g-00);
  --pen-red: #a8261c;
  --pen-green: #1d6437;
  --pen-blue: #1f4c9e;

  --focus: var(--pen-blue);
  --scrim-ink: #ffffff;
  --scrim: linear-gradient(
    to top,
    rgba(12, 14, 15, 0.86) 0%,
    rgba(12, 14, 15, 0.66) 38%,
    rgba(12, 14, 15, 0.18) 72%,
    rgba(12, 14, 15, 0.05) 100%
  );

  /* Type */
  --font-serif: "IBM Plex Serif", "Iowan Old Style", "Source Serif 4", Georgia,
    "Times New Roman", serif;
  --font-sans: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Helvetica, Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo,
    Consolas, "Liberation Mono", monospace;

  --fs-provocation: clamp(1.6rem, 1.05rem + 2.2vw, 2.6rem);
  --fs-title: clamp(1.3rem, 1.05rem + 1.1vw, 1.85rem);
  --fs-lead: clamp(1.0625rem, 1rem + 0.35vw, 1.2rem);
  --fs-body: 1.0625rem;
  --fs-machine: 0.9375rem;
  --fs-small: 0.875rem;
  --fs-label: 0.6875rem;

  --lh-tight: 1.24;
  --lh-body: 1.62;
  --track-caps: 0.14em;

  /* Rules, from the print weights */
  --rule-datum: 3px;
  --rule-close: 2px;
  --rule-hair: 1px;

  /* Space. Pages decompress downward: bands use ascending air. */
  --s1: 0.5rem;
  --s2: 0.75rem;
  --s3: 1rem;
  --s4: 1.5rem;
  --s5: 2rem;
  --s6: 3rem;
  --s7: 4.5rem;
  --s8: 7rem;
  --s9: 10rem;

  --page-max: 66rem;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --measure: 65ch;
}

/* ---- 2. Dark: redefine tokens only ------------------------------------- */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --g-00: #eef0ec;
    --g-12: #e2e5e0;
    --g-20: #d3d7d2;
    --g-30: #b6bbb7;
    --g-40: #9aa09c;
    --g-45: #8e948f;
    --g-50: #7d8480;
    --g-55: #4b5153;
    --g-60: #363b3e;

    --paper: #131618;
    --surface: #1a1e21;
    --surface-2: #22272a;

    --pen-red: #f28a80;
    --pen-green: #74cf90;
    --pen-blue: #8fb6f5;
    --focus: var(--pen-blue);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --g-00: #eef0ec;
  --g-12: #e2e5e0;
  --g-20: #d3d7d2;
  --g-30: #b6bbb7;
  --g-40: #9aa09c;
  --g-45: #8e948f;
  --g-50: #7d8480;
  --g-55: #4b5153;
  --g-60: #363b3e;

  --paper: #131618;
  --surface: #1a1e21;
  --surface-2: #22272a;

  --pen-red: #f28a80;
  --pen-green: #74cf90;
  --pen-blue: #8fb6f5;
  --focus: var(--pen-blue);
}

/* ---- 3. Reset and base -------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

hr {
  border: 0;
  border-top: var(--rule-hair) solid var(--guide);
  margin: var(--s5) 0;
}

hr.rule-close {
  border-top: var(--rule-close) solid var(--ink);
}

a {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: var(--ink-faint);
}

a:hover {
  text-decoration-thickness: 2px;
  text-decoration-color: var(--ink);
}

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

::selection {
  background: var(--surface-2);
}

/* ---- 4. Layout ---------------------------------------------------------- */

.wrap {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.measure {
  max-width: var(--measure);
}

/* Bands decompress downward: ascending air toward the bottom of a page. */
.band {
  padding-block: var(--s6);
}
.air-1 {
  padding-block: var(--s5) var(--s6);
}
.air-2 {
  padding-block: var(--s6) var(--s7);
}
.air-3 {
  padding-block: var(--s7) var(--s8);
}
.air-4 {
  padding-block: var(--s8) var(--s9);
}

.stack > * + * {
  margin-block-start: var(--s3);
}
.stack-4 > * + * {
  margin-block-start: var(--s4);
}

.scroller {
  overflow-x: auto;
  max-width: 100%;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  padding: var(--s2) var(--s3);
  border: var(--rule-close) solid var(--ink);
  z-index: 20;
}
.skip:focus {
  left: var(--gutter);
  top: var(--s2);
}

/* ---- 5. Voices ---------------------------------------------------------- */

/* Sans: infrastructure. Furniture, not a voice. */
.label,
.nav__list,
.btn,
.footer__meta,
.chip,
th,
.page-foot {
  font-family: var(--font-sans);
}

.label {
  display: block;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin: 0 0 var(--s2);
}

.label--strong {
  color: var(--ink);
}

/* Serif: the sheet asks. */
.provocation {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--fs-provocation);
  line-height: var(--lh-tight);
  letter-spacing: -0.005em;
  margin: 0;
  max-width: 22ch;
}

.provocation--wide {
  max-width: 30ch;
}

.page-title {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-title);
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0 0 var(--s3);
}

.intent {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-lead);
  color: var(--ink-2);
  max-width: 58ch;
  margin: 0;
}

.aside {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-small);
  color: var(--ink-2);
}

/* Mono: the machine reports. On this site Mono means one thing — the words
   are quoted verbatim out of the repository, not written for marketing. */
.machine {
  font-family: var(--font-mono);
  font-size: var(--fs-machine);
  line-height: 1.6;
  color: var(--ink-2);
}

.machine > .caption {
  display: block;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: var(--s1);
  border-bottom: var(--rule-close) solid var(--ink);
  margin-bottom: var(--s3);
}

.machine :is(h2, h3, h4, h5, h6) {
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.3;
  color: var(--ink);
}

.machine strong {
  color: var(--ink);
  font-weight: 500;
}

.machine a {
  text-decoration-color: var(--ink-faint);
}

/* ---- 6. Prose ----------------------------------------------------------- */

.prose {
  max-width: var(--measure);
}

.prose > * + * {
  margin-block-start: var(--s3);
}

.prose :is(h2, h3, h4) {
  font-family: var(--font-sans);
  font-weight: 600;
  line-height: 1.25;
  margin-block-start: var(--s6);
  margin-block-end: var(--s2);
}

.prose h2 {
  font-size: 1.25rem;
}
.prose h3 {
  font-size: 1.0625rem;
}
.prose h4 {
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
}

.prose :is(ul, ol) {
  padding-inline-start: 1.4em;
}

.prose li + li {
  margin-block-start: var(--s2);
}

.prose blockquote {
  margin: var(--s4) 0;
  padding-inline-start: var(--s3);
  border-inline-start: var(--rule-close) solid var(--ink);
  font-style: italic;
  color: var(--ink-2);
}

.prose del {
  text-decoration-thickness: 1px;
  color: var(--ink-quiet);
}

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

pre.code {
  font-family: var(--font-mono);
  font-size: var(--fs-machine);
  line-height: 1.55;
  background: var(--surface);
  border: var(--rule-hair) solid var(--guide);
  padding: var(--s3);
  overflow-x: auto;
  margin: var(--s4) 0;
}

pre.code code {
  font-size: inherit;
}

/* Belt and braces: a code block never widens its container. */
pre.code {
  max-width: 100%;
}

pre.code--diagram {
  display: none;
}

/* Tables: hairline separators, no fills — the print system bans tint panels. */
table {
  border-collapse: collapse;
  width: 100%;
  font-size: var(--fs-small);
  line-height: 1.5;
}

th {
  text-align: start;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  padding: var(--s2) var(--s3) var(--s2) 0;
  border-bottom: var(--rule-close) solid var(--ink);
  vertical-align: bottom;
}

td {
  padding: var(--s3) var(--s3) var(--s3) 0;
  border-bottom: var(--rule-hair) solid var(--guide);
  vertical-align: top;
  min-width: 8rem;
}

/* ---- 7. Header, nav, footer -------------------------------------------- */

.masthead {
  padding-block: var(--s3) 0;
}

.masthead__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  padding-bottom: var(--s2);
}

.wordmark {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
}

.wordmark:hover {
  text-decoration: underline;
  text-decoration-thickness: 2px;
}

.nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s4);
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.nav__list a {
  text-decoration: none;
  color: var(--ink-quiet);
  padding-block: 2px;
  border-bottom: var(--rule-close) solid transparent;
}

.nav__list a:hover {
  color: var(--ink);
  border-bottom-color: var(--guide);
}

.nav__list a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--ink);
}

/* The 2pt datum rule that opens every sheet, opening every page. */
.datum {
  height: var(--rule-datum);
  background: var(--ink);
  border: 0;
  margin: 0;
}

.page-foot {
  font-size: var(--fs-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  font-weight: 600;
}

.footer {
  padding-block: var(--s4) var(--s7);
}

.footer__grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s5);
  justify-content: space-between;
  align-items: baseline;
}

.footer__meta {
  font-size: var(--fs-label);
  letter-spacing: 0.06em;
  color: var(--ink-quiet);
  margin: 0;
}

.footer__meta a {
  text-decoration-color: var(--guide);
}

.theme-toggle {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  background: none;
  border: var(--rule-hair) solid var(--guide);
  padding: 0.35rem 0.7rem;
  cursor: pointer;
}

.theme-toggle:hover {
  color: var(--ink);
  border-color: var(--ink);
}

/* The header's one-click copy: same quiet treatment as the theme toggle,
   because it is furniture, not a call to action. */
.copy-ai {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  background: none;
  border: var(--rule-hair) solid var(--guide);
  padding: 0.35rem 0.7rem;
  cursor: pointer;
}

.copy-ai:hover {
  color: var(--ink);
  border-color: var(--ink);
}

.copy-ai[data-state="done"] {
  color: var(--ink);
  border-color: var(--ink);
}

/* Open territory: the closing 1.6pt rule and real, unstructured emptiness. */
.open-territory {
  margin-block-start: var(--s7);
}

.open-territory__rule {
  height: var(--rule-close);
  background: var(--ink);
  margin: var(--s2) 0 0;
  border: 0;
}

.open-territory__field {
  min-height: 34vh;
}

/* ---- 8. Buttons and chips ---------------------------------------------- */

.btn {
  display: inline-block;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.85rem 1.35rem;
  border: var(--rule-close) solid var(--ink);
  color: var(--ink);
  background: transparent;
  cursor: pointer;
}

.btn:hover {
  background: var(--ink);
  color: var(--paper);
}

/* The primary control is the filled one. It carries no shadow and no accent
   underline: the site's controls are outlined rectangles in the analog
   vocabulary, and a coloured edge here would be the pen's channel spent on
   furniture. Colour on this site appears once, on focus. */
.btn--primary {
  background: var(--ink);
  color: var(--paper);
}

.btn--primary:hover {
  background: transparent;
  color: var(--ink);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  align-items: center;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  padding: 0;
  margin: var(--s3) 0 0;
  list-style: none;
}

.chip {
  font-size: var(--fs-small);
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--ink-2);
  background: transparent;
  border: var(--rule-hair) solid var(--guide);
  padding: 0.35rem 0.75rem;
  cursor: pointer;
}

.chip:hover {
  border-color: var(--ink);
  color: var(--ink);
}

/* Pressed state is a real rule, not a shadow standing in for one. The extra
   weight comes off the padding so nothing shifts when a chip is pressed. */
.chip[aria-pressed="true"] {
  border-color: var(--ink);
  color: var(--ink);
  border-bottom-width: var(--rule-close);
  padding-bottom: calc(0.35rem - (var(--rule-close) - var(--rule-hair)));
}

.answer {
  margin-block-start: var(--s4);
  max-width: 58ch;
}

.answer:empty {
  margin-block-start: 0;
}

.answer__status {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink);
  display: block;
  margin-bottom: var(--s1);
}

.answer__line {
  margin: 0 0 var(--s3);
}

details.ledger-full {
  margin-block-start: var(--s4);
}

details.ledger-full > summary {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  cursor: pointer;
  padding-block: var(--s2);
}

details.ledger-full > summary:hover {
  color: var(--ink);
}

/* ---- 9. Hero ------------------------------------------------------------ */

.hero {
  position: relative;
  margin-block-start: var(--s3);
}

.hero__frame {
  position: relative;
  aspect-ratio: 3 / 2;
  max-height: 76vh;
  overflow: hidden;
}

.hero__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  background: var(--scrim);
}

.hero__overlay {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  padding: var(--gutter);
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  align-items: flex-start;
}

.hero--photo .hero__overlay {
  color: var(--scrim-ink);
}

.hero--photo .btn {
  border-color: var(--scrim-ink);
  color: var(--scrim-ink);
}

.hero--photo .btn:hover {
  background: var(--scrim-ink);
  color: #12100f;
}

.hero--photo .btn--primary {
  background: var(--scrim-ink);
  color: #12100f;
}

.hero--photo .btn--primary:hover {
  background: transparent;
  color: var(--scrim-ink);
}

/* Placeholder state. Dashed, because the print system uses dashes only where
   something is genuinely provisional — here, an asset that does not exist. */
.hero--placeholder .hero__frame {
  /* Same 3:2 slot the photograph will occupy, but it grows rather than
     clipping the note on a narrow screen. The dashed marking itself comes
     from the shared .placeholder component (section 18c). */
  aspect-ratio: auto;
  min-height: min(60vw, 70vh);
  overflow: visible;
  display: grid;
}

.hero--placeholder .hero__overlay {
  position: static;
  padding: var(--s5) 0 0;
}

/* ---- 10. Onramps -------------------------------------------------------- */

.onramps {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: onramp;
}

.onramp {
  counter-increment: onramp;
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  gap: var(--s3) var(--s4);
  padding-block: var(--s5);
  border-top: var(--rule-hair) solid var(--guide);
}

.onramp:first-child {
  border-top: var(--rule-close) solid var(--ink);
}

.onramp__num {
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  color: var(--ink-quiet);
  padding-top: 0.35rem;
}

.onramp__num::before {
  content: "0" counter(onramp);
}

.onramp__body {
  /* A grid item's default min-width is auto, so a <pre> inside one refuses to
     shrink below its content and pushes the whole page sideways on a phone.
     The scroll then belongs to the <pre>, which is what pre.code is for. */
  min-width: 0;
}

.onramp__body > * + * {
  margin-block-start: var(--s3);
}

.onramp h3 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.0625rem;
  line-height: 1.3;
  margin: 0;
}

.onramp p {
  margin: 0;
  max-width: 58ch;
}

.onramp__done {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  border-top: var(--rule-hair) solid var(--guide);
  padding-top: var(--s2);
  display: block;
}

@media (max-width: 34rem) {
  .onramp {
    grid-template-columns: minmax(0, 1fr);
  }
  .onramp__num {
    padding-top: 0;
  }
}

/* ---- 11. Specimen sheets ------------------------------------------------ */

.sheets {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--s4);
  margin: 0;
}

.sheet {
  margin: 0;
}

.sheet img {
  width: 100%;
  border: var(--rule-hair) solid var(--guide);
  background: #fff;
}

.sheet figcaption {
  margin-top: var(--s2);
}

.sheet__note {
  display: block;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-small);
  color: var(--ink-2);
  margin-top: var(--s1);
}

/* ---- 12. The print note ------------------------------------------------- */

.print-note {
  display: flex;
  gap: var(--s3);
  align-items: baseline;
  border-top: var(--rule-close) solid var(--ink);
  border-bottom: var(--rule-hair) solid var(--guide);
  padding-block: var(--s3);
  max-width: 58ch;
}

.print-note__key {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink);
}

.print-note__body {
  margin: 0;
  font-size: var(--fs-small);
  color: var(--ink-2);
}

.print-note__body strong {
  color: var(--ink);
}

@media (max-width: 34rem) {
  .print-note {
    flex-direction: column;
    gap: var(--s1);
  }
}

/* ---- 13. Numbers -------------------------------------------------------- */

.numbers {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--s5);
}

.number {
  border-top: var(--rule-close) solid var(--ink);
  padding-top: var(--s3);
}

.number__figure {
  font-family: var(--font-mono);
  font-size: 1.5rem;
  font-weight: 500;
  line-height: 1.15;
  color: var(--ink);
  margin: 0 0 var(--s2);
}

.number__line {
  font-size: var(--fs-small);
  color: var(--ink-2);
  margin: 0;
}

.thesis {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  line-height: 1.5;
  max-width: 46ch;
  margin: 0;
}

.prompts {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-machine);
  color: var(--ink-2);
}

.prompts li + li {
  margin-top: var(--s1);
}

/* ---- 14. Pen channel swatches (colour, always named) -------------------- */

.pen-key {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s4);
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-small);
}

.pen-key li {
  display: flex;
  align-items: baseline;
  gap: var(--s1);
}

.pen-key b {
  font-weight: 600;
}

.pen-key .pen-red {
  color: var(--pen-red);
}
.pen-key .pen-green {
  color: var(--pen-green);
}
.pen-key .pen-blue {
  color: var(--pen-blue);
}
.pen-key .pen-black {
  color: var(--pen-black);
}

/* ---- 15. Motion and print ---------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

@media print {
  .nav,
  .theme-toggle,
  .chips,
  .hero__frame {
    display: none !important;
  }
  body {
    background: #fff;
    color: #000;
  }
  a {
    text-decoration: underline;
  }
  .band,
  .air-1,
  .air-2,
  .air-3,
  .air-4 {
    padding-block: 1rem;
  }
  .open-territory__field {
    min-height: 0;
  }
}

/* ---- 16. Footer rule ---------------------------------------------------- */

.footer__rule {
  height: var(--rule-hair);
  background: var(--guide);
  margin-bottom: var(--s3);
}

/* ---- 17. Additions ------------------------------------------------------ */

[hidden] {
  display: none !important;
}

/* A question the site asks, one register below a full provocation. */
.question {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(1.2rem, 1.05rem + 0.7vw, 1.5rem);
  line-height: 1.32;
  margin: 0 0 var(--s3);
  max-width: 40ch;
}

.machine > * + * {
  margin-block-start: var(--s3);
}

.machine p,
.machine li {
  margin-block: 0;
}

.machine :is(ul, ol) {
  padding-inline-start: 1.3em;
}

.machine li + li {
  margin-block-start: var(--s2);
}

.machine pre.code {
  background: var(--surface-2);
}

.machine .caption + * {
  margin-block-start: 0;
}

/* ---- 18. Promoted components -------------------------------------------
   Everything below arrived as a page-scoped <style> block in a template.
   A page author cannot reach this file, so each of these shipped inline and
   was reported as a candidate for the shared sheet; they are promoted here so
   the second page that needs one inherits it instead of reinventing it, and
   so no template has to put a <style> element in <body>.
   ------------------------------------------------------------------------ */

/* A visually-hidden label for a control whose visible text is too terse to
   stand alone out of context ("Copy" -> "Copy the premortem line"). */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Spacing utilities, in the same ascending scale the bands use. */
.after-note {
  margin-block-start: var(--s4);
}
.after-lead {
  margin-block-start: var(--s5);
}
.after-block {
  margin-block-start: var(--s6);
}
.after-close {
  margin-block-start: var(--s7);
}

/* A verbatim block wide enough for a table or a source paragraph. */
.machine--wide {
  max-width: 78ch;
}

/* README §Install carries the sentence a person types into a chat with no
   skills runtime. Unstyled it arrives as an anonymous browser indent. */
.machine blockquote {
  margin: var(--s3) 0;
  padding-inline-start: var(--s3);
  border-inline-start: var(--rule-close) solid var(--ink);
  color: var(--ink);
}

/* Headings inside components that sit outside .prose. Bare h3 would inherit
   the body serif and read as prose rather than as a component's name. */
.source-entry h3,
.cluster-index h3,
.ruled-list__item h3,
.route h3 {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.25;
  margin: 0 0 var(--s2);
  color: var(--ink);
}

/* ---- 18a. Disclosure ---------------------------------------------------- */

/* A <details> whose summary is infrastructure, not prose. With JavaScript off
   these stay open: the content is the fallback, the fold is the enhancement. */
.disclosure > summary,
details.ledger-full > summary {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  cursor: pointer;
  padding-block: var(--s2);
}

.disclosure > summary:hover,
details.ledger-full > summary:hover {
  color: var(--ink);
}

/* ---- 18b. Status line --------------------------------------------------- */

/* Feedback from a control. The sentence carries the state; the rule beside it
   is a second, redundant signal, so colour is never doing the work alone. */
.status {
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 52ch;
  margin: var(--s3) 0 0;
  padding-inline-start: var(--s3);
  border-inline-start: var(--rule-close) solid var(--guide);
}

.status:empty {
  display: none;
}

.status[data-state="ok"] {
  color: var(--ink);
  border-inline-start-color: var(--pen-green);
}

.status[data-state="warn"] {
  color: var(--ink);
  border-inline-start-color: var(--pen-red);
}

/* ---- 18c. Pending-asset placeholder ------------------------------------- */

/* An asset that does not exist yet. Dashed and red, and the word "placeholder"
   is always in the text: the colour marks it, the sentence states it. */
.placeholders {
  display: grid;
  gap: var(--s4);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 52rem) {
  .placeholders--pair {
    grid-template-columns: 1fr 1fr;
  }
}

.placeholder {
  border: var(--rule-close) dashed var(--pen-red);
  background: var(--surface);
  padding: var(--s4);
  min-height: 16rem;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.placeholder__key {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--pen-red);
}

.placeholder p {
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--pen-red);
  margin: 0;
  max-width: 44ch;
}

.placeholder code {
  color: inherit;
}

/* ---- 18d. Ruled prose lists --------------------------------------------- */

/* A numbered list of prose blocks, ruled rather than bulleted: the counter is
   infrastructure, the content is a heading plus a paragraph. */
.ruled-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: ruled-item;
  max-width: 62ch;
}

.ruled-list__item {
  counter-increment: ruled-item;
  border-top: var(--rule-close) solid var(--ink);
  padding-block: var(--s3) var(--s5);
}

.ruled-list__item h3::before {
  content: "0" counter(ruled-item);
  display: block;
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: var(--track-caps);
  color: var(--ink-quiet);
  margin-bottom: var(--s1);
}

.ruled-list__item h3 {
  font-weight: 700;
  line-height: 1.3;
}

.ruled-list__item p {
  margin: 0;
  max-width: 58ch;
}

.ruled-list__item p + p {
  margin-block-start: var(--s3);
}

/* ---- 18e. Anchored source entries --------------------------------------- */

/* A claim made elsewhere on the site, with the section of the source file it
   comes from quoted under it. The anchor is the point: a figure on the front
   page links straight to the entry that states its conditions. */
.source-entry {
  border-top: var(--rule-hair) solid var(--guide);
  padding-top: var(--s3);
  scroll-margin-top: var(--s4);
}

.source-entry + .source-entry {
  margin-top: var(--s5);
}

/* Arriving on an anchor is visible in weight, not in hue. */
.source-entry:target {
  border-top-width: var(--rule-close);
  border-top-color: var(--ink);
}

.source-entry > p {
  max-width: var(--measure);
  margin: 0 0 var(--s4);
}

.source-entry .machine,
.sourced .machine {
  max-width: 78ch;
}

.sourced > * + * {
  margin-block-start: var(--s4);
}

.cluster-index {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 78ch;
}

.cluster-index > li + li {
  margin-top: var(--s4);
  border-top: var(--rule-hair) solid var(--guide);
  padding-top: var(--s4);
}

/* A front-page figure that links to its own limitations. */
.number__link {
  color: inherit;
  text-decoration-color: var(--ink-faint);
  text-underline-offset: 0.22em;
}

/* ---- 18f. Route cards --------------------------------------------------- */

/* Ways in, as equal peers: no primary, no recommended badge, same rule weight
   and same type on every one. Both install tracks matter equally, so nothing
   here is allowed to look bigger than anything else. */
.routes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 0 var(--s5);
  list-style: none;
  margin: var(--s5) 0 0;
  padding: 0;
}

.route {
  border-top: var(--rule-close) solid var(--ink);
  padding: var(--s3) 0 var(--s5);
}

.route h3 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 1.0625rem;
  line-height: 1.3;
}

.route p {
  margin: 0 0 var(--s3);
  font-size: var(--fs-small);
  color: var(--ink-2);
}

.route__jump {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-decoration-color: var(--ink-faint);
  text-underline-offset: 0.35em;
}

/* ---- 18g. Ledger verdicts ----------------------------------------------- */

/* Every row's status is boxed identically, tested or not. The box is the whole
   encoding: no colour grades these rows, so colour cannot be the sole carrier
   of meaning, and a traffic light would render a true finding as a warning.
   Selector note: the ledger is parsed generically, so this assumes no column
   or row count. The agent name is the first cell; a verdict is a bolded phrase
   opening any later cell. */
.verdict,
.ledger-table tbody td:not(:first-child) > strong:first-child {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  line-height: 1.35;
  color: var(--ink);
  border: var(--rule-hair) solid var(--ink);
  padding: 0.25rem 0.5rem;
  margin-block-end: 0.35rem;
}

.verdict-key {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1) var(--s3);
  align-items: baseline;
  max-width: 62ch;
  margin: var(--s5) 0 var(--s3);
  font-size: var(--fs-small);
  color: var(--ink-2);
}

.verdict-key span:last-child {
  flex: 1 1 22rem;
}

.ledger-table {
  margin-block-start: var(--s3);
}

.ledger-table td:first-child {
  min-width: 11rem;
}

/* The extra ledger columns the chip answer used to drop. */
.answer__extra {
  margin: 0 0 var(--s3);
}

.answer__extra dt {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
}

.answer__extra dd {
  margin: 0 0 var(--s2);
}

/* ---- 18h. Specimen plate and anatomy key -------------------------------- */

/* One sheet per row, at a size where the smallest printed labels are still
   legible. The shared .sheets grid is a thumbnail strip; this is for the page
   where people actually read them. */
.specimen-plate {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s7);
  max-width: 46rem;
}

.specimen-plate .sheet figcaption {
  margin-top: var(--s3);
  border-top: var(--rule-close) solid var(--ink);
  padding-top: var(--s2);
}

/* The specimen's own intent lines, read out of the generator. */
.specimen-intents {
  margin: 0;
  padding-inline-start: 1.6em;
  max-width: 62ch;
}

.specimen-intents li + li {
  margin-block-start: var(--s2);
}

.specimen-intents__title {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
}

/* A key of named parts: the name on the left, what it does on the right. */
.anatomy {
  display: grid;
  grid-template-columns: minmax(9rem, 15rem) minmax(0, 1fr);
  gap: 0 var(--s4);
  margin: var(--s4) 0 0;
  max-width: 62ch;
}

.anatomy dt {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink);
}

.anatomy dd {
  margin: 0;
  font-size: var(--fs-small);
  color: var(--ink-2);
}

.anatomy dt,
.anatomy dd {
  border-top: var(--rule-hair) solid var(--guide);
  padding-block: var(--s3);
}

@media (max-width: 40rem) {
  .anatomy {
    grid-template-columns: minmax(0, 1fr);
  }
  .anatomy dd {
    border-top: 0;
    padding-top: 0;
  }
  .anatomy dt {
    padding-bottom: var(--s1);
  }
}

/* ---- 18i. A long verbatim file ------------------------------------------ */

/* pre.code already supplies surface, hairline and padding. These few lines are
   what make a four-thousand-word markdown file survive a phone: wrap instead
   of scrolling sideways, and stay bounded when it is open — which, with
   JavaScript off, it always is. */
.filebox {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 70vh;
  overflow: auto;
  resize: vertical;
  margin: var(--s3) 0 0;
}

/* ---- 18j. Copyable sentences and their notes ---------------------------- */

/* The sentence is the visitor's own, so it is set in the asking voice. Mono on
   this site means one thing only: quoted verbatim from the repo. */
.say {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--ink);
  margin: 0;
  padding-inline-start: var(--s3);
  border-inline-start: var(--rule-close) solid var(--ink);
  max-width: 54ch;
}

.say .slot {
  border-bottom: var(--rule-hair) dotted var(--ink-faint);
}

.say__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s3);
  margin: var(--s3) 0 0;
  padding-inline-start: calc(var(--s3) + var(--rule-close));
}

.say__copy {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink);
  background: transparent;
  border: var(--rule-hair) solid var(--ink);
  padding: 0.5rem 0.9rem;
  cursor: pointer;
}

.say__copy:hover,
.say__copy[data-state="done"] {
  background: var(--ink);
  color: var(--paper);
}

.say__hint {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-small);
  color: var(--ink-quiet);
  margin: 0;
}

/* Two tiers of note, distinguished by the words first and the rule second.
   Red is the pen protocol's review channel and never carries meaning alone. */
.note {
  margin: var(--s4) 0 0;
  padding-inline-start: var(--s3);
  border-inline-start: var(--rule-hair) solid var(--guide);
  max-width: 58ch;
  font-size: var(--fs-small);
  color: var(--ink-2);
}

.note--caution {
  border-inline-start: var(--rule-close) solid var(--pen-red);
}

.note p {
  margin: 0;
}

.note p + p {
  margin-block-start: var(--s2);
}

.note__key {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-block-end: var(--s1);
}

.note--caution .note__key {
  color: var(--pen-red);
}

/* ---- 18k. Grouped openers ----------------------------------------------- */

.openers {
  list-style: none;
  margin: 0;
  padding: 0;
}

.opener {
  border-top: var(--rule-hair) solid var(--guide);
  padding-block: var(--s4) var(--s5);
}

.opener__format {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 var(--s3);
}

.opener__num {
  color: var(--ink-quiet);
}

.opener__format .opener__scope {
  font-weight: 400;
  color: var(--ink-quiet);
}

.label--spaced {
  margin-block-start: var(--s5);
}

.situation {
  margin-block-start: var(--s7);
}

.situation:first-of-type {
  margin-block-start: var(--s5);
}

.situation__lede {
  font-family: var(--font-serif);
  font-size: var(--fs-body);
  color: var(--ink-2);
  max-width: 58ch;
  margin: 0 0 var(--s4);
}

/* ---- 19. Flush left, always --------------------------------------------
   `.wrap` centres its own max-width inside the viewport. Putting `.measure`
   on the same element shrinks that max-width, so the whole band drifts to the
   middle of the page — which reads as a centred layout, and this system is
   flush left without exception. Keep the band at page width and constrain its
   children instead, so `class="wrap measure"` and `.wrap > .measure` produce
   the same left edge.
   ------------------------------------------------------------------------ */

.wrap.measure {
  max-width: var(--page-max);
}

.wrap.measure > * {
  max-width: var(--measure);
}

.wrap.measure > .open-territory {
  max-width: none;
}

/* ---- 20. Verbatim-block paragraph spacing -------------------------------
   `.machine p { margin-block: 0 }` (§17) exists to drop the browser's default
   paragraph margins so `.machine > * + *` can own the rhythm — but at (0,1,1)
   it also outranks that rule at (0,1,0), so two consecutive paragraphs inside
   a verbatim block ran together with no gap. Every multi-paragraph quotation
   on the site was affected. Match the specificity, and keep the caption
   flush against the first block under it.
   ------------------------------------------------------------------------ */

.machine > * + p {
  margin-block-start: var(--s3);
}

.machine > .caption + * {
  margin-block-start: 0;
}

/* ---- 21. The sheet: the print organ -------------------------------------
   Print is a verb. This is not a web page that happens to be printable — it
   is the sheet, in the DOM, at US Letter proportions, and Ctrl+P (or a
   [data-print] control) is what turns it into the artifact.

   Every number here arrives as a --ps-* custom property generated from
   paper-session/references/design.md by site/sheetspec.py. There is no design
   number written by hand in this section. If you find yourself typing `54pt`
   or `#737373` below, stop: the token exists.

   design.md places type by baseline, the way reportlab does; CSS places boxes.
   --ps-baseline-from-top and --ps-baseline-from-bottom carry that conversion,
   computed from the hhea metrics of the very font files §1 registers, so even
   the conversion is derived. What it cannot fix: Chromium snaps each block to a
   whole device pixel, so a printed baseline lands within one pixel (0.75pt) of
   the spec and small errors accumulate down the header. That is the browser's
   floor, not a number anyone chose, and it is why the specimen PDF that
   reportlab makes stays the reference artifact.

   Any template using these classes must declare `sheet: true` in its front
   matter, which makes build.py print the built page to PDF and run
   verify_layout.py over it. An unverified sheet is not allowed to ship.
   ------------------------------------------------------------------------ */

.ps-sheet {
  /* On screen the sheet scales as one object: a point is the sheet's own
     width divided into 612 of them, so every token inside resolves against
     the rendered size and nothing needs a second set of values. */
  --ps-pt: calc(100cqw / var(--ps-page-width-pt));

  position: relative;
  box-sizing: border-box;
  width: 100%;
  aspect-ratio: var(--ps-page-width-pt) / var(--ps-page-height-pt);
  padding: var(--ps-margin);
  display: flex;
  flex-direction: column;

  /* design.md §0: grayscale only, no fills, no tint panels. The sheet is
     white paper in both themes, because it is paper. */
  background: #fff;
  color: var(--ps-gray-0);
  font-family: var(--ps-face-sans);
  font-weight: var(--ps-face-sans-weight);
}

/* The container the point is measured against. Crop marks hang outside it so
   the sheet's own width stays exactly 100cqw. */
.ps-sheet-hold {
  container-type: inline-size;
  position: relative;
  margin: var(--s2);
  max-width: 100%;
}

.ps-sheet-hold::before,
.ps-sheet-hold::after,
.ps-sheet-hold > .cm1,
.ps-sheet-hold > .cm2 {
  content: "";
  position: absolute;
  width: 9px;
  height: 9px;
  pointer-events: none;
}

.ps-sheet-hold::before {
  top: -9px;
  left: -9px;
  border-top: var(--rule-hair) solid var(--guide);
  border-left: var(--rule-hair) solid var(--guide);
}

.ps-sheet-hold::after {
  top: -9px;
  right: -9px;
  border-top: var(--rule-hair) solid var(--guide);
  border-right: var(--rule-hair) solid var(--guide);
}

.ps-sheet-hold > .cm1 {
  bottom: -9px;
  left: -9px;
  border-bottom: var(--rule-hair) solid var(--guide);
  border-left: var(--rule-hair) solid var(--guide);
}

.ps-sheet-hold > .cm2 {
  bottom: -9px;
  right: -9px;
  border-bottom: var(--rule-hair) solid var(--guide);
  border-right: var(--rule-hair) solid var(--guide);
}

/* -- §4 Header anatomy: datum, title, date line, intent line -------------- */

.s-datum {
  height: var(--ps-datum-rule-weight);
  background: var(--ps-datum-rule-color);
  flex: none;
}

.s-title {
  font-family: var(--ps-sheet-title-family);
  font-weight: var(--ps-sheet-title-weight);
  font-style: var(--ps-sheet-title-style);
  font-size: var(--ps-sheet-title-size);
  line-height: 1;
  letter-spacing: var(--ps-sheet-title-track);
  color: var(--ps-sheet-title-color);
  text-transform: var(--ps-sheet-title-transform);
  /* §4 measures every header baseline from the top margin, and the datum rule
     sits ON that margin rather than above the title, so its weight comes out of
     the drop. What is left is the drop less the ascender the box carries. */
  margin: calc(
      var(--ps-header-title-drop) - var(--ps-datum-rule-weight) -
        var(--ps-sheet-title-size) * var(--ps-baseline-from-top)
    )
    0 0;
}

.s-meta {
  font-family: var(--ps-metadata-family);
  font-weight: var(--ps-metadata-weight);
  font-style: var(--ps-metadata-style);
  font-size: var(--ps-metadata-size);
  line-height: 1;
  letter-spacing: var(--ps-metadata-track);
  color: var(--ps-metadata-color);
  text-transform: var(--ps-metadata-transform);
  /* The gap between two baselines, less what hangs below the line above and
     what sits above this one. */
  margin: calc(
      var(--ps-header-date-drop) - var(--ps-header-title-drop) -
        var(--ps-sheet-title-size) * var(--ps-baseline-from-bottom) -
        var(--ps-metadata-size) * var(--ps-baseline-from-top)
    )
    0 0;
}

.s-intent {
  font-family: var(--ps-intent-line-family);
  font-weight: var(--ps-intent-line-weight);
  font-style: var(--ps-intent-line-style);
  font-size: var(--ps-intent-line-size);
  line-height: 1;
  letter-spacing: var(--ps-intent-line-track);
  color: var(--ps-intent-line-color);
  margin: calc(
      var(--ps-header-intent-drop) - var(--ps-header-date-drop) -
        var(--ps-metadata-size) * var(--ps-baseline-from-bottom) -
        var(--ps-intent-line-size) * var(--ps-baseline-from-top)
    )
    0 0;
  max-width: var(--ps-text-width);
}

/* §4: the body begins at its own drop from the top margin. Put `s-body-top`
   on the first element under the header; it is a class and not a positional
   selector because the datum rule is a sibling and any :first-of-type rule
   would quietly match nothing. */
.ps-sheet .s-body-top {
  margin-top: calc(
    var(--ps-header-body-drop) - var(--ps-header-intent-drop) -
      var(--ps-intent-line-size) * var(--ps-baseline-from-bottom)
  );
}

/* -- Zones ---------------------------------------------------------------- */

.s-zone {
  margin-top: var(--ps-writing-guide-leading);
}

.s-label {
  display: block;
  font-family: var(--ps-section-labels-open-territory-label-family);
  font-weight: var(--ps-section-labels-open-territory-label-weight);
  font-style: var(--ps-section-labels-open-territory-label-style);
  font-size: var(--ps-section-labels-open-territory-label-size);
  line-height: 1;
  letter-spacing: var(--ps-section-labels-open-territory-label-track);
  color: var(--ps-section-labels-open-territory-label-color);
  text-transform: uppercase;
  /* A zone is a flex item, so margins do not collapse and a UA paragraph
     margin would push the whole body off its §4 drop. The class carries its
     own spacing; the author's choice of element does not change the layout. */
  margin: 0;
}

/* §6 constraint box: a 1pt frame sized to fit the words it asks for. */
.s-box {
  border: var(--ps-answer-frame-weight) solid var(--ps-answer-frame-color);
  padding: calc(var(--ps-writing-guide-leading) / 2);
  margin-top: calc(var(--ps-writing-guide-leading) / 2);
}

.s-prompt {
  font-family: var(--ps-provocation-standard-family);
  font-weight: var(--ps-provocation-standard-weight);
  font-style: var(--ps-provocation-standard-style);
  font-size: var(--ps-constraint-prompt-size);
  line-height: 1.3;
  color: var(--ps-provocation-standard-color);
  margin: 0;
}

/* Loose in a zone rather than inside the frame, the prompt needs the gap that
   the frame's own padding was providing. */
.s-zone > .s-prompt {
  margin-top: calc(var(--ps-writing-guide-leading) / 2);
}

/* Ruled lines: the writing guide, at the writing guide's own leading. */
.s-lines,
.s-guides {
  display: grid;
  gap: calc(var(--ps-writing-guide-leading) - var(--ps-writing-guide-weight));
  margin-top: var(--ps-writing-guide-leading);
}

.s-line {
  display: grid;
  grid-template-columns: calc(var(--ps-slot-numbers-size) * 2) 1fr;
  align-items: end;
  margin: 0;
}

.s-num {
  font-family: var(--ps-slot-numbers-family);
  font-weight: var(--ps-slot-numbers-weight);
  font-size: var(--ps-slot-numbers-size);
  line-height: 1;
  color: var(--ps-slot-numbers-color);
}

.s-rule {
  display: block;
  height: var(--ps-writing-guide-weight);
  background: var(--ps-writing-guide-color);
}

/* §3 dot grid: gray 0.6, radius 0.5-0.6pt, pitch 12-16pt. Every value is a
   token; a row count is the only number a template supplies.

   The gradient is not the spec's hard-edged dot, and that is measured rather
   than preferred: Chromium rasterises a tiled background gradient and drops a
   hard stop at this radius entirely — `circle, C 0.6pt, transparent 0.6pt`
   prints a blank band. A solid core to radius-max fading out across one
   radius-min is what actually reaches paper, and it reaches it at the spec's
   own 0.6pt. print-color-adjust keeps it there when the browser would
   otherwise economise on background ink. */
.s-dots {
  /* The template supplies a row count and nothing else; the arithmetic that
     turns it into a height lives here, with the rest of the spec. */
  height: calc(var(--s-dot-rows, 6) * var(--ps-dot-grid-pitch-max));
  margin-top: var(--ps-writing-guide-leading);
  background-image: radial-gradient(
    circle,
    var(--ps-dot-grid-color) var(--ps-dot-grid-radius-max),
    transparent calc(var(--ps-dot-grid-radius-max) + var(--ps-dot-grid-radius-min))
  );
  background-size: var(--ps-dot-grid-pitch-max) var(--ps-dot-grid-pitch-max);
  background-position: center center;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

/* -- The provocation ------------------------------------------------------ */

.s-prov {
  font-family: var(--ps-provocation-standard-family);
  font-weight: var(--ps-provocation-standard-weight);
  font-style: var(--ps-provocation-standard-style);
  font-size: var(--ps-provocation-standard-size);
  line-height: var(--ps-provocation-standard-leading);
  color: var(--ps-provocation-standard-color);
  /* §6: the provocation block runs to the text width less 60pt. */
  max-width: calc(var(--ps-text-width) - var(--ps-react-gutter) * 2.5);
  margin: calc(var(--ps-writing-guide-leading) / 2) 0 0;
}

.s-sub {
  font-family: var(--ps-provocation-subline-family);
  font-weight: var(--ps-provocation-subline-weight);
  font-style: var(--ps-provocation-subline-style);
  font-size: var(--ps-provocation-subline-size);
  line-height: 1.2;
  color: var(--ps-provocation-subline-color);
  margin: calc(var(--ps-writing-guide-leading) / 2) 0 0;
}

.s-aside {
  font-family: var(--ps-house-rule-aside-family);
  font-weight: var(--ps-house-rule-aside-weight);
  font-style: var(--ps-house-rule-aside-style);
  font-size: var(--ps-house-rule-aside-size);
  line-height: 1.3;
  color: var(--ps-house-rule-aside-color);
  margin: var(--ps-writing-guide-leading) 0 0;
}

/* -- Open territory: always last, always empty ---------------------------- */

.s-open {
  margin-top: var(--ps-writing-guide-leading);
}

.s-close {
  height: var(--ps-open-territory-rule-weight);
  background: var(--ps-open-territory-rule-color);
  margin-top: calc(var(--ps-writing-guide-leading) / 3);
}

/* design.md §0: at least half of every page is space for the pen, and the
   territory takes whatever the zones above did not. The floor is §6's. */
.s-territory {
  flex: 1 1 auto;
  min-height: var(--ps-open-territory-deep);
}

.s-territory--light {
  min-height: var(--ps-open-territory-light);
}

/* -- Footer: below the margin box, on the §0 baseline --------------------- */

.s-foot {
  position: absolute;
  left: var(--ps-margin);
  right: var(--ps-margin);
  bottom: calc(
    var(--ps-footer-baseline) - var(--ps-footer-size) * var(--ps-baseline-from-bottom)
  );
  display: flex;
  justify-content: space-between;
  gap: var(--ps-react-gutter);
  margin: 0;
  font-family: var(--ps-footer-family);
  font-weight: var(--ps-footer-weight);
  font-style: var(--ps-footer-style);
  font-size: var(--ps-footer-size);
  line-height: 1;
  letter-spacing: var(--ps-footer-track);
  color: var(--ps-footer-color);
  text-transform: var(--ps-footer-transform);
}

/* -- Print: the sheet is the document ------------------------------------- */

@media print {
  /* A true point, so the printed sheet is the spec at 1:1. The generated
     @page rule already sets Letter at margin zero; the 54pt margins are the
     sheet's own, because design.md §0 puts the footer below them. */
  .ps-sheet {
    --ps-pt: var(--ps-pt-px);
    width: var(--ps-page-width);
    height: var(--ps-page-height);
    aspect-ratio: auto;
    margin: 0;
    break-inside: avoid;
  }

  .ps-sheet-hold {
    container-type: normal;
    margin: 0;
  }

  .ps-sheet-hold::before,
  .ps-sheet-hold::after,
  .ps-sheet-hold > .cm1,
  .ps-sheet-hold > .cm2 {
    display: none;
  }

  /* Everything that is not the sheet is site furniture and does not print. */
  body.ps-sheet-page .masthead,
  body.ps-sheet-page .footer,
  body.ps-sheet-page .skip,
  body.ps-sheet-page .print-note,
  body.ps-sheet-page [data-print] {
    display: none !important;
  }

  /* Anything the page says to a person looking at a screen. A sheet page
     cannot carry a visible sentence otherwise: it would print, push the sheet
     onto a second page, and fail the gate. */
  body.ps-sheet-page .screen-only {
    display: none !important;
  }

  body.ps-sheet-page,
  body.ps-sheet-page main,
  body.ps-sheet-page .band,
  body.ps-sheet-page .wrap {
    margin: 0;
    padding: 0;
    max-width: none;
    background: #fff;
  }
}

/* The print control. Print is a verb, so the control is one: it says what it
   does and nothing else. It ships hidden and site.js reveals it, the same
   way the copy buttons do, so a browser that cannot be asked to print never
   shows a button that would do nothing. */
[data-print] {
  margin-block-start: var(--s4);
}


/* ---- 22. The door: the front page ---------------------------------------
   The index is one bounded screen. The masthead datum opens it, six numbered
   first-person rows are the table of contents and the router at once, and the
   footer rule closes it. Nothing sits below that rule.

   Each band splits into a tracked-caps rail and a body divided by a hairline.
   The rail names the section, so the heading does not have to argue, so the
   paragraph under the heading has nothing left to explain. That is where the
   front page's word count went.
   ------------------------------------------------------------------------ */

body.door {
  /* The rail width, declared once: the bands, the separator and the margin
     below the last row all measure from the same column. */
  --door-rail: 12.5rem;
}

/* The hero: a 3:2 photograph of a real completed sheet, opening
   the landing page at the column width of the rest of the content.
   The slot keeps its ratio at every width, so the figure grows on a
   narrow screen instead of clipping. Until site/static/hero.jpg
   exists the build renders the placeholder below, dashed and red,
   occupying the same slot. */
.hero {
  margin: 0;
}

.hero img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  background: #fff;
}

.hero--placeholder {
  aspect-ratio: 3 / 2;
  display: grid;
  place-items: center;
  border: 3px dashed #c00;
  color: #c00;
  font-family: var(--font-mono);
}

.door-grid {
  display: grid;
  grid-template-columns: var(--door-rail) minmax(0, 1fr);
  align-items: start;
}

/* The rule between the two bands. It is its own element inside the wrap and
   not a border on the wrap, because a border on the wrap paints across the
   gutter: it would run wider than the masthead datum and the footer rule, and
   the whole point of this page is that every rule on it lands on one datum. */
.door-sep {
  border-top: var(--rule-hair) solid var(--guide);
}

.door-rail {
  grid-column: 1;
  grid-row: 1;
  margin: 0;
  padding-right: var(--s4);
}

.door-body {
  grid-column: 2;
  grid-row: 1;
  min-width: 0;
  border-left: var(--rule-hair) solid var(--guide);
  padding-left: var(--s4);
}

/* Slack in a tall window goes into the bands before it pools at the bottom,
   so the page fills rather than sagging. */
body.door .door-band--lead {
  padding-block: clamp(var(--s3), 3vh, var(--s5)) clamp(var(--s4), 4vh, var(--s6));
}
/* No bottom padding: the margin below carries that space, so the column rule
   runs from the top of the band to the closing rule without a break in it. */
body.door .door-band--index {
  padding-block: 0;
}
.door-band--index .door-grid {
  padding-top: clamp(var(--s3), 3vh, var(--s5));
}

/* The ask: one sentence per line, because the page is finite and says so. */
.door-ask {
  max-width: 34ch;
}
.door-ask > span {
  display: block;
}
.door-ask > span + span {
  margin-top: 0.12em;
}

/* The premise, then what it actually does. Two steps down in scale from the
   ask, and the second one plainer than the first: the provocation earns the
   reader's attention, the sentence after it has to be worth the trade. */
.door-intent {
  margin: var(--s4) 0 0;
  max-width: 52ch;
}
.door-does {
  margin: var(--s3) 0 0;
  max-width: 52ch;
  color: var(--ink);
}

.door-verbatim {
  margin: var(--s4) 0 0;
  max-width: 34ch;
}
.door-verbatim__line {
  display: block;
  font-weight: 500;
  color: var(--ink);
}

/* The problem band: same door rhythm, one new voice. The lead is a serif
   sentence in the visitor's own words; the moments are ruled like the index
   rows but not links, because there is nowhere else for them to go. */
body.door .door-band--problem {
  padding-block: 0 clamp(var(--s4), 4vh, var(--s6));
}
.door-band--problem .door-grid {
  padding-top: clamp(var(--s3), 3vh, var(--s5));
}
.door-problem__lead {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  line-height: 1.3;
  max-width: 40ch;
}
.door-problem__moments {
  margin: var(--s3) 0 0;
  max-width: 52ch;
}
.door-problem__moments > li {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  line-height: 1.3;
  padding-block: 0.5rem;
}
.door-problem__moments > li + li {
  border-top: var(--rule-hair) solid var(--guide);
}
.door-problem__plain {
  margin: var(--s3) 0 0;
  max-width: 52ch;
}

/* Six rows: a mono numeral, a serif statement in the visitor's own voice, and
   the destination that answers it. The whole row is the link. */
.door-rows {
  max-width: none;
  margin: 0;
}
.door-rows > li + li {
  border-top: var(--rule-hair) solid var(--guide);
}

.door-row {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0 var(--s4);
  padding-block: 0.68rem;
  text-decoration: none;
  transition: background-color 120ms linear;
}
.door-row:hover {
  background: var(--surface-2);
}
.door-row:focus-visible {
  outline-offset: -2px;
}

.door-row__n {
  font-family: var(--font-mono);
  font-size: var(--fs-machine);
  font-variant-numeric: tabular-nums;
  color: var(--ink-quiet);
}
.door-row__stmt {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  line-height: 1.3;
}
.door-row__dest {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-quiet);
  white-space: nowrap;
}
.door-row__dest::after {
  content: " \2192";
}
.door-row:hover .door-row__dest,
.door-row:focus-visible .door-row__dest {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 0.35em;
}

/* The margin below the last band. Not open territory: nobody writes on a
   website. It is what makes the footer rule read as an ending.

   The column rule runs on through it to the closing rule, so a page whose
   content stops early reads as a sheet with room left rather than as a build
   that ran out. */
.door-margin {
  min-height: clamp(var(--s5), 7vh, var(--s7));
  display: grid;
  grid-template-columns: var(--door-rail) minmax(0, 1fr);
}
.door-margin::after {
  content: "";
  grid-column: 2;
  border-left: var(--rule-hair) solid var(--guide);
}

@media (max-width: 780px) {
  .door-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  /* One column, so there is no column rule left to run on. */
  .door-margin::after {
    display: none;
  }
  .door-rail {
    grid-column: 1;
    grid-row: 1;
    padding: 0 0 var(--s2);
  }
  .door-body {
    grid-column: 1;
    grid-row: 2;
    border-left: 0;
    padding-left: 0;
  }
}

@media (max-width: 560px) {
  .door-row {
    grid-template-columns: 2.5rem minmax(0, 1fr);
    row-gap: var(--s1);
  }
  .door-row__dest {
    grid-column: 2;
  }
}
