/* ox landing page. Plain CSS, no build step. Fonts and icons are self-hosted (fonts/LICENSES.md). */
@font-face { font-family: "Switzer"; src: url("fonts/switzer-300.woff2") format("woff2"); font-weight: 300; font-display: swap; }
@font-face { font-family: "Switzer"; src: url("fonts/switzer-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Switzer"; src: url("fonts/switzer-500.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Switzer"; src: url("fonts/switzer-600.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Familjen Grotesk"; src: url("fonts/familjen-var.woff2") format("woff2"); font-weight: 400 700; font-display: swap; }
@font-face { font-family: "Fragment Mono"; src: url("fonts/fragment-mono-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Caveat"; src: url("fonts/caveat-500.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Geist"; src: url("fonts/geist-var.woff2") format("woff2"); font-weight: 100 900; font-style: normal; font-display: swap; }
@font-face { font-family: "JetBrains Mono"; src: url("fonts/jetbrains-mono-var.woff2") format("woff2"); font-weight: 400 800; font-style: normal; font-display: swap; }

@property --n { syntax: "<integer>"; initial-value: 0; inherits: false; }

:root {
  /* Light surfaces: neutral, not cream. */
  --bg: #FBFBFA;
  --stage: #F1F1EF;
  --card: #FFFFFF;
  --line: #E7E7E4;
  --ink: #111111;
  --on-ink: #F5F5F3;
  --text: #333333;
  --subtle: #6F6F6F;
  --faint: #A6A6A2;
  /* Dark surfaces: the dashboard, the AI card, the footer. */
  --night: #0F0F0E;
  --night-2: #171716;
  --night-line: #292927;
  --night-text: #D2D2CE;
  --night-subtle: #8D8D88;
  /* State colors, used only where a state is shown. */
  --ok: #2FB463;
  --ok-ink: #1C7F45;
  --ok-soft: #74D6A2;
  --warn: #E9A23B;
  /* Danger, the console's tokens (docs/design/README.md "Danger"): a flat
     maroon surface with white text and a hairline; a readable red only
     for the rare text on a neutral surface. */
  --danger-bg: #871c27;
  --danger-bg-hover: #972631;
  --danger-bg-active: #781923;
  --danger-fg: #ffffff;
  --danger-border: #5e1219;
  --danger-soft: color-mix(in srgb, var(--danger-bg) 8%, transparent);
  --danger-text: #a52230;
  --blue: #519DFA;
  --bar: #0077E6;
  --radius: 14px;
  --display: "Familjen Grotesk", ui-sans-serif, system-ui, sans-serif;
  --sans: "Switzer", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Fragment Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --hand: "Caveat", "Bradley Hand", cursive;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  /* The landing's text sizes. Each one reaches the board's size at 1440px
     wide and shrinks with the viewport down to a phone's size at 390px. */
  --fs-lede: clamp(18px, calc(16.5px + 0.381vw), 22px);
  --fs-body: clamp(16.5px, calc(15.2px + 0.333vw), 20px);
  --fs-small: clamp(15.5px, calc(14.57px + 0.238vw), 18px);
  --fs-note: clamp(13.5px, calc(12.57px + 0.238vw), 16px);
  --fs-h3: clamp(19px, calc(17.14px + 0.476vw), 24px);
  --fs-item: clamp(18px, calc(16.5px + 0.381vw), 22px);
}
/* The page defaults to the OS theme; the nav toggle overrides it
   (PRD_ox1.md V-42). The attribute is set by the inline script in the
   pages' head; dark resolves to the console's Blue palette. */
:root[data-theme="dark"] {
  --bg: #030614;
  --stage: #04081a;
  --card: #070d1e;
  --line: #10172b;
  --ink: #f1f5f9;
  --on-ink: #030614;
  --text: #cbd5e1;
  --subtle: #8b9bb4;
  --faint: #5b6b85;
  /* The "night" components (the dashboard mock, the comparison column,
     the report, the pro plan, the AI card, the footer, code blocks) take
     the blue palette too, instead of clashing neutral blacks (V-42). */
  --night: #050a1a;
  --night-2: #0a1120;
  --night-line: #15203a;
  --night-text: #cbd5e1;
  --night-subtle: #8b9bb4;
  --danger-bg: #701a23;
  --danger-bg-hover: #7d212a;
  --danger-bg-active: #60151d;
  --danger-border: #bc4f5a;
  --danger-soft: color-mix(in srgb, var(--danger-bg) 30%, transparent);
  --danger-text: #ef8d97;
  color-scheme: dark;
}
/* The head's color-scheme meta says "light dark" for the first paint; the
   page's own choice then wins. */
:root:not([data-theme="dark"]) { color-scheme: light; }

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
/* Controls skip the double-tap-zoom wait and never end up text-selected
   by a long press. */
.nav-links a, .nav-login, .theme-toggle { -webkit-user-select: none; user-select: none; touch-action: manipulation; }
body { margin: 0; background: var(--bg); color: var(--text); font: 400 17px/1.6 var(--sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; }
img, svg { display: block; }
a { color: inherit; }
p, h1, h2, h3, ul, ol, figure, blockquote, pre { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button { font: inherit; color: inherit; }
code { font: 400 .88em var(--mono); font-variant-ligatures: none; background: var(--stage); padding: 2px 6px; border-radius: 5px; color: var(--ink); }

.wrap { width: min(var(--max, 1200px), 100% - var(--gutter)); margin-inline: auto; }
:root { --gutter: clamp(32px, 5vw, 72px); }
@media (min-width: 1600px) { :root { --max: 1320px; } }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip-link { position: absolute; left: 16px; top: -60px; background: var(--ink); color: var(--on-ink); padding: 10px 14px; border-radius: 8px; z-index: 100; }
.skip-link:focus { top: 12px; }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 6px; }
.muted { color: var(--subtle); }
.ic { width: 18px; height: 18px; flex: none; }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  height: 46px; padding: 0 20px; border-radius: 8px; border: 1px solid transparent;
  font: 500 15px/1 var(--sans); text-decoration: none; cursor: pointer; white-space: nowrap;
  transition-property: transform, background-color, border-color, color;
  transition-duration: 160ms; transition-timing-function: var(--ease);
}
.btn:active:not(:disabled) { transform: scale(.97); }
.btn-sm { height: 36px; padding: 0 14px; font-size: 14px; border-radius: 7px; gap: 7px; }
.btn-sm .ic { width: 16px; height: 16px; }
.nav-login { display: inline-flex; align-items: center; gap: 7px; }
.nav-login .ic { width: 16px; height: 16px; }
.btn-dark { background: var(--ink); color: var(--on-ink); }
@media (hover: hover) { .btn-dark:hover:not(:disabled) { background: #333; } }
.btn-ghost { color: var(--ink); border-color: var(--line); background: var(--card); }
@media (hover: hover) { .btn-ghost:hover { border-color: #C9C9C5; } }
.btn:disabled { cursor: not-allowed; opacity: .8; }

/* Nav */
.nav { position: sticky; top: 0; z-index: 50; padding-top: env(safe-area-inset-top); background: color-mix(in srgb, var(--bg) 86%, transparent); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 68px; }
.logo { display: block; border-radius: 4px; }
.logo-mark { width: 30px; height: 24px; color: var(--ink); }
.logo-mark-sm { width: 22.5px; height: 18px; }
.nav-links { display: flex; gap: 28px; }
.nav-links a { display: inline-flex; align-items: center; gap: 7px; }
.nav-links .ic { width: 16px; height: 16px; color: var(--subtle); transition: color 150ms ease; }
.nav-links a[aria-current] .ic { color: var(--ink); }
@media (hover: hover) { .nav-links a:hover .ic { color: var(--ink); } }
.nav-links a[aria-current] { color: var(--ink); }
.nav-links a, .nav-login { font-size: 15px; text-decoration: none; color: var(--text); transition: color 150ms ease; }
@media (hover: hover) { .nav-links a:hover, .nav-login:hover { color: var(--ink); } }
.nav-actions { display: flex; align-items: center; gap: 22px; }

/* Theme toggle: flips between light and dark, saved in localStorage. */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 8px; border: none;
  background: transparent; color: var(--subtle); cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease;
}
@media (hover: hover) { .theme-toggle:hover { background: var(--stage); color: var(--ink); } }
.theme-toggle .ic { width: 18px; height: 18px; }
/* The sun shows in dark mode (press to go light), the moon in light mode. */
.theme-toggle .ic-sun { display: none; }
html[data-theme="dark"] .theme-toggle .ic-sun { display: block; }
html[data-theme="dark"] .theme-toggle .ic-moon { display: none; }

/* Type scale. Familjen Grotesk 600 carries every headline, Switzer everything else. */
.display { font: 600 clamp(52px, 6.6vw, 92px)/1 var(--display); letter-spacing: -0.035em; color: var(--ink); text-wrap: balance; }
.h2 { font: 600 clamp(36px, 4.2vw, 54px)/1.06 var(--display); letter-spacing: -0.028em; color: var(--ink); text-wrap: balance; }
.body { margin-top: 20px; max-width: 540px; font-size: 18px; color: var(--text); text-wrap: pretty; }

/* Board pages: the landing and /features, drawn to the v11 boards
   (docs/design/README.md "Site boards"). The palette and type are set on
   the nav and main only, so the footer and the phone's sign-up bar keep
   the site's own. Light is the board redrawn on white; dark is the
   board's black. The release console, the bill's ox row and the closing
   mountains are dark in both themes, so they always take the black set. */
body.site-board { background: var(--bg); }
.site-board .nav, .site-board main {
  color-scheme: light;
  --bg: #FBFBFA; --stage: #F1F1EF; --card: #FFFFFF; --line: #E5E5E2;
  --ink: #0A0A0A; --on-ink: #FFFFFF; --text: #333333; --subtle: #616161; --faint: #8A8A8A;
  --hair: #D4D4D4; --hair-hover: #A3A3A3; --panel: #FFFFFF; --panel-hover: #F4F4F2;
  --body: #525252; --strong: #262626; --ink-hover: #333333; --nav-line: #EDEDEA;
  --navy: #061545; --navy-line: #13296B; --link: #1A3A8F;
  --display: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --sans: var(--display);
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  font-family: var(--sans); color: var(--text);
}
[data-theme="dark"] body.site-board { background: #000; }
[data-theme="dark"] .site-board .nav, [data-theme="dark"] .site-board main,
.site-board .hero-band, .site-board .final {
  color-scheme: dark;
  --bg: #000000; --stage: #0A0A0A; --card: #0A0A0A; --line: #262626;
  --ink: #FFFFFF; --on-ink: #000000; --text: #D4D4D4; --subtle: #A1A1A1; --faint: #737373;
  --hair: #404040; --hair-hover: #737373; --panel: #050505; --panel-hover: #111111;
  --body: #A3A3A3; --strong: #E5E5E5; --ink-hover: #E5E5E5; --nav-line: #1A1A1A;
  --link: #8FA3D9;
}
.site-board main code { background: var(--stage); color: var(--text); }

/* Nav: the lockup, the links beside it, then Log in and Deploy free. */
.site-board .nav { background: var(--bg); border-bottom: 1px solid var(--nav-line); backdrop-filter: none; -webkit-backdrop-filter: none; }
.site-board .nav-inner { height: 63px; justify-content: flex-start; gap: 32px; }
.site-board .nav-inner > nav { flex: 1; }
.site-board .logo { display: flex; align-items: center; gap: 6px; text-decoration: none; }
.site-board .logo-mark { width: 25px; height: 20px; }
.logo-word { display: none; }
.site-board .logo-word { display: block; font: 600 23px/1 var(--display); letter-spacing: -1px; color: var(--ink); }
.site-board .nav-links a, .site-board .nav-login { font-size: 16px; font-weight: 500; line-height: 16px; }
.site-board .nav-links a { color: var(--subtle); }
.site-board .nav-login { color: var(--ink); }
.site-board .nav-actions { gap: 32px; }
.site-board .nav-cta { height: auto; padding: 9px 14px; gap: 10px; border-radius: 8px; font-size: 16px; line-height: 16px; }
.site-board .nav-cta .ic { width: 17px; height: 17px; }

/* Type and buttons */
.site-board .display { font: 600 clamp(52px, 6.74vw, 97px)/1 var(--display); letter-spacing: -0.036em; }
.site-board .h2 { font: 600 clamp(36px, 3.68vw, 53px)/1.075 var(--display); letter-spacing: -0.028em; }
.site-board .h2 > span { color: var(--faint); }
.site-board main .btn { height: auto; padding: 14px 22px; gap: 10px; border-radius: 8px; font-size: 18px; line-height: 18px; }
.site-board main .btn .ic { width: 20px; height: 20px; }
.site-board main .btn-ghost { background: transparent; border-color: var(--hair); color: var(--ink); }
@media (hover: hover) {
  .site-board .btn-dark:hover:not(:disabled) { background: var(--ink-hover); }
  .site-board .btn-ghost:hover { border-color: var(--hair-hover); }
}
.site-board .eyebrow { font: 500 15px/23px var(--mono); font-variant-ligatures: none; color: var(--subtle); }
.site-board .sec-head .h2 { margin-top: 16px; }
.site-board .cta-note { font-size: 16px; font-weight: 500; line-height: 24px; color: var(--subtle); }
/* Each section is a full-width band ruled at its top, 96px in from it. */
.site-board .section { padding-block: 96px; border-top: 1px solid var(--line); }
.site-board .ill { margin: 0; }
.site-board .ill img { width: 100%; height: 100%; object-fit: contain; }

/* Hero: the promise centered, then the releases console on a navy band. */
.hero { padding-top: 40px; }
.hero-head { display: flex; flex-direction: column; align-items: center; text-align: center; }
.hero-pill { display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border: 1px solid var(--line); border-radius: 99px; font-size: 16px; font-weight: 500; line-height: 22px; color: var(--text); }
.hero-pill .ic { width: 16px; height: 16px; color: #2FA36B; }
.hero-title { margin-top: 32px; }
.hero-title span { display: block; }
.hero-sub { margin-top: 28px; max-width: 740px; font-size: var(--fs-lede); line-height: 1.6; color: var(--subtle); text-wrap: pretty; }
.hero-head .cta-row { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 40px; }
.hero-head .cta-note { margin-top: 16px; }

.hero-band { width: min(calc(var(--max, 1200px) + 64px), 100% - var(--gutter) / 2); margin-top: 32px; padding: 24px 32px 0; border: 1px solid var(--navy-line); border-bottom: 0; border-radius: 20px 20px 0 0; background: var(--navy); }
.rel { border: 1px solid var(--line); border-bottom: 0; border-radius: 12px 12px 0 0; background: #0A0A0A; color: var(--subtle); font: 500 15px/23px var(--mono); font-variant-ligatures: none; overflow: hidden; }
.rel-bar { display: flex; align-items: center; gap: 12px; padding: 16px 24px; border-bottom: 1px solid var(--line); }
.rel-app { display: flex; align-items: baseline; gap: 12px; }
.rel-app strong { font: 600 18px/18px var(--sans); color: var(--ink); }
.rel-tabs { display: flex; gap: 6px; margin: 0 16px 0 auto; }
.rel-tabs span { padding: 5px 10px; border-radius: 6px; line-height: 18px; }
.rel-tabs .is-on { background: var(--navy-line); color: #E7ECF7; }
.rel-live { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 99px; background: #0F2A1D; color: #4CC38A; font-size: 14px; line-height: 17px; }
.rel-live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #2FA36B; }
.rel-body { display: grid; gap: 22px; padding: 20px 24px; }
.rel-head { display: flex; justify-content: space-between; gap: 16px; }
/* The release rail: a node per release, joined by a line to the next. */
.rel-line { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)) 140px; }
.rel-line li { position: relative; display: grid; align-content: start; gap: 2px; padding-top: 22px; color: var(--subtle); }
.rel-line li::before { content: ""; position: absolute; top: 0; left: 0; width: 10px; height: 10px; box-sizing: border-box; border: 1px solid var(--hair); border-radius: 50%; background: var(--bg); }
.rel-line li::after { content: ""; position: absolute; top: 4.5px; left: 10px; right: 0; height: 1px; background: var(--hair); }
.rel-line li:last-child::after { display: none; }
.rel-line b { font-weight: 500; color: var(--ink); }
.rel-line .is-gone, .rel-line .is-gone b { color: #8F8F8F; }
.rel-line .is-gone::before { border-color: #262626; background: #262626; }
.rel-line .is-gone::after { background: #262626; }
.rel-line .is-live { color: #2FA36B; }
.rel-line .is-live::before { border-color: #FAFAFA; background: #FAFAFA; }
.rel-line .is-live::after { background: repeating-linear-gradient(90deg, #737373 0 6px, transparent 6px 11px); }
.rel-line .is-next::before { border-color: #737373; }
.rel-line .is-next b { color: var(--subtle); }
.rel-undo { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; padding-top: 6px; }
.rel-btn { display: inline-flex; align-items: center; gap: 10px; padding: 9px 14px; border: 1px solid var(--hair); border-radius: 8px; font: 500 16px/16px var(--sans); color: var(--ink); }
.rel-btn .ic { width: 16px; height: 16px; }

/* Stacks: a calm, static wall of what ox runs, in a ruled strip. */
.stack { padding-block: 72px 80px; border-block: 1px solid var(--line); }
.stack-label { display: flex; align-items: center; gap: 10px; font-size: var(--fs-small); line-height: 1.5; color: var(--subtle); }
.stack-label .ic { width: 20px; height: 20px; color: var(--link); }
.stack-list { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
.stack-list li { display: flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px; border: 1px solid var(--line); border-radius: 99px; background: var(--card); font-size: 16px; font-weight: 500; color: var(--text); white-space: nowrap; }
.stack-list .ic { width: 16px; height: 16px; color: var(--subtle); }

/* How it works: three steps on a rail beside the drawing, then the button. */
#how { border-top: 0; }
.how-grid { display: grid; grid-template-columns: minmax(0, 460px) minmax(0, 1fr); gap: 80px; align-items: center; }
.how-grid .sec-head { margin-bottom: 48px; }
.steps li { position: relative; display: grid; gap: 6px; padding: 0 0 32px 30px; }
.steps li::before { content: ""; position: absolute; left: 0; top: 10px; width: 10px; height: 10px; box-sizing: border-box; border: 1px solid var(--hair-hover); border-radius: 50%; }
.steps li::after { content: ""; position: absolute; left: 4.5px; top: 20px; bottom: 0; width: 1px; background: var(--hair); }
.steps li:last-child::after { display: none; }
.steps h3 { display: flex; align-items: center; gap: 12px; font: 600 var(--fs-h3)/1.25 var(--sans); letter-spacing: -0.3px; color: var(--ink); }
.step-n { font: 500 15px/15px var(--mono); font-variant-ligatures: none; color: var(--subtle); }
.steps p { max-width: 430px; font-size: var(--fs-body); line-height: 1.6; color: var(--subtle); text-wrap: pretty; }
.how-cta { margin-top: 56px; }
.how-cta .cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }

/* What you get: the PaaS parts, four across. */
.parts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 48px 40px; }
.parts h3 { display: flex; align-items: center; gap: 10px; font: 600 var(--fs-item)/1.3 var(--sans); color: var(--ink); }
.parts h3 .ic { width: 18px; height: 18px; color: var(--link); }
.parts p { margin-top: 8px; font-size: var(--fs-small); line-height: 1.55; color: var(--subtle); text-wrap: pretty; }

/* Compare: the usual choices beside ox, one question per row. */
.bill-head { display: flex; align-items: center; justify-content: space-between; gap: 40px; margin-bottom: 48px; }
.bill-head .sec-head { max-width: 680px; margin-bottom: 0; }
.bill-ill { flex: 0 1 420px; aspect-ratio: 3 / 2; }
.compare-scroll { overflow-x: auto; }
.compare-table { width: 100%; min-width: 760px; border-collapse: separate; border-spacing: 0; font-size: var(--fs-small); line-height: 1.55; table-layout: fixed; }
.compare-table th, .compare-table td { padding: 18px 20px; text-align: left; vertical-align: top; text-wrap: pretty; }
.compare-table tbody th, .compare-table tbody td { border-top: 1px solid var(--line); }
.compare-table thead th { font: 600 var(--fs-item)/1.3 var(--sans); color: var(--ink); vertical-align: bottom; }
.compare-table thead th span { display: block; margin-top: 4px; font-size: var(--fs-note); font-weight: 500; color: var(--subtle); }
.compare-table thead td:first-child { width: 22%; }
.compare-table tbody th { font-weight: 600; color: var(--ink); }
.compare-table td { color: var(--text); }
.compare-table .is-ox { background: var(--stage); color: var(--ink); font-weight: 500; }
.compare-table thead .is-ox { border-radius: 10px 10px 0 0; }
.compare-table tbody tr:last-child .is-ox { border-radius: 0 0 10px 10px; }
.bill-note { margin-top: 24px; font-size: var(--fs-note); font-weight: 500; line-height: 1.5; color: var(--subtle); }

/* Up close: four features, two across, each under its drawing; the full list below. */
.upclose-head { margin-bottom: 80px; }
.upclose { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 80px 48px; }
.upclose .ill { height: 350px; }
.upclose h3 { display: flex; align-items: center; gap: 10px; margin-top: 28px; font: 600 var(--fs-h3)/1.25 var(--sans); letter-spacing: -0.3px; color: var(--ink); }
.upclose h3 .ic { width: 22px; height: 22px; color: var(--link); }
.upclose p { margin-top: 14px; font-size: var(--fs-body); line-height: 1.6; color: var(--body); text-wrap: pretty; }
.upclose code { display: inline-block; margin-top: 14px; padding: 7px 12px; border-radius: 6px; font-size: 15px; line-height: 20px; }
.see-all { display: flex; align-items: center; justify-content: center; gap: 8px; height: 56px; margin-top: 80px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); font-size: var(--fs-small); font-weight: 500; color: var(--ink); text-decoration: none; transition: border-color 150ms ease; }
@media (hover: hover) { .see-all:hover { border-color: var(--hair); } }
.see-all .ic { width: 16px; height: 16px; }

/* Trust: two questions, each beside its drawing. */
#trust { padding-bottom: 64px; }
#trust .sec-head { margin-bottom: 56px; }
.trust-row { display: grid; grid-template-columns: minmax(0, 720px) minmax(0, 432px); gap: 48px; align-items: center; justify-content: space-between; }
.trust-row + .trust-row { margin-top: 56px; }
.trust-row-flip { grid-template-columns: minmax(0, 432px) minmax(0, 720px); }
.trust-row .ill { aspect-ratio: 12 / 7; }
.trust-q { margin-bottom: 24px; font: 600 clamp(22px, calc(19px + 0.762vw), 30px)/1.27 var(--sans); letter-spacing: -0.3px; color: var(--ink); }
.trust-row-flip .trust-q { margin-bottom: 20px; font-size: var(--fs-h3); line-height: 1.25; }
.trust-list { display: grid; gap: 20px; }
.trust-list li { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 14px; padding-top: 20px; border-top: 1px solid var(--line); }
.trust-list .ic { width: 24px; height: 24px; color: var(--link); }
.trust-list strong { display: block; font-size: var(--fs-body); font-weight: 600; line-height: 1.4; color: var(--ink); }
.trust-list p { margin-top: 6px; font-size: var(--fs-body); line-height: 1.6; color: var(--body); text-wrap: pretty; }

/* From the founder: the greeting and byline beside the note. */
.founder { display: grid; grid-template-columns: auto minmax(0, 660px); gap: 80px; align-items: start; justify-content: center; }
.founder .sec-head { margin-bottom: 40px; }
.founder-by { display: flex; align-items: center; gap: 14px; }
.founder-by img { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; }
.founder-by > span { display: grid; gap: 4px; }
.founder-by strong { font-size: var(--fs-small); font-weight: 500; line-height: 1.5; color: var(--ink); }
.founder-by span span { font: 500 15px/23px var(--mono); font-variant-ligatures: none; color: var(--subtle); }
.founder-text { display: grid; gap: 20px; padding-top: 8px; font-size: var(--fs-body); line-height: 1.6; color: var(--strong); text-wrap: pretty; }
.founder-text a { display: inline-flex; align-items: center; gap: 4px; color: var(--link); text-decoration: none; }
.founder-text a .ic { width: 16px; height: 16px; }
@media (hover: hover) { .founder-text a:hover { text-decoration: underline; text-underline-offset: 3px; } }

/* Apps: the proven apps in one ruled grid, the first four rows until "Show all" opens. */
.apps-lede { margin-top: 20px; max-width: 820px; font-size: var(--fs-lede); line-height: 1.6; color: var(--subtle); text-wrap: pretty; }
.apps-how { display: inline-flex; align-items: center; gap: 6px; margin: 40px 0; font-size: var(--fs-small); font-weight: 500; line-height: 1.5; color: var(--link); text-decoration: none; }
.apps-how .ic { width: 16px; height: 16px; }
@media (hover: hover) { .apps-how:hover { text-decoration: underline; text-underline-offset: 3px; } }
.apps-box { padding: 1px; border-radius: 12px; background: var(--line); overflow: hidden; }
.apps-box .oneshot-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1px; }
.apps-box .oneshot-grid li { display: grid; }
.apps-box .oneshot-grid a { grid-template-columns: 18px minmax(0, 1fr); column-gap: 12px; row-gap: 2px; min-height: 56px; padding: 8px 16px; border: 0; border-radius: 0; background: var(--panel); }
.apps-box .oneshot-grid .ic { width: 18px; height: 18px; }
.apps-box .oneshot-grid strong { font-size: 16px; font-weight: 500; line-height: 19px; color: var(--strong); }
.apps-box .oneshot-grid span { font: 400 14px/17px var(--mono); font-variant-ligatures: none; color: var(--body); }
.apps-box .oneshot-grid li:nth-child(n+21) { display: none; }
.apps-box:has(.apps-more[open]) .oneshot-grid li { display: grid; }
.apps-more { margin-top: 1px; background: var(--panel); }
.apps-more summary { display: flex; justify-content: center; align-items: center; gap: 8px; height: 56px; list-style: none; cursor: pointer; font-size: var(--fs-small); font-weight: 500; color: var(--ink); }
.apps-more summary::-webkit-details-marker { display: none; }
.apps-more .ic { width: 16px; height: 16px; transition: transform 200ms var(--ease); }
.apps-more[open] .ic { transform: rotate(180deg); }
@media (hover: hover) { .apps-box .oneshot-grid a:hover, .apps-more summary:hover { background: var(--panel-hover); } }

/* Pricing: a cream band on the board, as on the board. It sets its own
   light palette, so every rule inside reads the same tokens. */
.pricing-band { --ink: #000000; --text: #404040; --subtle: #525252; --faint: #6B6B6B; --line: #E8E5DC; --card: #FFFFFF; padding-block: 96px; background: #F6F4EE; color: var(--text); }
.pricing-lede { margin-top: 20px; max-width: 620px; font-size: var(--fs-lede); line-height: 1.6; color: var(--text); text-wrap: pretty; }
.plans { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; margin-top: 56px; }
.plan { position: relative; display: flex; flex-direction: column; padding: 32px; border: 1px solid #DCD8CC; border-radius: 16px; background: var(--card); }
.plan-pro { border-color: var(--navy); }
.plan h3 { font: 600 var(--fs-item)/1.3 var(--sans); color: var(--ink); }
.price { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 16px 0 20px; }
.price strong { font: 600 clamp(52px, calc(48.3px + 0.952vw), 62px)/1 var(--display); letter-spacing: -2px; color: var(--ink); font-variant-numeric: tabular-nums; }
.price span { font-size: var(--fs-small); color: var(--subtle); }
.plan ul { flex: 1; margin-bottom: 32px; }
.plan li { display: grid; grid-template-columns: 16px minmax(0, 1fr); gap: 12px; padding: 12px 0; border-top: 1px solid var(--line); font-size: var(--fs-small); line-height: 1.55; color: var(--text); text-wrap: pretty; }
.plan li .ic { width: 16px; height: 16px; margin-top: 4px; color: #1C7F45; }
.site-board .btn-plan { width: 100%; height: 50px; padding-block: 0; border-color: var(--navy); background: transparent; color: var(--navy); font-size: 16px; }
.site-board .btn-plan-pro { background: var(--navy); color: #F6F4EE; }
@media (hover: hover) { .site-board .btn-plan:hover { background: #0615450d; } .site-board .btn-plan-pro:hover { background: #0b1f5c; } }

.plans-fine { margin-top: 40px; font-size: 16px; line-height: 24px; color: #404040; }

/* FAQ */
#faq { padding-bottom: 70px; }
.faq-grid { display: grid; grid-template-columns: minmax(0, 460px) minmax(0, 660px); gap: 80px; justify-content: space-between; align-items: start; }
.faq-grid .sec-head { margin-bottom: 24px; }
.faq-ask { display: flex; align-items: center; gap: 10px; max-width: 464px; font-size: 20px; line-height: 32px; color: var(--subtle); }
.faq-ask .ic { flex: none; width: 59px; height: 66px; color: var(--link); }
.faq-ask span span { display: block; }
.faq-ask a { color: var(--link); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: color-mix(in srgb, var(--link) 40%, transparent); }
.faq-ask a:hover { text-decoration-color: currentColor; }
.faq details { border-top: 1px solid var(--line); }
.faq summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 20px; padding: 24px 0; font: 600 var(--fs-item)/1.32 var(--sans); color: var(--ink); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: ""; flex: none; width: 14px; height: 14px; background: linear-gradient(currentColor, currentColor) center / 14px 1.5px no-repeat, linear-gradient(currentColor, currentColor) center / 1.5px 14px no-repeat; color: var(--subtle); transition: background-size 200ms var(--ease); }
.faq details[open] summary::after { background-size: 14px 1.5px, 1.5px 0; }
.faq details p { max-width: 600px; padding: 0 0 24px; margin-top: -14px; font-size: var(--fs-body); line-height: 1.6; color: var(--text); animation: fade-up .35s var(--ease); }
.faq-link { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-small); font-weight: 500; color: var(--link); text-decoration: none; }
.faq-link .ic { width: 16px; height: 16px; }
@media (hover: hover) { .faq-link:hover { text-decoration: underline; text-underline-offset: 3px; } }

/* One-shot apps (oneshot_apps.go): the apps whose guide is served, on the landing and /self-hosting. */
.oneshot-grid, .prose .oneshot-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; padding: 0; list-style: none; }
.oneshot-grid a { display: grid; grid-template-columns: 20px minmax(0, 1fr); column-gap: 10px; align-items: center; padding: 12px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); color: var(--ink); text-decoration: none; transition: border-color 150ms ease; }
.oneshot-grid .ic { grid-row: span 2; width: 20px; height: 20px; color: var(--subtle); }
.oneshot-grid strong { font-size: 15px; font-weight: 600; line-height: 1.3; }
.oneshot-grid span { font-size: 13px; line-height: 1.3; color: var(--subtle); }
@media (hover: hover) { .oneshot-grid a:hover { border-color: color-mix(in srgb, var(--ink) 26%, var(--line)); } }
@media (max-width: 560px) { .oneshot-grid, .prose .oneshot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Sections */
.section { padding-top: clamp(104px, 12vw, 168px); }

/* Section heads: a small mono label, then a two-line heading whose second line is quieter. */
.eyebrow { display: flex; align-items: center; gap: 8px; font: 400 15px/1.4 var(--mono); font-variant-ligatures: none; color: var(--subtle); }
.eyebrow .ic { width: 16px; height: 16px; }
.sec-head { max-width: 760px; margin-bottom: 48px; }
.sec-head .h2 { margin-top: 14px; }
.h2 > span { display: block; color: var(--subtle); }


/* The ox leaning on the ox Pro card. Its body is clipped at the card's top edge (y=84 in the
   SVG) so it rises from behind the card; the forelegs are drawn over it. 132px = 1.1x the viewBox. */
.ox-buddy { position: absolute; left: 26px; top: -92px; pointer-events: none; }
.ox-fig { width: 132px; height: 114px; overflow: visible; }
.ox-fig * { transform-box: view-box; }
/* The ox's own palette. It always sits on the light pricing band, so one palette serves both themes. */
.ox-fig { --ox-line: #111111; --ox-body: #FFFFFF; --ox-horn: #F1E2C2; --ox-muzzle: #F4D6C8; --ox-pink: #F2C2B3; --ox-cheek: #F2A594; --ox-hoof: #3A3A37; }
.ox-skin { fill: var(--ox-body); stroke: var(--ox-line); stroke-width: 2; stroke-linejoin: round; }
.ox-horn { fill: var(--ox-horn); stroke: var(--ox-line); stroke-width: 2; stroke-linejoin: round; }
.ox-muzzle { fill: var(--ox-muzzle); stroke: var(--ox-line); stroke-width: 2; }
.ox-pink { fill: var(--ox-pink); }
.ox-cheek { fill: var(--ox-cheek); opacity: .55; }
.ox-ink { fill: var(--ox-line); }
.ox-line { fill: none; stroke: var(--ox-line); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* Forelegs are round-capped strokes: an ink stroke under a narrower white one draws an outlined limb. */
.ox-leg path { fill: none; stroke-linecap: round; }
.ox-leg-line { stroke: var(--ox-line); stroke-width: 15; }
.ox-leg-fill { stroke: var(--ox-body); stroke-width: 11; }
.ox-hoof { stroke: var(--ox-hoof); stroke-width: 11; }
.ox-note { position: absolute; left: 150px; top: 14px; display: flex; align-items: flex-start; gap: 2px; white-space: nowrap; font: 500 25px/1 var(--hand); color: #061545; transform: rotate(-4deg); }
.ox-note-arrow { width: 44px; height: 36px; margin-top: 12px; }

.ox-head { transform-origin: 60px 60px; animation: ox-tilt 5.5s ease-in-out infinite alternate; }
.ox-blink { transform-origin: 60px 36px; animation: ox-blink 4.8s infinite; }
.ox-ear-l { transform-origin: 38px 36px; animation: ox-flick-l 7s ease-in-out infinite; }
.ox-ear-r { transform-origin: 82px 36px; animation: ox-flick-r 7s ease-in-out 2.4s infinite; }
.ox-tap { transform-origin: 99px 81px; animation: ox-tap 3.6s ease-in-out 2s infinite; }
.ox-joy { transform-origin: 60px 84px; }
.ox-eyes { transition: transform 180ms var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .plan-pro:hover .ox-joy { animation: ox-hop 520ms var(--ease); }
}
/* Entrance, once the ox Pro card scrolls in: rise, drop the forelegs on the edge, then speak. */
.js .plan-pro.in .ox-rise { animation: ox-rise 760ms var(--ease) backwards; }
.js .plan-pro.in .ox-paws { animation: ox-paws 320ms var(--ease) 520ms backwards; }
.js .plan-pro.in .ox-note { animation: ox-note 420ms var(--ease) 870ms backwards; }
@keyframes ox-rise { from { transform: translateY(90px); } 72% { transform: translateY(-3px); } to { transform: none; } }
@keyframes ox-paws { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes ox-note { from { opacity: 0; transform: translateY(6px) rotate(-4deg); } to { opacity: 1; transform: rotate(-4deg); } }
@keyframes ox-tilt { from { transform: rotate(-3deg); } to { transform: rotate(4deg); } }
@keyframes ox-blink { 0%, 93%, 97%, 100% { transform: none; } 95% { transform: scaleY(.1); } }
@keyframes ox-flick-l { 0%, 88%, 100% { transform: none; } 92% { transform: rotate(14deg); } 96% { transform: rotate(-4deg); } }
@keyframes ox-flick-r { 0%, 88%, 100% { transform: none; } 92% { transform: rotate(-14deg); } 96% { transform: rotate(4deg); } }
@keyframes ox-tap { 0%, 70%, 100% { transform: none; } 76%, 88% { transform: rotate(9deg); } 82%, 94% { transform: none; } }
@keyframes ox-hop { 40% { transform: translateY(-6px) scaleY(1.03); } 70% { transform: translateY(1px) scaleY(.98); } }

/* Final: the dark mountains that close the landing, above the footer. */
.final { position: relative; background: var(--night); overflow: hidden; isolation: isolate; border-top: 1px solid var(--line); }
.mountains { position: absolute; inset: auto 0 0 0; width: 100%; height: 72%; z-index: -1; }
.final-grid { display: grid; grid-template-columns: 1fr 1.1fr; gap: 64px; align-items: end; padding: clamp(96px, 11vw, 140px) 0 clamp(80px, 9vw, 120px); }
.final-mark { width: 121px; height: 97px; color: #F5F5F3; }
.final-tag { margin-top: 32px; font: 300 26px/1.25 var(--sans); letter-spacing: -0.02em; color: #F5F5F3; }
.final .cta-row { display: flex; align-items: center; gap: 12px; margin-top: 40px; flex-wrap: wrap; }
.final .cta-note { margin-top: 16px; }
@media (max-width: 880px) { .final-grid { grid-template-columns: 1fr; gap: 40px; } }

/* Footer */
.footer { background: var(--night); color: var(--night-subtle); border-top: 1px solid var(--night-line); }
.footer-inner { display: flex; align-items: flex-start; justify-content: space-between; gap: 32px 56px; flex-wrap: wrap; padding-block: 44px calc(40px + env(safe-area-inset-bottom)); font-size: 14.5px; }
.footer-brand { display: grid; gap: 14px; }
.footer a.footer-love { display: inline-grid; grid-template-columns: auto auto auto; justify-content: start; align-items: start; gap: 8px; padding-block: 4px; font-size: 14px; line-height: 1.45; }
.footer-love .ic { width: 18px; height: 18px; margin-top: 2px; }
.footer-love .ic-go { opacity: .6; transition: transform 150ms ease, opacity 150ms ease; }
@media (prefers-reduced-motion: reduce) { .footer-love .ic-go { transition: none; } }
@media (hover: hover) { .footer-love:hover .ic-go { opacity: 1; transform: translate(2px, -2px); } .footer-love:hover span { text-decoration: underline; text-underline-offset: 3px; } }
.footer .logo-mark { color: #F5F5F3; }
.footer-cols { display: grid; grid-template-columns: repeat(5, auto); gap: 24px 64px; }
.footer-h { margin-bottom: 6px; font: 500 14px/20px var(--sans); color: #F5F5F3; }
.footer ul { display: grid; }
.footer a { display: inline-flex; align-items: center; min-height: 32px; text-decoration: none; transition: color 150ms ease; }
.footer a[aria-current] { color: #F5F5F3; }
.footer a.footer-ext { gap: 8px; }
.footer-ext .ic { width: 16px; height: 16px; }
@media (hover: hover) { .footer a:hover { color: #F5F5F3; } }

/* Headline motion. Hero words rise out of a mask, then "own" gets a hand-drawn
   underline. Transforms only: the old blur and font-weight settle repainted
   every frame (see the 60fps-animation skill). Section headings behave the
   same; their final weight is set statically. */
.display em { font-style: normal; font-weight: 600; position: relative; white-space: nowrap; }
.display .w { display: inline-block; overflow: clip; overflow-clip-margin: .12em; vertical-align: top; padding-bottom: .06em; }
.display .w > span { display: inline-block; }
.display .ul { position: absolute; left: -2%; bottom: -.08em; width: 104%; height: .22em; overflow: visible; color: var(--ink); }
.display .ul path { stroke-dasharray: 1; stroke-dashoffset: 0; }
.js .display .w > span { transform: translateY(105%); animation: word-in 1100ms var(--ease) forwards; animation-delay: calc(120ms + var(--i) * 90ms); }
.js .display .ul path { stroke-dashoffset: 1; animation: draw 700ms cubic-bezier(.6,0,.2,1) 1050ms forwards; }
@keyframes word-in { to { transform: none; } }
@keyframes draw { to { stroke-dashoffset: 0; } }
.reveal .h2 { font-weight: 600; }
/* Scroll reveal: only hidden when JS runs, so the page still reads without it. */
.js .reveal { opacity: 0; transform: translateY(12px); transition: opacity 600ms var(--ease), transform 600ms var(--ease); }
.js .reveal.in { opacity: 1; transform: none; }

/* Keyframes */
@keyframes fade-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Responsive */
@media (max-width: 880px) {
  .nav-links { display: none; }
  .hero-band { padding: 16px 16px 0; }
  .how-grid, .faq-grid, .founder { grid-template-columns: 1fr; gap: 40px; }
  .parts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bill-head { flex-direction: column; align-items: stretch; gap: 24px; }
  .bill-ill { flex: none; max-width: 420px; }
  .upclose { grid-template-columns: 1fr; gap: 56px; }
  .upclose-head { margin-bottom: 48px; }
  .see-all { margin-top: 56px; }
  .trust-row, .trust-row-flip { grid-template-columns: 1fr; gap: 32px; }
  .trust-row-flip > .ill { order: -1; }
  .apps-box .oneshot-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .plans { grid-template-columns: 1fr; max-width: 560px; }
  .plan-pro { margin-top: 88px; }
}
@media (max-width: 560px) {
  .nav-login { display: none; }
  .rel-tabs { display: none; }
  /* The timeline as a column: each release a row, the line runs down. */
  .rel-line { grid-template-columns: 1fr; }
  .rel-line .is-gone { display: none; }
  .rel-line li { padding: 0 0 16px 24px; }
  .rel-line li:last-child { padding-bottom: 0; }
  .rel-line li::before { top: 6px; }
  .rel-line li::after { top: 16px; bottom: 0; left: 4.5px; right: auto; width: 1px; height: auto; }
  .rel-line .is-live::after { background: repeating-linear-gradient(180deg, #737373 0 6px, transparent 6px 11px); }
  .parts { grid-template-columns: 1fr; }
  .upclose .ill { height: auto; aspect-ratio: 12 / 7; }
  .compare-table { min-width: 0; table-layout: auto; }
  .compare-table thead { display: none; }
  .compare-table tbody, .compare-table tr, .compare-table th, .compare-table td { display: block; }
  .compare-table tbody tr { padding: 16px 0; border-top: 1px solid var(--line); }
  .compare-table tbody th, .compare-table tbody td { border-top: 0; }
  .compare-table tbody th { width: auto; padding: 0 0 8px; }
  .compare-table td { padding: 6px 12px; border-radius: 8px; }
  .compare-table td::before { display: block; font-size: var(--fs-note); font-weight: 600; color: var(--subtle); }
  .compare-table td:nth-of-type(1)::before { content: "A hosting platform"; }
  .compare-table td:nth-of-type(2)::before { content: "A self-hosted panel"; }
  .compare-table td:nth-of-type(3)::before { content: "ox"; }
  .compare-table tbody tr:last-child .is-ox { border-radius: 8px; }
  .apps-box .oneshot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .apps-box .oneshot-grid li:nth-child(n+11) { display: none; }
  .cta-row { flex-wrap: wrap; }
  .cta-row .btn { flex: 1 1 auto; }
  .ox-buddy { left: 14px; }
  .ox-note { left: 140px; font-size: 22px; }
  .ox-note-arrow { display: none; }
}

/* Short landscape phones: less space above the hero. */
@media (max-height: 520px) and (orientation: landscape) { .hero { padding-top: 40px; } }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 1ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; }
  .js .reveal { opacity: 1; transform: none; }
  .js .display .w > span { animation: none; transform: none; }
  .js .display .ul path { animation: none; stroke-dashoffset: 0; }
}

@media (max-width: 1080px) { .nav-links { gap: 20px; } .nav-links .ic { display: none; } }


/* ---------- Docs: a quiet sidebar and a reading column ---------- */
.docs { padding: clamp(40px, 6vw, 72px) 0 clamp(96px, 10vw, 140px); }
.docs-grid { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: clamp(40px, 6vw, 96px); align-items: start; }
.docs-nav { position: sticky; top: 92px; max-height: calc(100vh - 112px); max-height: calc(100dvh - 112px); overflow-y: auto; font-size: 14px; }
.docs-nav-label { display: flex; align-items: center; gap: 8px; font: 500 12px/16px var(--sans); color: var(--subtle); letter-spacing: .02em; margin-bottom: 12px; }
.docs-nav-label .ic { width: 15px; height: 15px; }
.docs-nav ul { display: grid; gap: 2px; border-left: 1px solid var(--line); }
.docs-nav li a { display: block; margin-left: -1px; padding: 5px 0 5px 14px; border-left: 1px solid transparent; color: var(--subtle); text-decoration: none; transition: color 150ms ease, border-color 150ms ease; }
@media (hover: hover) { .docs-nav li a:hover { color: var(--ink); border-left-color: #C9C9C5; } }
.docs-nav code { background: none; padding: 0; font-size: .92em; color: inherit; }
.docs-skill { display: inline-flex; align-items: center; gap: 8px; margin-top: 24px; font-weight: 500; color: var(--ink); text-decoration: none; }
.docs-skill .ic { width: 16px; height: 16px; }

.prose { max-width: 720px; font-size: 16.5px; line-height: 1.7; color: var(--text); }
.prose > * + * { margin-top: 18px; }
.prose h1 { font: 600 clamp(38px, 4.4vw, 54px)/1.06 var(--display); letter-spacing: -0.028em; color: var(--ink); margin-bottom: 8px; }
.prose h1 + p { font-size: 19px; line-height: 1.6; }
.prose h2 { font: 600 clamp(24px, 2.4vw, 30px)/1.2 var(--display); letter-spacing: -0.018em; color: var(--ink); margin-top: 72px; padding-top: 28px; border-top: 1px solid var(--line); scroll-margin-top: 88px; }
.prose h2 code, .prose h1 code { font-size: .82em; background: var(--stage); }
.prose h3 { font: 600 19px/1.3 var(--display); color: var(--ink); margin-top: 40px; scroll-margin-top: 88px; }
.prose strong { font-weight: 600; color: var(--ink); }
.prose a { color: var(--ink); text-decoration-color: #C9C9C5; text-underline-offset: 3px; }
@media (hover: hover) { .prose a:hover { text-decoration-color: currentColor; } }
.prose ul { display: grid; gap: 10px; padding-left: 20px; list-style: disc; }
.prose ul ul { margin-top: 10px; list-style: circle; }
.prose li::marker { color: #B5B5B0; }
.prose code { overflow-wrap: anywhere; }
/* App guides (blog_guides.go): the proof box, the facts list and the screenshot. */
.guide-proof { display: grid; grid-template-columns: 20px 1fr; gap: 2px 10px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; background: var(--card); font-size: 15px; line-height: 1.5; }
.guide-proof .ic { grid-row: 1 / 3; width: 20px; height: 20px; margin-top: 2px; color: var(--ok); }
.guide-proof span { color: var(--subtle); }
.prose .guide-facts { list-style: none; padding-left: 0; }
.prose .guide-quote { padding-left: 14px; border-left: 2px solid var(--line); color: var(--subtle); }
.guide-shots { display: grid; gap: 20px; margin: 24px 0; }
.guide-shot { margin: 0; }
.guide-shot img { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: 12px; }
.guide-shot figcaption { margin-top: 8px; font-size: 14px; line-height: 1.5; color: var(--subtle); }

.doc-table { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; background: var(--card); }
.doc-table table { width: 100%; border-collapse: collapse; font-size: 14.5px; line-height: 1.55; }
.doc-table th { font: 500 12px/16px var(--sans); color: var(--subtle); text-align: left; padding: 12px 16px; background: var(--bg); border-bottom: 1px solid var(--line); }
.doc-table td { padding: 12px 16px; vertical-align: top; }
.doc-table tr + tr td { border-top: 1px solid var(--line); }
.doc-table td:first-child { white-space: nowrap; color: var(--ink); }
.doc-table td code { overflow-wrap: normal; }

/* display: grid turns figcaption and pre into grid items, so the scrolling
   pre's long lines no longer push the max-content of the whole section:
   without it, .docs-grid's mobile track was as wide as the widest pre. */
.code { display: grid; border-radius: 12px; overflow: hidden; background: var(--night); color: var(--night-text); }
.code figcaption { font: 500 12px/16px var(--sans); color: var(--night-subtle); padding: 12px 18px; border-bottom: 1px solid var(--night-line); }
.code pre { margin: 0; padding: 16px 18px 18px; overflow-x: auto; font: 400 13.5px/1.7 var(--mono); font-variant-ligatures: none; }
.code code { background: none; padding: 0; color: inherit; font-size: inherit; }
.code .c { color: #7C7C76; } .code .k { color: #9CC3FF; } .code .s { color: #D9C9A3; }
/* The per-block copy button (docs.js wires it, on /docs and the posts). */
.code figcaption { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.code-copy, .code-wrap { display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px; border: 1px solid var(--night-line); border-radius: 6px; background: transparent; color: var(--night-subtle); font: 500 11.5px/1.4 var(--sans); cursor: pointer; transition: color 150ms ease, border-color 150ms ease; }
@media (hover: hover) { .code-copy:hover, .code-wrap:hover { color: #F5F5F3; border-color: #3A3A37; } }
.code-copy .ic, .code-wrap .ic { width: 13px; height: 13px; }
.code-copy.is-copied { color: var(--ok-soft); border-color: var(--ok); }

@media (max-width: 880px) {
  .docs-grid { grid-template-columns: 1fr; }
  .docs-nav { position: static; max-height: none; padding: 18px 20px; border: 1px solid var(--line); border-radius: 14px; background: var(--card); }
  .docs-nav ul { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); border-left: 0; }
  .docs-nav li a { padding-left: 0; border: 0; }
}

/* ---------- Blog: the index, the cards, and the post page. Colors come
   from the tokens. */
.blog-hero { padding-top: clamp(64px, 9vw, 120px); padding-bottom: clamp(32px, 4vw, 48px); }
.blog-hero .lede { margin-top: 24px; max-width: 520px; color: var(--subtle); }

/* The category filter: plain links to fixed, empty targets, so a click
   filters in place without a script and never scrolls the page. */
.filter-target { position: fixed; top: 0; left: 0; width: 0; height: 0; }
.blog-filter { margin-bottom: clamp(36px, 4vw, 52px); }
.blog-filter ul { display: flex; gap: 8px; }
.chip { display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 14px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); color: var(--text); font: 500 14px/1 var(--sans); text-decoration: none; white-space: nowrap; transition: border-color 150ms ease, background-color 150ms ease, color 150ms ease; -webkit-user-select: none; user-select: none; touch-action: manipulation; }
.chip .ic { width: 15px; height: 15px; color: var(--subtle); transition: color 150ms ease; }
@media (hover: hover) { .chip:hover { border-color: color-mix(in srgb, var(--ink) 24%, var(--line)); color: var(--ink); } }
.chip-all,
.blog-index:has(#c-guides:target) .chip[data-cat="guides"],
.blog-index:has(#c-engineering:target) .chip[data-cat="engineering"],
.blog-index:has(#c-product:target) .chip[data-cat="product"],
.blog-index:has(#c-opinion:target) .chip[data-cat="opinion"] { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }
.blog-index:has(#c-guides:target) .chip[data-cat="guides"] .ic,
.blog-index:has(#c-engineering:target) .chip[data-cat="engineering"] .ic,
.blog-index:has(#c-product:target) .chip[data-cat="product"] .ic,
.blog-index:has(#c-opinion:target) .chip[data-cat="opinion"] .ic { color: var(--on-ink); }
.blog-index:has(.filter-target[id^="c-"]:target) .chip-all { background: var(--card); border-color: var(--line); color: var(--text); }
.blog-index:has(#c-guides:target) .post-card:not([data-cat="guides"]),
.blog-index:has(#c-engineering:target) .post-card:not([data-cat="engineering"]),
.blog-index:has(#c-product:target) .post-card:not([data-cat="product"]),
.blog-index:has(#c-opinion:target) .post-card:not([data-cat="opinion"]) { display: none; }

/* The grid: three columns, two on tablets, one on phones. The newest post
   on the index is a wide card above the rest. */
.post-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(44px, 5vw, 64px) clamp(24px, 2.6vw, 36px); }
.blog-index .post-grid { padding-bottom: clamp(96px, 11vw, 160px); }
.post-card { position: relative; }
.card-inner { display: flex; flex-direction: column; gap: 22px; height: 100%; }
.card-body { display: flex; flex-direction: column; flex: 1; }
.card-cat { font: 500 13px/1 var(--sans); color: var(--subtle); letter-spacing: .01em; }
.card-title { margin: 12px 0 14px; font: 600 21px/1.25 var(--display); letter-spacing: -0.014em; color: var(--ink); text-wrap: balance; }
.card-link { color: inherit; text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px; text-underline-offset: 4px; transition: text-decoration-color 200ms ease; }
.card-link::after { content: ""; position: absolute; inset: -10px; border-radius: calc(var(--radius) + 6px); }
.card-link:focus-visible { outline: none; }
.card-link:focus-visible::after { outline: 2px solid var(--blue); outline-offset: 2px; }
.card-excerpt { margin-top: 10px; font-size: 15.5px; line-height: 1.6; color: var(--subtle); text-wrap: pretty; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
.card-body .byline { margin-top: auto; padding-top: 18px; }

.post-card-featured { grid-column: 1 / -1; padding-bottom: clamp(44px, 5vw, 64px); border-bottom: 1px solid var(--line); }
.post-card-featured .card-inner { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); align-items: center; gap: clamp(32px, 4vw, 56px); }
.post-card-featured .card-title { margin-top: 16px; font-size: clamp(28px, 2.9vw, 38px); line-height: 1.12; letter-spacing: -0.024em; }
.post-card-featured .card-excerpt { margin-top: 16px; font-size: 17px; -webkit-line-clamp: 4; line-clamp: 4; }
.post-card-featured .card-body .byline { margin-top: 0; padding-top: 26px; }

/* The byline: the author's photo, the author, the date and reading time. */
.byline { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 13.5px; line-height: 1.4; color: var(--subtle); }
.avatar { display: block; flex: none; width: 26px; height: 26px; border-radius: 50%; object-fit: cover; object-position: 62% 30%; background: var(--stage); box-shadow: 0 0 0 1px var(--line); }
.avatar-lg { width: 52px; height: 52px; }
.byline-name { font-weight: 500; color: var(--ink); }
.byline-meta { display: inline-flex; gap: 6px; }
.byline-sep { color: var(--faint); }

/* The cover (blog_render.go coverFor): a line-art vignette of the post's
   category on the stage tint, drawn by the C illustrations block below. */
.cover { position: relative; display: grid; place-items: center; aspect-ratio: 16 / 9; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--stage);
  transition: transform 420ms var(--ease), box-shadow 420ms var(--ease); }

@media (hover: hover) and (pointer: fine) {
  .post-card:hover .cover { transform: translateY(-4px); box-shadow: 0 22px 44px -28px rgb(0 0 0 / .4); }
  .post-card:hover .card-link { text-decoration-color: color-mix(in srgb, var(--ink) 35%, transparent); }
}

/* ---------- A post ---------- */
/* Reading progress: a scroll-driven animation, so no script; browsers
   without scroll timelines simply show no bar. */
.read-progress { display: none; }
@supports (animation-timeline: scroll()) {
  .read-progress { display: block; position: fixed; inset: 0 0 auto; z-index: 60; height: 2px; background: var(--ok); transform-origin: 0 50%; transform: scaleX(0); animation: read-grow linear both; animation-timeline: scroll(root block); }
}
@keyframes read-grow { to { transform: scaleX(1); } }

.post-head { --max: 820px; padding-top: clamp(48px, 7vw, 88px); text-align: center; }
.post-kicker { display: flex; align-items: center; justify-content: center; gap: 10px; font-size: 14px; color: var(--faint); }
.post-kicker > a:first-child { color: var(--subtle); text-decoration: none; }
@media (hover: hover) { .post-kicker > a:first-child:hover { color: var(--ink); } }
.post-kicker .chip { height: 30px; padding: 0 12px; font-size: 13px; }
.post-head h1 { margin-top: 24px; font: 600 clamp(36px, 4.8vw, 58px)/1.05 var(--display); letter-spacing: -0.03em; color: var(--ink); text-wrap: balance; }
.post-dek { max-width: 640px; margin: 20px auto 0; font-size: clamp(17px, 1.6vw, 19.5px); line-height: 1.55; color: var(--subtle); text-wrap: pretty; }
.post-head .byline { justify-content: center; margin-top: 28px; font-size: 14px; }
.post-head .avatar { width: 30px; height: 30px; }
.post-cover { --max: 1080px; margin-top: clamp(36px, 5vw, 56px); }
.post-cover .cover { aspect-ratio: 21 / 9; border-radius: 20px; }

.post-layout { --max: 1200px; display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; margin-top: clamp(48px, 6vw, 72px); }
.post-body { width: 100%; max-width: 680px; font-size: 18px; line-height: 1.75; }
.post-toc { display: none; }
@media (min-width: 1240px) {
  .post-layout { grid-template-columns: minmax(0, 1fr) 680px minmax(0, 1fr); align-items: start; }
  .post-body { grid-column: 2; }
  .post-toc { display: block; grid-column: 3; justify-self: start; position: sticky; top: 100px; width: min(232px, 100% - 48px); max-height: calc(100dvh - 140px); margin-left: 56px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
}
.post-toc-label { font: 500 12px/16px var(--sans); color: var(--subtle); letter-spacing: .02em; margin-bottom: 10px; }
.post-toc ul { display: grid; border-left: 1px solid var(--line); }
.post-toc a { display: block; margin-left: -1px; padding: 5px 0 5px 14px; border-left: 1px solid transparent; font-size: 13.5px; line-height: 1.4; color: var(--subtle); text-decoration: none; text-wrap: pretty; transition: color 150ms ease, border-color 150ms ease; }
.post-toc .sub a { padding-left: 26px; font-size: 13px; }
@media (hover: hover) { .post-toc a:hover { color: var(--ink); } }
.post-toc a.is-here { color: var(--ink); border-left-color: var(--ink); }

/* Body typography: a 680px measure, 18px at 1.75, steady heading rhythm. */
.post-body > * + * { margin-top: 22px; }
.post-body h2 { margin-top: 64px; padding-top: 0; border-top: 0; font: 600 clamp(25px, 2.5vw, 31px)/1.2 var(--display); letter-spacing: -0.02em; scroll-margin-top: 96px; }
.post-body h3 { margin-top: 44px; font: 600 21px/1.3 var(--display); letter-spacing: -0.01em; scroll-margin-top: 96px; }
.post-body h4 { margin-top: 32px; font: 600 18px/1.35 var(--display); color: var(--ink); }
.post-body h2 + *, .post-body h3 + *, .post-body h4 + * { margin-top: 14px; }
.h-anchor { margin-left: .35em; color: var(--faint); font-weight: 400; text-decoration: none; opacity: 0; transition: opacity 150ms ease, color 150ms ease; }
@media (hover: hover) { .post-body h2:hover .h-anchor, .post-body h3:hover .h-anchor { opacity: 1; } }
@media (hover: hover) { .h-anchor:hover { color: var(--ink); } }
.post-body p, .post-body li { text-wrap: pretty; }
.post-body ul, .post-body ol { display: grid; gap: 10px; padding-left: 22px; }
.post-body ol { list-style: decimal; }
.post-body ol li::marker { color: var(--subtle); font-variant-numeric: tabular-nums; }
.post-body li > p + p { margin-top: 10px; }
.post-body li > ul, .post-body li > ol { margin-top: 10px; }
.post-body code { font-size: .84em; }
.post-body blockquote { padding: 2px 0 2px 22px; border-left: 3px solid var(--ok); font: 400 20px/1.55 var(--display); color: var(--ink); }
.post-body blockquote > * + * { margin-top: 12px; }
.post-body hr { height: 1px; margin-block: 48px; border: 0; background: var(--line); }
.post-body img { max-width: 100%; height: auto; border: 1px solid var(--line); border-radius: 12px; }
.post-body .code { margin-top: 26px; }
.post-body .code + * { margin-top: 26px; }
.post-body .code pre { font-size: 13.5px; line-height: 1.7; }
.post-body .code figcaption { padding-block: 9px; }
/* Pasted posts carry highlight.js classes; these follow the docs' three. */
.post-body .hljs-comment, .post-body .hljs-meta { color: #7C7C76; }
.post-body .hljs-keyword, .post-body .hljs-built_in, .post-body .hljs-literal, .post-body .hljs-selector-tag { color: #9CC3FF; }
.post-body .hljs-string, .post-body .hljs-attr, .post-body .hljs-attribute, .post-body .hljs-number { color: #D9C9A3; }
.post-body .hljs-variable, .post-body .hljs-title, .post-body .hljs-section { color: var(--ok-soft); }
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; background: var(--card); }
.post-body table { width: 100%; border-collapse: collapse; font-size: 15px; line-height: 1.55; }
.post-body th { padding: 11px 16px; background: var(--stage); font: 500 13px/1.3 var(--sans); color: var(--subtle); text-align: left; white-space: nowrap; }
.post-body td { padding: 12px 16px; border-top: 1px solid var(--line); vertical-align: top; }
.post-body th + th, .post-body td + td { border-left: 1px solid var(--line); }
/* The privacy table: on a phone three columns leave a few words a line,
   so each row stacks, its column names as labels. */
@media (max-width: 640px) {
  .legal-table thead { display: none; }
  .legal-table table, .legal-table tbody, .legal-table tr, .legal-table td { display: block; }
  .post-body .legal-table td { padding: 4px 16px; border: 0; }
  .post-body .legal-table tr + tr { border-top: 1px solid var(--line); }
  .post-body .legal-table td:first-child { padding-top: 14px; font-weight: 500; color: var(--ink); }
  .post-body .legal-table td:last-child { padding-bottom: 14px; }
  .legal-table td:nth-child(2)::before { content: "Why"; }
  .legal-table td:nth-child(3)::before { content: "Where and how long"; }
  .legal-table td + td::before { display: block; margin-bottom: 2px; font: 500 12px/16px var(--sans); color: var(--subtle); }
}
.blog-source { margin-top: 56px; padding-top: 20px; border-top: 1px solid var(--line); font-size: 15px; color: var(--subtle); }
.blog-source a { color: var(--ink); }
.blog-source + .blog-hub { margin-top: 10px; padding-top: 0; border-top: 0; }

/* The end of a post: the author, then newer and older, then more posts. */
.post-end { --max: 680px; margin-top: 72px; }
.author-card { display: flex; align-items: center; gap: 18px; padding: 24px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); }
.author-name { font: 600 17px/1.3 var(--display); color: var(--ink); }
.author-bio { margin-top: 4px; font-size: 15px; line-height: 1.55; color: var(--subtle); text-wrap: pretty; }
.post-pager { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 16px; }
.pager-link { display: grid; align-content: start; gap: 8px; padding: 18px 20px; border: 1px solid var(--line); border-radius: var(--radius); text-decoration: none; transition: border-color 150ms ease, background-color 150ms ease; }
@media (hover: hover) { .pager-link:hover { border-color: color-mix(in srgb, var(--ink) 24%, var(--line)); background: var(--card); } }
.pager-dir { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--subtle); }
.pager-dir .ic { width: 14px; height: 14px; }
.pager-title { font: 600 16.5px/1.3 var(--display); color: var(--ink); text-wrap: balance; }
.pager-newer { grid-column: 2; justify-items: end; text-align: right; }
.pager-newer .ic { transform: scaleX(-1); }

.post-more { margin-top: clamp(88px, 10vw, 128px); padding-top: clamp(48px, 5vw, 64px); border-top: 1px solid var(--line); }
.post-more h2 { margin-bottom: clamp(28px, 3vw, 40px); font: 600 clamp(26px, 2.6vw, 32px)/1.15 var(--display); letter-spacing: -0.02em; color: var(--ink); }

.post-cta { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 28px; margin-block: clamp(72px, 9vw, 112px) clamp(88px, 10vw, 136px); padding: clamp(24px, 3vw, 36px); border: 1px solid var(--line); border-radius: 20px; background: var(--stage); }
.post-cta h2 { font: 600 22px/1.2 var(--display); letter-spacing: -0.015em; color: var(--ink); }
.post-cta p { margin-top: 6px; font-size: 15px; line-height: 1.55; color: var(--subtle); max-width: 520px; text-wrap: pretty; }
.post-cta-actions { display: flex; flex-wrap: wrap; gap: 10px; }

@media (max-width: 1080px) {
  .post-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .post-card-featured .card-inner { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
}
@media (max-width: 880px) {
  .post-card-featured .card-inner { grid-template-columns: 1fr; gap: 22px; }
  .post-cta { grid-template-columns: 1fr; gap: 18px; }
  .blog-filter { margin-inline: calc(var(--gutter) / -2); }
  .blog-filter ul { overflow-x: auto; padding-inline: calc(var(--gutter) / 2); scrollbar-width: none; }
  .blog-filter ul::-webkit-scrollbar { display: none; }
}
@media (max-width: 640px) {
  .post-grid { grid-template-columns: 1fr; }
  .post-body { font-size: 17px; line-height: 1.72; }
  .post-cover .cover { aspect-ratio: 16 / 10; border-radius: var(--radius); }
  .post-pager { grid-template-columns: 1fr; }
  .pager-newer { grid-column: auto; grid-row: 1; }
  .author-card { align-items: flex-start; padding: 20px; }
  .post-kicker { flex-wrap: wrap; }
}
@media (prefers-reduced-motion: reduce) {
  .read-progress { display: none; }
  .cover { transition: none; }
  .post-card:hover .cover { transform: none; }
}

/* Story (/story): the post's measure and type, a round portrait on top. */
.story-portrait { display: grid; justify-items: center; gap: 12px; }
.story-portrait img { width: clamp(128px, 22vw, 176px); height: auto; aspect-ratio: 1; border-radius: 50%; object-fit: cover; object-position: 54% 28%; background: var(--stage); box-shadow: 0 0 0 1px var(--line), 0 12px 32px -18px rgba(0, 0, 0, .35); }
.story-portrait figcaption { font-size: 14px; color: var(--subtle); }
.story .post-head h1 { margin-top: 28px; }
.story-cta { --max: 760px; }
.post-body .story-wide img, .post-body .story-trips img { display: block; width: 100%; height: auto; border-radius: var(--radius); background: var(--stage); }
.post-body .story-wide { margin-top: 30px; }
.post-body .story-mtn { display: flex; align-items: center; gap: 12px; }
.story-mtn .ic { flex: none; width: 28px; height: 28px; color: var(--subtle); }
.story-gallery { --gap: clamp(8px, 1.6vw, 16px); display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: clamp(22px, 3vw, 30px) var(--gap); width: min(1000px, calc(100vw - 40px)); margin-top: 40px; margin-left: 50%; transform: translateX(-50%); }
.sg { display: flex; flex-direction: column; min-width: 0; }
.sg-6 { grid-column: span 6; } .sg-4 { grid-column: span 4; } .sg-3 { grid-column: span 3; } .sg-2 { grid-column: span 2; }
.story-gallery img, .story-gallery video { display: block; width: 100%; border: 1px solid var(--line); border-radius: 16px; background: var(--stage); object-fit: cover; }
.story-gallery img { height: auto; }
.sg-clip video { flex: 1 1 0; min-height: 0; height: 0; aspect-ratio: auto; }
.story-hint { display: none; }
.story-gallery figcaption { margin-top: 9px; font-size: 13.5px; line-height: 1.4; color: var(--subtle); }
.post-body .story-trips { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(8px, 2vw, 14px); margin-top: clamp(8px, 2vw, 14px); }
.post-body .story-trips img { aspect-ratio: 3 / 4; object-fit: cover; }
.story-wide figcaption, .story-trips figcaption { margin-top: 8px; font-size: 13.5px; line-height: 1.4; color: var(--subtle); }

/* ===== C illustrations (editorial line art) =====
   Brand and concept art (docs/DECISIONS.md, 2026-10-08): isometric line
   drawings generated as inline SVG, colored only through these tokens so
   light and dark both work. Hatching is drawn as lines, not <pattern>s, so
   the SVGs carry no ids. Product UI stays real UI (direction A). */
.ln-svg { --ln-ink: var(--ink); --ln-paper: var(--card); --ln-pen: color-mix(in srgb, var(--blue) 72%, var(--ink)); --ln-ok: var(--ok);
  --ln-bad: var(--danger-text); --ln-hand: var(--hand); --ln-mono: var(--mono); --ln-sans: var(--sans); --ln-ease: var(--ease); }
.ln-svg { display: block; max-width: 100%; height: auto; overflow: visible; color: var(--ln-ink); --ln-ink2: color-mix(in srgb, var(--ln-ink) 60%, var(--ln-paper)); --ln-shade: color-mix(in srgb, var(--ln-pen) 45%, var(--ln-ink)); }
/* The mixed tokens fall under AA on the light stage (green is 2.4:1). */
:root:not([data-theme="dark"]) .ln-svg { --ln-ok: #1D7344; --ln-pen: #2F5F9E; --ln-ink2: #5C5C5C; }
.ln-svg path, .ln-svg circle, .ln-svg ellipse { stroke-linecap: round; stroke-linejoin: round; }
.ln-ft, .ln-fl, .ln-fr { stroke: currentColor; stroke-width: 2; vector-effect: non-scaling-stroke; }
.ln-ft { fill: var(--ln-paper); }
.ln-fl { fill: color-mix(in srgb, currentColor 5%, var(--ln-paper)); }
.ln-fr { fill: color-mix(in srgb, currentColor 12%, var(--ln-paper)); }
.ln-ft.ln--pen { fill: color-mix(in srgb, var(--ln-pen) 16%, var(--ln-paper)); }
.ln-ft.ln--ok { fill: color-mix(in srgb, var(--ln-ok) 20%, var(--ln-paper)); }
.ln-h { fill: none; stroke: currentColor; stroke-width: .8; opacity: .34; }
.ln-sh { fill: none; stroke: var(--ln-shade); stroke-width: .7; opacity: .45; }
.ln-l { fill: none; stroke: currentColor; stroke-width: 1.5; }
.ln-thin { fill: none; stroke: currentColor; stroke-width: 1; opacity: .55; }
.ln-led { stroke: currentColor; stroke-width: 1; fill: var(--ln-paper); }
.ln-led.ln--ok { fill: var(--ln-ok); }
.ln-led.ln--pen { fill: var(--ln-pen); }
.ln-ox { fill: var(--ln-paper); stroke: currentColor; stroke-width: 1; vector-effect: non-scaling-stroke; }
.ln-snow { fill: var(--ln-paper); stroke: currentColor; stroke-width: 1.5; }
.ln-paper { fill: var(--ln-paper); stroke: currentColor; stroke-width: 1.5; }
.ln-note { font: 500 21px/1 var(--ln-hand); fill: var(--ln-pen); }
.ln-note.ln--ok { fill: var(--ln-ok); }
.ln-note.ln--s { font-size: 18px; }
.ln-mono { font: 400 11.5px/1 var(--ln-mono); font-variant-ligatures: none; fill: currentColor; }
.ln-mono.ln--dim, .ln-dim { fill: var(--ln-ink2); }
.ln-mono.ln--pen { fill: var(--ln-pen); }
.ln-mono.ln--ok { fill: var(--ln-ok); }
.ln-mono.bad { fill: var(--ln-bad); }
.ln-mono.ln--s { font-size: 10px; }
.ln-mono.ln--l { font-size: 13px; }
.ln-strike { fill: none; stroke: var(--ln-bad); stroke-width: 1.5; }
.ln-fig { font: 400 10px/1 var(--ln-mono); font-variant-ligatures: none; letter-spacing: .14em; fill: var(--ln-ink2); }
.ln-pen { fill: none; stroke: var(--ln-pen); stroke-width: 1.75; }
.ln-pen.ln--ok { stroke: var(--ln-ok); }
.ln-pen.ln--dim { stroke: var(--ln-ink2); }
.ln-ghost { fill: none; stroke: var(--ln-pen); stroke-width: 1.5; stroke-dasharray: 5 5; }
.ln-rail { fill: none; stroke: var(--ln-ink2); stroke-width: 6; opacity: .28; }
.ln-flow { fill: none; stroke: var(--ln-pen); stroke-width: 1.8; stroke-dasharray: 2 7; }
.ln-tag path { fill: var(--ln-paper); stroke: var(--ln-pen); stroke-width: 1.5; }
.ln-tag circle { fill: none; stroke: var(--ln-pen); stroke-width: 1.2; }
.ln-tag text { font: 400 11px/1 var(--ln-mono); font-variant-ligatures: none; fill: var(--ln-pen); }
.ln-chk circle { fill: var(--ln-paper); stroke: var(--ln-ok); stroke-width: 1.5; }
.ln-chk path { fill: none; stroke: var(--ln-ok); stroke-width: 2; }
.ln-chk.ln-no circle, .ln-chk.ln-no path { stroke: var(--ln-bad); }
.ln-seal circle { fill: var(--ln-paper); stroke: currentColor; stroke-width: 1.5; }
.ln-seal .ln--in { stroke-width: 1; stroke-dasharray: 1.5 2.5; }
.ln-stamp rect { fill: none; stroke: var(--ln-ok); stroke-width: 2; }
.ln-stamp rect + rect { stroke-width: 1; }
.ln-stamp text { font: 400 14px/1 var(--ln-mono); font-variant-ligatures: none; letter-spacing: .04em; fill: var(--ln-ok); }
/* Motion. The resting styles above are the final frame; reduced motion and
   paused figures keep or start from them. */
.ln-draw { stroke-dasharray: 1; }
.ln-svg .ln-draw, .ln-svg .ln-chk path { animation: ln-draw 1s var(--ln-ease) backwards; animation-delay: var(--d, 0s); }
.ln-svg .ln-chk path { stroke-dasharray: 1; }
.ln-svg .ln-note { animation: ln-write 1.3s steps(14, end) backwards; animation-delay: var(--d, 0s); }
.ln-svg .ln-pop, .ln-svg .ln-tag, .ln-svg .ln-stamp, .ln-svg .ln-seal { animation: ln-pop .7s var(--ln-ease) backwards; animation-delay: var(--d, 0s); }
.ln-svg .ln-flow { animation: ln-flow 1.1s linear infinite; }
.ln-svg .ln-float { animation: ln-float 6s ease-in-out infinite; }
.ln-svg .ln-ghost { animation: ln-ghost 2.8s ease-in-out infinite; }
@keyframes ln-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes ln-write { from { clip-path: inset(-40% 100% -40% -4%); } to { clip-path: inset(-40% -4% -40% -4%); } }
@keyframes ln-pop { from { opacity: 0; translate: 0 6px; } }
@keyframes ln-flow { to { stroke-dashoffset: -18; } }
@keyframes ln-float { 50% { translate: 0 -5px; } }
@keyframes ln-ghost { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .ln-svg, .ln-svg * { animation: none !important; } }
.ln-ttl { font: 600 12.5px/1 var(--ln-sans); fill: currentColor; }
.ln-svg .ln--t-pen { fill: var(--ln-pen); }
.ln-svg .ln--t-ok { fill: var(--ln-ok); }
.ln-svg .ln--t-bad { fill: var(--ln-bad); }
.ln-svg .ln--t-dim, .ln-svg .ln-old { fill: var(--ln-ink2); }
.ln-btn { fill: color-mix(in srgb, var(--ln-pen) 12%, var(--ln-paper)); stroke: var(--ln-pen); stroke-width: 1.5; }
.ln-svg .ln-sweep { animation: ln-sweep 6s linear infinite; }
@keyframes ln-sweep { from { translate: 0 0; } to { translate: var(--ln-span, 0) 0; } }
/* Pages: the story's signature drawing, and the blog's covers. */
.post-body a.story-ext .ic { display: inline-block; width: 16px; height: 16px; margin-right: 4px; vertical-align: -2px; }
.story-art { --max: 760px; margin-top: clamp(32px, 5vw, 56px); }
.story-art .ln-svg { width: 100%; }
.js .story-art:not(.in) .ln-svg, .js .story-art:not(.in) .ln-svg * { animation-play-state: paused; }
.ln-cover .ln-svg { width: 100%; height: 100%; padding: 6% 8%; }
.ln-cover .ln-svg .ln-float, .ln-cover .ln-svg .ln-ghost { animation: none; }
@media (hover: hover) and (pointer: fine) {
  .post-card:hover .ln-cover .ln-float { animation: ln-float 3s ease-in-out infinite; }
}

/* ===== Mobile system ===== */
/* Most visitors arrive on a phone (DECISIONS 2026-10-09). The rules, also in
   docs/design/README.md "Mobile and touch rules":
   - A touch target is at least --tap (44px) on both axes, 8px from the next.
   - Every control has an :active state; hover styles live inside
     @media (hover: hover), so a tap never leaves a stuck hover.
   - Fixed layers clear the notch and the home bar with env(safe-area-*).
   - Text is 14px or larger; a mock's tiny print is aria-hidden decoration.
   - Sideways strips (the story's photos) snap, show a peek
     of the next card, and contain their overscroll.
   - The menu, the docs pages and search open as sheets that lock the page
     behind them. */
:root { --tap: 44px; --sheet-r: 20px; }
a, button, summary, label, [role="tab"] { touch-action: manipulation; -webkit-tap-highlight-color: color-mix(in srgb, var(--ink) 8%, transparent); }

/* The phone menu: a native <details> whose content is a full-width sheet
   under the bar. popover.js closes it on an outside tap and on Esc. */
.nav-menu { display: none; }
.nav-menu summary { display: grid; place-items: center; width: var(--tap); height: var(--tap); border-radius: 10px; cursor: pointer; list-style: none; color: var(--ink); }
.nav-menu summary::-webkit-details-marker { display: none; }
.nav-menu summary:active { background: var(--stage); }
.nav-menu summary .ic { width: 22px; height: 22px; }
.nav-menu .ic-close, .nav-menu[open] .ic-open { display: none; }
.nav-menu[open] .ic-close { display: block; }
.nav-sheet { position: fixed; top: calc(68px + env(safe-area-inset-top)); left: 0; right: 0; bottom: 0; z-index: 49; display: flex; flex-direction: column; gap: 24px; padding: 8px 16px calc(24px + env(safe-area-inset-bottom)); overflow-y: auto; overscroll-behavior: contain; background: var(--bg); border-top: 1px solid var(--line); animation: sheet-down 220ms var(--ease) both; }
.sheet-links { display: grid; }
.sheet-links li + li { border-top: 1px solid var(--line); }
.sheet-links a { display: flex; align-items: center; gap: 14px; min-height: 56px; padding: 0 12px; border-radius: 12px; font: 500 18px/1.2 var(--sans); color: var(--ink); text-decoration: none; }
.sheet-links a:active { background: var(--stage); }
.sheet-links a[aria-current] { background: var(--stage); }
.sheet-links .ic { width: 20px; height: 20px; color: var(--subtle); }
.sheet-actions { display: grid; gap: 10px; margin-top: auto; }
.sheet-actions .btn { width: 100%; height: 52px; font-size: 16.5px; border-radius: 12px; }
/* The bar's blur makes it the containing block of fixed children, which
   would trap the sheet inside the bar; it goes solid while the menu is open,
   and the page behind stops scrolling. */
.nav:has(.nav-menu[open]) { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--bg); }
html:has(.nav-menu[open]), html:has(.docs-menu[open]) { overflow: hidden; }
@keyframes sheet-down { from { opacity: 0; transform: translateY(-8px); } }
@keyframes sheet-up { from { transform: translateY(100%); } }
@keyframes scrim-in { from { opacity: 0; } }

/* A bottom sheet (the docs pages) over a scrim. The scrim is a sibling
   outside the <details>, so a tap on it counts as outside and closes it. */
.sheet-scrim { display: none; }
.sheet-head { position: sticky; top: 0; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0 8px; background: inherit; font: 600 17px/1.3 var(--display); color: var(--ink); }
.sheet-close { display: grid; place-items: center; width: var(--tap); height: var(--tap); margin-right: -10px; border: 0; border-radius: 10px; background: none; color: var(--subtle); cursor: pointer; }
.sheet-close:active { background: var(--stage); color: var(--ink); }
.sheet-close .ic { width: 20px; height: 20px; }

/* The phone's sticky sign-up bar (site-chrome.html; main.js shows it). */
.m-cta { display: none; }

/* "On this page" as chips, where the side list doesn't fit. */
.onpage { display: none; margin: 24px 0 28px; }
.onpage summary { display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap); padding: 0 16px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); font: 500 15px/1 var(--sans); color: var(--ink); cursor: pointer; list-style: none; }
.onpage summary::-webkit-details-marker { display: none; }
.onpage summary:active { background: var(--stage); }
.onpage .ic { width: 16px; height: 16px; flex: none; }
.onpage-caret { color: var(--subtle); transition: transform 200ms var(--ease); }
.onpage[open] .onpage-caret { transform: rotate(90deg); }
.onpage ul { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.onpage a { display: inline-flex; align-items: center; min-height: var(--tap); padding: 10px 16px; border: 1px solid var(--line); border-radius: 22px; background: var(--card); font-size: 15px; line-height: 1.3; color: var(--text); text-decoration: none; }
.onpage a:active { background: var(--stage); color: var(--ink); }
.post-onpage { --max: 680px; }
@media (max-width: 1179px) { .docs-main .onpage { display: block; } }
@media (max-width: 1239px) { .post-onpage .onpage { display: block; } }
@media (min-width: 1240px) { .post-onpage { display: none; } }

/* Code: a Wrap toggle beside Copy (docs.js adds it), and wide tables fade
   at the edge that still scrolls. */
.code-wrap { display: none; }
.code.is-wrapped pre { white-space: pre-wrap; overflow-wrap: anywhere; }
.post-body .code code { font-size: inherit; }
.table-wrap, .doc-table {
  --fade: var(--card); --shade: color-mix(in srgb, var(--ink) 16%, transparent);
  background:
    linear-gradient(to right, var(--fade) 40%, transparent) left / 40px 100% no-repeat local,
    linear-gradient(to left, var(--fade) 40%, transparent) right / 40px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, var(--shade), transparent) left / 14px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, var(--shade), transparent) right / 14px 100% no-repeat scroll,
    var(--card);
}

@media (hover: none), (pointer: coarse), (max-width: 880px) {
  .btn-sm { height: var(--tap); padding: 0 16px; }
  .chip { height: var(--tap); padding: 0 16px; }
  .see-all { min-height: var(--tap); }
  .h-anchor { opacity: 1; display: inline-block; min-width: var(--tap); padding: 10px 15px; margin: -10px -15px -10px 0; text-align: center; }
  .nav-login { min-height: var(--tap); }
  .post-kicker .chip { height: var(--tap); padding: 0 16px; font-size: 14px; }
  /* A list of links only (a post's "In this guide") is a list of rows; the one-shot grid's cards are taller already. */
  .post-body :not(.oneshot-grid) > li > a:only-child { display: inline-flex; align-items: center; min-height: var(--tap); }
  .code-wrap { display: inline-flex; margin-left: auto; }
  .code-copy, .code-wrap { min-width: var(--tap); min-height: var(--tap); justify-content: center; padding: 0 14px; border-radius: 10px; font-size: 14px; }
  .code-copy .ic, .code-wrap .ic { width: 16px; height: 16px; }
  .code figcaption { padding-block: 6px; font-size: 14px; }
  .post-body .code figcaption { padding-block: 6px; }
  .chip:active, .pager-link:active, .post-card:active .cover { opacity: .85; }
  .faq summary:active { color: var(--subtle); }
}
.code-wrap[aria-pressed="true"] { color: #F5F5F3; border-color: #75756F; }

@media (max-width: 880px) {
  .nav-menu { display: block; }
  .nav-actions, .site-board .nav-actions { gap: 8px; }
  .theme-toggle { width: var(--tap); height: var(--tap); }
  .nav-actions .nav-cta { height: var(--tap); }

  /* Grouped footer: two columns of thumb-sized rows. */
  .footer-inner { display: grid; grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 16px; }
  .footer a { display: flex; min-height: var(--tap); font-size: 15.5px; }

  .m-cta:not([hidden]) { display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); background: color-mix(in srgb, var(--bg) 88%, transparent); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); border-top: 1px solid var(--line); transform: translateY(100%); visibility: hidden; transition: transform 260ms var(--ease), visibility 0s linear 260ms; }
  .m-cta.is-on { transform: none; visibility: visible; transition: transform 260ms var(--ease); }
  .m-cta .btn { width: 100%; height: 52px; font-size: 16.5px; border-radius: 12px; }
  .m-cta .ic { width: 20px; height: 20px; }

  /* FAQ rows and the pager are full thumb rows. */
  .faq summary { min-height: 64px; padding-block: 16px; }
  .faq summary::after { width: 16px; height: 16px; background-size: 16px 1.5px, 1.5px 16px; }
  .faq details[open] summary::after { background-size: 16px 1.5px, 1.5px 0; }
  .post-kicker > a:first-child { display: inline-flex; align-items: center; min-height: var(--tap); min-width: var(--tap); }
  .logo { display: inline-flex; align-items: center; min-height: var(--tap); }
  .read-progress { top: env(safe-area-inset-top); }
}

@media (max-width: 640px) {
  .code pre, .post-body .code pre { font-size: 14px; }
  .byline, .post-kicker { font-size: 14px; }
  .card-cat, .pager-dir { font-size: 14px; }
  .story-wide figcaption, .story-trips figcaption, .story-gallery figcaption { font-size: 14px; }
  /* Photos become a swipe strip that bleeds to the screen edge, so a thumb
     moves through them instead of scrolling past five tall pictures. */
  .story { overflow-x: clip; }
  .story-hint { display: flex; align-items: center; gap: 6px; margin-top: 28px; font-size: 14px; color: var(--subtle); }
  .story-hint .ic { width: 16px; height: 16px; }
  .story-gallery { display: flex; gap: 12px; width: 100vw; margin-top: 10px; padding: 0 20px 6px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: 20px; overscroll-behavior-x: contain; scrollbar-width: none; align-items: stretch; -webkit-overflow-scrolling: touch; }
  .story-gallery::-webkit-scrollbar { display: none; }
  .sg { flex: 0 0 82%; scroll-snap-align: start; }
  .sg-6 { flex-basis: 90%; }
  .sg-clip { flex-basis: 60%; }
  .sg:not(.sg-clip) img { aspect-ratio: 4 / 3; }
  .sg.sg-6 img { aspect-ratio: 16 / 9; }
  .sg-clip video { flex: 1 1 0; min-height: 0; height: 0; aspect-ratio: auto; }
  /* Story photos: a swipeable strip with a peek. */
  .post-body .story-trips { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 72%; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain; scrollbar-width: none; }
  .post-body .story-trips::-webkit-scrollbar { display: none; }
  .post-body .story-trips figure { scroll-snap-align: start; }
}

@media (max-width: 560px) {
  /* The releases mock on a phone: the timeline drops the pruned releases
     and runs as a column (see the board rules above). */
  .hero-band { padding: 12px 12px 0; }
  .rel-head span:last-child { display: none; }
  .rel-app { flex-wrap: wrap; row-gap: 2px; }
  .rel { font-size: 14px; }
}
}

/* Short landscape phones: a slimmer sign-up bar. */
@media (max-width: 880px) and (max-height: 500px) {
  .m-cta { padding-block: 6px calc(6px + env(safe-area-inset-bottom)); padding-inline: max(16px, env(safe-area-inset-left)) max(16px, env(safe-area-inset-right)); }
  .m-cta .btn { height: var(--tap); }
  .nav-sheet { gap: 12px; }
  .sheet-links a { min-height: 48px; }
}

@media (prefers-reduced-motion: reduce) {
  .m-cta:not([hidden]), .m-cta.is-on { transition: none; }
  .story-trips { scroll-behavior: auto; }
}
/* ===== End of the mobile system ===== */
