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

  /* The page recedes so that raised can mean raised. A card cannot be lighter
     than #ffffff, so the earlier light theme made base and raised the same
     colour and stepped the card *down* instead: same size of step as dark,
     opposite direction, and a card that reads as sunken rather than lifted.
     Stepping the page down instead keeps the direction the dark theme has and
     the size it uses, 1.06 between the two. */
  --surface-sunken: #f4f5f7;
  --surface-base: #f7f8f9;
  --surface-raised: #ffffff;
  --surface-card: var(--surface-raised);
  --surface-overlay: #ffffff;
  --surface-hover: #f4f5f7;
  --surface-active: #eceef1;
  --surface-selected: rgb(234 88 12 / 0.07);
  /* Recessed against the card it sits inside, which is now #ffffff. It was
     #f7f8f9, which is the page. */
  --surface-inset: #f4f5f7;

  --border-subtle: #eceef1;
  --border-default: #dfe2e7;
  --border-strong: #c3c8d0;
  --border-accent: rgb(234 88 12 / 0.35);

  --fg-primary: #14161a;
  --fg-secondary: #5b6270;
  --fg-tertiary: #69707e;
  --fg-disabled: #a8aeb9;
  --fg-on-accent: var(--grey-000);


  --accent-fg: var(--orange-600);
  --accent-solid: var(--orange-500);
  --accent-solid-hover: var(--orange-600);
  --accent-solid-active: #9a3412;
  --accent-muted: rgb(234 88 12 / 0.09);

  --status-running-fg: #1d64d8;
  --status-running-muted: rgb(59 130 246 / 0.1);
  --status-waiting-fg: #a55a00;
  --status-waiting-muted: rgb(245 158 11 / 0.12);
  --status-passed-fg: #047857;
  --status-passed-muted: rgb(16 185 129 / 0.1);
  --status-failed-fg: #c22626;
  --status-failed-muted: rgb(239 68 68 / 0.1);
  --status-idle-fg: #7b8290;
  --status-idle-muted: rgb(123 130 144 / 0.12);
  --status-idle-border: #dfe2e7;

  --data-1: var(--orange-500);
  --data-2: #1d64d8;
  --data-3: #047857;
  --data-4: #a55a00;
  --data-5: #c22626;
  --data-6: #7b8290;

  --shadow-xs: 0 1px 2px rgb(16 18 22 / 0.06);
  --shadow-sm: 0 1px 3px rgb(16 18 22 / 0.08), 0 0 0 1px rgb(16 18 22 / 0.04);
  --shadow-md: 0 4px 12px rgb(16 18 22 / 0.1), 0 0 0 1px rgb(16 18 22 / 0.05);
  --shadow-lg: 0 12px 32px rgb(16 18 22 / 0.12), 0 0 0 1px rgb(16 18 22 / 0.05);
  --shadow-overlay: 0 16px 48px rgb(16 18 22 / 0.16), 0 0 0 1px rgb(16 18 22 / 0.06);
  --scrim: rgb(20 22 26 / 0.32);
}
}
/* Dark is canonical. Crewbit is a build surface that engineers keep open next to
   an editor and a terminal, so the dark theme is designed first and the light
   theme is derived from it — not the other way round.

   Neutrals are a single cool-grey ramp with a trace of warmth so they sit with
   the orange accent instead of fighting it. Nothing here is a raw hex in a
   component: components only ever reference the semantic names. */
:root {
  color-scheme: dark;

  /* ── Neutral ramp ───────────────────────────────────────── */
  --grey-1000: #08090b;
  --grey-950: #0c0d10;
  --grey-900: #121418;
  --grey-850: #171a1f;
  --grey-800: #1d2027;
  --grey-750: #23272f;
  --grey-700: #2b2f38;
  --grey-600: #3a3f4a;
  --grey-500: #545a67;
  /* Lifted from #6e747f on 30 August 2026. `--fg-tertiary` reads it, and at
     12px that was 3.92:1 on `--surface-raised` against the 4.5:1 AA asks; it is
     4.52:1 now, and 4.88:1 on the darkest surface. `--status-idle-fg` and
     `--data-6` read it too and both improved. */
  --grey-400: #787e89;
  --grey-300: #8f96a2;
  --grey-200: #b4bac4;
  --grey-100: #d7dae0;
  --grey-050: #eceef1;
  --grey-000: #ffffff;

  /* ── Accent: the factory hue ─────────────────────────────── */
  --orange-600: #c2410c;
  --orange-500: #ea580c;
  --orange-400: #f97316;
  --orange-300: #fb923c;
  --orange-200: #fdba74;

  /* ── Raw semantic hues ───────────────────────────────────── */
  --green-500: #10b981;
  --green-400: #34d399;
  --amber-500: #f59e0b;
  --amber-400: #fbbf24;
  --red-500: #ef4444;
  --red-400: #f87171;
  --blue-500: #3b82f6;
  --blue-400: #60a5fa;

  /* ── Surfaces ────────────────────────────────────────────── */
  --surface-sunken: var(--grey-1000);
  --surface-base: var(--grey-950);
  --surface-raised: var(--grey-900);
  /* A card that has to read as a card where `--surface-raised` cannot do it.
     On dark the two are the same, because raised is already a step off the base;
     on light both are #ffffff, so a card there is its border and nothing else.
     #f4f5f7 is the darkest step that keeps `--fg-tertiary` above AA on top of
     it: 4.56:1, against 4.36:1 one step further down. */
  --surface-card: var(--surface-raised);
  --surface-overlay: var(--grey-850);
  --surface-hover: var(--grey-800);
  --surface-active: var(--grey-750);
  --surface-selected: rgb(234 88 12 / 0.1);
  --surface-inset: var(--grey-1000);

  /* ── Borders ─────────────────────────────────────────────── */
  --border-subtle: var(--grey-850);
  --border-default: var(--grey-750);
  --border-strong: var(--grey-600);
  --border-accent: rgb(234 88 12 / 0.4);

  /* ── Foreground ──────────────────────────────────────────── */
  --fg-primary: var(--grey-050);
  --fg-secondary: var(--grey-300);
  --fg-tertiary: var(--grey-400);
  --fg-disabled: var(--grey-500);
  /* Ink on a solid accent fill, and it is dark because white does not pass on
     this orange. Measured: #ffffff on --accent-solid is 3.56:1 and on
     --accent-solid-hover 2.80:1, against the 4.5:1 AA asks for text this size;
     --grey-1000 is 5.60:1 and 7.11:1, so the hover gets clearer rather than
     worse. Darkening the orange instead was the other way out and it would have
     moved the mark and the favicon, which read the same token. */
  --fg-on-accent: var(--grey-1000);

  /* ── Accent, applied ─────────────────────────────────────── */
  --accent-fg: var(--orange-300);
  --accent-solid: var(--orange-500);
  --accent-solid-hover: var(--orange-400);
  --accent-solid-active: var(--orange-600);
  --accent-muted: rgb(234 88 12 / 0.14);
  --accent-border: rgb(234 88 12 / 0.35);

  /* ── Status, applied. Mapped onto the Run state machine ──── */
  --status-running-fg: var(--blue-400);
  --status-running-muted: rgb(59 130 246 / 0.14);
  --status-running-border: rgb(59 130 246 / 0.32);

  --status-waiting-fg: var(--amber-400);
  --status-waiting-muted: rgb(245 158 11 / 0.14);
  --status-waiting-border: rgb(245 158 11 / 0.32);

  --status-passed-fg: var(--green-400);
  --status-passed-muted: rgb(16 185 129 / 0.14);
  --status-passed-border: rgb(16 185 129 / 0.32);

  --status-failed-fg: var(--red-400);
  --status-failed-muted: rgb(239 68 68 / 0.14);
  --status-failed-border: rgb(239 68 68 / 0.32);

  --status-idle-fg: var(--grey-400);
  /* `--grey-400` at 0.16, written out because a custom property cannot carry an
     alpha of another one. It moves when the ramp moves, or it derives from a
     colour the palette no longer has. */
  --status-idle-muted: rgb(120 126 137 / 0.16);
  --status-idle-border: var(--grey-700);

  /* ── Focus ───────────────────────────────────────────────── */
  --focus-ring: rgb(249 115 22 / 0.45);
  --focus-border: var(--orange-400);

  /* ── Charts and syntax, in accent-neighbour order ────────── */
  --data-1: var(--orange-400);
  --data-2: var(--blue-400);
  --data-3: var(--green-400);
  --data-4: var(--amber-400);
  --data-5: var(--red-400);
  --data-6: var(--grey-400);
}

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

  /* The page recedes so that raised can mean raised. A card cannot be lighter
     than #ffffff, so the earlier light theme made base and raised the same
     colour and stepped the card *down* instead: same size of step as dark,
     opposite direction, and a card that reads as sunken rather than lifted.
     Stepping the page down instead keeps the direction the dark theme has and
     the size it uses, 1.06 between the two. */
  --surface-sunken: #f4f5f7;
  --surface-base: #f7f8f9;
  --surface-raised: #ffffff;
  --surface-card: var(--surface-raised);
  --surface-overlay: #ffffff;
  --surface-hover: #f4f5f7;
  --surface-active: #eceef1;
  --surface-selected: rgb(234 88 12 / 0.07);
  /* Recessed against the card it sits inside, which is now #ffffff. It was
     #f7f8f9, which is the page. */
  --surface-inset: #f4f5f7;

  --border-subtle: #eceef1;
  --border-default: #dfe2e7;
  --border-strong: #c3c8d0;
  --border-accent: rgb(234 88 12 / 0.35);

  --fg-primary: #14161a;
  --fg-secondary: #5b6270;
  --fg-tertiary: #69707e;
  --fg-disabled: #a8aeb9;
  --fg-on-accent: var(--grey-000);


  --accent-fg: var(--orange-600);
  --accent-solid: var(--orange-500);
  --accent-solid-hover: var(--orange-600);
  --accent-solid-active: #9a3412;
  --accent-muted: rgb(234 88 12 / 0.09);

  --status-running-fg: #1d64d8;
  --status-running-muted: rgb(59 130 246 / 0.1);
  --status-waiting-fg: #a55a00;
  --status-waiting-muted: rgb(245 158 11 / 0.12);
  --status-passed-fg: #047857;
  --status-passed-muted: rgb(16 185 129 / 0.1);
  --status-failed-fg: #c22626;
  --status-failed-muted: rgb(239 68 68 / 0.1);
  --status-idle-fg: #7b8290;
  --status-idle-muted: rgb(123 130 144 / 0.12);
  --status-idle-border: #dfe2e7;

  --data-1: var(--orange-500);
  --data-2: #1d64d8;
  --data-3: #047857;
  --data-4: #a55a00;
  --data-5: #c22626;
  --data-6: #7b8290;
}

/* 13px is the interface base. Crewbit's screens are lists of many small facts —
   run ids, states, paths, turn counts — and 13/18 fits them without crowding.
   Prose (a plan, a verdict, a spec body) steps up to 14/22.

   Mono is not decoration: it marks something the machine produced or something
   you can paste back into a terminal. Never use it for interface labels. */
:root {
  --font-sans: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif;
  --font-mono: "Spline Sans Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-core: var(--font-sans);

  --text-2xs: 10px;
  --text-xs: 11px;
  --text-sm: 12px;
  --text-md: 13px;
  --text-lg: 14px;
  --text-xl: 16px;
  --text-2xl: 18px;
  --text-3xl: 21px;
  --text-4xl: 26px;
  --text-5xl: 34px;
  --text-6xl: 44px;

  --leading-tight: 1.15;
  --leading-snug: 1.35;
  --leading-normal: 1.5;
  --leading-relaxed: 1.6;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* Headings tighten; small labels open up. */
  --tracking-tight: -0.02em;
  --tracking-snug: -0.01em;
  --tracking-normal: 0;
  --tracking-wide: 0.02em;
  --tracking-caps: 0.06em;

  /* Composed roles */
  --type-display: var(--weight-semibold) var(--text-5xl) / var(--leading-tight) var(--font-sans);
  --type-title: var(--weight-semibold) var(--text-3xl) / var(--leading-snug) var(--font-sans);
  --type-heading: var(--weight-semibold) var(--text-xl) / var(--leading-snug) var(--font-sans);
  --type-subheading: var(--weight-semibold) var(--text-lg) / var(--leading-snug) var(--font-sans);
  --type-body: var(--weight-regular) var(--text-lg) / var(--leading-relaxed) var(--font-sans);
  --type-ui: var(--weight-regular) var(--text-md) / var(--leading-snug) var(--font-sans);
  --type-ui-medium: var(--weight-medium) var(--text-md) / var(--leading-snug) var(--font-sans);
  --type-label: var(--weight-medium) var(--text-sm) / var(--leading-snug) var(--font-sans);
  --type-caption: var(--weight-regular) var(--text-sm) / var(--leading-normal) var(--font-sans);
  --type-code: var(--weight-regular) var(--text-sm) / var(--leading-normal) var(--font-mono);
  --type-code-lg: var(--weight-regular) var(--text-md) / var(--leading-normal) var(--font-mono);
}

/* A 4px grid with a 2px half-step for optical work (icon nudges, chip padding).
   Dashboard density lives between --space-2 and --space-4; page rhythm uses
   --space-6 and up. */
:root {
  --space-0: 0;
  --space-05: 2px;
  --space-1: 4px;
  --space-15: 6px;
  --space-2: 8px;
  --space-25: 10px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;
  --space-9: 48px;
  --space-10: 64px;
  --space-11: 80px;
  --space-12: 96px;

  /* Layout constants */
  --sidebar-width: 232px;
  --sidebar-width-collapsed: 56px;
  --topbar-height: 48px;
  --row-height: 40px;
  --row-height-compact: 32px;
  --content-max: 1200px;
  --prose-max: 68ch;
  --control-height-sm: 24px;
  --control-height-md: 30px;
  --control-height-lg: 36px;
}

/* Small and consistent. Nothing in a dense dashboard should look soft: 6px is
   the default for controls and cards alike, 4px for chips inside them. */
:root {
  --radius-xs: 3px;
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 12px;
  --radius-2xl: 16px;
  --radius-full: 999px;
}

/* On dark, elevation is mostly a lighter surface plus a hairline; the shadow is
   there to separate an overlay from what it covers, not to make cards float.
   Every shadow carries a 1px inset ring so an overlay keeps its edge on any
   background. */
:root {
  --shadow-none: none;
  --shadow-xs: 0 1px 2px rgb(0 0 0 / 0.28);
  --shadow-sm: 0 2px 4px rgb(0 0 0 / 0.3), 0 0 0 1px rgb(0 0 0 / 0.2);
  --shadow-md: 0 4px 12px rgb(0 0 0 / 0.36), 0 0 0 1px rgb(0 0 0 / 0.22);
  --shadow-lg: 0 12px 32px rgb(0 0 0 / 0.44), 0 0 0 1px rgb(0 0 0 / 0.24);
  --shadow-overlay: 0 16px 48px rgb(0 0 0 / 0.5), 0 0 0 1px rgb(0 0 0 / 0.28);
  --shadow-focus: 0 0 0 3px var(--focus-ring);
  --scrim: rgb(4 5 7 / 0.6);
}

:root[data-theme="light"] {
  --shadow-xs: 0 1px 2px rgb(16 18 22 / 0.06);
  --shadow-sm: 0 1px 3px rgb(16 18 22 / 0.08), 0 0 0 1px rgb(16 18 22 / 0.04);
  --shadow-md: 0 4px 12px rgb(16 18 22 / 0.1), 0 0 0 1px rgb(16 18 22 / 0.05);
  --shadow-lg: 0 12px 32px rgb(16 18 22 / 0.12), 0 0 0 1px rgb(16 18 22 / 0.05);
  --shadow-overlay: 0 16px 48px rgb(16 18 22 / 0.16), 0 0 0 1px rgb(16 18 22 / 0.06);
  --scrim: rgb(20 22 26 / 0.32);
}

/* Short and decelerating. Nothing bounces, nothing overshoots, nothing springs:
   this is a tool people watch work, and a playful transition on a state that
   means "your pull request failed" reads as flippant.

   Above --duration-slow, use a progress indicator instead of an animation. */
:root {
  --duration-instant: 80ms; /* @kind other */
  --duration-fast: 120ms; /* @kind other */
  --duration-normal: 160ms; /* @kind other */
  --duration-slow: 240ms; /* @kind other */

  --ease-out: cubic-bezier(0.2, 0, 0, 1); /* @kind other */
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); /* @kind other */
  --ease-linear: linear; /* @kind other */

  --transition-color:
    color var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
  --transition-transform: transform var(--duration-normal) var(--ease-out);
  --transition-opacity: opacity var(--duration-normal) var(--ease-out);
}

/* The minimum a consuming page needs so it does not start from browser defaults. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  background: var(--surface-base);
  color: var(--fg-primary);
  font: var(--type-ui);
  letter-spacing: var(--tracking-snug);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a {
  color: var(--accent-fg);
  text-decoration: none;
  transition: var(--transition-color);
}

a:hover {
  color: var(--accent-solid-hover);
  text-decoration: underline;
  text-underline-offset: 2px;
}

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

::selection {
  background: var(--accent-muted);
}

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

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

/* Three labels, one shown. CSS picks it from the root attribute, so the word is
   right on the first paint and no script is needed to make it right. */
.theme {
  display: inline-flex;
  align-items: center;
  height: var(--control-height-sm);
  padding: 0 var(--space-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: transparent;
  font: var(--type-code);
  color: var(--fg-secondary);
  text-transform: capitalize;
  cursor: pointer;
  transition: var(--transition-color);
}

.theme:hover {
  border-color: var(--border-strong);
  color: var(--fg-primary);
}

.theme > span {
  display: none;
}

:root:not([data-theme]) .theme-system,
:root[data-theme="light"] .theme-light,
:root[data-theme="dark"] .theme-dark {
  display: inline;
}
/*
 * The site's own layout. The palette, the type scale and the spacing come from
 * the product's tokens, which this file only reads.
 *
 * `--site-max` is narrower than the app's `--content-max`: the app is a dense
 * table and wants the width, and a marketing page at 1200px puts a heading a
 * long way from the paragraph under it.
 */

:root {
  --site-max: 1080px;
}

body {
  margin: 0;
  background: var(--surface-base);
  color: var(--fg-primary);
  font: var(--type-body);
}

/* Declared before every rule that darkens or lightens a link, so the ones that
   do are the more specific selector rather than the later one. */
a {
  color: var(--accent-fg);
}

a:hover {
  color: var(--orange-200);
}

.wrap {
  max-width: var(--site-max);
  margin: 0 auto;
  padding: 0 var(--space-6);
}

/* Present for a screen reader, absent for an eye: the comparison table's first
   header has no visible label because the rows carry it. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── The bar ─────────────────────────────────────────────── */

.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--surface-base);
  border-bottom: 1px solid var(--border-subtle);
}

.nav-inner {
  height: 56px;
  display: flex;
  align-items: center;
  gap: var(--space-7);
}

.nav-mark {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--fg-primary);
  font: var(--weight-semibold) var(--text-xl) / 1 var(--font-sans);
  letter-spacing: var(--tracking-tight);
  text-decoration: none;
}

.mark {
  width: 15px;
  height: 15px;
  border-radius: var(--radius-sm);
  background: var(--accent-solid);
  display: block;
}

.nav-links {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

/* `display: contents`: the four text links and the rule lay out as if this
   wrapper were not there at all, participating directly in `.nav-links`'
   own row. It exists only so `@media (max-width: 560px)` has one thing to
   hide instead of five. */
.nav-text-links {
  display: contents;
}

/* `:not(.button)`, and it is load-bearing rather than tidy. `.nav-links a` is a
   class and an element, which outranks `.button`'s single class, so without it
   the bar's call to action takes this grey instead of the ink meant for a solid
   accent fill: measured 1.20:1 against the orange, and 1.06:1 on hover. */
.nav-links a:not(.button) {
  font: var(--type-ui);
  color: var(--fg-secondary);
  text-decoration: none;
  white-space: nowrap;
}

.nav-links a:not(.button):hover {
  color: var(--fg-primary);
}

.nav-links a:not(.button)[aria-current] {
  font: var(--type-ui-medium);
  color: var(--fg-primary);
}

.nav-rule {
  width: 1px;
  height: 18px;
  background: var(--border-default);
}

/* ── Buttons ─────────────────────────────────────────────── */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--control-height-lg);
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  font: var(--type-ui-medium);
  text-decoration: none;
  white-space: nowrap;
  background: var(--accent-solid);
  color: var(--fg-on-accent);
  border: 1px solid transparent;
  transition: var(--transition-color);
}

.button:hover {
  background: var(--accent-solid-hover);
  color: var(--fg-on-accent);
  text-decoration: none;
}

.button-sm {
  height: var(--control-height-md);
  padding: 0 var(--space-3);
}

.button-quiet {
  background: var(--surface-raised);
  border-color: var(--border-default);
  color: var(--fg-primary);
}

.button-quiet:hover {
  background: var(--surface-hover);
  border-color: var(--border-strong);
  color: var(--fg-primary);
}

/* Two controls of the same shape side by side make a choice out of what is one
   action and one aside, and the aside wins some of the clicks the action wanted.
   The hero's second control is a link again. `.button-quiet` stays, because the
   closing pair is a real choice between starting and reading the prices. */
.link-quiet {
  font: var(--type-ui-medium);
  color: var(--fg-secondary);
}

.link-quiet:hover {
  color: var(--fg-primary);
}

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

/* ── Page rhythm ─────────────────────────────────────────── */

main {
  display: block;
}

/* The bar is sticky and 56px tall, so anything reached by a `#fragment` lands
   underneath it and the heading somebody clicked for is the one thing they
   cannot see. Every id is a possible target, so every id gets the clearance. */
main [id] {
  scroll-margin-top: var(--space-11);
}

.band {
  border-top: 1px solid var(--border-subtle);
  padding: var(--space-11) 0;
}

.band-sunken {
  background: var(--surface-sunken);
}

.band-tight {
  padding: var(--space-10) 0;
}

.band h2 {
  margin: 0;
  font: var(--type-display);
  letter-spacing: var(--tracking-tight);
}

.band h2.small {
  font: var(--type-title);
}

/* Vertical only: `.hero` is always on a `.wrap`, and a `padding` shorthand here
   would drop the gutter that keeps it in line with the bar. */
.hero {
  padding-top: var(--space-12);
  padding-bottom: var(--space-10);
}

.hero h1 {
  margin: 0;
  max-width: 22ch;
  font: var(--weight-semibold) var(--text-6xl) / 1.06 var(--font-sans);
  letter-spacing: var(--tracking-tight);
  text-wrap: pretty;
}

.hero-narrow h1 {
  max-width: none;
}

/* The hero used to be one column of prose. The first thing on the page was an
   argument, and the thing being sold is a ten-second decision, so the decision
   is drawn beside it. */
.hero-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
  gap: var(--space-9);
  align-items: center;
}

.hero-split h1 {
  max-width: 16ch;
}

.eyebrow {
  margin: 0 0 var(--space-5);
  font: var(--type-code);
  color: var(--fg-tertiary);
  letter-spacing: var(--tracking-wide);
}

/* The introductory paragraph, in the hero and under every section heading. */
.lede {
  margin: var(--space-5) 0 0;
  max-width: var(--prose-max);
  font: var(--weight-regular) var(--text-xl) / var(--leading-relaxed) var(--font-sans);
  color: var(--fg-secondary);
  text-wrap: pretty;
}

.prose {
  margin: var(--space-5) 0 0;
  max-width: var(--prose-max);
  font: var(--type-body);
  color: var(--fg-secondary);
}

.note {
  margin: var(--space-5) 0 0;
  max-width: var(--prose-max);
  font: var(--type-caption);
  color: var(--fg-tertiary);
}

.plans + .note {
  margin-bottom: var(--space-6);
  max-width: none;
}

.mono {
  font: var(--type-code-lg);
  color: var(--fg-primary);
}

.mono-waiting {
  color: var(--status-waiting-fg);
}

.mono-failed {
  color: var(--status-failed-fg);
}

/* ── The pipeline strip ──────────────────────────────────── */

.pipeline {
  border-top: 1px solid var(--border-subtle);
  border-bottom: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
}

.pipeline-inner {
  padding-top: var(--space-7);
  padding-bottom: var(--space-7);
  /* The drawing is 960 wide and its labels are 13px. Scaled to a phone they are
     five, so it scrolls in its own box rather than shrinking to nothing. */
  overflow-x: auto;
}

.flow {
  display: block;
  width: 100%;
  min-width: 720px;
  height: auto;
}

.flow-box {
  fill: var(--surface-raised);
  stroke: var(--border-default);
}

.flow-box-gate {
  fill: var(--status-waiting-muted);
  stroke: var(--status-waiting-border);
}

.flow-out {
  fill: none;
  stroke-dasharray: 3 3;
}

.flow-out-pass {
  stroke: var(--status-passed-border);
}

.flow-out-fail {
  stroke: var(--status-failed-border);
}

.flow-name,
.flow-out-name {
  font: var(--type-code);
  fill: var(--fg-secondary);
  text-anchor: middle;
  dominant-baseline: central;
}

.flow-name-gate {
  fill: var(--status-waiting-fg);
}

.flow-name-pass {
  fill: var(--status-passed-fg);
}

.flow-name-fail {
  fill: var(--status-failed-fg);
}

.flow-line {
  fill: none;
  stroke: var(--border-strong);
  stroke-width: 1.5;
}

.flow-line-pass {
  stroke: var(--status-passed-border);
}

.flow-line-fail {
  stroke: var(--status-failed-border);
}

.flow-head {
  fill: var(--border-strong);
}

.flow-head-pass {
  fill: var(--status-passed-border);
}

.flow-head-fail {
  fill: var(--status-failed-border);
}

.flow-note {
  font: var(--type-caption);
  fill: var(--fg-tertiary);
  text-anchor: middle;
}

.pipeline-note {
  margin: var(--space-4) 0 0;
  font: var(--type-caption);
  color: var(--fg-tertiary);
  text-align: center;
}

/* ── Stats ───────────────────────────────────────────────── */

.stats {
  margin-top: var(--space-8);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-6);
}

.stat {
  padding: var(--space-5);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

.stat dt {
  margin: 0 0 var(--space-3);
  font: var(--type-label);
  color: var(--fg-tertiary);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.stat dd {
  margin: 0;
}

.stat-value {
  font: var(--weight-medium) var(--text-4xl) / 1 var(--font-mono);
  letter-spacing: var(--tracking-tight);
  color: var(--fg-primary);
}

.stat-unit {
  margin-left: var(--space-2);
  font: var(--type-caption);
  color: var(--fg-tertiary);
}

.stat-hint {
  margin: var(--space-3) 0 0;
  font: var(--type-caption);
  color: var(--fg-secondary);
}

/* The one tile its section is an argument about. Three tiles of equal weight are
   three tiles nobody ranks, and the section that quotes 45.1% is not making
   three points. */
.stat-feature {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
}

/* Drawn under the numeral, not instead of it: the width is the comparison the
   three tiles are for, and the numeral is still the number. */
.stat-bar {
  margin: var(--space-4) 0 0;
  height: 4px;
  border-radius: var(--radius-sm);
  background: var(--status-idle-muted);
  overflow: hidden;
}

.stat-bar span {
  display: block;
  height: 100%;
  background: var(--status-idle-fg);
}

.stat-passed .stat-bar span {
  background: var(--status-passed-fg);
}

.stat-passed .stat-value {
  color: var(--status-passed-fg);
}

.stat-failed .stat-bar span {
  background: var(--status-failed-fg);
}

.stat-failed .stat-value {
  color: var(--status-failed-fg);
}

/* ── Numbered steps ──────────────────────────────────────── */

.steps {
  margin: var(--space-8) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-1);
  counter-reset: step;
}

.steps li {
  display: grid;
  grid-template-columns: 40px minmax(0, 260px) minmax(0, 1fr);
  gap: var(--space-5);
  padding: var(--space-5);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

.steps li::before {
  counter-increment: step;
  content: "0" counter(step);
  font: var(--type-code-lg);
  color: var(--fg-tertiary);
}

/* The index shades with the stage it names: grey while the Spec is still yours,
   amber at the gate, blue while the machine has it, green at the pull request.
   They are the Runs page's own status colours, so the page teaches the palette
   somebody will be reading later.

   Scoped through `.steps` rather than written as `.step-waiting::before` alone,
   which loses to the `.steps li::before` above it: one class and one element
   outrank one class, and the numbers came out grey with the rule sitting right
   there. */
.steps .step-idle::before {
  color: var(--status-idle-fg);
}

.steps .step-waiting::before {
  color: var(--status-waiting-fg);
}

.steps .step-running::before {
  color: var(--status-running-fg);
}

.steps .step-passed::before {
  color: var(--status-passed-fg);
}

.steps h3 {
  margin: 0;
  font: var(--type-heading);
  letter-spacing: var(--tracking-snug);
}

.steps p {
  margin: 0;
  font: var(--type-body);
  color: var(--fg-secondary);
}

/* ── Text beside a frame ─────────────────────────────────── */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
  gap: var(--space-9);
  align-items: start;
}

.badges {
  margin-top: var(--space-6);
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.badge {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--status-idle-border);
  background: var(--status-idle-muted);
  color: var(--status-idle-fg);
  font: var(--type-code);
}

.badge-waiting {
  border-color: var(--status-waiting-border);
  background: var(--status-waiting-muted);
  color: var(--status-waiting-fg);
}

.badge-running {
  border-color: var(--status-running-border);
  background: var(--status-running-muted);
  color: var(--status-running-fg);
}

.badge-passed {
  border-color: var(--status-passed-border);
  background: var(--status-passed-muted);
  color: var(--status-passed-fg);
}

.badge-failed {
  border-color: var(--status-failed-border);
  background: var(--status-failed-muted);
  color: var(--status-failed-fg);
}

/*
 * A drawing of the Runs list, not a screenshot. Its columns and its state
 * labels are `web/pages/runs.ts` and `web/components/state-badge.ts`, so a
 * column renamed there makes this wrong in review rather than in the wild.
 */
.frame {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  overflow: hidden;
}

.frame-bar {
  height: var(--control-height-md);
  display: flex;
  align-items: center;
  padding: 0 var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  font: var(--type-code);
  color: var(--fg-tertiary);
}

.frame-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3) var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
}

.frame-row:last-child {
  border-bottom: 0;
}

.frame-spec {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-05);
}

.frame-title {
  font: var(--type-ui);
  color: var(--fg-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* `--fg-tertiary` and not `--fg-disabled`, here and in the five other places
   this file used to reach for it. That token is named for a control you cannot
   operate; a run id, a clause number and the company name in the foot are text
   somebody reads, and on `--surface-raised` the difference is 2.66:1 against
   3.92:1. */
.frame-meta {
  font: var(--type-code);
  color: var(--fg-tertiary);
}

/* ── The gate, drawn ─────────────────────────────────────── */

/* The hero's drawing. It sits here rather than beside `.hero-split`, where it
   was written, because it borrows `.frame-bar`, `.frame-title` and `.badge`:
   an override written above the rule it overrides wins on specificity and reads
   like a mistake, and Biome's `noDescendingSpecificity` says so. */
.gate {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  overflow: hidden;
}

.gate-body {
  padding: var(--space-4);
  display: grid;
  gap: var(--space-4);
}

.gate-head {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: var(--space-3);
}

/* `.frame-title` is written for a row in a list, where one line and an ellipsis
   are right. Here it is the headline of the scene, so it wraps instead — and
   without the `min-width` a `nowrap` title sets the flex item's minimum to its
   full length, which is what pushed the whole card past the edge of a phone. */
.gate-head .frame-title {
  min-width: 0;
  white-space: normal;
}

.gate-head .badge {
  flex-shrink: 0;
}

.gate-plan {
  margin: 0;
  font: var(--type-caption);
  color: var(--fg-secondary);
}

.gate-choices {
  display: flex;
  gap: var(--space-2);
}

/* Drawn, not operable: these are `<span>`s, so they carry no hover, no focus
   ring and nothing for a keyboard to land on. A control that looks live and
   does nothing is worse than a picture of one. */
.gate-button {
  display: inline-flex;
  align-items: center;
  height: var(--control-height-md);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  background: var(--accent-solid);
  color: var(--fg-on-accent);
  font: var(--type-ui-medium);
}

.gate-button-quiet {
  background: var(--surface-raised);
  border-color: var(--border-default);
  color: var(--fg-primary);
}

.gate-note {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
  font: var(--type-caption);
  color: var(--fg-secondary);
}

/* ── Card grids ──────────────────────────────────────────── */

.cards {
  margin-top: var(--space-7);
  display: grid;
  gap: var(--space-4);
}

.cards-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.cards-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.card {
  padding: var(--space-5);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

.card h3 {
  margin: 0 0 var(--space-2);
  font: var(--type-subheading);
}

.card p {
  margin: 0;
  font: var(--type-caption);
  color: var(--fg-secondary);
}

/* Only the four stage cards take an accent, and the accent is the stage's own
   colour. Red on Review is the card's argument rather than decoration: that
   stage defaults to fail, which is the sentence inside it. The limits below take
   none, so the stripe keeps meaning "stage" and not "important". */
.card-idle,
.card-running,
.card-failed,
.card-passed {
  border-left-width: 3px;
}

.card-idle {
  border-left-color: var(--status-idle-border);
}

.card-running {
  border-left-color: var(--status-running-border);
}

.card-failed {
  border-left-color: var(--status-failed-border);
}

.card-passed {
  border-left-color: var(--status-passed-border);
}

/* ── The closing band ────────────────────────────────────── */

.close-inner {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  flex-wrap: wrap;
}

.close-text {
  flex: 1;
  min-width: 320px;
}

.close-inner h2 {
  max-width: 30ch;
  text-wrap: pretty;
}

.close-inner .actions {
  margin-top: 0;
}

/* ── Plans ───────────────────────────────────────────────── */

.plans {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
}

.plan {
  display: flex;
  flex-direction: column;
  padding: var(--space-6);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

.plan-featured {
  border-color: var(--accent-border);
}

.plan-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.plan h2 {
  margin: 0;
  font: var(--type-heading);
  letter-spacing: var(--tracking-snug);
}

.plan-price {
  margin: var(--space-4) 0 0;
  font: var(--weight-medium) var(--text-5xl) / 1 var(--font-mono);
  letter-spacing: var(--tracking-tight);
}

.plan-price-words {
  font: var(--weight-medium) var(--text-4xl) / 1.2 var(--font-sans);
}

.plan-unit {
  margin: var(--space-2) 0 0;
  font: var(--type-caption);
  color: var(--fg-tertiary);
}

/* Even out three cards whose sentences are not the same length. */
.plan-for {
  margin: var(--space-4) 0 var(--space-5);
  min-height: 60px;
  font: var(--type-caption);
  color: var(--fg-secondary);
}

.plan ul {
  margin: 0 0 var(--space-6);
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-25);
  font: var(--type-ui);
  color: var(--fg-secondary);
}

.plan .button {
  margin-top: auto;
}

/* Inline rather than a flex row: the line wraps on a narrow card, and a flex
   row puts the tag beside the first line with the rest of the sentence under
   it. */
.soon {
  color: var(--fg-tertiary);
}

.tag {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  height: 18px;
  padding: 0 var(--space-15);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  font: var(--type-code);
  color: var(--fg-tertiary);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}

.tag-accent {
  border-color: var(--accent-border);
  background: var(--accent-muted);
  color: var(--accent-fg);
}

/* ── The comparison table ────────────────────────────────── */

.compare {
  margin-top: var(--space-6);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  overflow-x: auto;
}

.compare table {
  width: 100%;
  border-collapse: collapse;
}

.compare th {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-default);
  font: var(--type-label);
  color: var(--fg-tertiary);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  text-align: left;
}

.compare th.accent {
  color: var(--accent-fg);
}

.compare td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  font: var(--type-ui);
  color: var(--fg-secondary);
  text-align: left;
  vertical-align: top;
}

.compare tbody tr:last-child td {
  border-bottom: 0;
}

.compare th:first-child {
  width: 40%;
}

.compare td:first-child {
  color: var(--fg-primary);
}

.compare .count {
  font: var(--type-code-lg);
}

.compare .none {
  color: var(--fg-tertiary);
}

/* ── Question and answer ─────────────────────────────────── */

.qa {
  margin-top: var(--space-6);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6) var(--space-9);
}

.qa h3 {
  margin: 0 0 var(--space-2);
  font: var(--type-subheading);
}

.qa p {
  margin: 0;
  font: var(--type-caption);
  color: var(--fg-secondary);
}

/* The FAQ page, where an answer is a paragraph rather than a line. */
.faq > section {
  margin-bottom: var(--space-9);
}

.faq h2 {
  margin: 0 0 var(--space-5);
  font: var(--type-subheading);
  color: var(--fg-tertiary);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.faq-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.faq h3 {
  margin: 0 0 var(--space-2);
  font: var(--type-heading);
  letter-spacing: var(--tracking-snug);
}

.faq p {
  margin: 0;
  font: var(--type-body);
  color: var(--fg-secondary);
}

/* ── A panel that ends a page ────────────────────────────── */

.panel {
  margin-top: var(--space-10);
  margin-bottom: var(--space-10);
  padding: var(--space-6);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  display: flex;
  align-items: center;
  gap: var(--space-6);
  flex-wrap: wrap;
}

.panel > div:first-child {
  flex: 1;
  min-width: 300px;
}

.panel h2 {
  margin: 0 0 var(--space-2);
  font: var(--type-heading);
}

.panel p {
  margin: 0;
  font: var(--type-caption);
  color: var(--fg-secondary);
}

.panel .actions {
  margin-top: 0;
}

/* ── A document with a sticky rail: changelog and legal ──── */

/* The bottom margin matches the top padding, so a release sits the same distance
   from the rule above it as from the one below. Without it the last bullet of one
   lands on the next one's border, because `.changes:last-child ul` takes that
   list's own bottom margin away. */
.doc {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: var(--space-9);
  padding-top: var(--space-7);
  margin-bottom: var(--space-7);
  border-top: 1px solid var(--border-subtle);
}

.doc-rail {
  position: sticky;
  top: 80px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
}

.doc-rail h2 {
  margin: 0;
  font: var(--weight-medium) var(--text-3xl) / 1 var(--font-mono);
  letter-spacing: var(--tracking-tight);
}

.doc-rail .kind {
  font: var(--type-label);
  color: var(--fg-tertiary);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.doc-rail .version {
  font: var(--type-code);
  color: var(--fg-tertiary);
}

.doc-entries article + article {
  margin-top: var(--space-7);
  padding-top: var(--space-7);
  border-top: 1px solid var(--border-subtle);
}

.doc-lede {
  margin: 0 0 var(--space-7);
  max-width: var(--prose-max);
  font: var(--type-body);
  color: var(--fg-secondary);
}

.changes h3 {
  margin: 0 0 var(--space-4);
  font: var(--type-label);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.changes-added h3 {
  color: var(--status-passed-fg);
}

.changes-fixed h3 {
  color: var(--status-running-fg);
}

.changes-changed h3 {
  color: var(--accent-fg);
}

.changes ul {
  margin: 0 0 var(--space-8);
  padding: 0 0 0 var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-25);
  max-width: var(--prose-max);
}

.changes li {
  margin: 0;
  font: var(--type-body);
  color: var(--fg-secondary);
}

.changes:last-child ul {
  margin-bottom: 0;
}

.callout {
  margin-top: var(--space-9);
  margin-bottom: var(--space-9);
  padding: var(--space-5) var(--space-6);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}

.callout p {
  margin: 0;
  font: var(--type-caption);
  color: var(--fg-secondary);
}

/* ── Legal ───────────────────────────────────────────────── */

.notice {
  margin: var(--space-6) 0 0;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--status-waiting-border);
  border-radius: var(--radius-md);
  background: var(--status-waiting-muted);
  max-width: var(--prose-max);
}

.notice p {
  margin: 0;
  font: var(--type-caption);
  color: var(--status-waiting-fg);
}

/* The strip's own underline is the separator, which is why the article below it
   drops the rule a release gets. */
.tabs {
  display: flex;
  gap: var(--space-5);
  margin-top: var(--space-6);
  border-bottom: 1px solid var(--border-default);
}

.hero-tabs {
  padding-bottom: 0;
}

.doc-plain {
  border-top: 0;
  padding-top: var(--space-8);
}

.tabs a:not(.button) {
  padding: var(--space-2) 0;
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  font: var(--type-ui);
  color: var(--fg-secondary);
  text-decoration: none;
}

.tabs a:not(.button):hover {
  color: var(--fg-primary);
}

.tabs a:not(.button)[aria-current] {
  border-bottom-color: var(--accent-solid);
  color: var(--fg-primary);
  font: var(--type-ui-medium);
}

.clauses h3 {
  margin: var(--space-8) 0 var(--space-3);
  font: var(--type-heading);
  letter-spacing: var(--tracking-snug);
}

.clauses h3:first-child {
  margin-top: 0;
}

.clauses h3 .num {
  font: var(--type-code);
  color: var(--fg-tertiary);
  margin-right: var(--space-2);
}

.clauses p {
  margin: 0 0 var(--space-3);
  max-width: var(--prose-max);
  font: var(--type-body);
  color: var(--fg-secondary);
}

.clauses strong {
  color: var(--fg-primary);
  font-weight: var(--weight-semibold);
}

/* #245: a rule file shown whole, on the baseline rules guide - not prose, so
   it sits outside the max-width `.clauses p` reads at and wraps rather than
   scrolling, since a line this site did not write can run past any width
   chosen for one that fits. */
.file-block {
  margin: var(--space-6) 0 0;
  padding: var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}

.file-path {
  margin: 0 0 var(--space-2);
  font: var(--type-code);
  color: var(--fg-tertiary);
}

.file-block pre {
  margin: 0;
  font: var(--type-code);
  color: var(--fg-secondary);
  white-space: pre-wrap;
  word-break: break-word;
}

/* ── The foot ────────────────────────────────────────────── */

.footer {
  border-top: 1px solid var(--border-subtle);
  background: var(--surface-base);
}

.footer-grid {
  padding-top: var(--space-9);
  padding-bottom: var(--space-9);
  display: grid;
  grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr));
  gap: var(--space-7);
}

.footer-brand p {
  margin: var(--space-3) 0 0;
  max-width: 34ch;
  font: var(--type-caption);
  color: var(--fg-tertiary);
}

.footer-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.footer-col h2 {
  margin: 0;
  font: var(--type-label);
  color: var(--fg-tertiary);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.footer-col a:not(.button) {
  font: var(--type-ui);
  color: var(--fg-secondary);
  text-decoration: none;
}

.footer-col a:not(.button):hover {
  color: var(--fg-primary);
}

.footer-bottom {
  border-top: 1px solid var(--border-subtle);
}

.footer-bottom-inner {
  padding-top: var(--space-4);
  padding-bottom: var(--space-4);
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  font: var(--type-code);
  color: var(--fg-tertiary);
}

/* ── Narrow ──────────────────────────────────────────────── */

@media (max-width: 900px) {
  .stats,
  .cards-2,
  .cards-3,
  .plans,
  .qa,
  .faq {
    grid-template-columns: minmax(0, 1fr);
  }

  .split,
  .doc {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
  }

  .hero-split {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-7);
  }

  /* The 16ch that keeps the headline out of the drawing's way is a headline of
     four short lines once the drawing is underneath it. */
  .hero-split h1 {
    max-width: 22ch;
  }

  .doc-rail {
    position: static;
  }

  .steps li {
    grid-template-columns: 32px minmax(0, 1fr);
  }

  .steps li::before {
    grid-row: span 2;
  }

  .footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .hero h1 {
    font: var(--weight-semibold) var(--text-5xl) / 1.1 var(--font-sans);
    letter-spacing: var(--tracking-tight);
  }

  .pipeline-note {
    margin-left: 0;
  }
}

@media (max-width: 560px) {
  .nav-inner {
    height: auto;
    padding-top: var(--space-3);
    padding-bottom: var(--space-3);
    flex-wrap: wrap;
    gap: var(--space-3);
  }

  .nav-links {
    gap: var(--space-4);
  }

  /* #210: Pricing, Docs, FAQ, Changelog and the rule between them - the mark,
     the theme control, Sign in and Start free stay, and the footer already
     carries the same four links for whoever wants them at this width. */
  .nav-text-links {
    display: none;
  }

  .footer-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
