@charset "utf-8";
/* DevBar site.
   Palette and shape come from .tastemaker/style-lock.md (the desktop app's locked tokens),
   so the page and the product read as one thing. Two themes, following the OS unless the
   reader picks one. The product itself is dark-only, so every screenshot stays on a dark
   surface in both themes: a screenshot is a photograph of the app, not page furniture.

   Shape rule: 6px on controls, 10px on surfaces, full-round only on the kbd-sized pill.
   Surfaces are neutral graphite, not the app's navy: no glow, no blobs, no gradients.
   Depth comes from 1px hairlines and two floor tones. The only colour on the page is
   the DevBar blue, plus green/amber where they carry real state.
   Z-index scale: 1 hero content, 10 sticky viewer, 50 nav. */

/* No bundled webfont. This is a site for a Windows tool, so it uses the
   typeface Windows already has: Segoe UI Variable for text, Cascadia for code,
   which is what the terminal the reader came from renders in. Two fewer
   downloads, no swap flash, and it reads as native rather than as every other
   product page. */

/* Shape, type and motion do not change with the theme. */
:root {
  --font-ui: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: "Cascadia Mono", "Cascadia Code", Consolas, ui-monospace, monospace;

  --r-ctl: 6px;
  --r-surface: 10px;
  --page: 1180px;
  --nav-h: 64px;

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  /* The surface a product screenshot sits on, and the mock bar chrome in the hero.
     Fixed in both themes because DevBar has no light mode: a light frame around a
     dark screenshot would claim a bar that does not exist. */
  --shot-bg: #111113;
  --shot-line: #2c2c31;
}

/* Dark is the default: the product is dark, and so is every screenshot on the page.
   The inline script in <head> switches this to light from the reader's stored choice,
   or from prefers-color-scheme when they have not made one. */
:root {
  color-scheme: dark;

  --bg: #111113;
  --bg-well: #0c0c0e;
  --bg-elevated: #1b1b1e;
  --hairline: #2c2c31;
  --hairline-soft: #212125;
  --hairline-strong: #45454c;
  --surface-hover: rgba(27, 27, 30, 0.7);
  --nav-bg: rgba(17, 17, 19, 0.82);

  --text: #ececec;
  --muted: #9c9ca3;

  --accent: #5ea1ff;
  --accent-hover: #7db3ff;
  --accent-dim: rgba(94, 161, 255, 0.1);
  --on-accent: #06111f;
  --selection: rgba(94, 161, 255, 0.28);

  --good: #3fb950;
  --good-dim: rgba(63, 185, 80, 0.08);
  --good-line: rgba(63, 185, 80, 0.2);
  --code-type: #c79bff;
}

/* Light. Not a tint of the dark one: every value is picked against the light floor so
   the contrast ratios hold. The blues and greens are darkened because #5ea1ff on paper
   is 2.2:1 and unreadable; these are 6:1 and 4.9:1. The page floor is #f5f5f6 rather
   than white, and the raised surfaces are the near-white, so depth still comes from two
   floor tones and a hairline, the same way it does in the dark. */
:root[data-theme="light"] {
  color-scheme: light;

  --bg: #f5f5f6;
  --bg-well: #ebebed;
  --bg-elevated: #fdfdfe;
  --hairline: #d2d2d8;
  --hairline-soft: #e1e1e5;
  --hairline-strong: #b7b7bf;
  --surface-hover: rgba(253, 253, 254, 0.8);
  --nav-bg: rgba(245, 245, 246, 0.82);

  --text: #17171a;
  --muted: #5d5d65;

  --accent: #1b62d4;
  --accent-hover: #124fb0;
  --accent-dim: rgba(27, 98, 212, 0.08);
  --on-accent: #ffffff;
  --selection: rgba(27, 98, 212, 0.18);

  --good: #177230;
  --good-dim: rgba(23, 114, 48, 0.09);
  --good-line: rgba(23, 114, 48, 0.26);
  --code-type: #8250df;
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
::selection { background: var(--selection); }

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

.skip {
  position: absolute;
  left: 16px;
  top: -60px;
  z-index: 60;
  padding: 8px 14px;
  background: var(--accent);
  color: var(--on-accent);
  border-radius: var(--r-ctl);
  font-weight: 600;
}
.skip:focus { top: 12px; text-decoration: none; }

/* ---------- icons: Phosphor (MIT), tinted with currentColor through a mask ---------- */

.i {
  display: inline-block;
  flex: none;
  width: 1.125em;
  height: 1.125em;
  background: currentColor;
  -webkit-mask: var(--m) center / contain no-repeat;
  mask: var(--m) center / contain no-repeat;
}
.i-github   { --m: url("../img/icons/github-logo.svg"); }
.i-download { --m: url("../img/icons/download-simple.svg"); }
.i-mic      { --m: url("../img/icons/microphone.svg"); }
.i-clip     { --m: url("../img/icons/clipboard-text.svg"); }
.i-shelf    { --m: url("../img/icons/folder-open.svg"); }
.i-bot      { --m: url("../img/icons/robot.svg"); }
.i-ports    { --m: url("../img/icons/plugs-connected.svg"); }
.i-docker   { --m: url("../img/icons/cube.svg"); }
.i-git      { --m: url("../img/icons/git-branch.svg"); }
.i-check    { --m: url("../img/icons/check-circle.svg"); }
.i-sound    { --m: url("../img/icons/speaker-high.svg"); }
.i-term     { --m: url("../img/icons/terminal-window.svg"); }
.i-shield   { --m: url("../img/icons/shield-check.svg"); }
.i-cpu      { --m: url("../img/icons/cpu.svg"); }
.i-arrow    { --m: url("../img/icons/arrow-right.svg"); }
.i-out      { --m: url("../img/icons/arrow-up-right.svg"); }
.i-keys     { --m: url("../img/icons/keyboard.svg"); }
.i-eye      { --m: url("../img/icons/eye.svg"); }
.i-cal      { --m: url("../img/icons/calendar-blank.svg"); }
.i-bell     { --m: url("../img/icons/bell.svg"); }
.i-brain    { --m: url("../img/icons/brain.svg"); }

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

.wrap {
  width: 100%;
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: 24px;
}
@media (max-width: 560px) { .wrap { padding-inline: 16px; } }

section { position: relative; }

.band {
  padding-block: clamp(80px, 10vw, 128px);
  border-top: 1px solid var(--hairline-soft);
}
.band--well { background: var(--bg-well); }

.head { max-width: 640px; }
.head--center { margin-inline: auto; text-align: center; }
.head--center .lead { margin-inline: auto; }

/* ---------- type ---------- */

h1, h2, h3 {
  margin: 0;
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.12;
  text-wrap: balance;
}
h1 {
  font-size: clamp(2.25rem, 4vw, 3.25rem);
  line-height: 1.04;
  letter-spacing: -0.035em;
}
h2 { font-size: clamp(1.75rem, 3vw, 2.5rem); }
h3 { font-size: 1.0625rem; letter-spacing: -0.012em; }
p { margin: 0; text-wrap: pretty; }

.lead {
  margin-top: 18px;
  font-size: clamp(1.0625rem, 1.4vw, 1.1875rem);
  line-height: 1.65;
  color: var(--muted);
  max-width: 58ch;
}
.note { font-size: 0.875rem; color: var(--muted); }
.mono { font-family: var(--font-mono); }
.accent { color: var(--accent); }

/* overline stays for the legal pages' "On this page" and "Legal" labels */
.overline {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

code.mono,
.kbd {
  font-family: var(--font-mono);
  font-size: 0.85em;
  padding: 2px 6px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-ctl);
  background: var(--bg-elevated);
  color: var(--text);
  white-space: nowrap;
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 11px 18px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-ctl);
  background: var(--bg-elevated);
  color: var(--text);
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, transform 160ms var(--ease-out);
}
.btn:hover { text-decoration: none; border-color: var(--hairline-strong); }
.btn:active { transform: scale(0.97); }
.btn .i { width: 17px; height: 17px; }

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn--ghost { background: transparent; }
.btn--sm { padding: 7px 13px; font-size: 0.875rem; }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-top: 32px;
}

/* ---------- nav ---------- */

.nav-sentinel { position: absolute; top: 0; height: 1px; width: 1px; }

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: var(--nav-bg);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 200ms ease;
}
.nav.is-stuck { border-bottom-color: var(--hairline-soft); }
.nav .wrap { display: flex; align-items: center; gap: 28px; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.brand:hover { text-decoration: none; }
.brand img { width: 26px; height: 26px; border-radius: 7px; }

.nav-links { display: flex; gap: 26px; margin-left: auto; align-items: center; }
.nav-links a:not(.btn) { color: var(--muted); font-size: 0.9375rem; transition: color 160ms ease; }
.nav-links a:not(.btn):hover { color: var(--text); text-decoration: none; }
/* Shows the theme you would switch to, not the one you are in, and is the same
   height as the buttons beside it so it reads as one of the nav controls. */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  background: none;
  color: var(--muted);
  cursor: pointer;
  transition: color 160ms ease, border-color 160ms ease;
}
.theme-toggle:hover { color: var(--text); border-color: var(--hairline); }
.theme-toggle .tt { width: 18px; height: 18px; fill: currentColor; }

/* Sun to moon as one shape, not two icons swapping: the disc grows, the rays fold
   into the centre and fade, and the bite circle slides in from off-icon to carve the
   crescent. Dark shows the sun, because the sun is what you would switch to. */
.tt-disc,
.tt-bite,
.tt-rays { transition: transform 520ms var(--ease-out), opacity 260ms ease; }
.tt-disc {
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(0.55);
}
.tt-bite { transform: translate(9px, -7px); }
.tt-rays { transform-box: fill-box; transform-origin: center; }

:root[data-theme="light"] .tt-disc { transform: scale(1); }
:root[data-theme="light"] .tt-bite { transform: translate(0, 0); }
:root[data-theme="light"] .tt-rays { transform: scale(0.35) rotate(-45deg); opacity: 0; }

.nav-links .btn { margin-left: -8px; }
.nav-links .btn + .btn { margin-left: -14px; }

@media (max-width: 900px) {
  .nav-links .nav-hide { display: none; }
  .nav-links { gap: 20px; }
}
@media (max-width: 480px) {
  .nav-links .btn--ghost { display: none; }
}

/* ---------- hero ---------- */

.hero {
  padding-top: clamp(48px, 7vw, 88px);
  padding-bottom: clamp(56px, 7vw, 88px);
  overflow: hidden;
}
.hero .wrap { position: relative; z-index: 1; }

/* Headline runs the full width so it holds two lines; copy and stage share the row below. */
.hero h1 { max-width: 15.5em; }
.hero-grid {
  margin-top: clamp(28px, 3.4vw, 44px);
  display: grid;
  grid-template-columns: minmax(0, 0.62fr) minmax(0, 1.38fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}
@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; }
}

.hero .lead { margin-top: 0; max-width: 34ch; }

/* The stage is "your screen". The bar docks to its top edge and unrolls like the real
   one: a clip-path shade, full width reached first because the pill is centred. */
.stage {
  position: relative;
  border: 1px solid var(--hairline);
  border-radius: var(--r-surface);
  background: var(--bg-well);
  padding: 0 clamp(12px, 3vw, 28px) clamp(52px, 6vw, 72px);
  overflow: hidden;
  isolation: isolate;
}
.stage::before {
  /* the top edge of the monitor */
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: var(--hairline);
}
.stage-hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(18px, 2.4vw, 26px);
  text-align: center;
  font-size: 0.8125rem;
  color: var(--muted);
  transition: opacity 200ms ease;
}
.stage.is-open .stage-hint { opacity: 0; }

.bar {
  position: relative;
  display: block;
  width: 100%;
  max-width: 640px;
  margin-inline: auto;
  aspect-ratio: 640 / 300;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.bar:focus-visible { outline-offset: 6px; }

.bar-card {
  position: absolute;
  inset: 0;
  border-radius: 0 0 10px 10px;
  overflow: hidden;
  background: var(--shot-bg);
  clip-path: inset(0 0 0 0 round 0 0 10px 10px);
  transition: clip-path 460ms var(--ease-out);
}
.bar-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 160ms ease;
}
.bar-card img.is-on { opacity: 1; }

/* the idle pill, 125 x 22 like the app, sitting on top of the clipped card */
.bar-pill {
  position: absolute;
  top: 0;
  left: 50%;
  width: 125px;
  height: 22px;
  margin-left: -62.5px;
  border: 1px solid var(--shot-line);
  border-top: 0;
  border-radius: 0 0 8px 8px;
  background: var(--shot-bg);
  display: grid;
  place-items: center;
  opacity: 0;
  transition: opacity 120ms ease;
  pointer-events: none;
}
.bar-pill i { display: block; width: 22px; height: 3px; border-radius: 2px; background: var(--accent); }

/* Collapsed only when JS runs the demo; without JS the page shows the open bar. */
.js .bar:not(.is-open) .bar-card {
  clip-path: inset(0 calc(50% - 62.5px) calc(100% - 22px) calc(50% - 62.5px) round 0 0 8px 8px);
  transition-duration: 240ms;
}
.js .bar:not(.is-open) .bar-pill { opacity: 1; transition-delay: 120ms; }

/* ---------- proof line ---------- */

/* This was four oversized numerals in a row. The numbers are the credible part
   of the pitch so they stay; the billboard treatment does not. Read as a
   sentence they say the same thing without asking to be admired. */
.proof {
  margin-top: clamp(48px, 6vw, 72px);
  padding-top: 20px;
  border-top: 1px solid var(--hairline-soft);
  max-width: 68ch;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--muted);
}
.proof b {
  font-family: var(--font-mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.proof .good { color: var(--good); }

/* ---------- module viewer: works like the bar's own tab strip ---------- */

.viewer {
  margin-top: 48px;
  display: grid;
  grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}

.mods { display: grid; gap: 2px; }
.mod {
  display: grid;
  grid-template-columns: 22px 1fr;
  column-gap: 12px;
  align-items: center;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  background: none;
  color: var(--muted);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}
.mod .i { width: 18px; height: 18px; }
.mod b { font-weight: 500; font-size: 0.9688rem; }
.mod .desc {
  grid-column: 2;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--muted);
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 260ms var(--ease-out), margin-top 260ms var(--ease-out);
}
.mod .desc span { overflow: hidden; }
@media (hover: hover) and (pointer: fine) {
  .mod:hover { color: var(--text); background: var(--surface-hover); }
}
.mod[aria-selected="true"] {
  color: var(--text);
  background: var(--bg-elevated);
  border-color: var(--hairline);
}
.mod[aria-selected="true"] .i { color: var(--accent); }
.mod[aria-selected="true"] .desc { grid-template-rows: 1fr; margin-top: 6px; }

.viewer-main { position: sticky; top: calc(var(--nav-h) + 32px); z-index: 10; }
.viewer-frame {
  position: relative;
  aspect-ratio: 640 / 300;
  border: 1px solid var(--hairline);
  border-radius: var(--r-surface);
  overflow: hidden;
  background: var(--shot-bg);
}
.viewer-frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  filter: blur(4px);
  transition: opacity 220ms ease, filter 220ms ease;
}
.viewer-frame img.is-on { opacity: 1; filter: none; }
.viewer-desc { display: none; margin-top: 14px; font-size: 0.9375rem; color: var(--muted); }
.viewer-foot { margin-top: 14px; font-size: 0.8125rem; color: var(--muted); }

@media (max-width: 860px) {
  .viewer { grid-template-columns: 1fr; gap: 20px; }
  .viewer-main { position: static; order: 2; }
  .mods {
    order: 1;
    display: flex;
    gap: 6px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    margin-inline: -16px;
    padding: 2px 16px 6px;
    scrollbar-width: none;
  }
  .mods::-webkit-scrollbar { display: none; }
  .mod {
    width: auto;
    flex: none;
    scroll-snap-align: start;
    grid-template-columns: auto auto;
    column-gap: 8px;
    padding: 8px 12px;
    border-color: var(--hairline-soft);
  }
  .mod .desc { display: none; }
  .viewer-desc { display: block; }
}

/* ---------- Jarvis: the voice loop as one rail ---------- */

.rail {
  --lit: 0;
  position: relative;
  margin: 56px 0 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 24px;
  padding: 28px 0 0;
}
.rail::before,
.rail::after {
  content: "";
  position: absolute;
  top: 5px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--hairline);
}
.rail::after {
  background: var(--accent);
  transform-origin: left;
  transform: scaleX(var(--lit));
  transition: transform 900ms var(--ease-in-out);
}
.leg { position: relative; }
.leg::before {
  content: "";
  position: absolute;
  top: -28px;
  left: 0;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 1px solid var(--hairline);
  background: var(--bg);
  z-index: 1;
  transition: background-color 200ms ease, border-color 200ms ease;
}
.leg.is-lit::before { background: var(--accent); border-color: var(--accent); }
.leg h3 { font-size: 1rem; }
.leg p { margin-top: 8px; font-size: 0.875rem; color: var(--muted); line-height: 1.55; }
.leg .ms {
  display: block;
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text);
}
@media (max-width: 900px) {
  .rail { grid-template-columns: 1fr; gap: 28px; padding: 0 0 0 30px; }
  .rail::before,
  .rail::after { top: 6px; bottom: 6px; left: 5px; right: auto; width: 1px; height: auto; }
  .rail::after { transform-origin: top; transform: scaleY(var(--lit)); }
  .leg::before { top: 6px; left: -30px; }
}

.say {
  margin-top: clamp(64px, 8vw, 104px);
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(32px, 5vw, 64px);
  align-items: start;
}
@media (max-width: 960px) { .say { grid-template-columns: 1fr; } }
.say h3 { font-size: clamp(1.375rem, 2.2vw, 1.75rem); letter-spacing: -0.022em; }

.quotes {
  margin: 28px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 26px 28px;
}
@media (max-width: 560px) { .quotes { grid-template-columns: 1fr; } }
.quotes li {
  display: grid;
  align-content: start;
  grid-template-columns: 18px minmax(0, 1fr);
  column-gap: 10px;
  font-size: 0.875rem;
  color: var(--muted);
  line-height: 1.55;
}
.quotes .i { color: var(--accent); width: 16px; height: 16px; margin-top: 4px; }
.quotes q {
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--text);
  quotes: "“" "”";
}
.quotes li > span:last-child { grid-column: 2; margin-top: 6px; }

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

.code {
  border: 1px solid var(--hairline-soft);
  border-radius: var(--r-surface);
  background: var(--bg-well);
  overflow: hidden;
}
.band--well .code { background: var(--bg); }
.code-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--hairline-soft);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--muted);
}
.code-head .i { width: 15px; height: 15px; }
.code pre {
  margin: 0;
  padding: 16px 18px 18px;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--text);
}
.code .k { color: var(--accent-hover); }
.code .c { color: var(--muted); }
.code .s { color: var(--good); }
.code .t { color: var(--code-type); }
.code + .note { margin-top: 14px; }

/* ---------- providers ---------- */

/* Was a bento. A bento is a layout hunting for content; this content is three
   facts per provider, which is a list with three columns. */
.providers {
  margin-top: 40px;
  list-style: none;
  border-top: 1px solid var(--hairline-soft);
}
.providers li {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 2.4fr) 96px;
  gap: 8px 28px;
  align-items: baseline;
  padding: 15px 0;
  border-bottom: 1px solid var(--hairline-soft);
}
.providers b { font-weight: 600; letter-spacing: -0.01em; }
.providers span { color: var(--muted); font-size: 0.9375rem; }
.providers em {
  font-style: normal;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--good);
  white-space: nowrap;
  text-align: right;
}
.providers em.paid { color: var(--muted); }
/* Narrow: name and price on one line, the description under both, rather than
   letting auto-placement strand the price in the middle of the row. */
@media (max-width: 760px) {
  .providers li { grid-template-columns: 1fr 96px; gap: 4px 16px; }
  .providers b { grid-area: 1 / 1; }
  .providers em { grid-area: 1 / 2; }
  .providers span { grid-area: 2 / 1 / 3 / -1; }
}

/* ---------- privacy ledger ---------- */

.ledger {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
@media (max-width: 820px) { .ledger { grid-template-columns: 1fr; } }
.ledger-col {
  padding: 26px 26px 28px;
  border: 1px solid var(--hairline-soft);
  border-radius: var(--r-surface);
}
.ledger-col--local { background: var(--good-dim); border-color: var(--good-line); }
.ledger-col h3 { display: flex; align-items: center; gap: 10px; font-size: 1.0625rem; }
.ledger-col--local h3 .i { color: var(--good); }
.ledger-col h3 .i { color: var(--muted); width: 20px; height: 20px; }
.ledger-col ul { margin: 20px 0 0; padding: 0; list-style: none; display: grid; gap: 14px; }
.ledger-col li { font-size: 0.9375rem; color: var(--muted); line-height: 1.55; }
.ledger-col li b { display: block; color: var(--text); font-weight: 500; }
.ledger + .btn-row { margin-top: 28px; }

/* ---------- contribute ---------- */

.contrib {
  margin-top: 48px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 64px);
  align-items: start;
}
@media (max-width: 900px) { .contrib { grid-template-columns: 1fr; } }

.links { display: grid; gap: 6px; }
.link {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 16px;
  align-items: center;
  padding: 18px 18px 18px 20px;
  border: 1px solid var(--hairline-soft);
  border-radius: var(--r-surface);
  color: var(--text);
  transition: border-color 160ms ease, background-color 160ms ease;
}
.link:hover { text-decoration: none; border-color: var(--hairline); background: var(--bg-elevated); }
.link b { font-weight: 500; }
.link p { grid-column: 1; font-size: 0.875rem; color: var(--muted); line-height: 1.55; }
.link .i { grid-row: 1 / span 2; grid-column: 2; width: 18px; height: 18px; color: var(--muted); transition: color 160ms ease; }
.link:hover .i { color: var(--accent); }

/* ---------- install ---------- */

.steps {
  max-width: 640px;
  margin: 48px auto 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}
.steps li {
  counter-increment: step;
  position: relative;
  padding: 0 0 36px 52px;
}
.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -2px;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  background: var(--bg);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--accent);
}
.steps li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 15px;
  top: 34px;
  bottom: 6px;
  width: 1px;
  background: var(--hairline-soft);
}
.steps li:last-child { padding-bottom: 0; }
.steps p { margin-top: 6px; font-size: 0.9375rem; color: var(--muted); }
.steps pre {
  margin: 12px 0 0;
  padding: 12px 14px;
  border: 1px solid var(--hairline-soft);
  border-radius: var(--r-ctl);
  background: var(--bg-well);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.65;
  color: var(--text);
  overflow-x: auto;
}
.steps + .btn-row { justify-content: center; margin-top: 40px; }
.reqs { margin-top: 20px; text-align: center; }

/* ---------- closing ---------- */

.cta {
  overflow: hidden;
  border-top: 1px solid var(--hairline-soft);
  padding-block: clamp(88px, 11vw, 136px);
  text-align: center;
}
.cta .wrap { position: relative; z-index: 1; }
.cta h2 { letter-spacing: -0.03em; }
.cta .lead { margin-inline: auto; }
.cta .btn-row { justify-content: center; }

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

.footer {
  border-top: 1px solid var(--hairline-soft);
  padding-block: 40px 48px;
  background: var(--bg-well);
}
.footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: flex-start;
  justify-content: space-between;
}
.footer-links { display: flex; flex-wrap: wrap; gap: 22px; }
.footer-links a { color: var(--muted); font-size: 0.875rem; }
.footer-links a:hover { color: var(--text); text-decoration: none; }
.footer .note { max-width: 44ch; margin-top: 12px; }

/* ---------- legal pages ---------- */

.legal { padding-block: clamp(52px, 7vw, 84px); }
.legal-grid {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: clamp(28px, 5vw, 64px);
  align-items: start;
}
@media (max-width: 900px) { .legal-grid { grid-template-columns: 1fr; } }

.toc {
  position: sticky;
  top: calc(var(--nav-h) + 24px);
  border-left: 1px solid var(--hairline-soft);
  padding-left: 18px;
  display: grid;
  gap: 10px;
}
.toc a { color: var(--muted); font-size: 0.875rem; }
.toc a:hover,
.toc a.is-current { color: var(--text); text-decoration: none; }
@media (max-width: 900px) { .toc { position: static; } }

.prose { max-width: 72ch; }
.prose h1 { font-size: clamp(2rem, 4vw, 2.75rem); }
.prose > * + * { margin-top: 18px; }
.prose h2 {
  margin-top: 46px;
  font-size: 1.375rem;
  padding-top: 26px;
  border-top: 1px solid var(--hairline-soft);
  scroll-margin-top: calc(var(--nav-h) + 20px);
}
.prose h3 { margin-top: 28px; font-size: 1.0625rem; }
.prose p,
.prose li { color: var(--muted); line-height: 1.75; }
.prose strong { color: var(--text); font-weight: 600; }
.prose ul { margin: 0; padding-left: 22px; display: grid; gap: 10px; }
.prose code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  padding: 2px 6px;
  border: 1px solid var(--hairline-soft);
  border-radius: var(--r-ctl);
  background: var(--bg-elevated);
  color: var(--text);
}
.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  border: 1px solid var(--hairline-soft);
}
.prose th,
.prose td {
  text-align: left;
  padding: 11px 14px;
  border-bottom: 1px solid var(--hairline-soft);
  color: var(--muted);
  vertical-align: top;
}
.prose th { background: var(--bg-elevated); color: var(--text); font-weight: 500; }
.prose tr:last-child td { border-bottom: none; }
.prose .callout {
  border: 1px solid var(--hairline);
  border-radius: var(--r-surface);
  background: var(--bg-elevated);
  padding: 16px 18px;
  color: var(--text);
}
.prose .callout p { color: var(--text); }
.updated { font-family: var(--font-mono); font-size: 0.75rem; color: var(--muted); letter-spacing: 0.02em; }

/* ---------- theme change ---------- */

/* The new theme is clipped to a circle at the toggle and grown past the far corner,
   so the colour arrives from the control you pressed instead of replacing the page
   under you. Both snapshots are the same page at the same scroll position, so nothing
   moves; only the colour travels. The default cross-fade is switched off because two
   themes fading through each other goes muddy in the middle. */
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
    mix-blend-mode: normal;
  }
  ::view-transition-old(root) { z-index: 1; }
  ::view-transition-new(root) { z-index: 2; }
}

/* Firefox and older Safari have no view transitions, so they get the same change as a
   plain colour crossfade. The universal selector is affordable because the class is on
   the page for less than half a second, and only while a theme is actually changing. */
.is-theming,
.is-theming *,
.is-theming *::before,
.is-theming *::after {
  transition: background-color 420ms var(--ease-out), border-color 420ms var(--ease-out),
    color 420ms var(--ease-out), fill 420ms var(--ease-out) !important;
  transition-delay: 0s !important;
}

/* ---------- entrance ---------- */

/* Content is visible by default. JS marks an element .will-reveal only just before it
   scrolls in, so no-JS visitors, crawlers and full-page screenshots never see holes. */
@media (prefers-reduced-motion: no-preference) {
  .will-reveal { opacity: 0; transform: translateY(16px); }
  .revealed {
    opacity: 1;
    transform: none;
    transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out);
    transition-delay: calc(var(--d, 0) * 70ms);
  }
}

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