/* ============================================================
   CameoDB — next-generation site, working base.

   Model: ordinary linear document scrolling. The horizontal rail
   is a scroll-spy — it reports which section you are in and how
   far through it you are, and never controls the scroll.

   Constraints this file holds to:
     - no ES modules      (CORS-blocked on file://)
     - no absolute paths  ("/" is filesystem root from disk)
     - no CDN for CSS, JS or fonts
   so it opens straight from disk, offline. Any real build for the
   site has to meet the same three.
   ============================================================ */

:root {
  --bg:          #0c1324;
  --bg-low:      #070d1f;
  --surf-1:      #151b2d;
  --surf-2:      #191f31;
  --surf-3:      #23293c;
  --line:        #2e3447;
  --line-soft:   #3e4850;
  --text:        #dce1fb;
  --muted:       #bec8d2;
  --dim:         #88929b;
  --primary:     #89ceff;
  --accent:      #0ea5e9;
  --amber:       #ffb95f;
  --good:        #6ee7a8;
  --bad:         #ff8f85;

  --header-h: 64px;
  --rail-h:   70px;
  /* The column both fixed bars line up on: the brand and the stepper in
     the header, the rail and its progress bar below it. */
  --shell-max: 1400px;
  --shell-pad: max(20px, calc((100% - var(--shell-max)) / 2));

  --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --ease: cubic-bezier(.4, .14, .3, 1);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* A net under the layout. Nothing should set a width wider than the
     viewport, but when something does the page scrolls sideways and carries
     the fixed header's controls off-screen with it — the navigation becomes
     unreachable, which is the worst failure this layout has. clip rather than
     hidden: hidden would make this a scroll container and break the sticky
     rail inside it. */
  overflow-x: clip;
}
body {
  margin: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Ambient background wash — static, cheap, no animation loop. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(900px 520px at 12% -8%,  rgba(14,165,233,.16), transparent 62%),
    radial-gradient(760px 460px at 92% 108%, rgba(137,206,255,.09), transparent 60%);
  z-index: 0;
}

/* ---------- Header ---------- */

.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 var(--shell-pad);
  background: rgba(7,13,31,.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
  z-index: 40;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
}
.brand-mark {
  width: 44px; height: 44px;
  flex: 0 0 44px;
  transition: filter .3s var(--ease);
}
.brand:hover .brand-mark {
  filter: drop-shadow(0 0 8px rgba(14,165,233,.5));
}
.brand-mark .mark-t { transition: transform .3s var(--ease); }
.brand:hover .brand-mark .mark-t { transform: translateX(4px); }
.brand-name {
  font-family: var(--mono);
  font-size: 25px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: #fff;
  line-height: 1;
}
.brand-db { color: var(--accent); }
.brand-ver {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--accent);
  border: 1px solid rgba(14,165,233,.35);
  background: rgba(14,165,233,.10);
  border-radius: 999px;
  padding: 2px 8px;
  letter-spacing: .06em;
  white-space: nowrap;
}

.themes {
  display: flex;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 10px;
  overflow-x: auto;
  scrollbar-width: none;
}
.themes::-webkit-scrollbar { display: none; }

.theme-btn {
  position: relative;
  border: 0;
  background: transparent;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 6px 14px;
  border-radius: 7px;
  cursor: pointer;
  white-space: nowrap;
  transition: color .2s var(--ease), background .2s var(--ease);
}
.theme-btn:hover { color: var(--muted); background: var(--surf-3); }
.theme-btn.is-on {
  color: var(--primary);
  background: linear-gradient(180deg, rgba(14,165,233,.22), rgba(14,165,233,.08));
  box-shadow: inset 0 0 0 1px rgba(137,206,255,.34);
}
.theme-btn small {
  display: block;
  font-size: 9px;
  letter-spacing: .06em;
  text-transform: none;
  opacity: .6;
  margin-top: 1px;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 14px;
}
.counter {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--dim);
  letter-spacing: .1em;
  white-space: nowrap;
}
.counter b { color: var(--primary); font-weight: 700; }

.stepper { display: flex; gap: 6px; }
.step-btn {
  width: 32px; height: 32px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--surf-1);
  color: var(--muted);
  cursor: pointer;
  transition: background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
.step-btn:hover:not(:disabled) {
  background: var(--surf-3);
  color: var(--primary);
  border-color: var(--line-soft);
}
.step-btn:disabled { opacity: .3; cursor: default; }
.step-btn svg { width: 15px; height: 15px; }

/* ---------- Segment-map rail ---------- */

.rail-wrap {
  position: fixed;
  top: var(--header-h);
  left: 0; right: 0;
  height: var(--rail-h);
  background: rgba(12,19,36,.78);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
  z-index: 35;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 var(--shell-pad);
}

.rail {
  display: flex;
  gap: 4px;
  align-items: stretch;
  height: 54px;
  max-width: var(--shell-max);
  width: 100%;
  margin: 0 auto;
}

/* Each chapter is an index "segment". Active one is lit and widened. */
.seg {
  position: relative;
  /* A tick holds a two-digit number, so it gets a tick's worth of width.
     The active segment (below) grows to absorb whatever is left, so the
     row always spans exactly the same width as the progress track. */
  flex: 0 1 56px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  padding: 7px 11px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surf-1);
  color: var(--dim);
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  font-family: var(--sans);
  transition: flex-basis .45s var(--ease), background .3s var(--ease),
              border-color .3s var(--ease), color .3s var(--ease);
}
.seg::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--line-soft);
  transition: background .3s var(--ease);
}
.seg:hover { background: var(--surf-3); color: var(--muted); }
.seg:hover::before { background: var(--primary); }

.seg.is-near {
  flex: 0 1 176px;
  background: var(--surf-2);
  color: var(--muted);
}
.seg.is-active {
  flex: 1 1 320px;
  background: linear-gradient(180deg, rgba(14,165,233,.16), rgba(14,165,233,.05));
  border-color: rgba(137,206,255,.45);
  color: var(--text);
}
.seg.is-active::before { background: var(--primary); }
.seg.is-done::before { background: rgba(137,206,255,.45); }

.seg-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.seg-idx {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .12em;
  opacity: .75;
  line-height: 1.3;
  flex: 0 0 auto;
}
.seg.is-active .seg-idx { color: var(--primary); opacity: 1; }

.seg-title {
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  max-width: 0;
  transition: opacity .3s var(--ease), max-width .4s var(--ease);
}
.seg.is-near .seg-title,
.seg.is-active .seg-title { opacity: 1; max-width: 100%; }

.seg-sum {
  font-size: 11.5px;
  color: var(--muted);
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  max-height: 0;
  transition: opacity .3s var(--ease) .05s, max-height .35s var(--ease);
}
.seg.is-active .seg-sum { opacity: 1; max-height: 18px; }

/* Continuous progress under the segments */
.progress-track {
  max-width: var(--shell-max);
  width: 100%;
  margin: 6px auto 0;
  height: 2px;
  background: var(--line);
  border-radius: 2px;
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--accent), var(--primary));
  border-radius: 2px;
}

/* ---------- Flow: an ordinary document ----------
   No snapping, no fixed scroll container, no intercepted wheel.
   The page scrolls the way every page scrolls; the rail only
   reports position. Browser find-in-page works across the whole
   group, which is the point of doing it this way. */

.deck {
  position: relative;
  z-index: 10;
  padding-top: calc(var(--header-h) + var(--rail-h));
}

.chapter {
  position: relative;
  /* Measured: median section renders ~648px. A 78vh floor (702px) padded
     13 of 19 sections, so content rhythm now leads and the floor only
     catches the genuinely thin ones. */
  min-height: 52vh;
  display: flex;
  align-items: center;
  align-items: safe center;
  /* This top padding is the whole gap between the rail and a section's first
     line, on load and on every jump the rail makes, so it is the cheapest
     vertical space on the page to buy back. */
  padding: 48px 28px;
  scroll-margin-top: calc(var(--header-h) + var(--rail-h));
}
/* The first section is already under the rail, so centring it inside the
   min-height floor only pushes the opening line further down a screen the
   reader has not scrolled yet. Start it at the top and give it less padding:
   this band is the most expensive vertical space on the site, because every
   page pays it before showing anything. */
.deck > .chapter:first-of-type { align-items: start; padding-top: 28px; }

.chapter + .chapter { border-top: 1px solid var(--line); }
.chapter-inner { width: 100%; max-width: 1080px; margin: 0 auto; }

/* ---------- Rail segment: fills as you read through the section ---------- */

.seg-prog {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0;
  background: linear-gradient(90deg, rgba(14,165,233,.30), rgba(137,206,255,.10));
  border-radius: 7px 0 0 7px;
  pointer-events: none;
  transition: width .1s linear;
}
.seg:not(.is-active) .seg-prog { display: none; }
.seg > .seg-head, .seg > .seg-sum { position: relative; z-index: 1; }

/* ---------- Shared chapter typography ---------- */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 18px;
}
.eyebrow::before {
  content: '';
  width: 22px;
  height: 1px;
  background: var(--accent);
}

h1.display {
  font-size: clamp(30px, 5.2vw, 62px);
  line-height: 1.04;
  letter-spacing: -.035em;
  font-weight: 800;
  margin: 0 0 20px;
}
h1.title,
h2.title {
  font-size: clamp(24px, 3.4vw, 40px);
  line-height: 1.12;
  letter-spacing: -.028em;
  font-weight: 800;
  margin: 0 0 16px;
}
.lede {
  font-size: clamp(15px, 1.5vw, 18px);
  color: var(--muted);
  max-width: 62ch;
  margin: 0 0 26px;
}
.grad {
  background: linear-gradient(100deg, var(--primary), var(--accent) 55%, var(--amber));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ---------- Reusable pieces ---------- */

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.chip {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 999px;
  padding: 5px 12px;
  letter-spacing: .04em;
}

.cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: 16px;
}
/* Four cards fall 3 + 1 on the auto-fit track, and the orphan reads as a
   mistake. Pair them instead — two rows of two, square. */
.cols.pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 720px) { .cols.pair { grid-template-columns: 1fr; } }

.card {
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 12px;
  padding: 18px;
}
.card h3 {
  margin: 0 0 10px;
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 8px;
}
/* Inline icons carry a viewBox but no intrinsic size. Without an explicit
   width they fall back to the default 300x150 replaced-element box and blow
   up as soon as the flex row has room to give them. */
.card h3 svg { width: 16px; height: 16px; flex: 0 0 16px; }
.card p { margin: 0; font-size: 13.5px; color: var(--muted); }

.card.bad  { border-color: rgba(255,143,133,.28); background: rgba(255,143,133,.05); }
.card.good { border-color: rgba(110,231,168,.28); background: rgba(110,231,168,.05); }
.card.bad h3  { color: var(--bad); }
.card.good h3 { color: var(--good); }

.ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.ticks li {
  display: flex;
  gap: 9px;
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.45;
}
.ticks svg { width: 15px; height: 15px; flex: 0 0 15px; margin-top: 3px; }

/* Code surfaces */
.code {
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.75;
  background: var(--bg-low);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px 18px;
  overflow-x: auto;
  margin: 0;
  color: var(--text);
  white-space: pre;
}
.code .k { color: var(--primary); }
.code .s { color: var(--amber); }
.code .c { color: var(--dim); }
.code .p { color: var(--dim); }

.code-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--dim);
  padding: 9px 14px;
  background: var(--surf-2);
  border: 1px solid var(--line);
  border-bottom: none;
  border-radius: 12px 12px 0 0;
  letter-spacing: .06em;
}
.code-head + .code { border-radius: 0 0 12px 12px; }
.dots { display: flex; gap: 5px; margin-right: 4px; }
.dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--line-soft); }

/* Numbered pipeline */
.pipeline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  gap: 12px;
  counter-reset: step;
}
.stage {
  position: relative;
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 12px;
  padding: 16px 16px 18px;
}
.stage-n {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  color: var(--accent);
  display: block;
  margin-bottom: 8px;
}
.stage h4 { margin: 0 0 6px; font-size: 13.5px; font-weight: 700; }
.stage p  { margin: 0; font-size: 12.5px; color: var(--muted); line-height: 1.5; }

/* Stat tiles — bare tiles, no plot, so no hover layer needed.
   Values use proportional figures at display size (not tabular). */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr));
  gap: 12px;
}
.stat {
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 12px;
  padding: 16px;
}
.stat-label {
  font-size: 11.5px;
  color: var(--dim);
  letter-spacing: .04em;
  margin-bottom: 7px;
}
.stat-value {
  font-family: var(--sans);
  font-size: 25px;
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.1;
  color: var(--text);
}
.stat-note {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 6px;
  line-height: 1.4;
}

/* Query syntax rows */
.syntax { display: grid; gap: 8px; }
.srow {
  display: grid;
  grid-template-columns: minmax(200px, 1.1fr) 1.3fr;
  gap: 14px;
  align-items: center;
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 10px;
  padding: 11px 14px;
}
.srow code {
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--primary);
  word-break: break-word;
}
.srow span { font-size: 12.5px; color: var(--muted); }

/* Below this the two columns do not both fit: the syntax column has a 200px
   floor and the description carries a type list that can run to 59 characters.
   Side by side they set a minimum width wider than a phone, and a page that
   is wider than the viewport takes the fixed header's controls off-screen
   with it. */
@media (max-width: 640px) {
  .srow { grid-template-columns: 1fr; gap: 5px; align-items: start; }
  .srow code { overflow-wrap: anywhere; }
}

/* Mesh diagram */
/* ---------- Cluster diagram ----------
   One self-contained SVG, so nodes and links share a coordinate space and
   stay aligned at any width. The default preserveAspectRatio keeps the ring
   circular instead of stretching with the container. */

.cluster {
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surf-1);
  padding: 6px 6px 14px;
  overflow: hidden;
}
.cluster-svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 320px;
}
.cluster-key {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 22px;
  padding: 2px 14px 2px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .05em;
  color: var(--dim);
}
.cluster-key span { display: inline-flex; align-items: center; gap: 7px; }
.cluster-key i { width: 14px; height: 3px; border-radius: 2px; flex: 0 0 14px; }
.cluster-key .k-range { background: var(--secondary); }
.cluster-key .k-node  { background: var(--primary); height: 9px; width: 9px; border-radius: 50%; flex-basis: 9px; }
.cluster-key .k-link  { background: none; border-top: 2px dashed rgba(137,206,255,.5); height: 0; }

/* Call-to-action cards */
.cta-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
  gap: 14px;
}
/* Six cards fall 4 + 2 on the auto-fit track. Three across makes two even
   rows, and the same cards stay readable at two and then one on the way down. */
.cta-grid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 900px) { .cta-grid.three { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .cta-grid.three { grid-template-columns: 1fr; } }
/* Icon and title share the top row; the description sits under the title
   rather than under the icon, so the text block reads as one column. */
.cta {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  column-gap: 12px;
  row-gap: 6px;
  align-items: center;
  text-decoration: none;
  color: var(--text);
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 14px;
  padding: 22px;
  transition: background .22s var(--ease), border-color .22s var(--ease), transform .22s var(--ease);
}
.cta:hover {
  background: var(--surf-3);
  border-color: rgba(137,206,255,.45);
  transform: translateY(-2px);
}
.cta-ico {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 9px;
  background: rgba(14,165,233,.14);
  color: var(--primary);
}
.cta-ico svg { width: 17px; height: 17px; }
.cta h3 { grid-column: 2; margin: 0; font-size: 15px; font-weight: 700; }
.cta p  { grid-column: 2; margin: 0; font-size: 13px; color: var(--muted); }

.hint {
  margin-top: 28px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--dim);
  letter-spacing: .05em;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
kbd {
  font-family: var(--mono);
  font-size: 10px;
  border: 1px solid var(--line-soft);
  background: var(--surf-2);
  border-radius: 5px;
  padding: 2px 6px;
  color: var(--muted);
}

/* ---------- Brand: hero mark & footer ---------- */

.site-footer {
  max-width: 1080px;
  margin: 0 auto;
  padding: 20px 28px 40px;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--dim);
}
.site-footer a { color: var(--dim); text-decoration: none; transition: color .2s var(--ease); }
.site-footer a:hover { color: var(--primary); }
.foot-social { display: flex; gap: 14px; align-items: center; }
.foot-social a { color: var(--accent); display: grid; place-items: center; }
.foot-social a:hover { color: #fff; }
.foot-social svg { width: 16px; height: 16px; }

/* ---------- Quickstart: numbered steps with a fading connector ----------
   The connector hangs below each node and fades out, the way the current
   public quickstart draws it. It signals "there is another step below"
   without ruling a line through the body copy. */

[data-page="quickstart"] .chapter {
  position: relative;
  --node: 46px;
}

.chapter-inner.step {
  display: grid;
  grid-template-columns: var(--node) minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.step-mark { position: relative; }
.step-mark::after {
  content: '';
  position: absolute;
  left: calc(var(--node) / 2 - 1px);
  top: calc(var(--node) + 12px);
  width: 2px;
  height: 128px;
  background: linear-gradient(to bottom, var(--line), transparent);
  transition: background .35s var(--ease);
  pointer-events: none;
}
#qs-next .step-mark::after { display: none; }
.chapter.is-reading .step-mark::after {
  background: linear-gradient(to bottom, rgba(137,206,255,.6), transparent);
}
.step-num {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: var(--node); height: var(--node);
  border-radius: 50%;
  background: var(--surf-2);
  border: 2px solid var(--line);
  font-family: var(--mono);
  font-size: 19px;
  font-weight: 600;
  line-height: 1;
  color: var(--dim);
  transition: color .35s var(--ease), border-color .35s var(--ease),
              background .35s var(--ease), box-shadow .35s var(--ease);
}

/* The step you are reading lights up; the ones behind you read as done. */
.chapter.is-reading .step-num {
  color: var(--primary);
  border-color: rgba(137,206,255,.7);
  background: linear-gradient(180deg, rgba(14,165,233,.26), rgba(14,165,233,.08));
  box-shadow: 0 0 0 5px rgba(14,165,233,.10), 0 0 18px rgba(14,165,233,.28);
}
.chapter.is-done .step-num {
  color: var(--muted);
  border-color: rgba(137,206,255,.38);
}

.step-body { min-width: 0; padding-top: 4px; }
.step-body .title, .step-body h1.title { margin-top: 0; }

@media (max-width: 900px) {
  [data-page="quickstart"] .chapter { --node: 38px; }
  .chapter-inner.step { grid-template-columns: var(--node) minmax(0, 1fr); gap: 15px; }
  .step-num { font-size: 16px; border-width: 1.5px; }
  .step-mark::after { height: 84px; }
}

/* ---------- Blog cards: the original posts' iconography ----------
   Material Symbols is a CDN font, so each post's icon is redrawn as an
   inline symbol and referenced with <use>. Gradients are the ones the
   original cards used. */

.post-visual {
  position: relative;
  height: 118px;
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--c1) 0%, #1a2332 54%, var(--c2) 100%);
  overflow: hidden;
}
.post-visual::before {
  content: '';
  position: absolute; inset: 0;
  background: rgba(12,19,36,.44);
}
.post-visual::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top, var(--surf-1) 2%, transparent 62%);
}
.pv-icon {
  position: relative; z-index: 1;
  width: 48px; height: 48px;
  color: #fff; opacity: .42;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}
.post-card:hover .pv-icon { opacity: .72; transform: scale(1.06); }
.pv-label {
  position: absolute; z-index: 2;
  left: 0; right: 0; bottom: 11px;
  text-align: center;
  font-family: var(--mono); font-size: 9px;
  letter-spacing: .3em; text-transform: uppercase;
  color: var(--muted);
}
.post-body { display: flex; flex-direction: column; gap: 9px; padding: 16px 18px 18px; }

/* The article view carries the same mark, so the two views agree. */
.article-badge {
  width: 44px; height: 44px; border-radius: 12px;
  display: grid; place-items: center;
  background: linear-gradient(135deg, var(--c1), var(--c2));
  margin-bottom: 16px;
}
.article-badge svg { width: 21px; height: 21px; color: #fff; opacity: .92; }

/* ---------- Blog: index grid and article view ---------- */

.post-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(290px, 100%), 1fr));
  gap: 14px;
}
.post-card {
  display: flex; flex-direction: column;
  text-align: left;
  text-decoration: none;
  color: inherit;
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 13px;
  padding: 0;
  overflow: hidden;
  cursor: pointer;
  font-family: var(--sans);
  transition: background .22s var(--ease), border-color .22s var(--ease), transform .22s var(--ease);
}
.post-card:hover {
  background: var(--surf-3);
  border-color: rgba(137,206,255,.45);
  transform: translateY(-2px);
}
.post-meta {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--dim);
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}
.post-meta .sep { width: 3px; height: 3px; border-radius: 50%; background: var(--line-soft); }
.post-card h3 {
  margin: 0; font-size: 15px; font-weight: 700; line-height: 1.3;
  color: var(--text); letter-spacing: -.01em;
}
.post-card p { margin: 0; font-size: 13px; color: var(--muted); line-height: 1.55; }
.post-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.post-tag {
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
  background: var(--surf-3); border-radius: 4px; padding: 3px 7px;
}

/* No rule under the head: .chapter + .chapter already draws one before the
   next section, and on a post whose opening section is only the head the two
   landed together with nothing between them. The line belongs to the boundary
   instead, so it shows up only where lead paragraphs follow the head inside
   the same section. */
.article-head { padding-bottom: 0; margin-bottom: 0; }
.article-head + .prose { margin-top: 26px; }
.article-standfirst {
  font-size: clamp(15px, 1.5vw, 18px);
  color: var(--muted); max-width: 68ch; margin: 14px 0 0;
}
.article-outline { display: grid; gap: 8px; max-width: 72ch; }
.outline-row {
  display: grid; grid-template-columns: 30px 1fr; gap: 12px; align-items: baseline;
  border-bottom: 1px solid var(--line); padding: 11px 2px;
}
.outline-n { font-family: var(--mono); font-size: 10px; color: var(--accent); letter-spacing: .1em; }
.outline-t { font-size: 14px; color: var(--text); font-weight: 600; }
.pending {
  margin-top: 22px; border: 1px dashed var(--line-soft); border-radius: 11px;
  padding: 14px 16px; font-size: 12.5px; color: var(--dim); max-width: 72ch;
}
.back-link {
  /* Its own line: it is followed by an inline-flex eyebrow on the client page,
     and two inline boxes would otherwise sit side by side. fit-content keeps
     the hit area to the text rather than the whole column. */
  display: flex; width: fit-content; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--dim);
  background: none; border: 0; padding: 0; margin-bottom: 16px; cursor: pointer;
  transition: color .2s var(--ease);
}
.back-link:hover { color: var(--primary); }

/* The post's top line: the index on the left, the neighbour on the right, so
   a reader who does not want this subject can move on from the heading alone
   without scrolling to the foot. */
.article-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-bottom: 16px;
}
.article-top .back-link { margin-bottom: 0; }
.back-link svg { width: 13px; height: 13px; }

/* ---------- Article foot ----------
   Reuses the .cta card. The index stands in for a missing neighbour at either
   end of the run, so the pair is always two cards wide. */

.cta-dir {
  grid-column: 2; margin: 0;
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim);
}
/* The docs cards carry an eyebrow above the title. The icon stands beside
   both of them, not beside the eyebrow on its own. */
.cta:has(.cta-dir) .cta-ico { grid-row: span 2; }
.cta:has(.cta-dir) { row-gap: 2px; }
.cta:has(.cta-dir) h3 { margin-bottom: 4px; }
.back-link.is-foot { margin: 18px 0 0; }

/* Browser download beside the curl line, for anyone who does not have curl or
   would rather click. Wraps to its own line before the sentence gets cramped. */
.alt-get {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 12px;
}
.alt-get span { font-size: 12.5px; color: var(--dim); }

/* The checksum row also stands alone under a Quickstart command block, where
   it has no artifact row to sit inside and needs its own breathing space. */
.step-body .art-sha { margin-top: 11px; }
.verify-note {
  margin: 18px 0 0; max-width: 72ch;
  font-size: 13.5px; line-height: 1.6; color: var(--dim);
  border-left: 2px solid rgba(137,206,255,.35); padding-left: 13px;
}
.verify-note a { color: var(--primary); text-decoration: none; }
.verify-note a:hover { text-decoration: underline; }

/* A link in body copy. Without this the browser paints its own — and a
   visited one comes out purple against the blue, which is unreadable. */
.lede a, .card p a, .srow span a {
  color: var(--primary); text-decoration: none;
  border-bottom: 1px solid rgba(137,206,255,.32);
}
.lede a:hover, .card p a:hover, .srow span a:hover { border-bottom-color: var(--primary); }

/* Heading and its pointer on one row. Bottom-aligned, so the link sits level
   with the last line of the heading rather than floating against its cap. */
.title-row {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 26px; flex-wrap: wrap; margin-bottom: 16px;
}
.title-row .title { margin-bottom: 0; flex: 1 1 24ch; }
.title-row .seealso { margin-top: 0; margin-bottom: 4px; }

/* A pointer out of a section to the page that covers it properly. Given its
   own line, because inside a paragraph it reads as an aside and gets missed. */
.seealso {
  display: inline-flex; align-items: center; gap: 9px;
  margin-top: 18px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; text-decoration: none;
  color: var(--primary);
  border: 1px solid rgba(137,206,255,.4);
  background: rgba(14,165,233,.10);
  border-radius: 9px; padding: 10px 15px;
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.seealso:hover { background: rgba(14,165,233,.2); border-color: var(--primary); }
.seealso svg { width: 14px; height: 14px; flex: 0 0 14px; }
.seealso .sa-arrow { margin-left: 2px; opacity: .7; }
.seealso small {
  display: block; font-size: 10px; letter-spacing: .02em;
  text-transform: none; color: var(--dim); margin-top: 2px;
}

.verify-note a:hover { text-decoration: underline; }

/* The field types an operator applies to, trailing its description. */
.stype {
  display: inline-block; margin-left: 6px;
  font-family: var(--mono); font-size: 10.5px;
  color: var(--dim);
}
.syntax + .verify-note, .verify-note + .verify-note { margin-top: 12px; }

/* ---------- Requirement matrix ----------
   A grid rather than a <table>: it has to collapse to a readable stack on a
   phone, which a table cannot do without losing its column meaning. */

.ptable {
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--surf-1); overflow: hidden;
}
.prow {
  display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: 12px; padding: 11px 16px; align-items: center;
  font-size: 13px; color: var(--muted);
}
.prow + .prow { border-top: 1px solid var(--line); }
.prow [role="rowheader"] { color: var(--text); font-weight: 600; }
.phead {
  background: var(--surf-2);
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim);
}
.phead [role="columnheader"]:not(:first-child) { color: var(--primary); }
.pyes  { color: var(--good); font-weight: 600; }
.pno   { color: var(--bad); font-weight: 600; }
.pwarn { color: var(--amber); }
.pmid  { color: var(--dim); }

@media (max-width: 720px) {
  .prow { grid-template-columns: 1fr 1fr; gap: 6px 12px; }
  .phead { display: none; }
  .prow [role="rowheader"] { grid-column: 1 / -1; margin-bottom: 2px; }
  .prow span:not([role="rowheader"])::before {
    content: attr(data-col); display: block;
    font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--dim); margin-bottom: 1px;
  }
}

/* ---------- Artifact rows: name, size, checksum, action ---------- */

.artifact {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 14px;
  align-items: center;
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 11px;
  padding: 14px 16px;
}
.artifact + .artifact { margin-top: 8px; }
.artifact.is-primary {
  border-color: rgba(137,206,255,.45);
  background: linear-gradient(180deg, rgba(14,165,233,.12), rgba(14,165,233,.03));
}
.art-name { font-family: var(--mono); font-size: 13px; color: var(--text); word-break: break-all; }
.art-meta { font-size: 11.5px; color: var(--dim); margin-top: 3px; display: flex; gap: 10px; flex-wrap: wrap; }

/* The whole 64-character checksum. A truncated one cannot be fed to
   `shasum -a 256 -c`, so it would be decoration rather than a verification
   aid; the copy button is there because nobody retypes 64 hex characters. */
.art-sha { display: flex; align-items: center; gap: 8px; margin-top: 7px; min-width: 0; }
.sha-tag {
  flex: 0 0 auto;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--dim);
  border: 1px solid var(--line); border-radius: 5px; padding: 2px 5px;
}
.art-sha code {
  font-family: var(--mono); font-size: 11px; line-height: 1.55;
  color: var(--muted); word-break: break-all; min-width: 0;
  -webkit-user-select: all; user-select: all;
}
.sha-copy {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0;
  border: 1px solid var(--line); border-radius: 6px;
  background: none; color: var(--dim); cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease);
}
.sha-copy:hover { color: var(--primary); border-color: rgba(137,206,255,.45); }
.sha-copy svg { width: 12px; height: 12px; }
.sha-copy .ico-done { display: none; }
.sha-copy.is-done { color: var(--good); border-color: rgba(110,231,168,.45); }
.sha-copy.is-done .ico-copy { display: none; }
.sha-copy.is-done .ico-done { display: block; }
.art-size { font-family: var(--mono); white-space: nowrap; color: var(--muted); font-size: 12px; }
.art-get {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; text-decoration: none;
  color: var(--primary);
  border: 1px solid rgba(137,206,255,.4);
  background: rgba(14,165,233,.10);
  border-radius: 8px; padding: 7px 13px; white-space: nowrap;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.art-get:hover { background: var(--primary); color: var(--bg); }
.art-get svg { width: 13px; height: 13px; }

@media (max-width: 640px) {
  .artifact { grid-template-columns: 1fr; gap: 10px; }
  .art-get { justify-self: start; }
}

/* ---------- OS awareness: show the visitor their own platform ---------- */

.os-switch {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--line);
  background: var(--surf-1);
  border-radius: 9px;
  margin-bottom: 14px;
}
.os-btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 0; background: transparent;
  color: var(--dim);
  font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .1em; text-transform: uppercase;
  padding: 6px 13px; border-radius: 6px; cursor: pointer;
  white-space: nowrap;
  transition: color .2s var(--ease), background .2s var(--ease);
}
.os-btn:hover { color: var(--muted); background: var(--surf-3); }
.os-btn.is-on {
  color: var(--primary);
  background: linear-gradient(180deg, rgba(14,165,233,.22), rgba(14,165,233,.08));
  box-shadow: inset 0 0 0 1px rgba(137,206,255,.34);
}
.os-btn .dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--good);
  display: none;
}
.os-btn.is-detected .dot { display: block; }

/* Only the selected platform's blocks render. */
.os-only { display: none; }
html[data-os="mac"]   .os-only.for-mac,
html[data-os="linux"] .os-only.for-linux,
html[data-os="win"]   .os-only.for-win { display: block; }

.detected-note {
  font-family: var(--mono); font-size: 10.5px;
  color: var(--dim); letter-spacing: .05em;
  margin: -6px 0 16px;
}
.detected-note b { color: var(--good); font-weight: 400; }

/* ---------- Mid widths: ease the rail down before it has to shrink ---------- */

@media (max-width: 1280px) {
  .seg.is-near { flex-basis: 132px; }
}

/* ---------- Narrow: the same document, tighter ----------
   Nothing structural changes — it was already an ordinary page. */

/* ---------- Header menu ----------
   Seven nav entries need ~550px, and the enlarged brand leaves the header
   out of room at about 910px, so below 940px the row collapses into a menu. */

.menu-btn { display: none; }

@media (max-width: 940px) {
  .menu-btn {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    height: 38px;
    padding: 0 11px 0 13px;
    border-radius: 9px;
    border: 1px solid var(--line);
    background: var(--surf-1);
    color: var(--muted);
    cursor: pointer;
    transition: color .2s var(--ease), background .2s var(--ease), border-color .2s var(--ease);
  }
  .menu-btn:hover { color: var(--primary); background: var(--surf-3); }
  .menu-btn svg { width: 15px; height: 15px; flex: 0 0 15px; }

  /* With the nav row hidden, the button is the only thing saying where you are. */
  .menu-current {
    font-family: var(--mono);
    font-size: 11.5px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--primary);
    max-width: 32vw;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .ico-caret { transition: transform .25s var(--ease); }
  .menu-btn[aria-expanded="true"] {
    color: var(--primary);
    border-color: rgba(137,206,255,.45);
    background: var(--surf-3);
  }
  .menu-btn[aria-expanded="true"] .ico-caret { transform: rotate(180deg); }

  .themes {
    display: none;
    position: fixed;
    top: calc(var(--header-h) + 8px);
    right: 14px;
    left: auto;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    min-width: 208px;
    max-width: calc(100vw - 28px);
    padding: 6px;
    overflow: visible;
    border: 1px solid var(--line-soft);
    border-radius: 13px;
    background: rgba(12,19,36,.98);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 20px 48px rgba(0,0,0,.55);
    z-index: 45;
  }
  .themes.is-open { display: flex; }

  .theme-btn {
    padding: 11px 14px;
    font-size: 12px;
    border-radius: 9px;
    justify-content: flex-start;
  }
}

@media (max-width: 900px) {
  :root { --rail-h: 50px; }

  .rail { height: 34px; gap: 3px; }
  .seg { padding: 4px 6px; border-radius: 6px; gap: 0; }
  .seg-title, .seg-sum { display: none; }
  .seg { flex: 1 1 0; }
  .seg.is-active { flex: 1.8 1 0; }
  .seg.is-near { flex: 1 1 0; }
  .counter, .stepper { display: none; }

  .chapter { min-height: 0; display: block; padding: 42px 18px; }
  .deck > .chapter:first-of-type { padding-top: 24px; }
}

@media (max-width: 430px) {
  /* The label shrinks rather than disappears: with the nav row collapsed it
     is the only thing on the page saying which section you are in. */
  .menu-current { max-width: 22vw; }
  .menu-btn { gap: 6px; padding: 0 9px 0 11px; }
}

@media (max-width: 600px) {
  .brand-ver { display: none; }
  .brand-mark { width: 36px; height: 36px; flex-basis: 36px; }
  .brand-name { font-size: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition-duration: .01ms !important; }
}

/* ---------- Multi-page additions ----------
   Nav entries and back links are real anchors now that each group is its
   own page, so they need the link reset the button versions did not. */

.theme-btn { text-decoration: none; display: inline-flex; align-items: center; }
a.back-link { text-decoration: none; }

/* ---------- Article prose ----------
   Migrated post bodies carry no classes — they are plain semantic HTML,
   so the typography is addressed by element. */

.prose { max-width: 74ch; color: var(--muted); font-size: 15.5px; line-height: 1.72; }
.prose > *:first-child { margin-top: 0; }
.prose > *:last-child  { margin-bottom: 0; }

.prose h2 {
  font-size: clamp(21px, 2.4vw, 28px);
  line-height: 1.2; letter-spacing: -.022em; font-weight: 800;
  color: var(--text); margin: 0 0 18px;
}
.prose h3 {
  font-size: 16px; font-weight: 700; color: var(--text);
  margin: 30px 0 10px; letter-spacing: -.01em;
}
.prose h4 { font-size: 14px; font-weight: 700; color: var(--text); margin: 24px 0 8px; }
.prose p { margin: 0 0 17px; }
.prose strong, .prose b { color: var(--text); font-weight: 700; }
.prose em, .prose i { font-style: italic; }
.prose a { color: var(--primary); text-decoration: none; border-bottom: 1px solid rgba(137,206,255,.3); }
.prose a:hover { border-bottom-color: var(--primary); }

.prose ul, .prose ol { margin: 0 0 18px; padding-left: 20px; }
.prose li { margin-bottom: 8px; }
.prose li::marker { color: var(--accent); }

.prose code {
  font-family: var(--mono); font-size: .88em;
  background: var(--surf-2); color: var(--primary);
  border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px;
}
.prose pre {
  font-family: var(--mono); font-size: 12.5px; line-height: 1.75;
  background: var(--bg-low); border: 1px solid var(--line);
  border-radius: 12px; padding: 16px 18px;
  overflow-x: auto; margin: 0 0 20px; color: var(--text); white-space: pre;
}
.prose pre code { background: none; border: 0; padding: 0; color: inherit; font-size: inherit; }

.prose blockquote {
  margin: 0 0 20px; padding: 2px 0 2px 18px;
  border-left: 2px solid var(--accent); color: var(--muted);
}
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 30px 0; }

.prose table { width: 100%; border-collapse: collapse; margin: 0 0 20px; font-size: 13.5px; }
.prose th, .prose td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); }
.prose th { color: var(--text); font-weight: 700; font-size: 12px;
            letter-spacing: .06em; text-transform: uppercase; }

@media (max-width: 900px) {
  .prose { font-size: 15px; }
  .site-footer { padding: 18px 18px 32px; }
}
