/* Colophon project site — single stylesheet, no external assets. */

/* ------------------------------------------------------------------ tokens */

:root {
  color-scheme: light dark;

  --font-sans:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
  --font-serif:
    "Iowan Old Style", "Palatino Linotype", Palatino, Palladio, Georgia,
    "Times New Roman", serif;
  --font-mono:
    ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono",
    monospace;

  /* Complete light palette. Dark mode overrides only these values. */
  --bg: #fbfaf7;
  --bg-alt: #f2f0ea;
  --surface: #ffffff;
  --fg: #1a1c1a;
  --fg-muted: #575a55;
  --fg-faint: #6b6e68;
  --border: #e1ded4;
  --border-strong: #c9c5b8;
  --accent: #0d5d54;
  --accent-strong: #0a463f;
  --accent-bg: #e2efec;
  --warn-fg: #7a5200;
  --warn-bg: #fbf2df;
  --warn-border: #e6d2a6;
  --shadow: 0 1px 2px rgba(26, 28, 26, 0.05), 0 8px 24px rgba(26, 28, 26, 0.04);

  /* The terminal panel is deliberately dark in both themes; both values are
     defined here so it never borrows a colour from the host page. */
  --term-bg: #141817;
  --term-border: #29302e;
  --term-fg: #d5dad4;
  --term-dim: #868d86;
  --term-prompt: #6ad1bb;
  --term-key: #f2f1ea;

  /* Diagram tokens resolve through the palette above, so inline SVG follows
     the theme without a second set of overrides. */
  --diag-node: var(--surface);
  --diag-node-alt: var(--bg-alt);
  --diag-stroke: var(--border-strong);
  --diag-ink: var(--fg-faint);
  --diag-accent: var(--accent);
  --diag-accent-bg: var(--accent-bg);
}

/* The dark palette is applied from two places and the values are written
   once, as --dark-* on :root, so the two cannot drift apart. Each block below
   only remaps; neither carries a colour of its own.

   Two blocks are needed because they answer different questions. The media
   query handles "the reader has no preference here, follow the system" — and
   excludes an explicit light choice, so choosing light on a dark OS sticks.
   The attribute rule handles "the reader chose dark", which must win whatever
   the system says. */

:root {
  --dark-bg: #101312;
  --dark-bg-alt: #171b19;
  --dark-surface: #181c1a;
  --dark-fg: #e8e8e2;
  --dark-fg-muted: #a4a8a2;
  --dark-fg-faint: #82867f;
  --dark-border: #282d2b;
  --dark-border-strong: #3c423f;
  --dark-accent: #63d0bb;
  --dark-accent-strong: #85dcca;
  --dark-accent-bg: #12302b;
  --dark-warn-fg: #e5ba6b;
  --dark-warn-bg: #262014;
  --dark-warn-border: #46391f;
  --dark-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.25);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: var(--dark-bg);
    --bg-alt: var(--dark-bg-alt);
    --surface: var(--dark-surface);
    --fg: var(--dark-fg);
    --fg-muted: var(--dark-fg-muted);
    --fg-faint: var(--dark-fg-faint);
    --border: var(--dark-border);
    --border-strong: var(--dark-border-strong);
    --accent: var(--dark-accent);
    --accent-strong: var(--dark-accent-strong);
    --accent-bg: var(--dark-accent-bg);
    --warn-fg: var(--dark-warn-fg);
    --warn-bg: var(--dark-warn-bg);
    --warn-border: var(--dark-warn-border);
    --shadow: var(--dark-shadow);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: var(--dark-bg);
  --bg-alt: var(--dark-bg-alt);
  --surface: var(--dark-surface);
  --fg: var(--dark-fg);
  --fg-muted: var(--dark-fg-muted);
  --fg-faint: var(--dark-fg-faint);
  --border: var(--dark-border);
  --border-strong: var(--dark-border-strong);
  --accent: var(--dark-accent);
  --accent-strong: var(--dark-accent-strong);
  --accent-bg: var(--dark-accent-bg);
  --warn-fg: var(--dark-warn-fg);
  --warn-bg: var(--dark-warn-bg);
  --warn-border: var(--dark-warn-border);
  --shadow: var(--dark-shadow);
}

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

/* ------------------------------------------------------------------- base */

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

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

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.65;
  font-feature-settings: "kern" 1;
  text-rendering: optimizeLegibility;
}

a {
  color: var(--accent-strong);
  text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent);
  text-underline-offset: 3px;
}

a:hover {
  text-decoration-color: currentColor;
}

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

/* The header is sticky, so anchored targets need room to clear it. */
[id] {
  scroll-margin-top: 5rem;
}

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 3rem 0;
}

code,
kbd,
samp,
pre {
  font-family: var(--font-mono);
}

/* Element-level resets live here, above every class rule, so that later
   component styles never have to out-specify them. */
p,
ul,
ol {
  margin: 0;
}

ul,
ol {
  padding-left: 1.3rem;
}

li + li {
  margin-top: 0.35rem;
}

li::marker {
  color: var(--fg-faint);
}

strong {
  font-weight: 650;
}

::selection {
  background: var(--accent-bg);
  color: var(--fg);
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--surface);
  color: var(--fg);
  padding: 0.75rem 1.25rem;
  border: 1px solid var(--border-strong);
  border-radius: 0 0 6px 0;
}

.skip:focus {
  left: 0;
}

.shell {
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px;
}

/* ----------------------------------------------------------------- header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(150%) blur(10px);
  border-bottom: 1px solid var(--border);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 60px;
  flex-wrap: wrap;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--fg);
  text-decoration: none;
  flex: none;
}

.brand svg {
  width: 20px;
  height: 20px;
  color: var(--accent);
}

.site-nav {
  margin-left: auto;
  overflow-x: auto;
  scrollbar-width: thin;
  max-width: 100%;
}

.site-nav ul {
  display: flex;
  /* Centre rather than the flex default of stretch: `overflow-x: auto` below
     makes the nav a little taller than its content, and a stretched item
     would grow into that space. */
  align-items: center;
  gap: 0.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The prose rule `li + li { margin-top }` is global and was reaching the nav,
   pushing every item except the first down by a third of a line. It read as
   "the current page's item is misaligned" only because the current item is
   the first one on the home page — on any other page the first item is the
   odd one out instead. */
.site-nav li {
  margin: 0;
}

.site-nav a {
  display: block;
  white-space: nowrap;
  padding: 0.35rem 0.7rem;
  border-radius: 5px;
  font-size: 0.9rem;
  color: var(--fg-muted);
  text-decoration: none;
}

.site-nav a:hover {
  background: var(--bg-alt);
  color: var(--fg);
}

.site-nav a[aria-current="page"] {
  color: var(--accent-strong);
  background: var(--accent-bg);
  font-weight: 600;
}

/* ------------------------------------------------- header controls */

/* The repository link and the theme toggle are the same shape: a 34px square
   sitting at the end of the header. Sharing the rule rather than copying it
   is what keeps them the same after the next change to either. */
.theme-toggle,
.repo-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: transparent;
  color: var(--fg-muted);
  cursor: pointer;
}

.theme-toggle:hover,
.repo-link:hover {
  background: var(--bg-alt);
  color: var(--fg);
  border-color: var(--border-strong);
}

.theme-toggle:focus-visible,
.repo-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.theme-toggle svg {
  width: 17px;
  height: 17px;
  display: none;
}

/* An anchor, not a button, so it inherits link decoration that the shared
   rule above does not clear. */
.repo-link {
  text-decoration: none;
}

.repo-link svg {
  width: 18px;
  height: 18px;
}

/* Which glyph shows follows the same three-way logic as the palette, so the
   button always reports the state actually in effect rather than the last
   one clicked. */
.theme-toggle .icon-system {
  display: block;
}

:root[data-theme="light"] .theme-toggle .icon-system,
:root[data-theme="dark"] .theme-toggle .icon-system {
  display: none;
}

:root[data-theme="light"] .theme-toggle .icon-light {
  display: block;
}

:root[data-theme="dark"] .theme-toggle .icon-dark {
  display: block;
}

/* ------------------------------------------------------------- doc layout */

main {
  display: block;
}

.doc {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  padding: 3rem 0 5rem;
}

.doc > * {
  max-width: 70ch;
  min-width: 0;
}

.doc > .bleed {
  max-width: none;
}

.doc > * + * {
  margin-top: 1.15rem;
}

.section {
  max-width: none;
  margin-top: 4rem;
}

.section > * {
  max-width: 70ch;
  min-width: 0;
}

.section > .bleed {
  max-width: none;
}

.section > * + * {
  margin-top: 1.15rem;
}

/* ------------------------------------------------------------- typography */

h1,
h2,
h3,
h4 {
  line-height: 1.2;
  letter-spacing: -0.02em;
  font-weight: 640;
  margin: 0;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.1rem, 1.4rem + 2.8vw, 3.1rem);
}

h2 {
  font-size: clamp(1.5rem, 1.2rem + 1.1vw, 1.95rem);
}

h3 {
  font-size: 1.18rem;
}

h4 {
  font-size: 1rem;
  letter-spacing: 0;
}

/* Sub-headings need more air above them than the flow rhythm gives, and must
   out-specify `.section > * + *` to get it. */
.doc > h3,
.section > h3 {
  margin-top: 2.25rem;
}

.doc > h4,
.section > h4 {
  margin-top: 1.75rem;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-strong);
  margin-bottom: 0.5rem;
}

.lead {
  font-family: var(--font-serif);
  font-size: clamp(1.15rem, 1.05rem + 0.5vw, 1.4rem);
  line-height: 1.55;
  color: var(--fg);
  max-width: 60ch;
}

.muted {
  color: var(--fg-muted);
}

.small {
  font-size: 0.9rem;
}

.epigraph {
  border-left: 2px solid var(--border-strong);
  padding-left: 1.25rem;
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--fg-muted);
  max-width: 56ch;
}

.dek {
  color: var(--fg-muted);
  font-size: 1.05rem;
}

/* ------------------------------------------------------------------ notes */

.note {
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  background: var(--bg-alt);
  border-radius: 0 8px 8px 0;
  padding: 1rem 1.25rem;
  font-size: 0.95rem;
  color: var(--fg-muted);
}

.note strong {
  color: var(--fg);
}

.note--status {
  border-color: var(--warn-border);
  border-left-color: var(--warn-fg);
  background: var(--warn-bg);
  color: var(--warn-fg);
}

.note--status strong {
  color: var(--warn-fg);
}

.tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.15rem 0.5rem;
  border-radius: 3px;
  border: 1px solid var(--border-strong);
  color: var(--fg-muted);
  background: var(--surface);
  vertical-align: 0.15em;
}

/* ------------------------------------------------------------------- code */

:not(pre) > code {
  font-size: 0.87em;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.08em 0.34em;
  word-break: break-word;
}

.code {
  margin: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  overflow: hidden;
  box-shadow: var(--shadow);
}

.code figcaption {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-faint);
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-alt);
}

.code pre {
  margin: 0;
  padding: 1rem 1.1rem;
  overflow-x: auto;
  font-size: 0.83rem;
  line-height: 1.6;
  tab-size: 2;
}

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

.cm {
  color: var(--fg-faint);
}

/* --------------------------------------------------------------- terminal */

.terminal {
  margin: 0;
  border-radius: 10px;
  border: 1px solid var(--term-border);
  background: var(--term-bg);
  overflow: hidden;
  box-shadow: var(--shadow);
}

.terminal .term-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--term-border);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--term-dim);
}

.terminal .term-head::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--term-prompt);
  flex: none;
}

.terminal pre {
  margin: 0;
  padding: 1.1rem 1.2rem 1.3rem;
  overflow-x: auto;
  color: var(--term-fg);
  font-size: 0.83rem;
  line-height: 1.7;
}

.terminal .p {
  color: var(--term-prompt);
}

.terminal .c {
  color: var(--term-key);
}

.terminal .n {
  color: var(--term-dim);
}

.terminal figcaption {
  padding: 0.75rem 1.2rem 0.9rem;
  border-top: 1px solid var(--term-border);
  color: var(--term-dim);
  font-size: 0.83rem;
  line-height: 1.5;
}

/* ----------------------------------------------------------------- tables */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
}

table {
  border-collapse: collapse;
  width: 100%;
  min-width: 34rem;
  font-size: 0.92rem;
}

th,
td {
  text-align: left;
  vertical-align: top;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--border);
}

thead th {
  font-size: 0.74rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--fg-faint);
  font-weight: 600;
  background: var(--bg-alt);
  white-space: nowrap;
}

tbody th {
  font-weight: 600;
  color: var(--fg);
  white-space: nowrap;
}

tbody tr:last-child td,
tbody tr:last-child th {
  border-bottom: 0;
}

td code {
  white-space: nowrap;
}

/* --------------------------------------------------------------- diagrams */

.figure {
  margin: 0;
}

.figure-scroll {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  padding: 1.25rem 1rem;
}

.diagram {
  display: block;
  width: 100%;
  height: auto;
  min-width: 620px;
}

.diagram--wide {
  min-width: 860px;
}

.figure figcaption {
  margin-top: 0.7rem;
  font-size: 0.88rem;
  color: var(--fg-muted);
  max-width: 66ch;
}

.diagram .node {
  fill: var(--diag-node);
  stroke: var(--diag-stroke);
  stroke-width: 1.25;
}

.diagram .node-alt {
  fill: var(--diag-node-alt);
  stroke: var(--diag-stroke);
  stroke-width: 1.25;
}

.diagram .node-accent {
  fill: var(--diag-accent-bg);
  stroke: var(--diag-accent);
  stroke-width: 1.4;
}

.diagram .node-ghost {
  fill: none;
  stroke: var(--diag-stroke);
  stroke-width: 1.25;
  stroke-dasharray: 5 4;
}

.diagram .edge {
  fill: none;
  stroke: var(--diag-ink);
  stroke-width: 1.5;
}

.diagram .edge-dash {
  stroke-dasharray: 5 4;
}

.diagram .edge-accent {
  stroke: var(--diag-accent);
}

.diagram .head {
  fill: var(--diag-ink);
}

.diagram .head-accent {
  fill: var(--diag-accent);
}

.diagram text {
  font-family: var(--font-sans);
}

.diagram .t {
  fill: var(--fg);
  font-size: 13.5px;
  font-weight: 600;
}

.diagram .t-sub {
  fill: var(--fg-muted);
  font-size: 11.5px;
  font-weight: 400;
}

.diagram .t-mono {
  fill: var(--fg-muted);
  font-size: 11.5px;
  font-family: var(--font-mono);
}

.diagram .t-accent {
  fill: var(--accent-strong);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
}

/* ---------------------------------------------------------------- mockups */

.mock {
  margin: 0;
  border: 2px dashed var(--border-strong);
  border-radius: 10px;
  background: var(--bg-alt);
  padding: 0.85rem;
  position: relative;
  /* How much room the mock UI has is a question about the mock, not about the
     page: two of these share a `.grid` row, so a roomy-looking 768px page
     hands each one a frame narrower than a phone gets. Querying the mock's own
     width is what lets the body below stack on the answer. */
  container-type: inline-size;
}

.mock-label {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin-bottom: 0.7rem;
}

.mock-label::before {
  content: "";
  width: 6px;
  height: 6px;
  border: 1px solid var(--fg-faint);
  transform: rotate(45deg);
}

.mock-frame {
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--surface);
  overflow: hidden;
  font-size: 0.8rem;
}

.mock-topbar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.85rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-alt);
  /* The frame clips rather than scrolls, so a row that outgrows it loses its
     last chips outright — the channel picker was showing a bisected "pr-42"
     wherever the mock column fell below ~290px. Wrapping is the only one of
     the three outcomes that keeps every chip readable. */
  flex-wrap: wrap;
  row-gap: 0.35rem;
}

.mock-title {
  font-weight: 650;
  font-size: 0.85rem;
}

.mock-chip {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--border-strong);
  border-radius: 3px;
  color: var(--fg-muted);
}

.mock-chip--on {
  border-color: var(--accent);
  color: var(--accent-strong);
  background: var(--accent-bg);
}

.mock-tabs {
  display: flex;
  gap: 1rem;
  padding: 0 0.85rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.75rem;
  color: var(--fg-faint);
  overflow-x: auto;
}

.mock-tabs span {
  padding: 0.5rem 0;
  white-space: nowrap;
}

.mock-tabs .on {
  color: var(--accent-strong);
  box-shadow: inset 0 -2px 0 var(--accent);
  font-weight: 600;
}

.mock-body {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr) 7.5rem;
  gap: 0.85rem;
  padding: 0.85rem;
}

.mock-body--two {
  grid-template-columns: 9.5rem minmax(0, 1fr);
}

.mock-col h5 {
  margin: 0 0 0.5rem;
  font-size: 0.65rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--fg-faint);
  font-weight: 600;
}

.mock-nav {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.75rem;
  color: var(--fg-muted);
}

.mock-nav li {
  padding: 0.16rem 0;
  margin: 0;
}

.mock-nav .sub {
  padding-left: 0.7rem;
}

.mock-nav .on {
  color: var(--accent-strong);
  font-weight: 600;
}

.bar {
  height: 8px;
  border-radius: 3px;
  background: var(--border);
  margin-bottom: 0.4rem;
}

.bar.w90 {
  width: 90%;
}
.bar.w75 {
  width: 75%;
}
.bar.w60 {
  width: 60%;
}
.bar.w45 {
  width: 45%;
}
.bar.tall {
  height: 14px;
  background: var(--border-strong);
  width: 55%;
  margin-bottom: 0.7rem;
}

.mock-block {
  border: 1px dashed var(--border-strong);
  border-radius: 4px;
  padding: 0.55rem 0.65rem;
  margin: 0.65rem 0;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  color: var(--fg-faint);
  letter-spacing: 0.04em;
}

/* The side columns are fixed, so they claim ~19rem between them before the
   content column gets anything, and below this threshold what is left stops
   reading as a third pane. It stopped being one entirely at a 768px page,
   where the middle column collapsed to 8px and printed "mermaid diagram —
   themed" a letter per line over the column beside it, while the frame's
   `overflow: hidden` cut "platform#services/billing" off mid-word. Chosen to
   sit just under the widest mock that still renders three panes, so the
   layouts that were already fine keep them. */
@container (max-width: 28rem) {
  .mock-body,
  .mock-body--two {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ------------------------------------------------------------------ cards */

.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.card {
  display: block;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  padding: 1.15rem 1.25rem;
  text-decoration: none;
  color: inherit;
}

a.card:hover {
  border-color: var(--accent);
  background: var(--accent-bg);
}

.card h3 {
  margin: 0 0 0.35rem;
  font-size: 1rem;
}

.card p {
  font-size: 0.88rem;
  color: var(--fg-muted);
}

.card .eyebrow {
  margin-bottom: 0.35rem;
}

/* ------------------------------------------------------- key/value blocks */

.kv {
  display: grid;
  grid-template-columns: minmax(7rem, auto) minmax(0, 1fr);
  gap: 0.35rem 1.25rem;
  font-size: 0.93rem;
  border-top: 1px solid var(--border);
  padding-top: 1rem;
}

.kv dt {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--fg-faint);
  padding-top: 0.15rem;
}

.kv dd {
  margin: 0;
  color: var(--fg-muted);
}

/* ----------------------------------------------------------------- footer */

.site-footer {
  border-top: 1px solid var(--border);
  background: var(--bg-alt);
  padding: 2.5rem 0 3.5rem;
  font-size: 0.88rem;
  color: var(--fg-muted);
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  align-items: baseline;
}

.footer-inner p {
  margin: 0;
  max-width: 46ch;
}

.pager {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  border-top: 1px solid var(--border);
  padding-top: 1.5rem;
  margin-top: 4rem;
  font-size: 0.92rem;
}

.pager .eyebrow {
  margin-bottom: 0.15rem;
}

/* ------------------------------------------------------------ small print */

@media (max-width: 760px) {
  body {
    font-size: 16px;
  }

  .shell {
    padding: 0 18px;
  }
}

/* Its own breakpoint, wider than the one above, because it answers a question
   about the header's contents rather than about the page: measured, the brand,
   the whole nav and both controls stop fitting on one line at ~845px, and the
   margin here covers system fonts wider than the one measured on.

   Left to flex wrapping the two controls dropped to a third line of their own,
   under the nav and hard against the left edge — three unrelated strips, and
   150px of permanently sticky chrome on a 390px phone. Placing the rows by
   grid area instead keeps the controls beside the brand and hands the nav the
   second row on its own.

   This block must stay after the one above: both set properties on the shell
   and its header, and the header's are the ones that should win. */
@media (max-width: 880px) {
  .header-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas:
      "brand repo theme"
      "nav   nav  nav";
    align-items: center;
    gap: 0.3rem 0.6rem;
    padding-top: 0.45rem;
    padding-bottom: 0.45rem;
  }

  .brand {
    grid-area: brand;
  }

  .repo-link {
    grid-area: repo;
  }

  .theme-toggle {
    grid-area: theme;
  }

  .site-nav {
    grid-area: nav;
    /* The auto margin that pushes the nav rightwards on a wide header would
       collapse it against the controls' edge here, where it owns the row. */
    margin-left: 0;
    /* A row of its own is room enough to wrap, and wrapping is what keeps
       every item visible — including the current page's, which on the last
       two pages sat outside the scrolled strip. Overlay scrollbars never
       advertised that the strip scrolled at all. */
    overflow-x: visible;
  }

  .site-nav ul {
    flex-wrap: wrap;
    row-gap: 0.15rem;
  }

  /* The sticky header is two rows tall here, so an anchored target needs more
     clearance than the single row's 5rem buys it. */
  [id] {
    scroll-margin-top: 8.5rem;
  }
}
