/* Somar site — the npm-flavoured system.
   ═══════════════════════════════════════════════════════════════════════════
   WHY IT LOOKS LIKE THIS (28 July 2026, owner): npm's site is the reference.
   The things being copied are specific, not vibes —
     · the RAINBOW RULE, 4px, under the header and along the footer;
     · a MONOSPACE wordmark and search field, because mono is what makes a
       site read as documentation rather than as marketing;
     · SQUARE corners (6px, was 12) and FLAT bordered boxes with no shadow;
     · ONE red for anything you click, and colour nowhere else;
     · a big centred SEARCH as the primary object on the page.

   EVERY CLASS NAME FROM THE OLD FILE SURVIVES. Seventeen pages share this
   stylesheet and only six of them were touched in the redesign — restyling
   the existing vocabulary is what lets the other eleven inherit the look
   without being edited. Adding a class would have meant editing every page
   to adopt it, which is how half a site ends up in one idiom and half in
   another.

   TOKENS ARE NEVER RENAMED, for the same reason: page-level <style> blocks
   read --card / --line / --ink directly, so retuning a token restyles those
   blocks too, and renaming one would silently drop them back to the browser
   default.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  color-scheme: light;

  --bg: #FFFFFF;
  /* --surface is the RAISED plane (cards, the search field, menus). It exists
     because #fff cannot flip: in dark mode the page ground and a raised card
     must differ, and a hardcoded white is what makes a dark theme look broken
     in exactly the places that matter most. */
  --surface: #FFFFFF;
  --ink: #1A1A1A;
  --soft: #57606A;
  --faint: #8B949E;
  --card: #F6F7F8;
  --card-deep: #EEF0F2;
  --line: #E5E7EA;
  --line-strong: #D0D7DE;

  /* npm's red is the ONLY call-to-action colour. A second CTA colour is how a
     page stops telling you where to click. */
  --red: #CB3837;
  --red-deep: #A82826;

  /* The rainbow rule. One definition — every bar on the site is this. */
  --grad: linear-gradient(90deg, #FB8817 0%, #FA4B2A 28%, #E70D67 64%, #C42AB5 100%);

  --sky: #7BD1FF;
  --pink: #F45CF2;
  --coral: #F1585B;
  --amber: #FFAA2B;

  --f: "Inter", -apple-system, "Helvetica Neue", system-ui, "Segoe UI", sans-serif;
  /* No webfont is loaded anywhere on this site and none is added here: a CDN
     font is a third-party request on every page load, and the system mono
     stack already carries the documentation feel this redesign is after. */
  --mono: ui-monospace, "SF Mono", "Fira Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  /* THE WORDMARK IS CHARTER (28 July 2026, owner). Charter ships with macOS and
     iOS, so it resolves for most visitors with no download; the rest fall
     through a serif stack that keeps the same bookish weight rather than
     dropping to a sans and changing the brand's shape. */
  --serif: Charter, "Bitstream Charter", "Sitka Text", Cambria, Georgia, serif;

  --maxw: 1120px;
  --pad: clamp(20px, 5vw, 56px);
  --r: 6px;
}

/* Dark mode follows the system by default and is OVERRIDDEN by the toggle.
   data-theme wins in both directions deliberately — a visitor whose OS is
   dark must still be able to choose light, and a one-way override only ever
   satisfies half of them. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0D1117;
    --surface: #161B22;
    --ink: #E6EDF3;
    --soft: #9DA7B3;
    --faint: #7D8590;
    --card: #161B22;
    --card-deep: #1C2129;
    --line: #262C36;
    --line-strong: #3A424D;
    --red: #F0655F;
    --red-deep: #FF7B72;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0D1117;
  --surface: #161B22;
  --ink: #E6EDF3;
  --soft: #9DA7B3;
  --faint: #7D8590;
  --card: #161B22;
  --card-deep: #1C2129;
  --line: #262C36;
  --line-strong: #3A424D;
  --red: #F0655F;
  --red-deep: #FF7B72;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--f);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: var(--pad); }
h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -0.02em; text-wrap: balance; }
p { margin: 0; }
a { color: inherit; }

.eyebrow {
  font-family: var(--mono);
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--soft);
}

/* ── The rainbow rule ────────────────────────────────────
   npm's one piece of pure decoration, and the single element that makes a
   page read as "npm" at a glance. Used under the header and above the footer,
   never more than twice on a screen. */
.rule { height: 4px; background: var(--grad); border: 0; margin: 0; }

/* ── Notice bar ──────────────────────────────────────────
   The dismissible strip above everything (npm runs its 2FA deprecation here).
   role="status" belongs on it in the markup — it is an announcement, and a
   div nobody announces is invisible to a screen reader. */
.notice {
  background: #FFF8DD; color: #4B3A05;
  border-bottom: 1px solid #F0E3B0;
  font-size: 14px;
}
:root[data-theme="dark"] .notice { background: #2B2413; color: #F0DFA8; border-bottom-color: #3D3320; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .notice { background: #2B2413; color: #F0DFA8; border-bottom-color: #3D3320; }
}
:root[data-theme="dark"] .notice .close:hover { background: rgba(255,255,255,0.1); }
.notice-in {
  display: flex; align-items: center; gap: 12px;
  padding-block: 11px; min-height: 44px;
}
.notice svg { flex: none; width: 17px; height: 17px; }
.notice p { flex: 1; }
.notice a { font-weight: 600; text-underline-offset: 3px; }
.notice .close {
  flex: none; background: none; border: 0; cursor: pointer;
  color: inherit; font-size: 20px; line-height: 1; padding: 4px 8px;
  border-radius: var(--r); opacity: 0.7;
}
.notice .close:hover { opacity: 1; background: rgba(0,0,0,0.06); }

.theme-toggle {
  background: none; border: 0; cursor: pointer; color: var(--ink);
  padding: 7px; border-radius: var(--r); display: grid; place-items: center;
  margin-right: 6px;
}
.theme-toggle:hover { background: var(--card); }
.theme-toggle svg { width: 17px; height: 17px; }

/* ── Nav — ONE row (28 July 2026, owner) ─────────────────
   Was two: a utility strip over a search-led header. The search row was
   removed outright, so the wordmark and the destinations moved up into the
   single remaining row — wordmark and links LEFT, account controls RIGHT.
   Nothing sits in the middle: a centred search was the only thing that ever
   justified the second row, and with it gone a two-row header was just
   height. */
.nav { background: var(--bg); border-bottom: 0; }
.nav-in { display: flex; align-items: center; gap: 18px; min-height: 60px; padding-block: 10px; }
/* THE WORDMARK IS PLAIN CHARTER — no tile, no monospace. It is the one place
   the brand's own voice sits, so it is deliberately unlike the UI type. */
.logo {
  font-family: var(--serif);
  font-weight: 700; font-size: 23px; letter-spacing: -0.01em;
  text-decoration: none; display: inline-flex; align-items: center;
  color: var(--ink);
  flex: none;
}
/* ⚠️ THE LINKS SCROLL ON A NARROW SCREEN, THEY DO NOT DISAPPEAR. This row is
   now the ONLY navigation on the site — the utility strip that used to carry a
   duplicate set is gone — so a `display: none` here would leave a phone with no
   way to reach Pricing or Docs at all. The old two-row header could afford to
   hide these because the strip above kept them; this one cannot. */
.nav-links {
  display: flex; align-items: center; gap: 2px;
  flex: 1 1 auto; min-width: 0;
  overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;
}
.nav-links::-webkit-scrollbar { display: none; }
.nav-links a {
  font-size: 14.5px; font-weight: 550; color: var(--soft); white-space: nowrap;
  text-decoration: none; padding: 7px 11px; border-radius: var(--r);
}
.nav-links a:hover { background: var(--card); color: var(--ink); }
.nav-links a[aria-current="page"] { color: var(--ink); font-weight: 650; }
.nav-cta { margin-left: auto; flex: none; display: flex; gap: 4px; align-items: center; }
.nav-cta a {
  font-size: 14.5px; font-weight: 550; color: var(--ink);
  text-decoration: none; padding: 7px 11px; border-radius: var(--r);
}
.nav-cta a:hover { background: var(--card); }
.nav-cta .btn { color: #fff; }
/* Below this the account links lose their labels' breathing room before the
   destinations do, so they tighten rather than the nav scrolling sooner. */
@media (max-width: 620px) {
  .nav-in { gap: 10px; }
  .nav-cta a { padding: 7px 7px; }
}

/* ── The flow — four steps, each one a link ──────────────
   `Track user behaviour → Run experiments → Analysis → Ship`. Every chip is an
   anchor into the step's own explanation below, because the four words are a
   summary and a summary that cannot be opened is a claim you have to take on
   faith. Anchors rather than tooltips: a tooltip cannot be linked to, shared,
   or read on a phone. */
.flow {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 8px 6px;
}
/* `.step` is the same pill with nowhere to go — the waitlist has no
   explanations to link to yet, and a link to nothing is worse than plain
   text. Styled together so the two sites cannot drift apart. */
.flow a, .flow .step {
  display: inline-flex; align-items: center;
  padding: 9px 16px; border-radius: 100px;
  background: var(--surface); border: 1px solid var(--line-strong);
  font-size: 14.5px; font-weight: 600; color: var(--ink); text-decoration: none;
  transition: border-color .15s ease, background .15s ease;
}
.flow a:hover { border-color: var(--ink); background: var(--card); }
.flow .arrow { color: var(--faint); font-size: 15px; }

/* The four explanations the chips open onto. */
.flow-steps { display: grid; gap: 14px; }
.flow-step {
  display: grid; grid-template-columns: 46px 1fr; gap: 20px; align-items: start;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: 26px 28px;
  scroll-margin-top: 24px;
}
.flow-step .n {
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--grad); padding: 2.5px; display: grid; place-items: center;
}
.flow-step .n span {
  width: 100%; height: 100%; border-radius: 50%;
  background: var(--surface); color: var(--red);
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 18px; font-weight: 700;
}
.flow-step h3 { font-size: 20px; }
.flow-step p { margin-top: 8px; font-size: 15px; color: var(--soft); max-width: 68ch; }
.flow-step .kinds { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.flow-step .kinds span {
  font-family: var(--mono); font-size: 12px; color: var(--soft);
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r); padding: 5px 10px;
}
@media (max-width: 560px) {
  .flow-step { grid-template-columns: 1fr; gap: 14px; padding: 22px; }
}

/* ── Nav dropdowns (built by site.js) ────────────────── */
.nav-item { position: relative; display: flex; align-items: center; }
.nav-item > a { display: block; }
.dropdown {
  position: absolute; top: 100%; left: -8px; z-index: 70;
  padding-top: 10px; /* hover bridge — keeps :hover alive across the gap */
  opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
}
.nav-item:hover .dropdown,
.nav-item:focus-within .dropdown {
  opacity: 1; visibility: visible; transform: none;
}
.panel {
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r); padding: 10px;
  box-shadow: 0 8px 24px rgba(27,31,36,0.12);
  display: flex; gap: 18px; flex-wrap: wrap;
  width: max-content;
  max-width: min(680px, calc(100vw - 24px));
}
.menu-col { min-width: 176px; }
.menu-label {
  font-family: var(--mono);
  font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--faint); padding: 8px 10px 4px; white-space: nowrap;
}
.menu-item {
  display: flex; gap: 10px; align-items: center;
  padding: 8px 10px; border-radius: var(--r); text-decoration: none;
  font-size: 14px; font-weight: 550; color: var(--ink); white-space: nowrap;
}
.menu-item:hover { background: var(--card); }
.menu-item .desc { display: block; font-size: 12px; font-weight: 450; color: var(--soft); margin-top: 1px; }
.menu-item .mi-tile { width: 28px; height: 28px; border-radius: 5px; display: grid; place-items: center; flex: none; }
.menu-item .mi-tile svg { width: 15px; height: 15px; }
.menu-item .mi-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.menu-foot {
  display: block; text-decoration: none; white-space: nowrap;
  border-top: 1px solid var(--line); margin-top: 8px; padding: 10px;
  font-size: 13px; font-weight: 600; color: var(--ink); border-radius: 0 0 var(--r) var(--r);
}
.menu-foot:hover { background: var(--card); }
@media (prefers-reduced-motion: reduce) { .dropdown { transition: none; transform: none; } }

/* ── Buttons ─────────────────────────────────────────────
   .btn-solid is now RED, not black. Every page's primary action inherits it,
   which is the whole point of restyling the class rather than adding one. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--f); font-size: 14.5px; font-weight: 650;
  text-decoration: none; cursor: pointer;
  padding: 10px 20px; border-radius: var(--r); border: 1px solid transparent;
  transition: background .15s ease, border-color .15s ease;
}
.btn-solid { background: var(--red); color: #fff; border-color: var(--red); }
.btn-solid:hover { background: var(--red-deep); border-color: var(--red-deep); }
:root[data-theme="dark"] .btn-solid { color: #1A1A1A; }
.btn-ghost { background: var(--surface); color: var(--ink); border-color: var(--line-strong); }
.btn-ghost:hover { background: var(--card); border-color: var(--faint); }
.btn-dark { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.btn-dark:hover { background: #000; }
:root[data-theme="dark"] .btn-dark:hover { background: #fff; }
.btn-big { padding: 14px 30px; font-size: 16px; }

/* ── Hero ────────────────────────────────────────────────
   Left-aligned by DEFAULT — the content pages read as documentation and
   centred prose is harder to scan. `.hero.center` is the npm product-page
   treatment and is used only on the home and waitlist pages. */
.hero { padding-block: clamp(48px, 8vw, 96px) clamp(32px, 5vw, 52px); }
.hero h1 {
  font-size: clamp(38px, 6.5vw, 76px);
  line-height: 1.04;
  max-width: 18ch;
}
.hero .sub {
  margin-top: 22px; max-width: 56ch;
  font-size: clamp(16px, 2vw, 19px); color: var(--soft); line-height: 1.6;
}
/* THE SECOND LINE OF THE HEADLINE IS LIGHTER THAN THE FIRST. "Track user
   behaviour" is what Somar does; "Build what matters" is what you get — so the
   two lines are one sentence in two voices, and the weight is what says so.
   No comma, no full stop: at this size punctuation reads as debris, and the
   line break already does the work the comma was doing.
   300 resolves against SF Pro's real Light on Apple platforms and degrades to
   the nearest available weight elsewhere — never below Regular, so it can go
   lighter but never illegible. */
.hero h1 .light { font-weight: 300; letter-spacing: -0.015em; }

.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
.hero.center { text-align: center; }
.hero.center h1 { margin-inline: auto; }
.hero.center .sub { margin-inline: auto; }
.hero.center .cta-row { justify-content: center; }

/* ── Cards ───────────────────────────────────────────────
   Flat, bordered, no lift on hover. npm's boxes do not move; the border
   darkens. A card that jumps is a card that reads as an advert. */
.cards { display: grid; gap: 16px; }
.cards.c3 { grid-template-columns: repeat(3, 1fr); }
.cards.c4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 860px) { .cards.c3, .cards.c4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) { .cards.c3, .cards.c4 { grid-template-columns: 1fr; } }

.card {
  display: flex; flex-direction: column; gap: 10px;
  background: var(--surface); border-radius: var(--r);
  padding: 24px; text-decoration: none; color: var(--ink);
  border: 1px solid var(--line);
  transition: border-color .15s ease, background .15s ease;
}
a.card:hover { border-color: var(--line-strong); background: var(--card); }
.card h3 { font-size: 17px; letter-spacing: -0.01em; }
.card p { font-size: 14px; color: var(--soft); }
.card .more { margin-top: auto; padding-top: 10px; font-size: 13.5px; font-weight: 650; color: var(--red); }
.card .soon { margin-top: auto; padding-top: 10px; font-size: 12.5px; font-weight: 600; color: var(--faint); }

/* A card that leads with the rainbow, for the one or two that must stand out
   (npm marks its numbered steps this way). */
.card.topped { position: relative; overflow: hidden; }
.card.topped::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 4px; background: var(--grad);
}

/* icon tile — the only place colour lives besides the rule and the CTA */
.tile {
  width: 34px; height: 34px; border-radius: 5px;
  display: grid; place-items: center; margin-bottom: 4px;
}
.tile svg { width: 18px; height: 18px; }
.tile.sky,   .mi-tile.sky   { background: rgba(123,209,255,0.22); color: #1E7CB8; }
.tile.pink,  .mi-tile.pink  { background: rgba(244,92,242,0.16);  color: #C22BC0; }
.tile.coral, .mi-tile.coral { background: rgba(241,88,91,0.16);   color: #D63B3E; }
.tile.amber, .mi-tile.amber { background: rgba(255,170,43,0.20);  color: #C97A0A; }

/* ── Numbered steps ──────────────────────────────────────
   npm's "1 / 2" circles: a white disc inside a gradient ring, centred over a
   bordered box. The ring is a padded background rather than a border because
   a gradient cannot be a border-color. */
.steps { display: grid; gap: 20px; max-width: 640px; margin-inline: auto; }
.step {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r); padding: 34px 28px 30px; text-align: center;
  position: relative;
}
.step .num {
  width: 58px; height: 58px; border-radius: 50%;
  background: var(--grad); padding: 3px;
  margin: 0 auto 18px; display: grid; place-items: center;
}
.step .num span {
  width: 100%; height: 100%; border-radius: 50%;
  background: var(--surface); color: var(--red);
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 24px; font-weight: 700;
}
.step h3 { font-size: 21px; }
.step p { margin-top: 10px; font-size: 15px; color: var(--soft); }
.step a { color: var(--red); font-weight: 600; text-underline-offset: 3px; }

/* ── Window mock ─────────────────────────────────────────
   Squarer and shadowless, to match the flat boxes. */
.window {
  border: 1px solid var(--line-strong); border-radius: var(--r); overflow: hidden;
  background: var(--surface);
}
.window-top {
  display: flex; align-items: center; gap: 7px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
  background: var(--card);
}
.wd { width: 10px; height: 10px; border-radius: 50%; }
.wd:nth-child(1) { background: var(--coral); }
.wd:nth-child(2) { background: var(--amber); }
.wd:nth-child(3) { background: var(--sky); }
.window-top .crumb { margin-left: 10px; font-family: var(--mono); font-size: 12.5px; color: var(--faint); }

/* ── Tabs ────────────────────────────────────────────────
   npm underlines the selected tab rather than filling a pill. Underlines read
   as navigation; filled pills read as buttons, and these do not act. */
.tabs { display: flex; gap: 4px; flex-wrap: wrap; border-bottom: 1px solid var(--line); }
.tab {
  font-family: var(--f); font-size: 14.5px; font-weight: 600; cursor: pointer;
  padding: 11px 18px; border: 0; background: none; color: var(--soft);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color .15s ease, border-color .15s ease;
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--red); }

/* ── Sections ────────────────────────────────────────── */
.section { padding-block: clamp(44px, 7vw, 88px); }
.section.alt { background: var(--card); }
.sec-head { max-width: 62ch; margin-bottom: 36px; }
.sec-head h2 { font-size: clamp(26px, 3.6vw, 40px); line-height: 1.08; }
.sec-head p { margin-top: 14px; font-size: 17px; color: var(--soft); max-width: 54ch; }

.group-label {
  font-family: var(--mono);
  font-size: 12px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--faint); margin: 44px 0 16px;
}

/* ── CTA band ────────────────────────────────────────── */
.band { text-align: center; padding-block: clamp(56px, 9vw, 104px); }
.band h2 { font-size: clamp(28px, 4.5vw, 50px); line-height: 1.05; max-width: 20ch; margin: 0 auto 24px; }

/* ── Footer ──────────────────────────────────────────────
   Columns, npm-style, with the rainbow rule closing the page. */
.footer { border-top: 1px solid var(--line); padding: 48px 0 0; margin-top: 40px; }
.footer-cols {
  display: grid; gap: 32px;
  grid-template-columns: auto repeat(3, minmax(0, 1fr));
  align-items: start;
}
@media (max-width: 760px) { .footer-cols { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px) { .footer-cols { grid-template-columns: 1fr; } }
.footer-brand { display: flex; flex-direction: column; gap: 14px; }
.footer-col h4 { font-size: 15px; font-weight: 700; margin-bottom: 12px; }
.footer-col a { display: block; font-size: 14px; color: var(--soft); text-decoration: none; padding: 5px 0; }
.footer-col a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.footer-in { display: flex; flex-wrap: wrap; gap: 18px; justify-content: space-between; align-items: center; }
.footer .links { display: flex; gap: 20px; flex-wrap: wrap; }
.footer .links a { font-size: 13.5px; color: var(--soft); text-decoration: none; }
.footer .links a:hover { color: var(--ink); }
.footer .fine { font-size: 13px; color: var(--faint); }
.footer-bottom { margin-top: 40px; padding-block: 22px; border-top: 1px solid var(--line); }

/* ── Reveal ──────────────────────────────────────────── */
.reveal { opacity: 0; transform: translateY(14px); transition: opacity .5s ease, transform .5s ease; }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

a:focus-visible, .btn:focus-visible, .tab:focus-visible,
.theme-toggle:focus-visible, .search-go:focus-visible, .notice .close:focus-visible {
  outline: 2px solid var(--red); outline-offset: 2px;
}

/* ── Inline code ─────────────────────────────────────────
   A documentation site needs this and the old file had none, so every page
   that wanted one styled it locally. */
code, .mono {
  font-family: var(--mono); font-size: 0.9em;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 4px; padding: 1.5px 6px;
}
.codeblock {
  font-family: var(--mono); font-size: 14px; line-height: 1.7;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r); padding: 18px 20px; overflow-x: auto;
  color: var(--ink); white-space: pre;
}
.codeblock code { background: none; border: 0; padding: 0; font-size: inherit; }

/* ── Legal pages (privacy / terms / cookies) ─────────── */
.legal { max-width: 76ch; padding-block: clamp(40px, 6vw, 72px); }
.legal .updated { font-size: 13.5px; color: var(--faint); margin-top: 10px; }
.legal h1 { font-size: clamp(30px, 4.5vw, 46px); line-height: 1.08; }
.legal h2 { font-size: 22px; margin: 44px 0 12px; }
.legal h3 { font-size: 16.5px; margin: 28px 0 8px; }
.legal p, .legal li { font-size: 15.5px; line-height: 1.65; color: var(--soft); }
.legal p { margin: 10px 0; }
.legal ul, .legal ol { margin: 10px 0 10px 22px; }
.legal li { margin: 6px 0; }
.legal strong { color: var(--ink); }
.legal a { color: var(--red); text-underline-offset: 3px; }
.legal .toc { background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  padding: 18px 22px; margin: 28px 0; }
.legal .toc ol { margin: 6px 0 0 20px; }
.legal .notice { background: var(--card); border: 1px solid var(--line-strong); border-radius: var(--r);
  padding: 16px 20px; margin: 18px 0; color: var(--ink); }
.legal .notice p { margin: 6px 0; color: var(--ink); }
.legal .table-scroll { overflow-x: auto; margin: 14px 0; }
.legal table { border-collapse: collapse; width: 100%; min-width: 560px; font-size: 14px; }
.legal th, .legal td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line);
  color: var(--soft); vertical-align: top; line-height: 1.5; }
.legal th { color: var(--ink); font-weight: 600; border-bottom: 1px solid var(--line-strong); }
.legal details { border: 1px solid var(--line); border-radius: var(--r); padding: 4px 18px; margin: 14px 0; background: var(--card); }
.legal details[open] { padding-bottom: 14px; }
.legal summary { cursor: pointer; padding: 12px 0; font-size: 14.5px; font-weight: 600; color: var(--ink); list-style: none; }
.legal summary::-webkit-details-marker { display: none; }
.legal summary::after { content: " ▸"; color: var(--faint); }
.legal details[open] summary::after { content: " ▾"; }

/* ── Cookie consent banner ───────────────────────────── */
.cookie-banner {
  position: fixed; inset: auto 16px 16px 16px; z-index: 60; margin-inline: auto;
  max-width: 620px; background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r); box-shadow: 0 12px 40px rgba(27,31,36,0.16);
  padding: 18px 20px; display: flex; flex-wrap: wrap; gap: 14px; align-items: center;
}
.cookie-banner p { font-size: 13.5px; line-height: 1.55; color: var(--soft); flex: 1 1 32ch; margin: 0; }
.cookie-banner a { color: var(--red); }
.cookie-banner .actions { display: flex; gap: 10px; flex-wrap: wrap; }
.cookie-banner .btn { font-size: 13.5px; padding: 9px 16px; }
@media (prefers-reduced-motion: no-preference) {
  .cookie-banner { animation: cookie-in .4s ease; }
  @keyframes cookie-in { from { opacity: 0; transform: translateY(12px); } }
}
