/*
 * AWO site styles — LOOP-SPEC 001 · Rev B.
 *
 * The values here are not a second design. They are the SAME tokens
 * `ui/src/styles/base.css` defines, restated for the site, and then mapped onto
 * VitePress's own `--vp-*` variables so the default theme picks them up
 * wholesale: nav, sidebar, code blocks, the home hero, buttons, tables and the
 * search dialog all inherit at once, instead of each being overridden by hand.
 * `tokens.test.ts` holds the two in step.
 *
 * The look is an engineering datasheet, for the reason the product's tokens
 * give: AWO is a control system, and the document that has always described a
 * control system is a spec sheet. Graph paper, hard offset shadows with no
 * blur, ink rules, and one oscilloscope-orange trace. Somebody arriving from the
 * docs and opening the Studio should not feel they have changed products.
 */

/* ── Type, self-hosted ──────────────────────────────────────────────────
   Bundled rather than fetched from a CDN, matching the Studio: the fonts ARE
   the identity here (the display face only exists at 125% width), so a blocked
   or slow CDN would render a near-right page, which is the worst way to be
   wrong. Copied from `ui/public/fonts` into `docs/public/fonts`. */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  /* The VARIABLE build: headings are set at 125% width, and that axis exists
     only here. A static Archivo would render at normal width. */
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("/static/marketing/fonts/archivo-var-latin.woff2") format("woff2");
}

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

:root {
  /* ── AWO tokens, identical to the Studio's ───────────────────────── */
  --paper: #eef0f3;
  --grid-line: #d6dae1;
  --grid-step: 28px;

  --ink: #14181f;
  --surface: #ffffff;
  --surface-hover: #e7eaef;
  --surface-active: #d9dee6;

  --line-faint: #e4e7ec;
  --line: #c9cfd8;
  --line-strong: var(--ink);

  --text: var(--ink);
  --text-secondary: #47505e;
  --text-tertiary: #6b7482;
  --text-on-accent: var(--ink);

  --accent: #e8541a;
  --accent-hover: #cf4712;
  --accent-active: #b03c0e;
  --accent-soft: rgb(232 84 26 / 12%);
  --accent-line: rgb(232 84 26 / 45%);

  --ok: #1a7f4b;
  --warn: #9a5b00;
  --err: #c22a1b;

  --invert-bg: var(--ink);
  --invert-text: #dfe3ea;
  --invert-line: #333b47;

  --font-display:
    "Archivo", "Archivo Expanded", ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
  --font-sans:
    "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, "Noto Sans", sans-serif;
  --font-mono:
    "IBM Plex Mono", ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, "Liberation Mono",
    monospace;

  /* Copied from the Studio's base.css, where they have always lived. Their
     absence here was not cosmetic: `body` set `line-height:
     var(--leading-normal)` against nothing, so every block on the site fell
     back to the browser default and the whole page read as cramped. */
  --leading-tight: 1.25;
  --leading-normal: 1.45;
  --leading-relaxed: 1.6;

  /* ── Type scale ───────────────────────────────────────────────────────
     A marketing page is read at arm's length on a large screen, and the
     Studio's UI sizes are tuned for the opposite: dense, close, deliberate.
     Same faces and same tokens, one step up in scale, and fluid so the
     headings do not fall off a phone. */
  --step-hero: clamp(2.125rem, 1.4rem + 2.6vw, 3rem);
  --step-h2: clamp(1.5rem, 1.2rem + 1.1vw, 2rem);
  --step-lede: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
  --step-body: 1rem;
  --step-small: 0.875rem;

  /* Vertical rhythm between arguments on the long page. */
  --section-gap: clamp(56px, 7vw, 96px);
}

/* ── Page ──────────────────────────────────────────────────────────────
   Graph paper, fixed so the page reads as ink laid ON the paper rather than
   as a texture scrolling behind it.

   The ruling is drawn far fainter here than in the Studio, and that difference
   is deliberate rather than drift. On the canvas the grid is a working surface:
   it is what you align nodes against, so it has to be legible. Full-bleed
   behind a page of prose the same ruling stops being a surface and becomes
   noise — it competes with every heading, and the page reads as a wireframe
   somebody forgot to finish. Here it is a watermark: present enough to say
   "same product", quiet enough to disappear while you read. */
* {
  box-sizing: border-box;
}
/* Both, because the property only reaches the viewport when the root carries
   it — set on `body` alone the page still scrolled sideways. */
html {
  overflow-x: clip;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step-body);
  line-height: var(--leading-relaxed);
  color: var(--text);
  background-color: var(--paper);
  background-image:
    linear-gradient(to right, rgb(20 24 31 / 4%) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(20 24 31 / 4%) 1px, transparent 1px);
  background-size: var(--grid-step) var(--grid-step);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  /* The full-bleed bands below paint themselves by reaching past the viewport.
     That is only visual, but the reach still counts towards scroll width, so
     the page gained a horizontal scrollbar. `clip` rather than `hidden`: hidden
     makes this a scroll container and quietly breaks the sticky header. */
  overflow-x: clip;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-stretch: 125%;
  letter-spacing: -0.02em;
}
h1 {
  font-size: var(--step-hero);
  line-height: 1.04;
  margin: 0 0 16px;
}
/*
  A section heading is where the eye lands when scanning, so it gets the space
  rather than the rule. The old hairline-plus-20px did the opposite: it drew a
  line across the page and left the heading crowded against the paragraph above
  it, which is why every block looked like the same block.
*/
h2 {
  font-size: var(--step-h2);
  line-height: 1.12;
  margin: var(--section-gap) 0 14px;
  padding-top: 0;
  border-top: 0;
  position: relative;
}
/* Close enough to read as this heading's mark rather than as a stray rule
   stranded in the gap between two sections. */
h2::before {
  content: "";
  position: absolute;
  top: -20px;
  left: 0;
  width: 30px;
  height: 3px;
  background: var(--accent);
}
h3 {
  font-size: 1.125rem;
  line-height: 1.2;
  margin: 28px 0 8px;
}
p {
  margin: 0 0 14px;
}
code,
.mono {
  font-family: var(--font-mono);
  font-size: 0.9em;
}
a {
  color: var(--accent-hover);
  text-decoration-color: var(--accent-line);
  text-underline-offset: 3px;
}
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Prose stops at a readable measure; figures, grids and tables use the width. */
.wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 28px;
}
main p:not([class]),
main .muted:not([style]) {
  max-width: 68ch;
}

/* ── Chrome ─────────────────────────────────────────────────────────── */
.topbar {
  /* Translucent rather than solid: content scrolling under a sticky bar that
     shares the page's exact background reads as content disappearing into
     nothing. A slight blur keeps the bar legible without hiding what passes
     beneath it. */
  background: rgb(255 255 255 / 88%);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar-inner {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 60px;
}
.wordmark {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-stretch: 125%;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
}
.wordmark-block {
  width: 14px;
  height: 14px;
  background: var(--accent);
}
.topnav {
  display: flex;
  gap: 18px;
  margin-left: auto;
  align-items: center;
}
.topnav a {
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 14px;
}
.topnav a:hover {
  color: var(--text);
}

/* ── The printed button ─────────────────────────────────────────────── */
.btn {
  display: inline-block;
  padding: 9px 18px;
  border-radius: 3px;
  border: 1px solid var(--ink);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 2px 2px 0 rgb(20 24 31 / 14%);
  transition:
    transform 90ms ease,
    box-shadow 90ms ease;
}
.btn:hover {
  background: var(--surface-hover);
}
.btn:active {
  transform: translate(2px, 2px);
  box-shadow: none;
}
.btn-primary {
  background: var(--accent);
  color: var(--text-on-accent);
}
.btn-primary:hover {
  background: var(--accent-hover);
}

/* ── Cards, tables, notes ───────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  padding: 26px;
  box-shadow: 4px 4px 0 rgb(20 24 31 / 9%);
}
.eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: 0 0 8px;
}
.muted {
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
}
.lede,
.muted.lede {
  font-size: var(--step-lede);
}
.note {
  border-left: 2px solid var(--accent);
  padding-left: 14px;
  color: var(--text-secondary);
}

/* ── Pricing ────────────────────────────────────────────────────────── */
.tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
  margin: 28px 0;
}
.tier {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.tier-price {
  font-family: var(--font-display);
  font-stretch: 125%;
  font-size: 34px;
  font-weight: 700;
}
.tier-price small {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 400;
  color: var(--text-tertiary);
}
.tier ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tier li {
  padding-left: 18px;
  position: relative;
  font-size: 14px;
}
.tier li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 5px;
  height: 5px;
  background: var(--accent);
}
.tier li.off {
  color: var(--text-tertiary);
}
.tier li.off::before {
  background: var(--line);
}
.tier-featured {
  border-width: 2px;
}

/* ── Download ───────────────────────────────────────────────────────── */
.dl {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
.dl-meta {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-tertiary);
}
pre.term {
  background: var(--invert-bg);
  color: var(--invert-text);
  border-radius: 4px;
  padding: 16px;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.6;
}
/*
  The run inspector shows real values, and a real value is usually longer than
  the box. Left to scroll horizontally the ends were simply invisible — the
  panel promised "what this step was given" and then hid half of it, which is
  the exact opposite of the point being made on that part of the page.
*/
.run-io pre.term {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
footer {
  margin: var(--section-gap) 0 48px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  color: var(--text-tertiary);
  font-size: 13px;
}

/* ── Insights ──────────────────────────────────────────────────────────
   The back office. Denser than the marketing pages on purpose: this is read
   by one person looking for a number, not by a visitor being persuaded. */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin: 28px 0;
}
.stat {
  padding: 18px;
}
.stat-figure {
  font-family: var(--font-display);
  font-stretch: 125%;
  font-size: 34px;
  font-weight: 700;
  margin: 0;
  line-height: 1.1;
}
.stat-note {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-tertiary);
  margin: 6px 0 0;
}

.bars {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 120px;
  padding: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
}
.bar-slot {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: flex-end;
}
/* A day with no activity still gets a hairline, so the axis reads as a row of
   days rather than as a gap in the chart. */
.bar {
  width: 100%;
  min-height: 1px;
  background: var(--accent);
}

.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
  margin: 20px 0;
}
table.grid {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--line);
  background: var(--surface);
}
table.grid th {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  text-align: left;
  background: var(--surface-hover);
  font-weight: 600;
}
table.grid th,
table.grid td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--line-faint);
  font-size: var(--step-small);
}
table.grid td.num {
  text-align: right;
  font-family: var(--font-mono);
}

/* ── Home ──────────────────────────────────────────────────────────────
   The long page. Each block is a separate argument, so they are spaced apart
   rather than run together, and the interactive ones sit in cards to mark them
   as things you can touch. */
/*
  The hero sits on white rather than on the paper, pulled full-bleed behind a
  centred column. It gives the page a top: something to land on, and a clean
  edge where the paper starts. Without it the first thing a visitor met was
  ruled paper with text floating on it and no sense of where the page began.
*/
.hero {
  position: relative;
  padding: clamp(56px, 8vw, 96px) 0 clamp(48px, 6vw, 72px);
  margin-bottom: var(--section-gap);
}
/*
  Full-bleed white band from inside a centred column.

  `calc(-50vw + 50%)` reaches from the element's own edge to exactly the
  viewport edge and no further. An earlier version used a 100vmax shadow spread
  with a clip, which painted the same band but told the page it was 2,600px
  wide — invisible, unscrollable, and still enough to make every full-page
  capture come out padded with empty paper.
*/
.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0 calc(-50vw + 50%);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.hero-grid {
  display: grid;
  gap: clamp(32px, 4vw, 56px);
  align-items: center;
}
.hero-copy > * {
  max-width: 58ch;
}
@media (min-width: 1000px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  }
}
.hero-file {
  background: var(--invert-bg);
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 6px 6px 0 rgb(20 24 31 / 12%);
}
.hero-file-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  border-bottom: 1px solid var(--invert-line);
  font: 400 11px var(--font-mono);
  color: var(--text-tertiary);
  letter-spacing: 0.05em;
}
.hero-file pre {
  margin: 0;
  padding: 18px;
  overflow-x: auto;
  font: 400 12.5px/1.75 var(--font-mono);
  color: var(--invert-text);
}
.hero-file .k {
  color: #8fb4ff;
}
.hero-file .s {
  color: #f0a071;
}
.hero-file .c {
  color: #6b7482;
}
.hero h1 {
  max-width: 20ch;
}
.hero .lede {
  font-size: var(--step-lede);
  line-height: 1.5;
  color: var(--text-secondary);
}
.hero-actions {
  margin: 32px 0 14px;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.hero-actions .btn {
  padding: 12px 24px;
  font-size: 15px;
}

/* The nine primitives, each carrying its kind's seam — the same 2px edge the
   canvas card and the inspector header use, so a node is recognisable before
   you have opened the product. */
.kinds {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px;
  margin: 26px 0 0;
}
.kind {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--seam);
  border-radius: 4px;
  padding: 16px 18px;
  transition:
    box-shadow 120ms ease,
    transform 120ms ease;
}
.kind:hover {
  box-shadow: 3px 3px 0 rgb(20 24 31 / 9%);
  transform: translateY(-1px);
}
.kind-name {
  margin: 0 0 5px;
  font-weight: 600;
  font-size: 15px;
}
.kind-note {
  margin: 0;
  font-size: var(--step-small);
  color: var(--text-secondary);
  line-height: 1.5;
}

/* The batch calculator. */
.calc {
  margin: 22px 0 8px;
}
.calc-controls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
  margin-bottom: 22px;
}
.calc-controls label {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.calc-controls input[type="range"] {
  width: 100%;
  accent-color: var(--accent);
}
.calc-out {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--line-faint);
}
.calc-figure {
  font-family: var(--font-display);
  font-stretch: 125%;
  font-size: clamp(28px, 2.4vw, 36px);
  font-weight: 700;
  margin: 6px 0 0;
  line-height: 1.05;
}
.calc-figure.accent {
  color: var(--accent-hover);
}
.calc-note {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-tertiary);
  margin: 5px 0 0;
  line-height: 1.4;
}

/* Opening a step in a finished run. */
.run {
  display: grid;
  grid-template-columns: minmax(200px, 260px) 1fr;
  gap: 18px;
  margin: 22px 0;
  align-items: start;
}
.run-steps {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.run-steps button {
  display: flex;
  align-items: center;
  gap: 10px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 10px 12px;
  font: 600 13px var(--font-sans);
  color: var(--text);
  cursor: pointer;
}
.run-steps button:hover {
  background: var(--surface-hover);
}
/* The open step carries the trace, the same seam the product uses for "this is
   the one you are looking at". */
.run-steps button.is-open {
  border-color: var(--ink);
  box-shadow: inset 2px 0 0 var(--accent);
}
.run-mark {
  font-family: var(--font-mono);
  font-size: 12px;
}
.run-mark.ok {
  color: var(--ok);
}
.run-mark.skip {
  color: var(--text-tertiary);
}
.run-detail {
  min-height: 200px;
}
.run-io {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}
.run-io pre {
  margin: 6px 0 0;
  max-height: 200px;
  overflow: auto;
}

.switch {
  display: flex;
  gap: 10px;
  margin: 18px 0 14px;
  flex-wrap: wrap;
}

.reasons {
  max-width: 66ch;
  list-style: none;
  padding-left: 20px;
}
.reasons li {
  position: relative;
  margin-bottom: 8px;
}
.reasons li::before {
  content: "";
  position: absolute;
  left: -18px;
  top: 0.6em;
  width: 5px;
  height: 5px;
  background: var(--accent);
}

.cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin: var(--section-gap) 0 0;
  padding: 30px;
  border-width: 2px;
}

@media (max-width: 720px) {
  .run {
    grid-template-columns: 1fr;
  }
  .hero h1 {
    font-size: 30px;
  }
}

/*
  A real screenshot, framed like the printed cards around it.

  Capped in height and cropped from the top, because the Studio's canvas is
  mostly empty space by design — shown whole it was two thousand pixels of
  blank graph paper, and the thing worth seeing (the palette, the nodes, the
  inspector) was a band across the top. A screenshot that has to be scrolled
  past is not showing the product, it is hiding it.
*/
.shot {
  margin: 26px 0 0;
}
.shot-frame {
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 6px 6px 0 rgb(20 24 31 / 10%);
  background: var(--surface);
}
/* A title bar, so the screenshot reads as an application window rather than a
   picture that happens to be rectangular. */
.shot-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-hover);
}
.shot-bar span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--line);
}
.shot-bar span:first-child {
  background: var(--accent);
}
.shot-bar em {
  margin-left: 8px;
  font: 400 11px var(--font-mono);
  font-style: normal;
  color: var(--text-tertiary);
  letter-spacing: 0.04em;
}
.shot img {
  width: 100%;
  display: block;
  max-height: 620px;
  object-fit: cover;
  object-position: top center;
}
.shot figcaption {
  font-size: 11px;
  margin-top: 10px;
}
.run-steps button {
  font-size: var(--step-small) !important;
}

/* The comparison scrolls inside itself rather than pushing the page sideways. */
.compare-wrap {
  overflow-x: auto;
  margin: 20px 0;
}
.compare {
  min-width: 640px;
}
.compare td:first-child {
  color: var(--text-secondary);
}
.compare th:nth-child(2),
.compare td:nth-child(2) {
  background: var(--accent-soft);
  font-weight: 600;
}

.trust {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 14px;
  margin: 22px 0;
}

/* ── Narrow ────────────────────────────────────────────────────────────
   Most of a marketing page is read on a phone, and a page that scrolls
   sideways reads as broken however good the content is. */
@media (max-width: 760px) {
  .topbar-inner {
    height: auto;
    padding: 10px 0;
    flex-wrap: wrap;
    gap: 10px;
  }
  .topnav {
    margin-left: 0;
    width: 100%;
    flex-wrap: wrap;
    gap: 14px;
  }
  .wordmark {
    font-size: 13px;
  }
  /* Every table on the site scrolls inside its own box rather than pushing the
     page. `display:block` is what makes a table honour overflow at all. */
  table.grid {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }
  .hero {
    padding-top: 32px;
  }
  .calc-out {
    gap: 12px;
  }
}

/* ── The live graph ────────────────────────────────────────────────────
   Sized as a diagram, not a second hero. The SVG is capped rather than
   stretched to the column: at full width its 11px labels scaled up to headline
   size and nine small boxes filled a screen, which made a supporting figure
   read as the main event. */
.graph-demo {
  max-width: 620px;
  margin: 34px auto 0;
  padding: 20px 22px 16px;
}
.graph-demo figcaption {
  margin-bottom: 14px;
}
.graph-blurb {
  margin: 0;
  font-size: var(--step-small);
}
.graph-svg {
  width: 100%;
  height: auto;
  display: block;
}
.graph-controls {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
/* Compact enough that three of them sit on one line beside the figure. */
.graph-pick {
  display: flex;
  flex-direction: column;
  gap: 1px;
  text-align: left;
  padding: 6px 11px;
  font-size: 12px;
  box-shadow: none;
}
.graph-pick-note {
  font-size: 9px;
  color: var(--text-tertiary);
}
.graph-pick.btn-primary .graph-pick-note {
  color: var(--ink);
}
.graph-note {
  margin: 12px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--line-faint);
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--text-secondary);
  min-height: 2.6em;
}

/* On a phone the figure would scale to ~340px wide and take its 11px labels
   down to six, which is a diagram nobody can read. Below the breakpoint it
   keeps a legible minimum and scrolls inside its own card instead. */
@media (max-width: 640px) {
  .graph-demo {
    overflow-x: auto;
  }

  .graph-svg {
    min-width: 460px;
  }
}

/* ── Chrome: skip link and footer ──────────────────────────────────────
   Both are new furniture built from existing parts — the same rule colour,
   card border and mono eyebrow the rest of the site uses. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 40;
  background: var(--accent);
  color: var(--ink);
  padding: 10px 16px;
  font-weight: 600;
  text-decoration: none;
}
.skip:focus {
  left: 0;
}

.site-footer {
  margin-top: var(--section-gap);
  padding: 40px 0 44px;
  background: var(--surface);
  border-top: 1px solid var(--line);
}
.footer-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 28px;
}
.footer-cols ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.footer-cols a {
  color: var(--text-secondary);
  text-decoration: none;
  font-size: var(--step-small);
}
.footer-cols a:hover {
  color: var(--text);
  text-decoration: underline;
}
.footer-note {
  margin: 0;
  font-size: var(--step-small);
  max-width: 30ch;
}
.footer-legal {
  margin: 32px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--line-faint);
  color: var(--text-tertiary);
  font-size: 12.5px;
}

/* ── Numbered steps ────────────────────────────────────────────────────
   "How it works" and the install sequence. The number is the point, so it
   carries the accent and everything else stays quiet. */
.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
  margin: 26px 0 0;
  counter-reset: step;
}
.step {
  position: relative;
  padding-top: 34px;
}
.step::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  top: 0;
  left: 0;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: var(--ink);
  font: 700 12px var(--font-mono);
  border-radius: 3px;
}
.step h3 {
  margin: 0 0 6px;
  font-size: 1rem;
}
.step p {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--step-small);
}

/* ── Use-case cards ────────────────────────────────────────────────────
   A card per real job, each naming the inputs and the actions it wires, so
   the reader recognises their own problem rather than a category. */
.cases {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  gap: 16px;
  margin: 26px 0 0;
}
.case h3 {
  margin: 0 0 8px;
  font-size: 1.0625rem;
}
.case p {
  margin: 0 0 12px;
  color: var(--text-secondary);
  font-size: var(--step-small);
}
.case-wire {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding-top: 12px;
  border-top: 1px solid var(--line-faint);
  font: 400 10.5px var(--font-mono);
  color: var(--text-tertiary);
}
.case-wire span {
  padding: 2px 7px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper);
  white-space: nowrap;
}
.case-wire em {
  font-style: normal;
  color: var(--accent-hover);
}

/* ── FAQ ───────────────────────────────────────────────────────────────
   Native `<details>`: no script, works before the JavaScript loads, and
   keyboard-operable for free. A hand-rolled accordion would be worse in every
   one of those ways. */
.faq {
  margin: 26px 0 0;
  border-top: 1px solid var(--line-faint);
}
.faq details {
  border-bottom: 1px solid var(--line-faint);
}
.faq summary {
  cursor: pointer;
  padding: 15px 30px 15px 0;
  font-weight: 600;
  font-size: var(--step-body);
  position: relative;
  list-style: none;
}
.faq summary::-webkit-details-marker {
  display: none;
}
.faq summary::after {
  content: "+";
  position: absolute;
  right: 4px;
  top: 13px;
  font: 400 18px var(--font-mono);
  color: var(--accent-hover);
}
.faq details[open] summary::after {
  content: "−";
}
.faq summary:hover {
  color: var(--accent-hover);
}
.faq .faq-body {
  padding: 0 0 16px;
  color: var(--text-secondary);
  font-size: var(--step-small);
  max-width: 70ch;
}
.faq .faq-body p {
  margin: 0 0 10px;
}
.faq .faq-body p:last-child {
  margin: 0;
}

/* ── Section intro ─────────────────────────────────────────────────────
   Heading plus one line, used often enough that repeating an inline style on
   every instance had started to produce four slightly different widths. */
.lead {
  max-width: 66ch;
  color: var(--text-secondary);
  font-size: var(--step-lede);
  line-height: 1.5;
}

/* ── Callout ───────────────────────────────────────────────────────────
   The card, with the accent seam already used for "this is the important
   one" on the canvas and in the error example. */
.callout {
  border-left: 3px solid var(--accent);
  margin: 22px 0 0;
}
.callout p:last-child {
  margin: 0;
}

/* ── Changelog ─────────────────────────────────────────────────────────── */
.log {
  margin: 26px 0 0;
  border-top: 1px solid var(--line-faint);
}
.log details {
  border-bottom: 1px solid var(--line-faint);
  padding: 2px 0;
}
.log summary {
  cursor: pointer;
  padding: 13px 30px 13px 0;
  font-size: var(--step-small);
  font-weight: 600;
  list-style: none;
  position: relative;
}
.log summary::-webkit-details-marker {
  display: none;
}
.log summary::after {
  content: "›";
  position: absolute;
  right: 6px;
  top: 11px;
  font: 400 16px var(--font-mono);
  color: var(--text-tertiary);
}
.log details[open] summary::after {
  transform: rotate(90deg);
}
.log summary:hover {
  color: var(--accent-hover);
}
.log .log-body {
  padding: 0 0 16px;
  color: var(--text-secondary);
  font-size: 13px;
  max-width: 78ch;
}

/* ── CTA band ──────────────────────────────────────────────────────────
   One per page, at the bottom. Two actions at most: a primary, and a lower
   friction alternative for somebody not ready to take it. */
.cta-band {
  margin: var(--section-gap) 0 0;
  padding: 32px;
  border-width: 2px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.cta-band h2 {
  margin: 0 0 6px;
  font-size: 1.375rem;
}
.cta-band h2::before {
  display: none;
}
.cta-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* ── Feature blocks ────────────────────────────────────────────────────
   Alternating text and evidence. Each block answers the same four questions,
   so the reader learns the shape once and can skim the rest. */
.feature {
  display: grid;
  gap: clamp(20px, 3vw, 40px);
  align-items: start;
  padding: 30px 0;
  border-bottom: 1px solid var(--line-faint);
}
@media (min-width: 900px) {
  .feature {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}
.feature h3 {
  margin: 0 0 10px;
  font-size: 1.25rem;
}
.feature-why {
  font-size: var(--step-small);
  color: var(--text-secondary);
}
.feature dl {
  margin: 14px 0 0;
  display: grid;
  gap: 10px;
}
.feature dt {
  font: 400 10px var(--font-mono);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.feature dd {
  margin: 2px 0 0;
  font-size: var(--step-small);
  color: var(--text-secondary);
}

/* ── Interactive feedback ──────────────────────────────────────────────
   Buttons and links already had hover; what was missing was the sense that a
   press does something. The offset shadow is the site's existing device, so
   the motion is the same idea, animated. */
.btn:hover {
  transform: translate(-1px, -1px);
  box-shadow: 3px 3px 0 rgb(20 24 31 / 18%);
}
.btn:active {
  transform: translate(2px, 2px);
  box-shadow: none;
}
@media (prefers-reduced-motion: reduce) {
  .btn,
  .btn:hover,
  .btn:active,
  .kind:hover {
    transform: none;
    transition: none;
  }
}

/* ── Page heads ────────────────────────────────────────────────────────
   Every page below the homepage opens the same way: eyebrow, h1, one lead
   paragraph. It was an inline style repeated on six templates, which is how
   six pages ended up with four different top margins. */
.page-head {
  padding: clamp(36px, 5vw, 56px) 0 0;
}
.page-head h1 {
  max-width: 20ch;
}

/* The first h2 on a page follows a lead paragraph, not another section, so it
   does not need the full between-sections gap. */
.page-head + h2 {
  margin-top: calc(var(--section-gap) * 0.7);
}

/* ── Download ──────────────────────────────────────────────────────────── */
.btn-lg {
  padding: 12px 24px;
  font-size: 15px;
}
.dl-main {
  margin: 30px 0 0;
  border-width: 2px;
}
.dl-name {
  margin: 0;
  font-weight: 600;
  font-size: 17px;
  font-family: var(--font-mono);
}
.dl-sub {
  font-size: 11px;
  margin: 10px 0 0;
}

.tier-blurb {
  margin: 6px 0 0;
  font-size: var(--step-small);
}

/* Sections carry their own rhythm now, so a heading that opens one must not
   add its gap on top of the section's. */
section > h2:first-child {
  margin-top: 0;
}
section {
  margin-top: var(--section-gap);
}
section:first-of-type {
  margin-top: 0;
}

/* ── Cycle badges ──────────────────────────────────────────────────────
   "read-only" and "gate" are the two properties that make Autopilot safe to
   leave running, so they are marked on the cycle rather than left to the
   paragraph. Green for a gate (it stops things), blue-grey for read-only (it
   cannot write) — the same semantic colours the canvas uses. */
.badge-ro,
.badge-gate {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 2px;
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: 1px;
  border: 1px solid var(--line);
  color: var(--text-tertiary);
  background: var(--paper);
}
.badge-gate {
  border-color: rgb(26 127 75 / 45%);
  color: var(--ok);
}
