/* ═══════════════════════════════════════════════════════════════════════════
   K GUIDE — THE DESIGN SYSTEM

   One stylesheet, used by two consumers:

     the live site   kpress ships its own token layer; this file is linked
                     after it through site.head_extra_html in kpress.yml.
     the study       explorations/collapsible-home/ has no kpress, so it
                     carries a verbatim copy of kpress's tokens in its own
                     template and inlines this file after them at build time.

   So this file may use kpress tokens and must never redefine them. It adds
   three local scales — type roles, spacing, icon size — one topic-hue formula,
   and the components built from them. The prose account of every decision here
   is docs/project/editorial/design-system.md; keep the two in step.

   ── TYPE ────────────────────────────────────────────────────────────────────
   Five roles. Nothing uses a size outside them.

     role      size                        family  weight  used for
     display   clamp(1.75rem,4.5vw,2.3rem) serif   400     the page title, once
     title     1.2rem  (size-large)        serif   400     section and box titles
     body      1rem    (size-normal)       either  400/370 chrome text, chapter numbers
     label     (caps-label-size)           sans    550     uppercase marks
     meta      0.85rem (size-tiny)         sans    370     control labels, the footer

   Plus the deck, a description at two altitudes: --type-deck-card in a card or
   a section head, --type-deck-page for the guide's own description. A read time
   and the crisis notice take the card altitude too, so the three things read in
   one pass down the page are set together.

   Serif (PT Serif) is content: titles, standfirsts, prose. Sans (Source Sans)
   is interface: labels, controls, contents lists. Mono is code and keys only,
   never numbering.

   ── COLOR ───────────────────────────────────────────────────────────────────
   Ink is the default and carries every sentence. Muted is for METADATA ONLY:
   counts, read times, section numbers, control labels at rest, placeholders.
   If it is a sentence, it is ink. Hierarchy comes from size, family and weight,
   not from graying text down.

   Each section additionally owns one topic hue, which paints its mark and its
   rule and nothing else. Color marks identity, never state; state is the fill
   behind an open row and the direction of its chevron. The danger role is
   defined but paints nothing: the crisis notice is help, not an error, and
   takes the neutral.

   ── ICONS ───────────────────────────────────────────────────────────────────
   Two families, split by role. Interface affordances are Lucide, stroked,
   sized from --ui-icon-sm/md, taking currentColor. Content marks are Phosphor
   duotone, larger, two-tone, taking the topic hue.

   The guide's own mark is the one deliberate crossing: `topic-icon-book-bookmark`
   is Phosphor, and it is used both as the home page's mark and in the nav,
   where the family rule would otherwise call for a Lucide glyph. The guide is
   one thing and wears one mark, and a stroked outline at mark size reads thin
   beside seventeen duotone siblings. It is the only glyph that crosses; keep it
   that way. References gave up `book-bookmark` for `quotes` so that nothing
   else wears the guide's mark.

   One action always shows the same glyph:

     chevron-right               disclosure state, rotated when open
     chevron-up                  close this section
     unfold-vertical / fold-…    open / close every section
     arrow-right                 go to a section
     arrow-left                  back to the contents
     book-bookmark (Phosphor)    the guide itself, in the nav and on the home page
     search / x                  search / clear
     sun / moon                  light / dark

   ── CONTROLS ────────────────────────────────────────────────────────────────
   Every control is .ctl: glyph then label, at meta size, muted until hover.
   No control is ever bordered — a bordered button reads as a card, and the page
   already uses hairlines to bound cards and chapter bars. Hit area and a hover
   fill do the work. Three variants — .ctl-box (its own hit area), .ctl-quiet
   (bare, inline in prose), .ctl-icon (square, glyph only). There is no fourth.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1.1 Local scales ─────────────────────────────────────────────────────── */
:root {
  /* ── The type scale ──────────────────────────────────────────────────────
     One dial, and every role a stated ratio of it. Turning --type-base moves
     the whole page and keeps the relationships; before this each role held its
     own value or aliased a kpress token, so the ratios existed only in whoever
     had last looked. The multipliers are the scale, and they are the thing to
     argue about. */
  --type-base: var(--kpress-font-size-normal); /* 1rem, kpress's own body size */

  --type-meta: calc(var(--type-base) * 0.85); /* control labels, the footer */
  --type-eyebrow: calc(var(--type-base) * 0.95); /* a part's "Part One" */
  --type-body: var(--type-base); /* chrome text, chapter numbers */
  --type-deck-card: var(--type-base); /* a card's description, and its read time */
  --type-prose: calc(var(--type-base) * 1.125); /* the guide's reading size */
  --type-table: var(--type-prose); /* a table is reading matter, not fine print */
  --type-title: calc(var(--type-base) * 1.2); /* section and box titles */
  --type-deck-page: calc(var(--type-base) * 1.3); /* the guide's own description */
  /* The page title, once. It leads the page it opens without overpowering the
     section titles under it: at the base size it lands a little under twice
     body, where before it ran to 2.3rem against a 1.2rem section title. */
  --type-display: clamp(
    calc(var(--type-base) * 1.5),
    calc(var(--type-base) + 2.5vw),
    calc(var(--type-base) * 1.9)
  );

  /* Roles that sit outside the ratio because kpress owns their measurement:
     the caps device, the square bullet, the table face, and mono. Named so a
     rule still states its role rather than reaching past the scale. */
  --type-label: var(--kpress-caps-label-size);
  --type-bullet: var(--kpress-bullet-size);

  --type-mono: var(--kpress-font-size-mono);
  --type-mono-small: var(--kpress-font-size-mono-small);
  --type-mono-tiny: var(--kpress-font-size-mono-tiny);

  /* The info boxes — the crisis notice and the legal notice. They state their
     colours rather than deriving a tint from an accent, so "the notice's
     background" is one value to change rather than a formula to unpick. The
     ground is the page's own: white in light, near-black in dark, so a notice
     reads as a bounded area of the page rather than a panel laid on top of it. */
  --callout-bg: var(--kpress-doc-bg);
  /* The notice carries no edge: its mark and its indent are enough to bound it,
     and a hairline around a box already sitting on the page's own ground draws
     a second boundary where there is one thing. Kept as a transparent border
     rather than removed, so the box measures the same either way — set this to
     var(--kpress-doc-border) to bring the hairline back, and nothing shifts. */
  --callout-edge: transparent;
  --callout-mark: var(--kpress-doc-muted);
  --callout-text: var(--kpress-doc-text);
  --callout-leading: 1.45; /* the notice's line-height, named so the mark can align to it */

  /* The document layer keeps kpress's rhythm rather than the chrome's --ui-*
     steps. It is the reading surface, tuned to the prose measure and not to the
     interface, so it gets its own named scale instead of being bent onto one
     chosen for controls and cards. */
  --prose-space-heading: 2rem;
  --prose-space-subhead: 1.9rem;
  --prose-space-after-heading: 1rem;
  --prose-space-after-subhead: 0.7rem;
  --prose-pad-code: 0.05em 0.25em;
  --prose-pad-key: 0.05rem 0.3rem;
  /* Table cells take the interface scale: they are a grid, and at the reading
     size the old value left rows touching. */
  --prose-pad-cell: var(--ui-2) var(--ui-3);

  /* Spacing. Six steps; every margin, gap and pad in this layer uses one. */
  --ui-1: 0.35rem;
  --ui-2: 0.5rem;
  --ui-3: 0.75rem;
  --ui-4: 1rem;
  --ui-5: 1.75rem;
  --ui-6: 2.75rem;
  /* An optical correction, not a step on the scale. A line of caps carries no
     descenders and sits high in its box, so a caps line between a display line
     and a description reads as crowded above and loose below even when both
     margins are the same token. Measured ink to ink on the guide's title block,
     one 12px margin on each side gives 22px of space above the subtitle against
     24px below it. Added above a caps line and removed below it, so the space
     above ends up the larger of the two — which is what the eye wants here: the
     description is three lines of a larger face, and a block that size pulls the
     line above it down unless the gap under it is the tighter one. */
  --ui-optical-caps: 0.25rem;
  /* The contents rail and the space between it and the text. The rail hangs in
     the margin beside the reading column rather than displacing it, so these
     two are what the column needs free to its left before the rail can show at
     all: below that the one-page view drops the side rail and reads like every
     other page. */
  --ui-rail-width: 12rem;
  --ui-rail-gap: 2rem;
  --ui-rail-lane: calc(var(--ui-rail-width) + var(--ui-rail-gap));

  /* Icon sizes. sm/md are interface; lg/xl are content marks. */
  --ui-icon-sm: 14px;
  --ui-icon-md: 16px;
  --ui-icon-lg: 19px;
  --ui-icon-xl: 21px;
  --ui-icon-2xl: 28px; /* the guide's own mark, which stands for the whole thing */

  /* The gutter kpress pads the document by. Named because the document's cap
     has to account for it: see the .kpress-doc rule in k-guide-site.css. */
  --ui-doc-inset: 2rem;

  /* Description weight. Source Sans is a variable face, so this is a real axis
     position rather than a synthetic bolding: one 50-unit step above the light
     default. It applies to section descriptions and to nothing else — they are
     the only text the chrome wrote about the guide, and at light weight they
     read as faded body copy rather than as a deliberate voice. */
  --ui-weight-description: 420;

  /* Part-heading weight. Set on the variable axis a step under the bold sans
     used elsewhere: at large caps with tracking, 650 is heavier than a divider
     between runs needs, and the extra weight reads as emphasis rather than as
     structure. */
  --ui-weight-part: 560;
  /* Caps this large need more air between letters than the label device gives. */
  --ui-tracking-part: 0.06em;

  /* Motion. One role per kind of change, built on kpress's durations and its
     single easing, so anything that moves for the same reason moves alike.
     Every transition on this page names one of these; none states a raw
     duration. All are suppressed under prefers-reduced-motion. */
  --ui-motion-edge: var(--kpress-transition-fast);      /* color, border, opacity */
  --ui-motion-move: var(--kpress-transition-med);       /* transforms: rotate, nudge */
  --ui-motion-surface: var(--kpress-transition-slow);   /* tint and fill */
  --ui-motion-disclose: var(--kpress-transition-slow);  /* opening and closing */

  /* Topic tint. How strongly a surface carries its section's hue. Only cards
     and section bars are tinted; nothing else on the page takes topic color as
     a background. Kept faint on purpose — seventeen hues at any real strength
     stop reading as one family. */
  --ui-tint: 5%;
  --ui-tint-hover: 11%;
  --ui-tint-open: 17%;

  /* The matching edge. A card or bar is bounded by a darker step of its own
     hue, so the object reads as one colored thing rather than a tint inside a
     gray box. Anything not tied to a section keeps the neutral hairline. */
  --ui-edge: 30%;
  --ui-edge-strong: 55%;

  /* Corner radius. kpress treats rounded-vs-square as a deliberate per-surface
     choice and supplies --kpress-radius-none for square; this layer makes that
     one dial. Every corner in the chrome reads it, so the page squares or
     rounds as a whole rather than drifting surface by surface. */
  --ui-radius: var(--kpress-radius-none);

  /* Control metrics, matching kpress's TOC toggle and settings gear. */
  --ui-control-h: 28px;
  /* Neutral hairline: page chrome that belongs to no section. */
  --ui-rule: 1px solid var(--kpress-doc-border);

  /* Frame */
  --ui-masthead-h: 2.75rem;
  --ui-rail-h: 2.5rem;
  --ui-page-max: 62rem;
}

/* ── 1.2 Base ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--ui-masthead-h) + var(--ui-rail-h) + var(--ui-2));
}
body {
  background: var(--kpress-doc-bg);
  color: var(--kpress-doc-text);
  font-family: var(--kpress-font-body);
  font-size: var(--type-body);
  line-height: var(--kpress-line-height-normal);
  margin: 0;
  overflow-wrap: break-word;
}
.wrap { margin-inline: auto; max-width: var(--ui-page-max); padding-inline: var(--ui-4); }

/* The shell — masthead, rail, footer — is one width on every page, so the site
   does not resize around the reader as they move between them. Only the guide's
   own column is narrower: it is a reading column, so chapter rows, their
   headings and the prose inside them share the reading measure and centre
   inside the shell. */
.guide { margin-inline: auto; max-width: var(--kpress-measure); }

a { color: var(--kpress-doc-link); text-decoration: none; transition: color var(--ui-motion-edge); }
a:hover { color: var(--color-primary-light); text-decoration: underline; }

/* Interface glyph: stroked Lucide, taking the surrounding color. */
.ico { flex: none; height: var(--ui-icon-md); width: var(--ui-icon-md); }
.ico-sm { height: var(--ui-icon-sm); width: var(--ui-icon-sm); }

/* Content mark: Phosphor duotone, painted by the section's topic hue. */
.mark { color: var(--topic); flex: none; height: var(--ui-icon-lg); width: var(--ui-icon-lg); }

/* ── 1.3 The label device ─────────────────────────────────────────────────── */
/* kpress's TOC-title treatment: uppercase, letter-spaced sans over a hairline. */
.label {
  color: var(--kpress-doc-text);
  font-family: var(--kpress-font-sans);
  font-size: var(--type-label);
  font-variant-caps: var(--kpress-caps-variant);
  font-weight: var(--kpress-font-weight-sans-medium);
  letter-spacing: var(--kpress-caps-spacing);
  line-height: var(--kpress-caps-heading-line-height);
  margin: 0;
  text-transform: var(--kpress-caps-transform);
}

/* ── 1.4 Controls ─────────────────────────────────────────────────────────── */
/* One vocabulary. Icon then label, muted until hover, never a bare icon where a
   label would fit and never a label where the map already gives one. */
.ctl {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: var(--ui-radius);
  color: var(--kpress-doc-muted);
  cursor: pointer;
  display: inline-flex;
  font-family: var(--kpress-font-sans);
  font-size: var(--type-meta);
  font-variant-caps: var(--kpress-caps-variant);
  font-weight: var(--kpress-font-weight-sans-medium);
  gap: var(--ui-1);
  letter-spacing: var(--kpress-caps-spacing);
  line-height: 1;
  padding: 0;
  text-decoration: none;
  text-transform: var(--kpress-caps-transform);
  transition:
    color var(--ui-motion-edge),
    background-color var(--ui-motion-edge);
  white-space: nowrap;
}
.ctl:hover { color: var(--kpress-doc-text); text-decoration: none; }
.ctl:focus-visible { outline: 2px solid var(--kpress-doc-link); outline-offset: 2px; }
.ctl .ico { height: var(--ui-icon-sm); width: var(--ui-icon-sm); }

/* Standing on its own: the reading rail and the guide's open/close pair. A hit
   area and a hover fill, never a border. */
.ctl-box {
  min-height: var(--ui-control-h);
  padding-inline: var(--ui-2);
}
.ctl-box:hover { background-color: var(--kpress-doc-surface-hover); }

/* Bare: inline at the end of a section. */
.ctl-quiet { color: var(--kpress-doc-link); }
.ctl-quiet:hover { color: var(--color-primary-light); text-decoration: underline; }

/* Square, icon only: theme and clear-search, matching kpress's gear. */
.ctl-icon {
  height: var(--ui-control-h);
  justify-content: center;
  padding: 0;
  width: var(--ui-control-h);
}
.ctl-icon:hover { background-color: var(--kpress-doc-surface-hover); }
.ctl-icon .ico { height: var(--ui-icon-md); width: var(--ui-icon-md); }

/* Checkbox control, same metrics and tone as the rest. */

:root[data-kpress-resolved-theme="dark"] .theme-sun { display: none; }
:root:not([data-kpress-resolved-theme="dark"]) .theme-moon { display: none; }

/* ── 1.5 Page frame ───────────────────────────────────────────────────────── */
.masthead {
  background: var(--kpress-doc-surface-bg);
  border-bottom: var(--ui-rule);
  position: sticky; top: 0; z-index: 40;
}
.masthead .wrap { align-items: center; display: flex; gap: var(--ui-3); min-height: var(--ui-masthead-h); }
.brand {
  align-items: center; color: var(--kpress-doc-text); display: flex;
  font-family: var(--kpress-font-sans); font-weight: var(--kpress-font-weight-sans-bold);
  gap: var(--ui-2);
}
.brand:hover { color: var(--kpress-doc-text); text-decoration: none; }
.brand svg { display: block; }
.masthead nav { align-items: center; display: flex; gap: var(--ui-3); margin-left: auto; }
.study {
  border: var(--ui-rule); border-radius: var(--ui-radius);
  color: var(--kpress-doc-muted); font-family: var(--kpress-font-sans);
  font-size: var(--type-meta); letter-spacing: var(--kpress-caps-spacing);
  padding: 0.05rem var(--ui-1); text-transform: var(--kpress-caps-transform);
}

/* Reading rail: present from the moment the chapters begin, because it carries
   the control that acts on all of them. It names the chapter you are in when
   there is one, and holds just the control when there is not. */
.rail {
  background: var(--kpress-doc-bg);
  border-bottom: var(--ui-rule);
  opacity: 0; pointer-events: none;
  position: sticky; top: var(--ui-masthead-h); z-index: 39;
  transition: opacity var(--ui-motion-edge);
}
.rail.on { opacity: 1; pointer-events: auto; }
.rail .wrap { align-items: center; display: flex; gap: var(--ui-2); min-height: var(--ui-rail-h); }
.rail .now {
  align-items: baseline; color: var(--kpress-doc-muted); display: flex; gap: var(--ui-2);
  font-family: var(--kpress-font-sans); font-size: var(--type-meta);
  font-weight: var(--kpress-font-weight-sans-light);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rail .now .num { color: var(--topic); }
/* The chapter's own mark, a size down: the rail is a report, not a heading. */
.rail .now .mark { height: var(--ui-icon-sm); width: var(--ui-icon-sm); }
/* The rail is chrome, not content — it reports where you are rather than
   saying anything — so the chapter's name takes the sans like every other
   label, even though the same name is set in serif on the chapter itself. */
.rail .now b {
  color: var(--kpress-doc-text); font-family: var(--kpress-font-sans);
  font-weight: var(--kpress-font-weight-sans-medium);
}
.rail .spacer { margin-left: auto; }

/* Title */
/* Centred, like the part headings and chapter headings below it — the welcome
   page reads down one axis. */
.title-block { padding-block: var(--ui-6) 0; text-align: center; }
.title-block h1 {
  font-family: var(--kpress-font-prose);
  font-size: var(--type-display);
  font-weight: 400; line-height: 1.12; margin: 0 auto var(--ui-2);
  max-width: 26ch; text-wrap: balance;
}
/* DO NOT DELETE AS A DUPLICATE. This restates the inline centring one line
   above it on purpose, and the page depends on it.

   `.title-block h1` and kpress's `.kpress-prose h1` are both specificity 0-1-1,
   and kpress's stylesheets load after this one, so on that tie kpress wins and
   its `margin-inline: 0` takes over. The heading is capped at 26ch, so losing
   the auto margins does not just shift it slightly — it parks the whole title
   against the column's left edge while everything around it stays centred.
   `:root` buys the one step of specificity that settles it.

   Inline margins only, deliberately. The rule this replaced used the `margin`
   shorthand, which held the bottom margin too and so outranked anything that
   later tried to set the space below the heading — including the caps
   correction above. A rule that exists to win a tie should hold exactly the
   property it is there for and nothing else.

   See docs/development.md, "Rules that look redundant and are not".
   `make audit-layout` measures this: the title must sit on its column's centre
   in every view. */
:root .title-block h1 {
  margin-inline: auto;
}
/* The guide's own description, from its frontmatter. Same treatment as a
   chapter description — sans, description weight, centred — a size up, because
   it describes the whole guide rather than one chapter. Written out rather than
   stacked on .teaser, which would win on specificity and quietly render it at
   the card size. */
.standfirst {
  font-family: var(--kpress-font-sans); font-size: var(--type-deck-page);
  font-weight: var(--ui-weight-description); line-height: 1.4;
  margin: var(--ui-3) auto 0; max-width: 40ch; text-wrap: pretty;
}
/* The other half of the caps correction. Scoped to a description that actually
   follows a caps subtitle: a title with no subtitle has nothing to correct for.
   The heading's own bottom margin is dropped rather than left to collapse, so
   the gap is this one declaration and not the larger of two. */
h1:has(.title-sub) + .standfirst {
  margin-block-start: calc(var(--ui-3) - var(--ui-optical-caps));
}
.title-block h1:has(.title-sub) {
  margin-block-end: 0;
}

/* Callout — kpress's box vocabulary (.key-claims / .concepts): a gentle
   hairline, sans, one pad, and a mark. The crisis notice is the one thing on
   this page that is never collapsible. */
.callout {
  /* The mark sits on the first line of the text, not in the middle of the box.
     Centred, it drifts as the notice wraps to two lines or three, and on the
     wider ones it ends up beside the middle of a sentence rather than beside
     the start of the notice. */
  align-items: start;
  background: var(--callout-bg);
  border: 1px solid var(--callout-edge); border-radius: var(--ui-radius);
  color: var(--callout-text);
  display: flex; gap: var(--ui-3);
  font-family: var(--kpress-font-sans); font-size: var(--type-deck-card);
  /* Space below as well as above: in the document flow the notice is followed
     straight away by the first heading, and without it the two touch. The
     stacked notices on the home page set their own tighter rhythm and are
     unaffected. */
  line-height: var(--callout-leading); margin: var(--ui-5) 0; padding: var(--ui-4);
}
.callout .mark {
  color: var(--callout-mark);
  height: var(--ui-icon-xl);
  width: var(--ui-icon-xl);
  /* Optical, not geometric: the mark is taller than a line, so aligning their
     boxes leaves it sitting high. Half the difference between the mark and the
     line beside it brings the two centres together. The line is computed from
     the notice's own size and leading rather than from `1lh`, which inside the
     SVG resolves against the SVG's line-height and not the paragraph's. */
  margin-block-start: calc(
    (var(--type-deck-card) * var(--callout-leading) - var(--ui-icon-xl)) / 2
  );
}
.callout p,
.kpress-prose .callout p { margin: 0; }
.callout a { font-weight: var(--kpress-font-weight-sans-bold); text-decoration: underline; }


/* ── 1.6 Topic hue ────────────────────────────────────────────────────────── */
/* One hue per section, set inline as --topic-h. Lightness and chroma are fixed
   to the kpress accent in light and to the warm dark link in dark, so all
   seventeen carry the same weight and none of them shouts. */
.box, .sec, .rail .now, .title-block {
  --topic: oklch(51.09% 0.0861 var(--topic-h, 208));
  /* The hued hairline and its two colors. Every edge belonging to this section
     takes one of these; nothing else on the page may. */
  --accent: var(--topic);
}

/* A tinted surface. Anything that carries a color — a card, a section bar, the
   crisis callout — declares --accent and takes its fill and its edge from the
   same two dials, so a danger callout and a section card are one object in two
   colors. Nothing on the page mixes an accent by hand. */
.box, .sec, .view-switch {
  --accent-fill: color-mix(in srgb, var(--accent) var(--ui-tint), var(--kpress-doc-bg));
  --accent-fill-hover: color-mix(in srgb, var(--accent) var(--ui-tint-hover), var(--kpress-doc-bg));
  --accent-fill-open: color-mix(in srgb, var(--accent) var(--ui-tint-open), var(--kpress-doc-bg));
  --accent-edge: color-mix(in srgb, var(--accent) var(--ui-edge), var(--kpress-doc-bg));
  --accent-edge-strong: color-mix(in srgb, var(--accent) var(--ui-edge-strong), var(--kpress-doc-bg));
  --accent-rule: 1px solid var(--accent-edge);
}
/* The crisis notice takes the neutral, not the danger role. Red states that
   something has gone wrong — a failed action, an invalid field — and nothing
   has: the notice is help, standing ready on every page a reader starts from.
   It also has to hold above seventeen hued sections without competing with the
   one they came to open. The hairline and the mark carry it; see the
   --callout-* tokens above. */
:root[data-kpress-resolved-theme="dark"] .box,
:root[data-kpress-resolved-theme="dark"] .sec,
:root[data-kpress-resolved-theme="dark"] .rail .now,
:root[data-kpress-resolved-theme="dark"] .title-block { --topic: oklch(74.90% 0.07 var(--topic-h, 208)); }

/* ── 1.7 Part headings ────────────────────────────────────────────────────
   The guide is grouped into parts, and both views show the same grouping in the
   same words. The label and the name come from the document, so the study
   cannot disagree with the guide about its own shape. The guide also states a
   purpose under each part heading and the live site renders it; the board does
   not repeat it, because a contents page is for finding your way, not reading.

   Both take the caps device — the label small, the name large — so a part
   heading reads as a divider between runs rather than as another title
   competing with the chapter titles under it. Centred, and with no rule above:
   the space and the caps do the separating, and a rule here would be a third
   horizontal line in a page already ruled by cards and rows. */
.part-head { margin: 0; text-align: center; }
.part-label {
  color: var(--kpress-doc-muted); display: block;
  font-family: var(--kpress-font-sans); font-size: var(--type-eyebrow);
  font-variant-caps: var(--kpress-caps-variant); font-weight: var(--ui-weight-part);
  letter-spacing: var(--kpress-caps-spacing); line-height: var(--kpress-caps-heading-line-height);
  text-transform: var(--kpress-caps-transform);
}
.part-name {
  display: block;
  font-family: var(--kpress-font-sans); font-size: var(--type-title);
  font-variant-caps: var(--kpress-caps-variant); font-weight: var(--ui-weight-part);
  letter-spacing: var(--ui-tracking-part); line-height: var(--kpress-caps-heading-line-height);
  /* The gap under the eyebrow, stated on the component rather than left to the
     line box of whatever element carries it — an h1 and an h2 lead differently,
     and the two views were 6px apart because of it. */
  margin: var(--ui-1) 0 0; text-transform: var(--kpress-caps-transform);
}
.part-label {
  line-height: var(--kpress-caps-heading-line-height);
}

/* On the board a part heading introduces a grid of cards; in the guide it
   introduces a run of rows. Same heading, different amount of air. */
.part-head-board { margin-bottom: var(--ui-4); }
.part-head-guide { margin-bottom: var(--ui-4); }
.band + .band, .part-group + .part-group { margin-top: var(--ui-6); }

/* ── 1.8 Chapter heading ──────────────────────────────────────────────────
   A chapter announces itself the same way on a card and on a row: its mark
   centred on its own line, the number holding the left, the read time — and on
   a row the disclosure chevron — holding the right, and the title centred under
   all three.

   The track is 1fr / auto / 1fr, so the mark centres on the heading itself
   rather than on whatever the number and the meta happen to measure. */
.ch-head { display: block; width: 100%; }
/* Number and read time hold the corners on one shared baseline; the mark sits
   centred between them, having no baseline of its own. The 1fr / auto / 1fr
   track centres the mark on the heading rather than on whatever those two
   happen to measure. The title follows on its own line. */
.ch-row {
  align-items: baseline; display: grid; gap: var(--ui-2);
  grid-template-columns: 1fr auto 1fr;
}
.ch-row .num { justify-self: start; }
.ch-mark { align-self: center; display: flex; justify-self: center; }
.ch-meta {
  align-items: center; color: var(--kpress-doc-muted); display: flex; gap: var(--ui-2);
  font-family: var(--kpress-font-sans); font-size: var(--type-deck-card);
  font-variant-numeric: tabular-nums; font-weight: var(--ui-weight-description);
  justify-self: end; white-space: nowrap;
}
/* The title line mirrors the row above it, so the title centres on the same
   axis as the mark and the chevron lands under the read time. */
.ch-title-row {
  align-items: center; display: grid; gap: var(--ui-2);
  grid-template-columns: 1fr auto 1fr; margin-top: var(--ui-2);
}
.ch-tail { align-items: center; display: flex; }
.ch-tail:last-child { justify-content: flex-end; justify-self: end; }
.ch-title { text-align: center; text-wrap: balance; }

/* A whole page rendered straight from one markdown file — About. It reads at
   the document measure, centred, the same as a chapter body. */
.page {
  margin-inline: auto; max-width: var(--kpress-measure);
  padding-block: var(--ui-6) var(--ui-6);
}
.page > :first-child { margin-top: 0; }

/* ── 1.9 The board ────────────────────────────────────────────────────────── */
/* A contents page. Every box looks the same at rest: the board is navigation,
   not a mirror of what is open. */
.board { padding-block: var(--ui-5) 0; }

/* Cards stand apart now that each carries its own tint and hued edge; butted
   together they read as one ruled table instead of seventeen objects. */
.box-grid {
  display: grid; gap: var(--ui-3);
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); margin-top: var(--ui-4);
}
.box {
  background: var(--accent-fill);
  border: var(--accent-rule);
  border-radius: var(--ui-radius);
  color: inherit; cursor: pointer; display: flex; flex-direction: column; gap: var(--ui-1);
  font-family: var(--kpress-font-sans); font-size: var(--type-body);
  font-weight: var(--kpress-font-weight-sans-light); line-height: var(--kpress-line-height-normal);
  padding: var(--ui-3) var(--ui-4) var(--ui-2); text-align: left;
  transition:
    background-color var(--ui-motion-surface),
    border-color var(--ui-motion-edge);
}
.box:hover {
  background-color: var(--accent-fill-hover);
  border-color: var(--accent-edge-strong);
  color: inherit; text-decoration: none;
}
.box:focus-visible { outline: 2px solid var(--kpress-doc-link); outline-offset: -2px; }
.box[data-here="true"] { border-color: var(--accent-edge-strong); }

/* Section numbering, one treatment wherever a number appears: sans, tabular,
   in the section's topic hue, alongside that section's mark. */
.num {
  color: var(--topic); font-family: var(--kpress-font-sans); font-size: var(--type-body);
  font-variant-numeric: tabular-nums; font-weight: var(--kpress-font-weight-sans-medium);
  letter-spacing: var(--kpress-caps-spacing); line-height: 1;
}
.box-title {
  font-family: var(--kpress-font-prose); font-size: var(--type-title); font-weight: 400;
  line-height: var(--kpress-line-height-tight); text-wrap: balance;
}
/* Section description: the same treatment on the card and at the head of the
   open section, so the sentence a reader chose from is the sentence that greets
   them. */
.teaser {
  font-family: var(--kpress-font-sans); font-size: var(--type-deck-card);
  font-weight: var(--ui-weight-description); line-height: 1.45;
  text-align: center; text-wrap: pretty;
}
/* The section states its description in its head, closed and open alike, at the
   size and treatment the card uses. Two consequences worth naming: a reader
   scanning shut sections reads the same sentences the board shows, so the guide
   page is navigable without one; and the sentence is not
   repeated inside the body when the section opens, which is what the deck
   treatment here used to be for. It sits inside the toggle rather than under
   it, so the row that describes itself is the row you click — the card's
   arrangement exactly, minus its Read control, which here would link to the
   page you are already on. */
.sec-toggle .teaser { margin-inline: auto; max-width: 46ch; }
.box-subs {
  font-size: var(--type-body); line-height: 1.4;
  list-style: none; margin: var(--ui-2) 0 0; padding: 0;
}
.box-subs li { margin-block: 0.2rem; padding-left: var(--ui-3); position: relative; }
.box-subs li::before { content: "\25AA\FE0E"; font-size: var(--type-bullet); left: 0; position: absolute; top: -0.1rem; }
.box-subs li.more { color: var(--kpress-doc-muted); font-style: italic; }
.box-subs li.more::before { content: none; }
.box-foot {
  align-items: center; color: var(--kpress-doc-muted);
  display: flex; font-size: var(--type-meta); gap: var(--ui-2); justify-content: center;
  margin-top: auto; padding-top: var(--ui-3);
}
.box-go {
  align-items: center; color: var(--topic); display: flex; gap: var(--ui-2);
  font-size: var(--type-body);
  font-variant-caps: var(--kpress-caps-variant); font-weight: var(--kpress-font-weight-sans-medium);
  letter-spacing: var(--kpress-caps-spacing);
  text-transform: var(--kpress-caps-transform);
}
/* Out and back are one behaviour: the arrow leans the way it points. `Read →`
   on a card and `← Contents` at the end of a chapter are the same control
   pointing opposite ways, so they share the rule rather than repeat it. */
/* The Read control's arrow is the thing a reader is looking for, so it is not
   the smallest glyph on the card: at meta-size caps a 14px arrow reads as a
   tick rather than a direction. Sized from --ui-icon-md and centred optically
   on the caps beside it — caps have no descenders, so their visual middle sits
   above the line box's, and an arrow centred on the box looks low. */
.box-go .ico {
  height: var(--ui-icon-md);
  width: var(--ui-icon-md);
  margin-block-start: -0.09em;
}
.ctl-back .ico {
  height: var(--ui-icon-sm); width: var(--ui-icon-sm);
  transition: transform var(--ui-motion-move);
}
/* A nudge, not a shift. The mark travels the same 2px at the same speed as the
   transform it replaces, then comes back: a control that stays displaced while
   the pointer rests on it reads as having moved permanently, and the movement
   stops meaning "this goes somewhere". Out and back each take the transform
   duration, so the speed is what it was.

   --ui-motion-move carries an easing as well as a time, which the animation
   shorthand takes; alternate reverses it on the way back. */
@keyframes nudge-forward {
  to { transform: translateX(2px); }
}
@keyframes nudge-back {
  to { transform: translateX(-2px); }
}
.box:hover .box-go,
.sec-link:hover .box-go {
  animation: nudge-forward var(--ui-motion-move) alternate 2;
}
.ctl-back:hover .ico {
  animation: nudge-back var(--ui-motion-move) alternate 2;
}


/* ── 1.10 The guide ────────────────────────────────────────────────────────── */
.guide { margin-top: var(--ui-6); }
/* Title, tagline and crisis notice at the head of the guide page. Centred on
   the reading column rather than the shell: they introduce the chapters, so
   they share the chapters' width instead of spanning the board's. */
.guide-intro { margin-inline: auto; max-width: var(--kpress-measure); }
/* The guide heading carries the controls that act on the guide, so open and
   close sit with the thing they open and close rather than up in the board. */
.guide-actions { display: flex; gap: var(--ui-2); }


.sec + .sec { margin-top: var(--ui-2); }
.sec-head { font-size: inherit; font-weight: inherit; margin: 0; }
.sec-toggle {
  align-items: stretch; border: 0; flex-direction: column;
  background-color: var(--accent-fill);
  color: inherit; cursor: pointer; display: flex; gap: var(--ui-1);
  font-family: var(--kpress-font-sans); font-size: var(--type-body);
  font-weight: var(--kpress-font-weight-sans-light); line-height: var(--kpress-line-height-normal);
  border: var(--accent-rule); border-radius: var(--ui-radius);
  padding: var(--ui-3) var(--ui-4) var(--ui-2); text-align: left; width: 100%;
  transition: background-color var(--ui-motion-surface), border-color var(--ui-motion-edge);
}
.sec-toggle:hover {
  background-color: var(--accent-fill-hover);
  border-color: var(--accent-edge-strong);
}
.sec-toggle:focus-visible { outline: 2px solid var(--kpress-doc-link); outline-offset: -2px; }
.sec.open .sec-toggle {
  background-color: var(--accent-fill-open);
  border-color: var(--accent-edge-strong);
}
.sec-toggle .mark { align-self: center; }
.sec-title { font-family: var(--kpress-font-prose); font-size: var(--type-title); font-weight: 400; line-height: var(--kpress-line-height-tight); }
/* Disclosure state, the usual convention: pointing right is closed, pointing
   down is open. One glyph rotated a quarter turn rather than two glyphs swapped
   — swapping cannot animate, since `display` has nothing to interpolate. Set in
   the section's own hue pulled toward ink, so it sits darker than the meta
   around it and still belongs to the section. */
.ch-title-row .ch-tail:last-child {
  align-items: end;
  display: flex;
  justify-content: flex-end;
}
.sec-chevron {
  align-self: center; height: var(--ui-icon-lg); width: var(--ui-icon-lg);
  justify-self: end;    /* the row's end, under the read time above it */
  stroke-width: 2.75;   /* Lucide draws at 2; the disclosure mark earns more */
  color: color-mix(in srgb, var(--topic) 40%, var(--kpress-doc-text));
  /* Disclosure turns the mark with `rotate`, the individual transform property,
     and the hover hint below turns it with `transform`. The two compose rather
     than compete: sharing one property, the hint's animation overrode the
     disclosure's transition, so opening a row while pointing at it swung the
     mark to the hint's angle and back instead of turning it the quarter it
     was meant to. */
  rotate: 0deg;
  transition: rotate var(--ui-motion-move), color var(--ui-motion-edge);
}
.sec.open .sec-chevron { rotate: 90deg; }
/* A hint, on hover, and only while the section is shut: the mark turns
   twenty-five degrees toward open and comes back, saying the row is pressable
   and which way pressing it will turn. An open section has nothing to hint at
   — the mark is already where pressing would take it, and the reader can see
   the chapter — so it stays still.

   It animates `transform` while disclosure uses `rotate`, so the hint adds to
   whatever the disclosure holds instead of overriding it. */
@keyframes chevron-hint {
  to { transform: rotate(25deg); }
}
.sec:not(.open) .sec-toggle:hover .sec-chevron {
  animation: chevron-hint var(--ui-motion-move) alternate 2;
}

/* 0fr → 1fr animates the disclosure without measuring height in JS. */
.sec-wrap { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--ui-motion-disclose); }
.sec.open .sec-wrap { grid-template-rows: 1fr; }
.sec-clip { overflow: hidden; }
.sec-body {
  margin-inline: auto; max-width: var(--kpress-measure);
  padding: var(--ui-5) var(--ui-2) var(--ui-6);
}

/* Left-aligned: the arrow points back the way you came, and a control that
   leads left reads oddly parked in the middle. It also lands under the start of
   the prose it follows, on the same edge the reader has been returning to on
   every line. */
.sec-end {
  display: flex; justify-content: flex-start; margin-top: var(--ui-6); padding-top: 0;
}

/* ── 1.11 Document prose — kpress's .kpress-prose ──────────────────────────── */
.kpress-prose {
  font-family: var(--kpress-font-prose);
  font-size: var(--type-prose);
  line-height: var(--kpress-line-height-normal);
}
.kpress-prose > :first-child { margin-top: 0; }
.kpress-prose h1 {
  font-family: var(--kpress-font-prose);
  font-size: calc(var(--type-prose) * 1.7);
  font-weight: 400;
  margin: var(--prose-space-heading) 0 var(--prose-space-after-heading);
}
.kpress-prose h2 {
  font-family: var(--kpress-font-prose);
  font-size: calc(var(--type-prose) * 1.32);
  font-style: italic;
  font-weight: 400;
  margin: var(--prose-space-heading) 0 var(--prose-space-after-heading);
}
.kpress-prose h3 {
  font-family: var(--kpress-font-sans);
  font-size: calc(var(--type-prose) * 1.08 * var(--kpress-caps-heading-size-multiplier));
  font-variant-caps: var(--kpress-caps-variant);
  font-weight: var(--kpress-font-weight-sans-medium);
  letter-spacing: var(--kpress-caps-spacing);
  line-height: var(--kpress-caps-heading-line-height);
  margin: var(--prose-space-subhead) 0 var(--prose-space-after-subhead);
  text-transform: var(--kpress-caps-transform);
}
.kpress-prose h4 {
  font-family: var(--kpress-font-sans); font-size: calc(var(--type-prose) * 1.05); font-style: italic;
  font-weight: 540; letter-spacing: 0.015em; margin: var(--ui-4) 0 0.7rem;
}
.kpress-prose p { margin-block: 0.75rem; }
.kpress-prose ul { list-style-type: none; margin-bottom: 0.7rem; margin-left: 1.8rem; padding-left: 0; }
.kpress-prose li { margin-block-start: 0.7rem; position: relative; }
.kpress-prose li > p { margin-block-end: 0; }
.kpress-prose ul > li::before {
  content: "\25AA\FE0E"; font-size: var(--type-bullet);
  left: -0.85rem; position: absolute; top: 0.25rem;
}
.kpress-prose ol { list-style-type: decimal; margin-bottom: 0.7rem; margin-left: 1.8rem; padding-left: 0; }
.kpress-prose ol > li { padding-left: 0.25rem; }
.kpress-prose table {
  border: 1px solid var(--color-border-hint); border-collapse: collapse;
  font-family: var(--kpress-font-table); font-size: var(--type-table);
  line-height: 1.3; margin-block: var(--ui-5); width: 100%; word-break: break-word;
}
.kpress-prose th, .kpress-prose td { padding: var(--prose-pad-cell); text-align: start; vertical-align: top; }
.kpress-prose th {
  background-color: var(--color-bg-alt-solid); border-bottom: 1px solid var(--color-border-hint);
  font-size: var(--type-label); font-weight: var(--kpress-font-weight-sans-bold);
  letter-spacing: var(--kpress-caps-spacing); line-height: var(--kpress-caps-heading-line-height);
  text-align: center; text-transform: var(--kpress-caps-transform);
}
.kpress-prose tbody tr:nth-child(even) { background-color: var(--color-bg-alt-solid); }
.kpress-prose blockquote {
  border-left: 2px solid var(--kpress-doc-border); color: var(--kpress-doc-muted);
  margin-inline: 0; padding-left: var(--ui-4);
}
.kpress-prose code {
  background: var(--kpress-doc-code-bg); font-family: var(--kpress-font-mono);
  font-size: var(--type-mono); padding: var(--prose-pad-code);
}

/* Whatever the guide's preamble holds besides the crisis notice. Set quietly:
   the chapter view opens on its title and its chapters, not on a second
   paragraph of running prose. */
.guide-note {
  color: var(--kpress-doc-muted);
  font-family: var(--kpress-font-sans);
  font-size: var(--type-meta);
  margin-block: var(--ui-3) 0;
  text-align: center;
}

/* ── The chapter view inside kpress's document layer ──────────────────────
   The behavior builds the chapter view inside `.kpress-prose`, which is right
   for the chapter bodies — they are the document, and should keep the document
   layer's prose, lists and tables. It is wrong for the scaffolding around them:
   a `.sec-head` is a chapter bar, not a heading in an essay, and kpress's
   `.kpress-prose h2` (0-1-1) outranks a bare `.sec-head` (0-1-0), so the
   furniture was being styled as prose — italic part names, essay margins
   between boxes, a title whose auto centring had been zeroed.

   Restated here at the scaffolding's own scope. Only the furniture: nothing
   below reaches inside `.sec-body`. */
.guide .sec-head,
.guide .part-head {
  font-style: normal;
  margin: 0;
}
.guide .part-head { text-align: center; }
.guide .part-head-guide { margin-block-end: var(--ui-3); }
/* The purpose the guide states under each part. Centred under its heading and
   set in the interface face, so it reads as part of the divider rather than as
   the first paragraph of the first chapter. */
.guide .part-intro {
  color: var(--kpress-doc-muted);
  font-family: var(--kpress-font-sans);
  font-size: var(--type-deck-card);
  margin: 0 auto var(--ui-4);
  max-width: 46ch;
  text-align: center;
  text-wrap: pretty;
}
.guide .part-name,
.guide .part-label { font-style: normal; }
/* The guide's title in three parts: the name in the display face, the subtitle
   in caps beneath it the way a part heading sets its name, and the description
   after that in the interface face, lowercase. The same shape wherever the
   guide introduces itself — the home page's box, the chapter view, the one-page
   view — with only the sizes changing.

   The caps line borrows the part heading's treatment rather than restating it,
   so the two stay in step. */
.title-name,
.title-sub {
  display: block;
}
.title-sub {
  font-family: var(--kpress-font-sans);
  font-size: var(--type-title);
  font-variant-caps: var(--kpress-caps-variant);
  font-weight: var(--ui-weight-part);
  letter-spacing: var(--ui-tracking-part);
  line-height: var(--kpress-caps-heading-line-height);
  /* The gap the description takes below, plus the caps correction. */
  margin-block-start: calc(var(--ui-3) + var(--ui-optical-caps));
  text-transform: var(--kpress-caps-transform);
}
/* In the home page's box the whole thing sits a size down, since the box is a
   card rather than a page opening. */
.sec-link .title-sub {
  font-size: var(--type-deck-card);
}

/* The guide's mark, centred over its title. A step larger than a chapter's,
   because it stands for the whole guide rather than one part of it — the same
   size in the home page's box and at the head of the chapter view, so the two
   openings weigh the same. */
.title-mark {
  display: flex;
  justify-content: center;
  margin-block-end: var(--ui-3);
}
.title-mark .mark,
.sec-link .ch-mark .mark {
  height: var(--ui-icon-2xl);
  width: var(--ui-icon-2xl);
}
/* The title block carries its own top padding for the study's welcome page,
   where it opens the page directly. Here the document layer above it already
   pads twice — the surface and the card — and the three stack into a band of
   dead space above the mark. */
.guide .title-block { padding-block-start: 0; }
/* The title and its description take the shared treatment unchanged. They were
   restated here once, value for value, which changed nothing on the page but
   outranked the shared rules — so the caps correction above, written once for
   every place the guide names itself, silently did not reach this one. */
.guide .guide-intro { margin-block-end: var(--ui-6); }
.guide .callout { text-align: start; }

/* The view switch: one line offering the same document read the other way.
   Built from the callout's parts — the same hairline, fill and radius — but a
   single row at control scale, because it is an offer rather than a notice and
   should not carry a notice's weight. The arrow is .sec-go, the mark the
   system already assigns to going somewhere. */
/* Above the title it needs no top margin of its own — the intro's own spacing
   is the gap — and a little room beneath it before the title begins. */
.guide-intro > .view-switch:first-child {
  margin-block: 0 var(--ui-6);
}
.view-switch {
  align-items: center;
  background: var(--accent-fill);
  border: var(--accent-rule);
  border-radius: var(--ui-radius);
  color: var(--kpress-doc-text);
  display: flex;
  font-family: var(--kpress-font-sans);
  font-size: var(--type-deck-card); /* a section's description size: it is a sentence */
  gap: var(--ui-2);
  justify-content: center;
  margin-block: var(--ui-5) 0;
  padding: var(--ui-2) var(--ui-4);
  text-decoration: none;
  transition: background-color var(--ui-motion-surface), border-color var(--ui-motion-edge);
}
.kpress .view-switch,
.kpress .view-switch:visited,
.kpress .view-switch:hover {
  color: var(--kpress-doc-text);
  text-decoration: none;
}
.view-switch {
  --accent: var(--kpress-doc-muted);
}
.view-switch:hover {
  background-color: var(--accent-fill-hover);
  border-color: var(--accent-edge-strong);
}
.view-switch:hover .sec-go {
  animation: nudge-forward var(--ui-motion-move) alternate 2;
}
/* The print offer is the same object as a button: it performs an action rather
   than going somewhere, so it needs the resets a <button> does and the cursor
   that says it is pressable. */
button.view-switch {
  cursor: pointer;
  font: inherit;
  font-family: var(--kpress-font-sans);
  font-size: var(--type-deck-card);
  width: 100%;
}
.view-switch:focus-visible {
  outline: 2px solid var(--kpress-doc-link);
  outline-offset: 2px;
}

/* ── 1.12 The overview ────────────────────────────────────────────────────
   The home page: the guide's own description, the crisis notice, and one way
   in. It states nothing the guide does not state about itself, so there is no
   second summary to keep in step.

   The call to action is .ctl .ctl-box carrying arrow-right — the control and
   the glyph the system already assigns to "go to a section". A page with one
   action does not need a fourth control variant to point at it; the space
   around it is what makes it the thing you reach for. */
.overview { margin-inline: auto; max-width: var(--kpress-measure); text-align: center; }
/* The way in comes first, then the two notices, stacked close to each other and
   set well below the box. The gap says they are a different kind of thing: the
   box is what the page is for, and the notices are what you should know before
   you follow it. */
.overview .callout { margin-block: var(--ui-3) 0; text-align: start; }
.overview .sec-link + .callout { margin-block-start: var(--ui-6); }

/* The home page is the guide page's language with one box instead of
   seventeen. It is a link rather than a disclosure — there is nothing to
   disclose, only somewhere to go — so it borrows .sec's surface and .sec-toggle's
   arrangement and swaps the chevron for the arrow the system already assigns to
   "go to a section". Hover deepens the same tint a chapter's does. */
/* The box is a link, but it reads as a card: ink, not link colour, or the
   title and description would look like a run of link text. Stated rather than
   inherited, and scoped past kpress's own `.kpress a`. */
.kpress .overview a.sec-link,
.kpress .overview a.sec-link:visited,
.kpress .overview a.sec-link:hover {
  color: var(--kpress-doc-text);
  display: block;
  text-decoration: none;
}
.sec-link .sec-toggle { display: flex; flex-direction: column; }
.sec-link:hover .sec-toggle {
  background-color: var(--accent-fill-hover);
  border-color: var(--accent-edge-strong);
}
/* Going somewhere, not disclosing something: the arrow the system already
   assigns to "go to a section", nudged on hover the way the card's is. It does
   not borrow .sec-chevron, whose stroke weight and hue mean "open or closed". */
.sec-go { color: var(--kpress-doc-muted); transition: transform var(--ui-motion-move); }
.view-switch:hover .sec-go { transform: translateX(2px); }

.overview-note {
  color: var(--kpress-doc-muted);
  font-family: var(--kpress-font-sans);
  font-size: var(--type-meta);
  line-height: var(--kpress-line-height-normal);
  margin-block: 0;
  text-wrap: pretty;
}

/* ── 1.12 Colophon ────────────────────────────────────────────────────────── */
.foot {
  border-top: var(--ui-rule); color: var(--kpress-doc-muted);
  font-family: var(--kpress-font-sans); font-size: var(--type-meta);
  font-weight: var(--kpress-font-weight-sans-light);
  margin-top: var(--ui-6); padding-block: var(--ui-4) var(--ui-6);
}
.foot p { margin: var(--ui-1) 0; max-width: 68ch; }
.foot code { font-family: var(--kpress-font-mono); font-size: var(--type-mono-small); }
.foot kbd {
  background: var(--kpress-doc-surface-bg); border: var(--ui-rule); border-radius: var(--ui-radius);
  font-family: var(--kpress-font-mono); font-size: var(--type-mono-tiny); padding: var(--prose-pad-key);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; }
}
