/* GENERATED from app/paper.css by scripts/sync-paper.mjs — edit the source, not this copy. */

/* paper.css — the document language, and its token layer.
 *
 * THE SOURCE OF TRUTH for every Ctrl surface. This file is served at /static/paper.css
 * (scripts/sync-paper.mjs copies it into public/ on `pnpm dev` and `pnpm build`; run
 * `pnpm sync:css` by hand after editing while a dev server is already up). It lives in app/
 * because it is design, not asset: the homepage and studio sessions inherit these tokens
 * rather than reinvent them.
 *
 * THE GENRE (PROMPT-D1): an authoritative typeset document — academic offprint, field manual,
 * a page from a beautifully set standards book. Confidence comes from typography and space,
 * never from decoration. No gradients, no shadows, no icons, no cards-for-everything, no
 * animation (the copy-success live region is the only state that changes, and it changes in
 * words). Corners are square: a document has edges, not bevels.
 *
 * THE TWO VOICES:
 *   serif — Source Serif 4, the document voice: title, prose, rules. Variable roman
 *           (wght 400–600, opsz 14–60, so large sizes get true display cuts) + static italic.
 *   mono  — IBM Plex Mono, the machine voice: hashes, versions, IDs, labels, the wordmark.
 * Both self-hosted under /static/fonts/ (§13 forbids external fetches), latin subset,
 * ~116 KB total, font-display: swap with metric-matched local fallbacks so the swap does
 * not shift the page (the overrides below are computed from the font files, not guessed).
 *
 * THE COLOR LAW: colour files, never decorates. The document is ink on paper; the one
 * accent (--mark) is a filing mark for state labels — a withdrawn notice, an erratum — and
 * nothing else. A link is an underline. Meaning is never carried by colour alone.
 *
 * NO ANIMATION: no transition, transform or keyframe anywhere in this file, which is how
 * the reduced-motion contract (§16.1) is met — there is no motion to reduce.
 *
 * Dark mode is deliberately deferred: the document is paper (recorded in NOTES-D1).
 */

/* ── fonts ─────────────────────────────────────────────────────────────────── */

@font-face {
  font-family: "Source Serif 4";
  src: url("/static/fonts/source-serif-4-roman.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Source Serif 4";
  src: url("/static/fonts/source-serif-4-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("/static/fonts/ibm-plex-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("/static/fonts/ibm-plex-mono-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* Metric-matched fallbacks: Georgia and Courier New sized to the webfonts' widths, so the
 * font-display swap reflows nothing it does not have to. Values computed from the fonts. */
@font-face {
  font-family: "Source Serif 4 Fallback";
  src: local("Georgia");
  size-adjust: 101.68%;
  ascent-override: 101.89%;
  descent-override: 32.95%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "IBM Plex Mono Fallback";
  src: local("Courier New");
  size-adjust: 99.98%;
  ascent-override: 102.52%;
  descent-override: 27.5%;
  line-gap-override: 0%;
}

/* ── tokens ────────────────────────────────────────────────────────────────── */

:root {
  color-scheme: light;

  /* ink and paper — the whole palette. --mark is the single filing accent (state labels
   * only: withdrawn, erratum). Contrast on --paper: ink 15.9:1, ink-2 7.6:1, ink-3 5.2:1
   * (AA at every size), mark 7.0:1. */
  --paper: #f5f1e8;
  --paper-2: #ece7d9;
  --paper-sheet: #faf7ef; /* one step brighter: a page laid ON the desk (the specimen) */
  --ink: #1a1712;
  --ink-2: #514c42;
  --ink-3: #6b6455;
  --line: rgba(26, 23, 18, 0.16);
  --mark: #7a3325;

  /* voices — serif carries the document, mono carries the machine facts. --sans remains
   * only for owner-surface form controls, where the platform face is the honest one. */
  --serif: "Source Serif 4", "Source Serif 4 Fallback", Georgia, serif;
  --mono:
    "IBM Plex Mono", "IBM Plex Mono Fallback", ui-monospace, Menlo, monospace;
  --sans:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  /* the serif scale — deliberate jumps, not a smooth ramp. Body is 17px; the display step
   * is fluid because a title must be the largest thing on any screen by a clear margin. */
  --text-display: clamp(2.375rem, 1.55rem + 3.4vw, 3.5rem);
  --text-xxl: 2.0625rem; /* the rule numerals, the handle title */
  --text-xl: 1.625rem;
  --text-l: 1.3125rem; /* the summary, rule titles */
  --text-m: 1.0625rem; /* body */
  --text-s: 0.9375rem; /* secondary prose: rationale, notes, the site foot */

  /* the mono scale — machine facts sit small and precise. */
  --mono-m: 0.8125rem; /* the colophon ledger, code */
  --mono-s: 0.75rem; /* identity lines, meta */
  --mono-xs: 0.6875rem; /* micro labels over content */

  /* space — a scale with real jumps, so hierarchy can be made of distance. */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1.25rem;
  --sp-5: 2rem;
  --sp-6: 3rem;
  --sp-7: 4.5rem;

  /* rules — the lines a document is built from. Hairline for filing, strong for the main
   * matter, double for cautions. Used as borders, weights stated here for the record. */
  --rule-hair: 1px solid var(--line);
  --rule-strong: 2px solid var(--ink);
  --rule-double: 3px double var(--ink);

  /* measure and frame — 35rem ≈ 66–70 characters of Source Serif at body size. The rail
   * appears at 1100px (media queries cannot read tokens; keep this number in sync with the
   * two @media (min-width: 1100px) blocks below). */
  --measure: 35rem;
  --rail-w: 15.5rem;
  --rail-gap: 4rem;
  --gutter: clamp(1.25rem, 5vw, 2.5rem);
}

/* ── base ──────────────────────────────────────────────────────────────────── */

*,
*::before,
*::after {
  box-sizing: border-box;
  /* The zero-animation law, enforced rather than assumed (PRACTICE-BUILD §9.4): the CSS
   * initial value of transition-property is `all` (inert only while durations stay 0s),
   * which reads as a violation-in-waiting in computed styles. State `none` explicitly.
   * If a state ever earns a transition (the ruling names only copy-success), it must
   * opt in locally — nothing inherits motion by default. */
  transition: none;
}

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 var(--text-m) / 1.68 var(--serif);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Long URLs and hashes wrap rather than pushing the page sideways (§16.1). */
a,
code,
dd {
  overflow-wrap: anywhere;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.16em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1rem;
  z-index: 2;
}

.skip:focus {
  left: 0;
}

/* A micro label: the mono voice naming what follows. The one uppercase treatment. */
.label,
.part > h2,
.rationale-label,
.example-label,
.colophon h2,
.colophon h3,
.actions h2 {
  font-family: var(--mono);
  font-size: var(--mono-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ── the frame: masthead and rail ──────────────────────────────────────────── */

/* One document, two framings. Below 1100px the masthead is one quiet line of chrome above
 * the manuscript. From 1100px the same DOM becomes a margin rail: the masthead's content —
 * brand, byline, identity, the Use affordance — stands in the left margin, sticky, while
 * the manuscript keeps its measure. Content order never changes; only where it stands. */

.masthead {
  border-bottom: var(--rule-hair);
  padding: var(--sp-4) var(--gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-4);
}

.masthead p {
  margin: 0;
}

/* The wordmark: Ctrl, set in the machine voice — the key the brand is named for.
 * §9.5 — a mark, not a label: one step up from the mono meta scale, wider tracked. */
.brand a {
  font-family: var(--mono);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  word-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
}

.brand a:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

.byline {
  font-size: var(--text-s);
  color: var(--ink-2);
}

.identity {
  font-family: var(--mono);
  font-size: var(--mono-s);
  letter-spacing: 0.02em;
  color: var(--ink-3);
  margin-left: auto;
}

.identity a {
  color: inherit;
}

.id-seal {
  text-decoration: none;
}

.id-seal:hover {
  text-decoration: underline;
}

.id-seal code {
  background: none;
  padding: 0;
  font-size: inherit;
}

.use-affordance {
  flex-basis: 100%;
  margin: var(--sp-2) 0 0;
  font-family: var(--mono);
  font-size: var(--mono-s);
  letter-spacing: 0.02em;
  color: var(--ink-3);
}

.use-affordance a {
  color: var(--ink-2);
}

.use-affordance .use-copy {
  color: var(--ink);
  font-weight: 600;
}

/* Below the margin-rail breakpoint the public masthead is letterhead, not a toolbar. The
 * document keeps its author beside the imprint; machine identity and all actions remain in the
 * document itself. Handle pages need only the imprint because the handle is already the h1. */
@media (max-width: 1099px) {
  body.doc-practice .masthead {
    flex-wrap: nowrap;
    align-items: flex-start;
  }

  body.doc-practice .masthead .byline {
    min-width: 0;
    margin-left: auto;
    max-width: 62%;
    line-height: 1.45;
    text-align: right;
  }

  body.doc-practice .identity,
  body.doc-practice .use-affordance,
  body.doc-handle .identity {
    display: none;
  }
}

/* ── the desk: the genre for the owner surfaces (PROMPT-D4) ─────────────────── */

/* The desk masthead: the wordmark and a quiet mono nav, one hairline beneath. Like the public
   masthead but operational — Studio · Library · @handle · Sign out. Wraps under the mark on
   mobile, exactly as the document masthead collapses. */
.desk-masthead {
  border-bottom: var(--rule-hair);
  padding: var(--sp-4) var(--gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-4);
}

.desk-masthead p {
  margin: 0;
}

.desk-nav {
  font-family: var(--mono);
  font-size: var(--mono-s);
  letter-spacing: 0.02em;
  color: var(--ink-3);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2);
}

.desk-nav a {
  color: var(--ink-2);
  text-decoration: none;
}

.desk-nav a:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

.desk-sep {
  color: var(--ink-3);
}

/* Sign-out is a one-button form (a server action), set to read as one more nav item. */
.desk-signout {
  display: inline;
  margin: 0;
}

.desk-signout button {
  font: inherit;
  letter-spacing: inherit;
  color: var(--ink-2);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.desk-signout button:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

/* The sign-in claim — one italic line of what an account is for. */
.sign-in-claim {
  color: var(--ink-2);
  font-style: italic;
  margin: 0 0 var(--sp-4);
}

/* A button that reads as an inline text link (the "use a different address" reset). */
.linklike {
  font: inherit;
  color: var(--ink-1);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

main {
  padding: 0 var(--gutter);
}

.practice {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--sp-6) 0 var(--sp-7);
}

/* The wide framing. Keep 1100px in sync with the token comment above. */
@media (min-width: 1100px) {
  /* §9.1 — the spread is centered: equal flexible margins either side of the used block
   * (rail + gap + manuscript), so 1440 and 1920 both read as a deliberately placed plate. */
  body.doc {
    display: grid;
    grid-template-columns:
      minmax(var(--gutter), 1fr) var(--rail-w) var(--rail-gap)
      var(--measure) minmax(var(--gutter), 1fr);
    grid-template-rows: auto auto;
  }

  body.doc > .masthead {
    grid-column: 2;
    grid-row: 1;
    align-self: start;
    position: sticky;
    top: 0;
    display: block;
    border-bottom: none;
    padding: var(--sp-6) 0 var(--sp-4);
  }

  body.doc > main {
    grid-column: 4;
    grid-row: 1;
    padding: 0;
  }

  body.doc > .site-foot {
    grid-column: 2 / 5;
    grid-row: 2;
    padding-left: 0;
    padding-right: 0;
  }

  /* The rail stacks; the identity facts become a small ledger. */
  body.doc .byline {
    margin-top: var(--sp-5);
    max-width: 14rem;
  }

  body.doc .identity {
    margin: var(--sp-3) 0 0;
    display: block;
  }

  body.doc .identity > span,
  body.doc .identity > a {
    display: block;
    margin: 0 0 var(--sp-1);
  }

  body.doc .identity > .sep {
    display: none;
  }

  body.doc .use-affordance {
    margin-top: var(--sp-4);
    border-top: var(--rule-hair);
    padding-top: var(--sp-3);
  }

  body.doc .use-affordance > a {
    display: inline-block;
    margin: 0 var(--sp-2) var(--sp-1) 0;
  }

  body.doc .use-affordance > .sep {
    display: none;
  }

  /* The title top-aligns with the wordmark: one hairline datum across both columns. */
  body.doc .practice {
    padding-top: var(--sp-6);
  }
}

/* ── the document ──────────────────────────────────────────────────────────── */

h1 {
  font-size: var(--text-display);
  line-height: 1.08;
  letter-spacing: -0.014em;
  font-weight: 560;
  font-variation-settings: "opsz" 42;
  margin: 0 0 var(--sp-4);
  text-wrap: balance;
}

.summary {
  font-size: var(--text-l);
  line-height: 1.45;
  font-style: italic;
  color: var(--ink-2);
  margin: 0 0 var(--sp-4);
  text-wrap: pretty;
}

.part {
  margin-top: var(--sp-6);
}

.part > h2 {
  border-top: var(--rule-hair);
  padding-top: var(--sp-3);
  margin: 0 0 var(--sp-4);
  color: var(--ink);
}

.part-gloss {
  font-family: var(--serif);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  font-size: var(--text-s);
  color: var(--ink-3);
}

.part p {
  margin: 0 0 var(--sp-4);
}

.gloss {
  color: var(--ink-3);
  font-size: var(--text-s);
}

/* ── the preface: use when · the failure · the outcome ─────────────────────── */

/* Trigger, Failure and Objective read as one abstract: three labelled clauses in a single
 * block, bounded by hairlines, the text a step quieter than the rules that follow. The DOM
 * stays three sections in §5.1 order; the unification is typographic. */

.preface {
  margin: 0;
  border-top: var(--rule-hair);
  padding: var(--sp-3) 0;
}

.preface-first {
  margin-top: var(--sp-6);
}

.preface-last {
  border-bottom: var(--rule-hair);
}

.preface > h2 {
  border-top: none;
  padding-top: 0;
  margin: 0 0 var(--sp-1);
  color: var(--ink-3);
}

.preface p,
.preface .conditions > li {
  font-size: 1rem;
  line-height: 1.6;
  margin: 0;
}

.preface .conditions > li + li {
  margin-top: var(--sp-1);
}

@media (min-width: 700px) {
  .preface {
    display: grid;
    grid-template-columns: 8.5rem 1fr;
    column-gap: var(--sp-4);
  }

  .preface > h2 {
    margin: 0;
    padding-top: 0.2em; /* optical: align the cap-height of an 11px label to 16px text */
  }
}

/* ── the rules: the heart of the document ──────────────────────────────────── */

.part-rules {
  margin-top: var(--sp-7);
}

.part-rules > h2 {
  border-top: var(--rule-strong);
  padding-top: var(--sp-3);
}

.rules {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: rule;
}

.rules > li {
  counter-increment: rule;
  position: relative;
  margin: 0 0 var(--sp-6);
}

.rules > li > h3 {
  font-size: var(--text-l);
  font-weight: 600;
  line-height: 1.3;
  margin: 0 0 var(--sp-3);
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
}

/* The numeral: display-cut serif at roughly twice the title's optical size, in the lighter
 * ink (§9.2) — it carries the document's rhythm without shouting, and a reader who skims
 * only numerals and titles must still receive the method. */
.rules > li > h3::before {
  content: counter(rule);
  font-size: 2.75rem;
  font-weight: 400;
  line-height: 1;
  font-variation-settings: "opsz" 60;
  color: var(--ink-3);
  flex: none;
  min-width: 1.75rem;
}

.rule-body > :first-child {
  margin-top: 0;
}

.rule-body > :last-child {
  margin-bottom: 0;
}

.rationale {
  color: var(--ink-2);
  font-size: var(--text-s);
  margin: var(--sp-3) 0 0;
}

.rationale-label {
  color: var(--ink-3);
  margin-right: var(--sp-1);
}

/* On wide screens the numerals hang in the margin: titles and body share one left edge,
 * and the numbers stand outside it, the way a standards book files its clauses. */
@media (min-width: 1100px) {
  body.doc .rules > li > h3::before {
    position: absolute;
    right: calc(100% + 1.25rem);
    top: -0.75rem;
    min-width: 0;
  }

  body.doc .rationale {
    padding-left: var(--sp-4);
    border-left: var(--rule-hair);
  }
}

/* ── limits and verify ─────────────────────────────────────────────────────── */

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

.conditions > li {
  margin: 0 0 var(--sp-3);
}

/* Limits are cautions: a double rule above the section, a doubled bar on each clause.
 * Typography carries the warning — no icon, no colour. */
.part-limits > h2 {
  border-top: var(--rule-double);
}

.part-limits .conditions > li {
  border-left: var(--rule-double);
  padding-left: var(--sp-4);
}

/* Verify is a checklist, and looks like one: an unfilled box before each check. */
.part-verify .conditions > li {
  display: grid;
  grid-template-columns: 1.5rem 1fr;
}

.part-verify .conditions > li::before {
  content: "";
  width: 0.72em;
  height: 0.72em;
  border: 1.5px solid var(--ink);
  margin-top: 0.34em;
}

/* ── prose inside a body ───────────────────────────────────────────────────── */

blockquote {
  margin: var(--sp-4) 0;
  padding-left: var(--sp-4);
  border-left: 2px solid var(--line);
  color: var(--ink-2);
}

code {
  font-family: var(--mono);
  font-size: 0.82em;
  background: var(--paper-2);
  padding: 0.1em 0.3em;
}

/* §16.1 — code blocks scroll horizontally without breaking the page. */
pre {
  margin: var(--sp-4) 0;
  padding: var(--sp-3) var(--sp-4);
  background: var(--paper-2);
  border: var(--rule-hair);
  overflow-x: auto;
}

pre code {
  background: none;
  padding: 0;
  font-size: var(--mono-m);
  line-height: 1.55;
  white-space: pre;
}

/* ── examples and resources: present, quiet ────────────────────────────────── */

.example {
  margin: 0 0 var(--sp-5);
}

.example + .example {
  border-top: var(--rule-hair);
  padding-top: var(--sp-4);
}

.example > h3 {
  font-size: var(--text-m);
  font-weight: 600;
  margin: 0 0 var(--sp-3);
}

.example > h3 > p {
  margin: 0;
}

.example-part {
  margin: 0 0 var(--sp-3);
}

.example-label {
  color: var(--ink-3);
  margin: 0 0 var(--sp-1);
}

.example-part > p,
.example-note > p {
  margin: 0;
}

.example-note {
  color: var(--ink-2);
  font-size: var(--text-s);
}

.resources {
  margin: 0;
  padding-left: var(--sp-4);
}

.resources > li {
  margin-bottom: var(--sp-2);
}

.resource-note {
  color: var(--ink-3);
  font-size: var(--text-s);
}

/* ── the colophon: the seal at the end of the document ─────────────────────── */

/* Version, date, hash, licence, credits, lineage — set as a formal ledger in the machine
 * voice: small, precise, dignified. The content hash is the jewel: the visible mark that
 * this object is sealed. It ends the document; it interrupts nothing. */

.colophon {
  margin-top: var(--sp-7);
  border-top: var(--rule-strong);
  padding-top: var(--sp-4);
  scroll-margin-top: var(--sp-4);
}

.colophon h2 {
  margin: 0 0 var(--sp-4);
}

.colophon h3 {
  margin: var(--sp-5) 0 var(--sp-3);
  color: var(--ink-3);
}

.colophon dl {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--mono-m);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}

.colophon dl > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--sp-3);
  padding: var(--sp-2) 0;
  border-top: var(--rule-hair);
}

.colophon dl > div:first-child {
  border-top: none;
}

.colophon dt {
  flex: 0 0 7.5rem;
  color: var(--ink-3);
}

.colophon dd {
  margin: 0;
  flex: 1 1 12rem;
}

.colophon .seal code {
  color: var(--ink);
  font-weight: 600;
  letter-spacing: 0.01em;
}

.colophon code {
  background: none;
  padding: 0;
  font-size: inherit;
}

.credits,
.lineage {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--mono);
  font-size: var(--mono-m);
  color: var(--ink-2);
}

.credits > li,
.lineage > li {
  padding: var(--sp-1) 0;
}

.lineage > li {
  border-left: var(--rule-hair);
  padding-left: var(--sp-4);
  margin-bottom: var(--sp-3);
}

.lineage .credits {
  margin-top: var(--sp-1);
}

.role {
  font-family: var(--mono);
  font-size: var(--mono-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  display: inline-block;
  min-width: 6.5rem;
}

.pin {
  margin: var(--sp-1) 0 0;
}

.pin code {
  background: none;
  padding: 0;
  font-size: var(--mono-s);
  color: var(--ink-3);
}

/* ── the actions (§5.1 ninth; the two copy gestures live in the wide rail) ── */

.actions {
  max-width: var(--measure);
  margin: 0 auto;
  border-top: var(--rule-hair);
  padding: var(--sp-5) 0 var(--sp-6);
}

.actions h2 {
  margin: 0 0 var(--sp-2);
  color: var(--ink);
}

.actions .gloss {
  margin: 0 0 var(--sp-4);
}

.action-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

.action-row > button,
.action-row > .action {
  font-family: var(--mono);
  font-size: var(--mono-s);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--ink);
  /* 44px tall — a comfortable target without a decorated one (WCAG 2.2). */
  padding: 0.9375rem 1.125rem;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}

.action-row > button {
  background: var(--ink);
  color: var(--paper);
}

.action-row > button:hover {
  background: var(--ink-2);
  border-color: var(--ink-2);
}

.action-row > .action:hover {
  background: var(--paper-2);
}

/* On a public Practice only the link-first gesture is filled. The complete-text fallback remains
 * a full-size target but outlined, so two useful choices do not become an undifferentiated wall. */
.actions .action-row > .action-secondary {
  background: transparent;
  color: var(--ink);
}

.actions .action-row > .action-secondary:hover {
  background: var(--paper-2);
  border-color: var(--ink);
}

/* Downloads and adaptation are references, not more buttons. They retain the whole §5.1.9
 * surface and every no-JS path while reading like a compact line in a document. */
.action-links {
  margin: var(--sp-4) 0 0;
  font-family: var(--mono);
  font-size: var(--mono-s);
  line-height: 1.8;
  color: var(--ink-3);
}

.action-links a {
  color: var(--ink-2);
}

/* The one caption that explains the copy pair (STRATEGY §1): full text is universal, the
   link works when the AI can browse. Sits directly under the action row. */
.use-hint {
  font-size: var(--text-s);
  color: var(--ink-3);
  margin: var(--sp-3) 0 0;
  max-width: 46ch;
}

/* The invocation line: the ratified link-first gesture, printed on the page. It teaches the
   move, it is the clipboard source the "Copy link for AI" controls read, and with JavaScript
   off it is the fallback the reader selects by hand. A framed mono block, wrapping (never a
   sideways scroll on a phone); the label is the mono microlabel above it. */
.invocation-label {
  margin: var(--sp-5) 0 var(--sp-2);
  color: var(--ink-3);
}

.invocation {
  display: block;
  font-family: var(--mono);
  font-size: var(--mono-m);
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper-2);
  border: var(--rule-hair);
  border-left: var(--rule-strong);
  padding: var(--sp-3) var(--sp-4);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  user-select: all; /* one tap/drag selects the whole line for the no-JS copy */
}

/* ── the handle page: a contents page of the same book ─────────────────────── */

.handle-page h1 {
  font-size: var(--text-xxl);
  font-variation-settings: "opsz" 36;
}

/* The handle in the machine voice, beside the display name (§9.3). */
.handle-at {
  font-family: var(--mono);
  font-size: var(--mono-m);
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--ink-3);
}

/* §5.4 / 0047 P4 — the proof line, in the colophon voice: a quiet, dated fact. Never a badge. */
.handle-proofs {
  font-family: var(--mono);
  font-size: var(--mono-s);
  color: var(--ink-2);
  margin: 0 0 var(--sp-4);
}

.handle-proofs-label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-3);
}

.handle-proofs a {
  color: var(--ink-1);
}

.handle-proof-meta {
  color: var(--ink-3);
}

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

.manifest > li {
  padding: var(--sp-4) 0 var(--sp-4);
}

.manifest > li + li {
  border-top: var(--rule-hair);
}

.toc-line {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-2);
}

.toc-line > h3 {
  font-size: var(--text-l);
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
}

/* The contents-page leader: a dotted line carrying the eye from title to number. */
.toc-leader {
  flex: 1 0 2rem;
  border-bottom: 1px dotted var(--ink-3);
  align-self: baseline;
  min-height: 1px;
  margin-bottom: 0.28em;
}

.toc-ref {
  font-family: var(--mono);
  font-size: var(--mono-s);
  color: var(--ink-3);
  white-space: nowrap;
}

.manifest-summary {
  color: var(--ink-2);
  margin: 0 0 var(--sp-2);
}

.manifest-meta {
  font-family: var(--mono);
  font-size: var(--mono-s);
  color: var(--ink-3);
  margin: 0;
}

/* §5 — the owner-private observations table: a small mono ledger, no chart theatre. */
.obs {
  font-family: var(--mono);
  font-size: var(--mono-s);
  border-collapse: collapse;
  margin: var(--sp-2) 0 0;
}

.obs th,
.obs td {
  text-align: left;
  padding: var(--sp-1) var(--sp-4) var(--sp-1) 0;
  border-bottom: var(--rule-hair);
  font-weight: 400;
}

.obs th {
  color: var(--ink-2);
}

.obs td {
  color: var(--ink-1);
}

.obs-detail {
  color: var(--ink-3);
}

/* ── the homepage: the title page (its own genre — cover, not document) ────── */

/* A centered axis and deliberate emptiness — the whitespace is the authority (PROMPT-D3).
   No rail, no header bar: six quiet movements down the middle of the page. */
.title-page {
  text-align: center;
}

.cover {
  max-width: 46rem;
  margin: 0 auto;
  padding: var(--sp-6) var(--gutter);
}

/* 1 — the mark, small and alone, with air above and below. */
.cover-mark {
  margin: 0 0 var(--sp-7);
}

.cover-mark a {
  font-family: var(--mono);
  font-size: var(--mono-m);
  font-weight: 600;
  letter-spacing: 0.24em;
  word-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
}

.cover-mark a:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
}

/* 2 — the claim: the title of the book, the largest thing on the page. */
.cover-claim {
  font-size: var(--text-display);
  line-height: 1.14;
  letter-spacing: -0.012em;
  font-weight: 480;
  font-variation-settings: "opsz" 44;
  /* D3 taste note (PROMPT-05 §7): a wider measure so the claim settles into three to four
     lines on a large screen, not five. text-wrap: balance keeps the ragged edge even. */
  max-width: 30ch;
  margin: 0 auto var(--sp-4);
  text-wrap: balance;
}

.cover-sub {
  font-size: var(--text-l);
  font-style: italic;
  color: var(--ink-2);
  max-width: 32rem;
  margin: 0 auto var(--sp-6);
  text-wrap: pretty;
}

/* 3 — the plate: the live first Practice, tipped in. A centered framed object; its inside is
   the document language, left-aligned, four-fifths scale. */
.plate {
  margin: 0 0 var(--sp-5);
}

.plate-frame {
  text-align: left;
  max-width: 34rem;
  margin: 0 auto;
  border: 1px solid var(--line);
  background: var(--paper-sheet);
  padding: var(--sp-5);
}

.plate-caption {
  margin: var(--sp-3) 0 0;
  font-family: var(--mono);
  font-size: var(--mono-s);
  color: var(--ink-3);
}

.plate-caption a {
  color: var(--ink-2);
}

/* 4 — the gesture: the ratified link-first flow, taught by showing the line. */
.gesture {
  margin: 0 0 var(--sp-7);
}

.gesture > .label {
  margin: 0 0 var(--sp-4);
  color: var(--ink-3);
}

.gesture-steps {
  list-style: none;
  margin: 0 auto var(--sp-5);
  padding: 0;
  max-width: 34rem;
  text-align: left;
}

.gesture-steps > li {
  margin: 0 0 var(--sp-3);
  line-height: 1.6;
}

.gesture-steps > li:last-child {
  margin-bottom: 0;
}

/* The invocation line and its copy control, a left-aligned block centered on the axis.
   The .invocation and .status rules are shared with the Practice page's actions. */
.gesture-line {
  max-width: 34rem;
  margin: 0 auto;
  text-align: left;
}

.gesture-line .invocation {
  margin: 0 0 var(--sp-3);
}

.gesture-line .status {
  margin: var(--sp-2) 0 0;
}

/* 5 — the covenant seal: the standing promises, centered like a colophon. */
.cover-covenant {
  margin: 0 0 var(--sp-5);
}

.cover-covenant > .label {
  margin: 0 0 var(--sp-4);
  color: var(--ink-3);
}

.cover-covenant .covenant-lines {
  max-width: 40rem;
  margin: 0 auto;
}

.cover-covenant .covenant-lines > li {
  border-top: none;
  padding: var(--sp-1) 0;
}

/* The specimen internals, shared by the plate. Everything inside is the document language
   at four-fifths scale. */
.specimen-byline {
  font-size: var(--text-s);
  color: var(--ink-2);
  margin: 0;
}

.specimen-identity {
  font-family: var(--mono);
  font-size: var(--mono-s);
  letter-spacing: 0.02em;
  color: var(--ink-3);
  margin: 0 0 var(--sp-4);
}

.specimen-title {
  font-size: var(--text-xl);
  font-weight: 600;
  font-variation-settings: "opsz" 32;
  line-height: 1.2;
  margin: 0 0 var(--sp-2);
  text-wrap: balance;
}

.specimen-summary {
  font-style: italic;
  color: var(--ink-2);
  margin: 0 0 var(--sp-4);
}

.specimen-preface {
  margin: 0 0 var(--sp-4);
}

.specimen-preface > div {
  padding: var(--sp-2) 0;
  border-top: var(--rule-hair);
}

.specimen-preface dt {
  color: var(--ink-3);
  margin: 0 0 var(--sp-1);
}

.specimen-preface dd {
  margin: 0;
  font-size: var(--text-s);
  line-height: 1.55;
}

@media (min-width: 700px) {
  .specimen-preface > div {
    display: grid;
    grid-template-columns: 7rem 1fr;
    column-gap: var(--sp-4);
  }

  .specimen-preface dt {
    margin: 0;
    padding-top: 0.2em;
  }
}

.specimen-rule-title {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-2);
}

.specimen-rule-title strong {
  font-size: var(--text-m);
  font-weight: 600;
}

.specimen-num {
  font-size: 1.875rem;
  font-weight: 400;
  line-height: 1;
  font-variation-settings: "opsz" 60;
  color: var(--ink-3);
  flex: none;
}

.specimen-rule-body {
  font-size: var(--text-s);
}

.specimen-rule-body > :first-child {
  margin-top: 0;
}

/* The covenant lines: standing promises in the mono voice. */
.covenant-lines {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--mono);
  font-size: var(--mono-m);
  color: var(--ink-2);
}

.covenant-lines > li {
  padding: var(--sp-2) 0;
}

/* 6 — the two doors, centered at the foot of the axis. */
.doors {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-3);
}

.door {
  font-family: var(--mono);
  font-size: var(--mono-s);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--ink);
  border: 1px solid var(--ink);
  padding: 0.9375rem 1.125rem;
  text-decoration: none;
  display: inline-block;
}

.door:hover {
  background: var(--paper-2);
}

.door-primary {
  background: var(--ink);
  color: var(--paper);
}

.door-primary:hover {
  background: var(--ink-2);
  border-color: var(--ink-2);
}

/* ── the foot, and the miss states ─────────────────────────────────────────── */

.site-foot {
  border-top: var(--rule-hair);
  padding: var(--sp-4) var(--gutter) var(--sp-6);
}

.site-foot p {
  max-width: var(--measure);
  margin: 0 auto;
  font-size: var(--text-s);
  line-height: 1.6;
  color: var(--ink-3);
}

body.doc .site-foot p {
  margin: 0;
}

.miss p {
  color: var(--ink-2);
  margin: 0 0 var(--sp-4);
}

/* A state label is the one thing the filing mark exists for. */
.state-label {
  color: var(--mark);
  margin: 0 0 var(--sp-3);
}

.status-code {
  font-family: var(--mono);
  font-size: var(--mono-s);
  color: var(--ink-3);
  margin-top: var(--sp-5);
}

/* ── print: a Practice on A4 is a document worth handing over ──────────────── */

@media print {
  @page {
    margin: 20mm;
  }

  :root {
    --paper: #ffffff;
    --paper-2: #ffffff;
  }

  body,
  body.doc {
    display: block;
    font-size: 10.5pt;
    line-height: 1.55;
  }

  /* Chrome leaves; the document stays. The masthead becomes a letterhead line. */
  .skip,
  .use-affordance,
  .actions,
  .site-foot {
    display: none;
  }

  .masthead {
    position: static;
    display: flex;
    padding: 0 0 var(--sp-3);
    border-bottom: var(--rule-strong);
  }

  main {
    padding: 0;
  }

  .practice {
    max-width: none;
    padding: var(--sp-5) 0 0;
  }

  h1 {
    font-size: 26pt;
  }

  .rules > li,
  .preface,
  .example,
  .colophon dl > div {
    break-inside: avoid;
  }

  .part-rules > h2,
  .colophon {
    break-before: auto;
  }

  a {
    text-decoration: none;
  }

  /* The paper reader still gets the machine addresses: print the licence and resource
   * destinations after their link text. Internal anchors stay quiet. */
  .resources a[href]::after,
  .colophon a[href^="https://"]::after {
    content: " (" attr(href) ")";
    font-family: var(--mono);
    font-size: 8pt;
    color: var(--ink-3);
  }

  pre {
    border: var(--rule-hair);
    overflow: hidden;
    white-space: pre-wrap;
  }
}

/* ── owner surfaces (studio, adapt): the same tokens, the platform's controls ─ */

.studio-form,
.editor .field {
  margin: 0 0 var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  max-width: var(--measure);
}

.studio-form label,
.editor .field > label {
  font-family: var(--mono);
  font-size: var(--mono-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}

input,
textarea,
select {
  font: 1rem/1.5 var(--sans);
  color: var(--ink);
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 0.55rem 0.7rem;
  width: 100%;
}

textarea {
  resize: vertical;
}

input:focus,
textarea:focus,
select:focus {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
}

button {
  font-family: var(--mono);
  font-size: var(--mono-s);
  font-weight: 600;
  letter-spacing: 0.06em;
  line-height: 1;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--ink);
  border-radius: 0;
  padding: 0.7rem 1rem;
  cursor: pointer;
  align-self: flex-start;
}

button:hover:not(:disabled) {
  background: var(--paper-2);
}

button.solid {
  background: var(--ink);
  color: var(--paper);
}

button.solid:hover:not(:disabled) {
  background: var(--ink-2);
  border-color: var(--ink-2);
}

button.quiet {
  border-color: var(--line);
  color: var(--ink-2);
}

button.deny {
  border-color: var(--line);
  color: var(--mark);
}

button.mini {
  padding: 0.4rem 0.6rem;
  font-size: var(--mono-xs);
}

button:disabled {
  opacity: 0.45;
  cursor: default;
}

.hint {
  font-size: var(--mono-s);
  font-family: var(--mono);
  color: var(--ink-3);
}

.err {
  color: var(--mark);
  font-size: var(--text-s);
}

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

.okline {
  font-family: var(--mono);
  font-size: var(--mono-s);
  color: #177a4c;
}

.handle-input {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}

.handle-prefix {
  font-family: var(--mono);
  font-size: var(--text-s);
  color: var(--ink-3);
  white-space: nowrap;
}

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

.row > .grow {
  flex: 1 1 12rem;
}

.row > select,
.row > input:not(.grow) {
  width: auto;
  flex: 0 1 auto;
}

.instruction-row {
  border: var(--rule-hair);
  padding: var(--sp-3);
  margin-bottom: var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.editor-actions {
  display: flex;
  gap: var(--sp-3);
  align-items: center;
  flex-wrap: wrap;
  margin-top: var(--sp-4);
}

/* §2.3 — the editor's section labels, in the machine small-caps voice, mirroring the document's own
   section order so writing a Practice visually rehearses reading one. A hairline over each. */
.section-label {
  font-family: var(--mono);
  font-size: var(--mono-s);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: var(--sp-6) 0 var(--sp-3);
  padding-top: var(--sp-3);
  border-top: var(--rule-hair);
}

.section-label:first-of-type {
  margin-top: var(--sp-4);
}

.ceremony {
  border: var(--rule-strong);
  padding: var(--sp-5) var(--sp-4) var(--sp-4);
}

.diff ul,
.version-list {
  list-style: none;
  padding: 0;
  font-size: var(--text-s);
}

.diff-changed {
  color: var(--ink);
  font-weight: 600;
}

.diff-same {
  color: var(--ink-3);
}

.preview-tabs {
  display: flex;
  gap: 0.4rem;
  margin: var(--sp-4) 0 var(--sp-2);
}

.preview-body {
  max-height: 24rem;
  overflow: auto;
  font-size: var(--mono-s);
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

/* §2.4 — the rendered document, embedded: the real page about to be published, on paper. */
.preview-frame {
  width: 100%;
  height: 26rem;
  border: var(--rule-hair);
  background: var(--paper);
}

/* §7.3 — the irrevocability statement, weighted like the legal line it is: bordered, deliberate. */
.legal-line {
  border-left: 3px solid var(--ink-2);
  padding: var(--sp-2) 0 var(--sp-2) var(--sp-3);
  margin: var(--sp-4) 0;
  font-size: var(--text-s);
  line-height: 1.5;
  color: var(--ink);
}

.confirms {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  margin: var(--sp-4) 0;
  font-size: var(--text-s);
}

.confirms label {
  display: flex;
  gap: var(--sp-2);
  align-items: flex-start;
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--serif);
  color: var(--ink);
}

.confirms input {
  width: auto;
  margin-top: 0.2rem;
  flex: none;
}

.version-list code {
  font-size: var(--mono-xs);
}

/* ── the library (§11.3) and the adoption acceptance screen ────────────────── */

.adopt-facts,
.colophon-dl {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--mono-m);
  color: var(--ink-2);
}

.adopt-facts > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--sp-3);
  padding: var(--sp-2) 0;
  border-top: var(--rule-hair);
}

.adopt-facts > div:first-child {
  border-top: none;
}

.adopt-facts dt {
  flex: 0 0 7.5rem;
  margin: 0;
  color: var(--ink-3);
}

.adopt-facts dd {
  margin: 0;
  flex: 1 1 12rem;
}

.adopt-facts code {
  background: none;
  padding: 0;
  font-size: inherit;
}

.library-row {
  border-top: var(--rule-strong);
}

/* An update the library detected — flagged, never a nag; the mark files the state (COLOR LAW). */
.update-available {
  border: var(--rule-hair);
  border-left: var(--rule-strong);
  padding: var(--sp-4);
  margin: var(--sp-4) 0;
}

.update-available > .state-label {
  color: var(--mark);
  margin: 0 0 var(--sp-2);
}

.diff-list {
  list-style: none;
  margin: 0 0 var(--sp-3);
  padding: 0;
  font-family: var(--mono);
  font-size: var(--mono-s);
}

.diff-list > li {
  padding: var(--sp-1) 0;
}

.withdrawn-note {
  border-left: var(--rule-double);
  padding-left: var(--sp-4);
  margin: var(--sp-4) 0;
}

.deliver {
  margin: var(--sp-4) 0;
}

.deliver .invocation {
  margin: 0;
}

.library-actions {
  margin-top: var(--sp-4);
  align-items: center;
}

.detach {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

/* the spec field table — a definition list that reads as a reference */
.spec-fields {
  margin: 0;
  font-size: var(--text-s);
}

.spec-fields > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 1rem;
  padding: 0.55rem 0;
  border-bottom: var(--rule-hair);
}

.spec-fields dt {
  flex: 0 0 12rem;
  margin: 0;
}

.spec-fields dd {
  flex: 1 1 14rem;
  margin: 0;
  color: var(--ink-2);
}
