/* borch's explanation pages and playground — zero dependencies.
   The repository's principle applies to the stylesheet too: no font and no script is
   fetched from outside. Fetching one makes the page load halfway when offline, and
   that state is indistinguishable from "slow". */

:root {
  color-scheme: dark;

  --bg: #0a0c10;
  --bg-soft: #0f1319;
  --surface: #141a22;
  --surface-2: #1a222c;
  --line: #232c38;
  --line-soft: #1b2430;

  --fg: #e8ecf3;
  --fg-dim: #a3aec0;
  --fg-faint: #7b8799;        /* 5.38:1 — some of what is written in this colour is content */

  --ember: #ff7a3d;      /* torch — half the name */
  /* **The orange used as text is kept separate.** Using one value for both background
     and text means fixing one side breaks the other the moment you do it — darkening
     the orange for text in the light theme dropped the primary button (dark text on
     orange) from 4.49 to 3.93 (measured). */
  --ember-text: #ff7a3d;
  --gpu: #4fd6c9;        /* the WebGPU side */
  --warn: #f5c451;
  --bad: #ff6b6b;
  --good: #5ed49a;

  --mono: ui-monospace, "SF Mono", SFMono-Regular, "JetBrains Mono", Menlo,
          Consolas, "Liberation Mono", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", "Pretendard", "Apple SD Gothic Neo",
          "Noto Sans KR", Roboto, sans-serif;

  --page: 68rem;
  --radius: 14px;
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;
    --bg: #fbfaf8;
    --bg-soft: #f4f2ee;
    --surface: #ffffff;
    --surface-2: #f6f4f1;
    --line: #e2ded7;
    --line-soft: #ebe7e1;
    --fg: #181c22;
    --fg-dim: #55606f;
    --fg-faint: #646f80;   /* 4.88:1 (2.90 before — below AA) */
    --ember: #d1500f;      /* the value used as a background — 4.49 against dark text */
    --ember-text: #c2490c; /* the value used as text — 4.73 (4.14 before) */
    --gpu: #0f8a80;
  }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 16px/1.7 var(--sans);
  -webkit-font-smoothing: antialiased;
  word-break: keep-all;
}

a { color: inherit; }

/* **Where you are has to be visible.** The stylesheet had exactly one `:focus` rule
   and it was **removing** the outline. On a site full of run buttons and editors,
   somebody navigating by keyboard had no way to know where they were. */
:focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 2px;
  border-radius: 4px;
}
/* In the editor an outline overlaps the text, so a box shadow stands in for it. */
.editor-wrap textarea:focus-visible,
.runnable .edit textarea:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--ember);
}

code, pre, kbd { font-family: var(--mono); }

/* ── Skeleton ──────────────────────────────────────────────────────────── */

.wrap { width: min(var(--page), calc(100% - 3rem)); margin-inline: auto; }

section { padding: 5.5rem 0; border-top: 1px solid var(--line-soft); }
section:first-of-type { border-top: 0; }

.eyebrow {
  font: 600 12px/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ember-text);
  margin: 0 0 1rem;
}

h1, h2, h3 { line-height: 1.2; letter-spacing: -0.02em; margin: 0 0 1rem; }
h2 { font-size: clamp(1.6rem, 3.4vw, 2.3rem); }
h3 { font-size: 1.1rem; }

p { margin: 0 0 1rem; color: var(--fg-dim); }
p.lead { font-size: 1.08rem; color: var(--fg-dim); max-width: 46rem; }

.muted { color: var(--fg-faint); }
.small { font-size: 0.86rem; }

/* ── Top bar ───────────────────────────────────────────────────────────── */

header.top {
  position: sticky; top: 0; z-index: 40;
  backdrop-filter: blur(12px);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  border-bottom: 1px solid var(--line-soft);
}
.top .wrap {
  display: flex; align-items: center; gap: 1.25rem;
  height: 58px;
}
/* **The menu did not wrap, so every page overflowed horizontally on a phone.** Six
   items took 404px against a 390px viewport, so every page pushed out by 125px
   regardless of its content (measured). It drops to the next line when it does not
   fit, and scrolls horizontally when even that overflows. */
@media (max-width: 700px) {
  .top .wrap { flex-wrap: wrap; height: auto; padding-block: .5rem; gap: .5rem 1rem; }
  .top nav { width: 100%; margin-left: 0; overflow-x: auto; gap: 1rem; padding-bottom: .15rem; }
  .top nav a { white-space: nowrap; }
  /* The header is no longer 58px tall, so whatever was pinned to that number is
     detached from it. */
  .subnav { position: static; }
  /* **Two clipped scrollers stacked read as a broken page.** The global bar and the
     landing's section list both cut off mid-word on a 390px screen — reachable by
     scrolling, which is not the same as looking finished, and together they spent 90px
     of an 844px viewport before any content. The section list is the one that can go:
     its entries are anchors into a page the reader is already scrolling, so nothing
     becomes unreachable. The global bar stays, because it is the only route to the
     rest of the site. */
  .subnav { display: none; }
}
.brand {
  font: 700 17px/1 var(--mono);
  letter-spacing: -0.03em;
  text-decoration: none;
  display: flex; align-items: center; gap: 0.5rem;
}
.brand .dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--ember);
  box-shadow: 0 0 14px var(--ember);
}
.top nav { margin-left: auto; display: flex; align-items: center; gap: 1.4rem; }
.top nav a { color: var(--fg-dim); text-decoration: none; font-size: 0.9rem; }
.top nav a:hover { color: var(--fg); }
/* Where you are now. The menu is identical on every page, so this mark is the only clue. */
.top nav a.on { color: var(--fg); font-weight: 600; }
.top nav a.on::after {
  content: ""; display: block; height: 2px; margin-top: 4px;
  background: var(--ember); border-radius: 2px;
}
/* Four groups — learn, look up, run, confirm — and a hairline between them. Twelve
   entries in one row read as twelve different things; the rule says which four. */
.top nav .sep { width: 1px; height: 1rem; background: var(--line); flex: none; }
@media (max-width: 900px) { .top nav .sep { display: none; } }
/* The language switch is not one entry in the list — a border keeps it apart. */
.top nav a.lang {
  padding: .25rem .6rem; border: 1px solid var(--line); border-radius: 7px;
  font-size: .82rem;
}
.top nav a.lang:hover { border-color: var(--fg-faint); }

/* ── In-page navigation ─────────────────────────────────────────────────────
   It has to look like **a different thing** from the global menu. One line lower,
   smaller, no underline. Looking like the global menu makes it read as though the
   menu changes from page to page. */

.subnav {
  position: sticky; top: 58px; z-index: 30;
  background: color-mix(in srgb, var(--bg-soft) 92%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line-soft);
  overflow-x: auto;
}
.subnav .wrap { display: flex; gap: 1.1rem; height: 40px; align-items: center; white-space: nowrap; }
.subnav a {
  color: var(--fg-faint); text-decoration: none;
  font: 500 .82rem/1 var(--sans);
}
.subnav a:hover { color: var(--ember-text); }
@media (max-width: 620px) { .subnav .wrap { width: auto; padding-inline: 1.5rem; } }

/* ── Buttons ───────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.62rem 1.05rem;
  border-radius: 9px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--fg);
  font: 500 0.92rem/1 var(--sans);
  text-decoration: none;
  cursor: pointer;
  transition: border-color .15s, background .15s, transform .06s;
}
.btn:hover { border-color: var(--fg-faint); }
.btn:active { transform: translateY(1px); }
.btn.primary {
  background: var(--ember);
  border-color: var(--ember);
  color: #180a02;
  font-weight: 640;
}
.btn.primary:hover { filter: brightness(1.08); }
.btn.ghost { background: transparent; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn.mono { font-family: var(--mono); font-size: 0.86rem; }

/* ── Hero ──────────────────────────────────────────────────────────────── */

.hero { padding: 5rem 0 4rem; position: relative; overflow: hidden; }
.hero::before {
  content: ""; position: absolute; inset: -40% 30% 40% -20%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--ember) 16%, transparent), transparent);
  pointer-events: none;
}
.hero .wrap { position: relative; }
.hero h1 {
  font-size: clamp(2.3rem, 6.2vw, 3.9rem);
  letter-spacing: -0.035em;
  max-width: 20ch;
}
.hero h1 .accent {
  background: linear-gradient(100deg, var(--ember), var(--gpu));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero .sub { font-size: 1.12rem; max-width: 40rem; }
.cta-row { display: flex; flex-wrap: wrap; gap: 0.7rem; margin: 1.8rem 0 0.9rem; }
.install {
  display: inline-flex; align-items: center; gap: .6rem;
  font: 0.86rem/1 var(--mono); color: var(--fg-faint);
}

/* ── Demo card (shared by the hero and the playground) ─────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.card-head {
  display: flex; align-items: center; gap: .75rem;
  padding: .6rem .9rem;
  border-bottom: 1px solid var(--line-soft);
  background: var(--surface-2);
  font: 0.8rem/1 var(--mono);
  color: var(--fg-faint);
}
.card-head .grow { margin-left: auto; }

.demo { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 0; }
.demo > * { min-width: 0; }
@media (max-width: 760px) { .demo { grid-template-columns: 1fr; } }
.demo pre {
  margin: 0; padding: 1.1rem 1.2rem;
  font-size: 0.82rem; line-height: 1.65;
  overflow-x: auto;
  border-right: 1px solid var(--line-soft);
}
.demo .side {
  padding: 1.1rem 1.2rem;
  display: flex; flex-direction: column; gap: .8rem;
  min-height: 12rem;
}
.out {
  margin: 0; flex: 1;
  font: 0.8rem/1.6 var(--mono);
  color: var(--fg-dim);
  white-space: pre-wrap; word-break: break-word;
  overflow: auto;
}
.out .err { color: var(--bad); }
.out .note { color: var(--fg-faint); }
.out .ok { color: var(--good); }

/* the device badge */
.badge {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .28rem .6rem; border-radius: 999px;
  border: 1px solid var(--line);
  font: 0.74rem/1 var(--mono);
  color: var(--fg-dim);
}
.badge .led { width: 7px; height: 7px; border-radius: 50%; background: var(--fg-faint); }
.badge.on .led { background: var(--good); box-shadow: 0 0 10px var(--good); }
.badge.off .led { background: var(--bad); }

/* ── Grid ──────────────────────────────────────────────────────────────── */

.grid { display: grid; gap: 1rem; }
/* **`1fr` does not shrink below its content.** With a `<pre>` in the cell, its
   minimum width pushes the track out and `overflow-x: auto` does nothing about it —
   what says shrinking is allowed is `minmax(0, …)` plus `min-width: 0`. This is the
   place where the landing page opened out from 390px to 664px. */
.grid.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid > * { min-width: 0; }
@media (max-width: 860px) { .grid.c3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .grid.c3, .grid.c2 { grid-template-columns: minmax(0, 1fr); } }

.tile {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1.3rem;
}
.tile h3 { margin-bottom: .5rem; }
.tile p { margin: 0; font-size: 0.92rem; }
.tile .icon { font-size: 1.15rem; color: var(--ember-text); margin-bottom: .6rem; display: block; }

/* ── Flow diagram ──────────────────────────────────────────────────────── */

.flow { display: grid; gap: .9rem; }
.flow-row {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: 1rem 1.1rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--surface);
}
.flow-row.now { border-color: color-mix(in srgb, var(--ember) 45%, var(--line)); }
.flow-tag {
  font: 600 .7rem/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--fg-faint); width: 6.5rem; flex: none;
}
.flow-row.now .flow-tag { color: var(--ember-text); }
.node {
  font: .8rem/1 var(--mono);
  padding: .45rem .65rem; border-radius: 7px;
  background: var(--surface-2); border: 1px solid var(--line-soft);
  white-space: nowrap;
}
.flow-row.now .node.hot { border-color: color-mix(in srgb, var(--ember) 55%, transparent); color: var(--fg); }
.arrow { color: var(--fg-faint); font-family: var(--mono); }

/* ── Tables ────────────────────────────────────────────────────────────── */

table.data {
  width: 100%; border-collapse: collapse;
  font-size: 0.9rem;
}
table.data th, table.data td {
  text-align: left; padding: .68rem .8rem;
  border-bottom: 1px solid var(--line-soft);
}
table.data th { color: var(--fg-faint); font-weight: 600; font-size: .8rem;
                text-transform: uppercase; letter-spacing: .07em; }
table.data td.num { font-family: var(--mono); }
table.data tr td strong { color: var(--fg); }
.scroll-x { overflow-x: auto; }

/* status marks */
.state { font: .74rem/1 var(--mono); padding: .22rem .5rem; border-radius: 5px; border: 1px solid var(--line); }
.state.now { color: var(--good); border-color: color-mix(in srgb, var(--good) 40%, transparent); }
.state.soon { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.state.never { color: var(--fg-faint); }

/* ── Footnotes ─────────────────────────────────────────────────────────── */

.note-box {
  border-left: 2px solid var(--ember);
  padding: .2rem 0 .2rem 1.1rem;
  margin: 1.5rem 0;
  color: var(--fg-dim);
  font-size: .93rem;
}

footer {
  border-top: 1px solid var(--line-soft);
  padding: 3rem 0 4rem;
  color: var(--fg-faint);
  font-size: .87rem;
}
footer a { color: var(--fg-dim); }

/* ── Code highlighting (very thin) ─────────────────────────────────────── */

.tok-key { color: var(--ember-text); }
.tok-str { color: var(--gpu); }
.tok-num { color: #b9a2ff; }
.tok-com { color: var(--fg-faint); font-style: italic; }
.tok-fn  { color: #8fb8ff; }

/* ── Playground ────────────────────────────────────────────────────────── */

/* Sized to the window — the panels scroll individually and the page itself does not
   move. Otherwise the instrumentation numbers below get pushed off screen, and they
   are half of what a run produces. */
body.pg { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
body.pg main { flex: 1; display: flex; flex-direction: column; min-height: 0; }

.pg-bar {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .7rem 1rem;
  border-bottom: 1px solid var(--line-soft);
  background: var(--bg-soft);
}
.pg-bar select {
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--line); border-radius: 8px;
  padding: .5rem .7rem; font: .88rem/1 var(--sans);
}
.pg-bar .spacer { margin-left: auto; }

.pg-body {
  flex: 1; display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  min-height: 0;
}
@media (max-width: 900px) { .pg-body { grid-template-columns: 1fr; } }

.editor-pane { display: flex; flex-direction: column; min-width: 0; border-right: 1px solid var(--line-soft); }
.editor-wrap { position: relative; flex: 1; min-height: 0; }

/* **The two layers have to share one metric.** Any mismatch in family, size, line
   height, padding or tab width slides the colour off the letters, and the mismatch
   grows the further down you go. So it is set once here and both inherit it. */
.editor-wrap textarea,
.editor-wrap #highlight {
  position: absolute; inset: 0;
  margin: 0;
  padding: 1rem 1.1rem;
  border: 0;
  font: 13px/1.65 var(--mono);
  tab-size: 2;
  /* No wrapping — if the two layers break lines in different places, everything
     below shifts as a block. It flows horizontally instead, and the scroll is
     synchronised below. */
  white-space: pre;
  overflow: auto;
  overflow-wrap: normal;
}
.editor-wrap textarea {
  z-index: 1;
  outline: none; resize: none;
  background: transparent;
  color: transparent;              /* the layer below draws the text */
  caret-color: var(--fg);          /* and this layer's caret has to stay visible */
}
.editor-wrap textarea::selection { background: color-mix(in srgb, var(--ember) 30%, transparent); }
.editor-wrap #highlight {
  z-index: 0;
  background: var(--bg-soft);
  color: var(--fg);
  pointer-events: none;
}
.right-pane { display: flex; flex-direction: column; min-width: 0; }

.pane-head {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .9rem;
  border-bottom: 1px solid var(--line-soft);
  font: .78rem/1 var(--mono); color: var(--fg-faint);
  background: var(--bg-soft);
}
.pane-head .grow { margin-left: auto; }

#console {
  flex: 1; margin: 0; padding: .9rem 1rem;
  font: 12.5px/1.65 var(--mono);
  white-space: pre-wrap; word-break: break-word;
  overflow: auto; min-height: 6rem;
  color: var(--fg-dim);
}
#console .err { color: var(--bad); }
#console .ok { color: var(--good); }
#console .note { color: var(--fg-faint); }

.stats {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line-soft);
}
.stat { padding: .7rem .9rem; border-right: 1px solid var(--line-soft); }
.stat:last-child { border-right: 0; }
.stat .k { font: .68rem/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--fg-faint); }
.stat .v { font: 600 1rem/1.4 var(--mono); color: var(--fg); }

#chart { display: block; width: 100%; height: 120px; flex: none; border-top: 1px solid var(--line-soft); background: var(--bg-soft); }

@media (max-width: 900px) {
  /* Stacked vertically it does not fit one screen — then the page has to scroll. */
  body.pg { height: auto; overflow: visible; }
  .editor-wrap { min-height: 20rem; }
  #console { min-height: 12rem; }
}

/* ══ The document shell — the API reference and Learn share it ═══════════ */

.docs {
  display: grid;
  grid-template-columns: 16rem minmax(0, 1fr);
  gap: 0;
  align-items: start;
}
@media (max-width: 900px) { .docs { grid-template-columns: 1fr; } }
/* **The header and the page under it have to share one edge.** `.top .wrap` is centred
   on `--page`, while this grid was pinned to both edges of the window, so on a wide
   screen the two never met: measured at 2560px, the brand sat at x=736 and the sidebar
   at x=0, and the reading column stopped 832px short of the nav directly above it.
   Nothing about a narrow window changes — the query starts at the width where centring
   begins to do anything at all (`--page` plus the 3rem the wrap keeps at its sides). */
@media (min-width: 1136px) {
  .docs { width: min(var(--page), calc(100% - 3rem)); margin-inline: auto; }
  /* The rail now has two free sides rather than one, so it is bordered on both. */
  .sidebar { border-left: 1px solid var(--line-soft); }
}

.sidebar {
  position: sticky; top: 58px;
  height: calc(100vh - 58px);
  overflow-y: auto;
  border-right: 1px solid var(--line-soft);
  padding: 1.1rem .9rem 3rem;
  background: var(--bg-soft);
}
@media (max-width: 900px) {
  .sidebar { position: static; height: auto; border-right: 0;
             border-bottom: 1px solid var(--line-soft); }
}
.sidebar h4 {
  margin: 1.2rem 0 .5rem;
  font: 600 .7rem/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--fg-faint);
}
.sidebar h4:first-child { margin-top: 0; }
.sidebar a {
  display: block; padding: .3rem .55rem; border-radius: 6px;
  text-decoration: none; color: var(--fg-dim);
  font-size: .88rem; line-height: 1.45;
}
.sidebar a:hover { background: var(--surface); color: var(--fg); }
.sidebar a.on { background: var(--surface); color: var(--ember-text); font-weight: 600; }
.sidebar a .n { font-family: var(--mono); font-size: .82rem; }
.sidebar a .c { float: right; color: var(--fg-faint); font-size: .74rem; }

#search {
  width: 100%; padding: .5rem .65rem;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--fg);
  font: .86rem/1 var(--sans);
}
#search:focus-visible { outline: none; border-color: var(--ember);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--ember) 35%, transparent); }

.doc-main { padding: 2rem 2rem 6rem; min-width: 0; }
@media (max-width: 620px) { .doc-main { padding: 1.5rem 1.1rem 4rem; } }
.doc-main > header { margin-bottom: 2rem; }
.doc-main h1 { font-size: clamp(1.7rem, 4vw, 2.4rem); }

/* ── Symbol cards ──────────────────────────────────────────────────────── */

.symbol {
  border-top: 1px solid var(--line-soft);
  padding: 1.6rem 0;
  scroll-margin-top: 70px;
}
.symbol > h3 {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  font: 600 1.05rem/1.4 var(--mono);
  margin-bottom: .6rem;
}
.kind {
  font: 600 .66rem/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  padding: .22rem .45rem; border-radius: 5px;
  border: 1px solid var(--line); color: var(--fg-faint);
}
.kind.class { color: var(--gpu); border-color: color-mix(in srgb, var(--gpu) 40%, transparent); }
.kind.function { color: var(--ember); border-color: color-mix(in srgb, var(--ember) 40%, transparent); }
.torch-hint {
  font: .78rem/1 var(--mono); color: var(--fg-faint);
  margin-left: auto;
}
.torch-hint b { color: var(--fg-dim); font-weight: 500; }

pre.sig {
  margin: 0 0 .8rem; padding: .7rem .85rem;
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: 8px; overflow-x: auto;
  font-size: .8rem; line-height: 1.6;
}
pre.sig + pre.sig { margin-top: -.4rem; }

.prose { font-size: .93rem; }
.prose p { margin: 0 0 .7rem; }
.prose p:last-child { margin-bottom: 0; }
.prose code {
  font-size: .86em; padding: .1em .32em; border-radius: 4px;
  background: var(--surface-2); border: 1px solid var(--line-soft);
}
.prose h4 { margin: 1rem 0 .4rem; font-size: .95rem; color: var(--fg); }
.prose ul { margin: 0 0 .7rem; padding-left: 1.1rem; }
.prose strong { color: var(--fg); }

table.tags { width: 100%; border-collapse: collapse; margin: .6rem 0 0; font-size: .86rem; }
table.tags td { padding: .35rem .6rem; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
table.tags td.t { font-family: var(--mono); color: var(--fg-faint); white-space: nowrap; width: 5rem; }

.members { margin-top: 1rem; }
.members > summary {
  cursor: pointer; font: .84rem/1 var(--mono); color: var(--fg-faint);
  padding: .45rem 0;
}
.members > summary:hover { color: var(--fg); }
.member {
  border-left: 2px solid var(--line-soft);
  padding: .7rem 0 .7rem .9rem;
  margin-left: .2rem;
  scroll-margin-top: 70px;
}
.member:target { border-left-color: var(--ember); }
.member h4 {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  margin: 0 0 .35rem; font: 600 .88rem/1.4 var(--mono);
}
.member .sigline {
  font: .8rem/1.6 var(--mono); color: var(--fg-dim);
  overflow-x: auto; white-space: pre;
}

.section-head {
  margin: 1.4rem 0 .3rem; padding-top: .7rem;
  border-top: 1px dashed var(--line-soft);
  font: 600 .72rem/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--fg-faint);
}
.members > .section-head:first-of-type { border-top: 0; margin-top: .6rem; }

.hits { margin: 0; padding: 0; list-style: none; }
.hits .why { font-size: .78rem; color: var(--fg-faint); padding: .15rem 0 .3rem; }
.hits li { padding: .3rem 0; border-bottom: 1px solid var(--line-soft); }
.hits a { text-decoration: none; font: .86rem/1.5 var(--mono); color: var(--fg-dim); }
.hits a:hover { color: var(--ember-text); }
.hits .where { color: var(--fg-faint); font-size: .78rem; }

/* ── Runnable code blocks (Learn uses these) ───────────────────────────── */

.runnable {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  margin: 1.4rem 0;
  background: var(--surface);
}
.runnable-head {
  display: flex; align-items: center; gap: .6rem;
  padding: .45rem .75rem;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line-soft);
  font: .74rem/1 var(--mono); color: var(--fg-faint);
}
.runnable-head .grow { margin-left: auto; }
.runnable-head button {
  padding: .3rem .7rem; border-radius: 6px;
  border: 1px solid var(--line); background: var(--surface);
  color: var(--fg); font: 600 .76rem/1 var(--sans); cursor: pointer;
}
.runnable-head button.go { background: var(--ember); border-color: var(--ember); color: #180a02; }

/* Language tabs. They appear only when one block holds both surfaces — whichever is
   pressed is the language that runs. `aria-pressed` is the authority on that state,
   so the CSS reads it too. */
.runnable-head button.tab {
  padding: .22rem .55rem; border-radius: 5px;
  border: 1px solid transparent; background: transparent;
  color: var(--fg-faint); font: 500 .74rem/1 var(--mono);
}
.runnable-head button.tab[aria-pressed="true"] {
  border-color: var(--line); background: var(--surface); color: var(--fg);
}
.runnable-head button.tab + button.tab { margin-left: -.35rem; }
.runnable-head a.open {
  color: var(--fg-faint); text-decoration: none;
  font: 500 .74rem/1 var(--sans); padding: .3rem 0;
}
.runnable-head a.open:hover { color: var(--ember-text); }
.runnable-head button:hover { filter: brightness(1.08); }
.runnable-head button[disabled] { opacity: .5; cursor: not-allowed; }

.runnable .edit { position: relative; }
.runnable .edit textarea,
.runnable .edit pre {
  margin: 0; padding: .85rem 1rem;
  font: 12.5px/1.6 var(--mono);
  tab-size: 2; white-space: pre; overflow: auto;
  border: 0;
}
.runnable .edit pre { background: var(--bg-soft); color: var(--fg); }
.runnable .edit textarea {
  position: absolute; inset: 0; width: 100%; height: 100%;
  resize: none; outline: none;
  background: transparent; color: transparent; caret-color: var(--fg);
}
.runnable .edit textarea::selection { background: color-mix(in srgb, var(--ember) 30%, transparent); }
.runnable .out {
  border-top: 1px solid var(--line-soft);
  padding: .7rem 1rem; margin: 0;
  font: 12px/1.6 var(--mono); color: var(--fg-dim);
  white-space: pre-wrap; word-break: break-word;
  /* **A short output must not become a slit.** Shrinking to fit its content gives a
     four-line box, and following that to the bottom stops with the first line cut off
     — to the reader it becomes a box where "the output is invisible and nothing
     moves" (an actual report). */
  min-height: 6.5rem;
  max-height: 28rem;
  overflow: auto;
  /* Too narrow, and it is dragged larger. Only the person editing the code knows how
     much will come out. */
  resize: vertical;
}
.runnable .out:empty { display: none; }
.runnable .canvas-out {
  border-top: 1px solid var(--line-soft);
  padding: .7rem 1rem; background: var(--bg-soft);
  overflow-x: auto;
}
.runnable .canvas-out:empty { display: none; }
.runnable .canvas-out canvas { display: block; margin-bottom: .5rem; image-rendering: pixelated; }
.runnable .out .err { color: var(--bad); }
.runnable .out .ok { color: var(--good); }
.runnable .out .note { color: var(--fg-faint); }

/* ── Lesson prose ──────────────────────────────────────────────────────── */

.lesson { max-width: 46rem; }
.lesson h2 { margin-top: 2.6rem; font-size: 1.45rem; }
.lesson h3 { margin-top: 1.8rem; }
.lesson p { font-size: .97rem; }
.lesson > p code, .lesson li code {
  font-size: .86em; padding: .1em .32em; border-radius: 4px;
  background: var(--surface-2); border: 1px solid var(--line-soft);
}
.lesson ul, .lesson ol { padding-left: 1.2rem; color: var(--fg-dim); }
.lesson li { margin: .3rem 0; }

.pager {
  display: flex; gap: 1rem; justify-content: space-between;
  margin-top: 3.5rem; padding-top: 1.5rem;
  border-top: 1px solid var(--line-soft);
}
.pager a { text-decoration: none; font-size: .9rem; color: var(--fg-dim); }
.pager a:hover { color: var(--ember-text); }
.pager a b { display: block; color: var(--fg); font-weight: 600; margin-top: .2rem; }

/* A name in the lesson prose → the API reference. A dotted line rather than an
   underline, so it does not break the reading. */
a.api-link { text-decoration: none; border-bottom: 1px dashed var(--line); }
a.api-link:hover { border-bottom-color: var(--ember); }
a.api-link code { color: var(--ember-text); }

/* ── Making a scrollable place visible ──────────────────────────────────────
   macOS's overlay scrollbars are 0 wide, so an overflowing box looks like **a box
   that is simply cut off**. A report came in saying exactly that: "the white part does
   not move up or down and the output is invisible." It was scrolling; there was only
   no sign that it could. */

/* **The standard properties go only to browsers that do not know
   `::-webkit-scrollbar`.**

   When `scrollbar-width` or `scrollbar-color` is set, Chrome **ignores the
   `::-webkit-scrollbar` rules entirely.** And the standard properties alone leave
   macOS's overlay scrollbars as they are, 0 wide. Writing both puts the second one in
   the position of switching off the first and doing nothing itself — the fix was
   cancelling itself.

   Measured (Chrome 150, macOS): on the same box, the webkit rules alone give a
   scrollbar taking 10px, and adding the standard properties gives 0. This is why the
   report ("the white part does not move up or down") stood after the fix. */
@supports not selector(::-webkit-scrollbar) {
  .runnable .out,
  .runnable .canvas-out,
  #console,
  .doc-main pre,
  .sidebar {
    scrollbar-width: thin;
    scrollbar-color: var(--line) transparent;
  }
}
.runnable .out::-webkit-scrollbar,
.runnable .canvas-out::-webkit-scrollbar,
#console::-webkit-scrollbar,
.doc-main pre::-webkit-scrollbar,
.sidebar::-webkit-scrollbar { width: 10px; height: 10px; }
.runnable .out::-webkit-scrollbar-track,
.runnable .canvas-out::-webkit-scrollbar-track,
#console::-webkit-scrollbar-track,
.doc-main pre::-webkit-scrollbar-track,
.sidebar::-webkit-scrollbar-track { background: transparent; }
.runnable .out::-webkit-scrollbar-thumb,
.runnable .canvas-out::-webkit-scrollbar-thumb,
#console::-webkit-scrollbar-thumb,
.doc-main pre::-webkit-scrollbar-thumb,
.sidebar::-webkit-scrollbar-thumb {
  background: var(--line); border-radius: 5px;
  border: 2px solid transparent; background-clip: content-box;
}
.runnable .out::-webkit-scrollbar-thumb:hover,
.runnable .canvas-out::-webkit-scrollbar-thumb:hover,
#console::-webkit-scrollbar-thumb:hover { background: var(--fg-faint); background-clip: content-box; }

/* A sign that it can be dragged larger. The resize handle is nearly invisible on
   macOS. */
.runnable .out { background-image: linear-gradient(135deg, transparent 50%, var(--line-soft) 50%);
  background-position: bottom right; background-size: 10px 10px; background-repeat: no-repeat; }

/* **A result needs a frame or it reads as prose.** The landing's demo puts its output in
   a card; the hub page had the same output as bare text, so a model that had just been
   downloaded, hashed and checked against its sample looked like a paragraph that happened
   to contain JSON. Same `.out` type as everywhere else, now with an edge around it. */
.panel {
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  background: var(--surface);
  padding: .85rem 1rem;
  margin: 1rem 0;
  max-height: 22rem;
  overflow: auto;
}

/* **A table is not prose and does not want prose's measure.** `.lesson` is 46rem, which
   is right for sentences and wrong for six columns: the catalog broke model names
   mid-token (`imagenet-mobilenetv3-` / `small-100`) and wrapped its own headings. This
   lets one child out to the page's width while the paragraphs around it stay readable. */
.lesson .wide {
  width: min(72rem, calc(100vw - 3rem));
  margin-left: 50%;
  transform: translateX(-50%);
}

/* **The Run button was cut off on a phone.** `.runnable` clips (`overflow: hidden`, which
   is what keeps the rounded corner), and on `python.html` the head carries five controls
   — label, spacer, an "open" link, reset and run — which is two more than a lesson page.
   Measured: `button.go` crossed the box by 21px at 390px and 51px at 360px, and fitted
   only from 414px up. So on most phones the primary control of that page was half there.
   It was found by geometry rather than by eye: an element overflowing an ancestor whose
   `overflow-x` is `hidden` is cut, and that is a number rather than an opinion.
   The row wraps instead. The spacer goes full-width and flat, which turns it from
   "push the rest right" into "break the line here". */
@media (max-width: 700px) {
  .runnable-head { flex-wrap: wrap; row-gap: .35rem; }
  .runnable-head .grow { margin-left: 0; width: 100%; height: 0; }
}

/* Lesson 0's verdict under a run. `good` is the `ok` green; `bad` is a warning, not an error. */
.out .verdict { font-weight: 600; margin-top: .3rem; }
.out .verdict.bad { color: var(--warn, #c9873a); }
