/* ==========================================================================
   rasen-site — brutalist / CRT-terminal design system
   One hand-written stylesheet. No preprocessor. No reset dependency beyond
   the few lines below. Custom properties are the single source of truth.
   ========================================================================== */

:root {
  /* --- pinned contract values (planning-context CRT contract) --- */
  --bg0: #0A0A0A;      /* substrate — never pure black */
  --bg1: #121212;      /* raised surface / cells */
  --fg: #EAEAEA;       /* phosphor */
  --fg2: #9A9A98;      /* secondary phosphor */
  --red: #E61919;      /* the one accent */
  --green: #4AF626;    /* the one optional status element */

  /* --- substrate/hairline shades, not new contract colors: same hue
     families as the pinned values above, added for depth and legibility
     the contract doesn't itemize. Each has a documented precedent in the
     brutalist-CRT reference deck (example.html): --bg-void matches its
     .audit .log background (#050505, a recessed/inset surface, not a
     second substrate — --bg0 remains the shallowest surface everything
     else sits on top of); --line-strong is a stronger hairline for
     interactive dividers (copy-button rule) alongside --line; --red-soft
     is the alpha-blended hazard-red already used for the stripe fill and
     card-alert backgrounds in the reference deck, not a distinct hue. --- */
  --bg-void: #050505;
  --fg3: #8A8A87;      /* muted phosphor — lightened from #6A6A67 (~3.45:1
                          on --bg1) to ~5.4:1, clearing WCAG AA for small
                          text; same family as --fg2, one step dimmer */
  --line: #2A2A28;     /* hairline */
  --line-strong: #3A3A36;
  --red-soft: rgba(230, 25, 25, 0.10);

  --mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --display: 'Archivo Black', 'Arial Black', 'Helvetica Neue', sans-serif;
}

/* ==== 00b · CJK LOCALE FONT FALLBACKS (site-l10n-i18n design D6) ====
   Redefining --mono/--display under :lang() localizes the change to the
   custom properties instead of re-declaring every rule that uses them.
   Per-family font stacks fall back per-GLYPH in evergreen browsers, so
   Latin characters and code tokens still render in the leading mono/
   display families (JetBrains Mono / Archivo Black) even on a CJK page —
   only characters those fonts don't cover fall through to the appended
   system CJK families. No webfonts are shipped for any of these. */
:root:lang(zh) {
  --mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, Consolas, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans CJK SC', monospace;
  --display: 'Archivo Black', 'Arial Black', 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans CJK SC', sans-serif;
}
:root:lang(ja) {
  --mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, Consolas, 'Hiragino Sans', 'Yu Gothic', Meiryo, 'Noto Sans CJK JP', monospace;
  --display: 'Archivo Black', 'Arial Black', 'Helvetica Neue', 'Hiragino Sans', 'Yu Gothic', Meiryo, 'Noto Sans CJK JP', sans-serif;
}
:root:lang(ko) {
  --mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, Consolas, 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans CJK KR', monospace;
  --display: 'Archivo Black', 'Arial Black', 'Helvetica Neue', 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans CJK KR', sans-serif;
}
/* Tight/wide Latin tracking looks wrong on CJK ideographs; scoped to
   prose classes only (never the hero .specimen, which stays Latin
   "RASEN" in every locale and keeps its own tracking). */
:lang(zh) h1, :lang(zh) h2, :lang(zh) h3, :lang(zh) h4,
:lang(ja) h1, :lang(ja) h2, :lang(ja) h3, :lang(ja) h4,
:lang(ko) h1, :lang(ko) h2, :lang(ko) h3, :lang(ko) h4 {
  letter-spacing: 0;
}
:lang(zh) .eyebrow, :lang(zh) .ascii-frame,
:lang(ja) .eyebrow, :lang(ja) .ascii-frame,
:lang(ko) .eyebrow, :lang(ko) .ascii-frame {
  letter-spacing: 0.05em;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

html {
  background: var(--bg0);
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--bg0);
  color: var(--fg);
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1.6;
  font-feature-settings: "tnum" 1;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { max-width: 100%; display: block; }

a { color: var(--fg); }
a:hover { color: var(--red); }

.red, .red-inline { color: var(--red); }

/* ---- scanline overlay: fixed, pointer-events-none, opacity <= 0.08 ---- */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 200;
  background: repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.32) 2px 3px);
  opacity: 0.08;
}

/* ==== layout shell ==== */
.shell { max-width: 1280px; margin: 0 auto; padding: 0 24px; }

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--bg1);
  border-bottom: 1px solid var(--line);
}
/* 6th column (.lang-switch) added for the site-l10n-i18n language switcher;
   the other five fractions were retuned, not restructured, to make room.
   The brand and docs-label columns get extra share because translated
   chrome strings (e.g. ja "上昇する螺旋のループ", "ドキュメント") run
   longer than the original English words and wrapped to two lines at
   ~900-1200px with the original narrower fractions. */
/* 7th column (.gh-link, site-gh-links design D1) appended as `auto` after
   .lang-switch — the icon itself is a fixed ~18px in every locale, so its
   OWN width doesn't need per-locale tuning. But the extra column and its
   gap do consume space from the row before the fr tracks divide up what's
   left: shaving gap 12px→10px alone only cost the brand column ~0.7px,
   which was enough to flip ja's translated brand tagline ("RASEN · 上昇
   する螺旋のループ") from fitting to wrapping at 900px (verified against
   a pre-change worktree: ja did NOT wrap there before this column
   existed — that margin was razor-thin even pre-change). Fix: reclaim
   real headroom by moving fr share INTO brand (1.4→1.7) FROM the three
   columns with slack — version/MIT/badge (0.6/0.6/0.9 → 0.5/0.5/0.8) —
   not from .lang-switch, which is `white-space: nowrap` and can't shrink
   below its own content width without overflowing. Re-verified via
   Playwright at 900/1000/1200 × 4 locales after this change: no locale
   wraps at any of those widths (en's own pre-existing 900px wrap, which
   predates this whole header, is unrelated — see site-l10n-i18n M1). */
.site-header .shell {
  display: grid;
  grid-template-columns: 1.7fr 0.9fr 0.5fr 0.5fr 0.8fr 1.5fr auto;
  gap: 10px;
  padding-top: 10px;
  padding-bottom: 10px;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg2);
}
.site-header b { color: var(--fg); font-weight: 500; }
.site-header .red { color: var(--red); }
.site-header a.site-brand { text-decoration: none; }
.site-header a.ascii-frame { text-decoration: none; }
/* Language switcher (site-l10n-i18n design D5): plain links, current
   locale marked in the existing .red hazard-accent marker idiom — no new
   colors, no radius, no JS. Docs pages never render this cell (renderPage
   defaults `switcher` to ''), so their header is untouched. */
.lang-switch { white-space: nowrap; text-align: right; }
.lang-switch a { color: var(--fg2); text-decoration: none; }
.lang-switch a:hover { color: var(--fg); }
.lang-switch a.current { color: var(--red); }
/* GitHub header icon (site-gh-links design D2): inline monochrome SVG
   mark, phosphor-secondary at rest, hazard red on hover — no radius (the
   mark's curves are brand imagery, not a UI control, so the radius-0
   audit doesn't apply here). Renders on every page via the shared shell,
   including docs (EN_CHROME carries the default English label). */
.gh-link { display: flex; align-items: center; color: var(--fg2); }
.gh-link:hover { color: var(--red); }
.gh-link svg { display: block; }
/* @keyframes blink is shared with the hero caret (the only sanctioned
   blink) — do not attach it to header/body copy; motion is caret + one
   pulsing dot only. */
@keyframes blink { 50% { opacity: 0.25; } }

@media (max-width: 720px) {
  .site-header .shell { grid-template-columns: 1fr auto auto auto; }
  .site-header .shell > *:nth-child(n+3) { display: none; }
  /* M1 fix (site-l10n-i18n review round 1): the switcher is the 6th
     header cell, but "hide everything past cell 2" would silently take
     locale-switching away from every mobile visitor — the spec requires
     the switcher on every viewport. Exempt it explicitly; it must come
     after the nth-child rule above to win at equal specificity. */
  .site-header .shell > .lang-switch { display: block; }
  .lang-switch { white-space: normal; font-size: 10px; }
  /* site-gh-links D1: same equal-specificity exemption pattern for the
     7th cell (icon) — a GitHub link is chrome users expect on mobile
     too, and it's the smallest-width affordance, so there's no reason to
     drop it here. Must also come after the nth-child hide rule. */
  .site-header .shell > .gh-link { display: flex; }
}

.ascii-frame {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
}
.ascii-frame::before { content: '['; }
.ascii-frame::after { content: ']'; }

section { padding: 72px 0; border-bottom: 1px solid var(--line); }
section:last-of-type { border-bottom: none; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.04em;
  line-height: 0.9;
  margin: 0;
  color: var(--fg);
}

/* Contractual title scale (planning-context CRT contract + website-landing
   spec): section headings are specimen-scale. .hero h1 and .colophon h2 are
   deliberately smaller variants (cover subhead / footer sign-off), not this
   rule's target. */
section > h2 {
  font-size: clamp(56px, 7vw, 96px);
  max-width: 20ch;
  margin-bottom: 28px;
  /* At the 56px floor on a 360px viewport, single long words (e.g.
     "Independent", "collision.") can exceed the available inline width
     and refuse to wrap, forcing horizontal page overflow. overflow-wrap
     only breaks the specific word that doesn't fit (unlike word-break,
     which breaks eagerly at nearly every line and looked far worse in
     testing), so normal space-wrapping is preferred and this is a true
     last resort. */
  overflow-wrap: break-word;
}
@media (max-width: 420px) {
  /* The 56px clamp floor still lets an individual long uppercase word
     (e.g. "INDEPENDENT", "NAMESPACES,") exceed a ~312px content column,
     forcing overflow-wrap to fragment it mid-word. Below 420px, step the
     floor down further so words fit at word boundaries; clamp(56,7vw,96)
     still governs at every wider width, per the pinned contract value. */
  section > h2 { font-size: clamp(38px, 11vw, 56px); }
}

.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0 0 18px;
  display: block;
}

.lede {
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1.7;
  color: var(--fg2);
  max-width: 78ch;
  margin: 20px 0 0;
}

/* ==== 01 · HERO ==== */
.hero { padding-top: 64px; }
.hero .grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  align-items: center;
  gap: 56px;
}
/* The specimen column (not the specimen itself) is the query container:
   containing it on the specimen's own box would let a nowrap line's
   min-content width feed back into the grid track's auto min-width,
   which feeds back into cqw, growing without bound. min-width: 0 stops
   the track from expanding to fit the nowrap text, so the container's
   inline size reflects the actual 1.15fr track width instead. */
.hero .specimen-col {
  container-type: inline-size;
  min-width: 0;
}
.hero .specimen {
  font-family: var(--display);
  /* RASEN + caret must never wrap or fragment: the wordmark is a fixed
     6-glyph-advance brand token (5 letters + caret), so it is sized from
     its column's own box (a container query, in cqw) rather than the
     viewport — the earlier vw-based clamp read the viewport width even
     though the specimen lives in a grid column that is only a fraction
     of it, so it overflowed the column at most widths and word-break
     fragmented it (RASE/N). The vw clamp below is a fallback for engines
     without container query units; cqw wins in the cascade wherever
     supported. */
  font-size: clamp(48px, 9.5vw, 200px);
  font-size: clamp(48px, 22.5cqw, 200px);
  line-height: 0.85;
  letter-spacing: -0.05em;
  text-transform: uppercase;
  color: var(--fg);
  position: relative;
  white-space: nowrap;
}
.hero .specimen .caret { color: var(--red); animation: blink 1s steps(1) infinite; }
/* Renamed from .thesis-cn (site-l10n-i18n): the tagline under the hero
   wordmark is now locale-specific copy, not always Chinese. */
.hero .hero-tagline {
  font-size: 15px;
  letter-spacing: 0.14em;
  color: var(--fg2);
  margin: 18px 0 0;
}
.hero h1 { font-size: clamp(28px, 3.2vw, 40px); margin: 0 0 14px; max-width: 22ch; }
.hero .meta-col { display: flex; flex-direction: column; gap: 20px; }
/* GitHub hero link (site-gh-links design D3): reuses the ">>>" arrow idiom
   already used elsewhere on the page (thesis items), mono, phosphor at
   rest / hazard red on hover, hairline top border matching the dl's own
   border-top rhythm directly below it. The repository URL text stays
   untranslated; only the label word localizes via hero.githubLabel. */
.gh-row {
  display: block;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--fg2);
  text-decoration: none;
  border-top: 1px solid var(--line);
  padding-top: 18px;
  margin-top: 4px;
}
.gh-row:hover { color: var(--red); }
.gh-row .arrow { color: var(--red); margin-right: 6px; }
.hero dl {
  display: grid;
  grid-template-columns: 15ch 1fr;
  gap: 9px 16px;
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-top: 1px solid var(--line);
  padding-top: 18px;
}
.hero dl dt { color: var(--red); }
.hero dl dd { margin: 0; color: var(--fg); }
.hero dl dd .green-dot {
  display: inline-block;
  width: 7px; height: 7px;
  background: var(--green);
  margin-right: 8px;
  animation: pulse 1.6s steps(1) infinite;
}
@keyframes pulse { 50% { opacity: 0.3; } }

@media (max-width: 880px) {
  .hero .grid { grid-template-columns: 1fr; gap: 32px; }
}

/* ==== 02 · BRIEFING STRIP ==== */
.briefing .strip {
  margin-top: 32px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
.briefing .cell { background: var(--bg1); padding: 20px 20px 24px; }
.briefing .cell .k {
  color: var(--red);
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-bottom: 8px;
  display: block;
}
.briefing .cell .v {
  font-family: var(--display);
  font-weight: 900;
  font-size: 22px;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--fg);
  word-break: break-word;
}
.briefing .cell .v small {
  display: block;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  color: var(--fg2);
  margin-top: 6px;
  font-weight: 400;
  text-transform: none;
}
@media (max-width: 720px) {
  .briefing .strip { grid-template-columns: repeat(2, 1fr); }
}

/* ==== 03 · SPIRAL THESIS ==== */
.thesis .list { border-top: 1px solid var(--line); margin-top: 28px; }
.thesis .item {
  display: grid;
  grid-template-columns: 6ch 1fr;
  gap: 24px;
  padding: 22px 0;
  border-bottom: 1px solid var(--line);
}
.thesis .item .n {
  font-family: var(--display);
  font-weight: 900;
  font-size: 30px;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--fg);
}
.thesis .item .arrow { color: var(--red); margin-right: 10px; letter-spacing: 0.1em; }
.thesis .item h4 {
  font-size: 19px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0 0 8px;
}
.thesis .item p { font-size: 13px; color: var(--fg2); line-height: 1.65; max-width: 72ch; margin: 0; }
@media (max-width: 640px) {
  .thesis .item { grid-template-columns: 1fr; gap: 8px; }
}

/* ==== 04 · TELEMETRY GRID (features) ==== */
.telemetry .grid {
  /* Item count (7) doesn't divide evenly into every auto-fit column count,
     so this grid uses per-cell borders rather than the gap+background-bleed
     hairline trick — that trick paints the *container* background in any
     track a partial last row leaves empty, which reads as a stray filled
     box. Borders always belong to a real cell, so there is nothing to leak
     into. See other grids (.briefing .strip, .coexist .table) for the
     gap:1px module required by the visual-system checklist — their cell
     counts are exact multiples of their column counts. */
  margin-top: 32px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}
.telemetry .tcell {
  background: var(--bg1);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 22px 22px 26px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 150px;
}
.telemetry .tcell .k {
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg3);
}
.telemetry .tcell .v {
  font-family: var(--display);
  font-weight: 900;
  font-size: 20px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--fg);
}
.telemetry .tcell p {
  font-size: 12.5px;
  color: var(--fg2);
  line-height: 1.55;
  margin: 0;
}

/* ==== 05 · TERMINAL TRANSCRIPT ==== */
.transcript .term {
  margin-top: 28px;
  border: 1px solid var(--line);
  background: var(--bg-void);
  padding: 24px 26px;
  font-size: 12.5px;
  line-height: 1.75;
  overflow-x: auto;
}
.transcript .term .you { color: var(--fg2); }
.transcript .term .you b { color: var(--red); font-weight: 600; }
.transcript .term .ai { color: var(--fg); }
.transcript .term .ai b { color: var(--fg); font-weight: 700; }
.transcript .term .ok::before { content: '✓ '; color: var(--fg2); }
.transcript .term pre { margin: 0; white-space: pre-wrap; font-family: var(--mono); }

/* ==== 06 · ALERT / INSTALL ==== */
.alert-block {
  margin-top: 28px;
  padding: 44px 40px;
  border: 2px solid var(--red);
  background: repeating-linear-gradient(135deg, transparent 0 18px, var(--red-soft) 18px 36px);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
}
.alert-block .cmd-row {
  display: flex;
  align-items: stretch;
  gap: 0;
  background: var(--bg-void);
  border: 1px solid var(--line-strong);
  overflow-x: auto;
}
.alert-block .cmd-row code {
  flex: 1;
  padding: 16px 18px;
  font-family: var(--mono);
  font-size: 13.5px;
  color: var(--fg);
  white-space: pre;
  user-select: all;
}
.alert-block .copy-btn {
  border: none;
  border-left: 1px solid var(--line-strong);
  background: var(--bg1);
  color: var(--fg2);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0 18px;
  cursor: pointer;
  white-space: nowrap;
}
.alert-block .copy-btn:hover { color: var(--red); border-left-color: var(--red); }
.alert-block p { font-size: 14px; line-height: 1.65; color: var(--fg); margin: 0; max-width: 62ch; }
.alert-block p strong { background: var(--red); color: var(--bg0); padding: 1px 6px; font-weight: 600; }

/* ==== 07 · COEXISTENCE TABLE ==== */
.coexist .table {
  margin-top: 28px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  font-size: 12.5px;
}
.coexist .table > div { background: var(--bg1); padding: 14px 16px; }
.coexist .table .h {
  background: var(--fg);
  color: var(--bg0);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
}
.coexist .table .rasen-col { color: var(--red); }
@media (max-width: 640px) {
  .coexist .table { font-size: 11px; }
  .coexist .table > div { padding: 10px 10px; }
}

/* ==== 08 · COLOPHON / FOOTER ==== */
.colophon { padding: 72px 0 96px; border-top: 1px solid var(--line); }
.colophon h2 { font-size: clamp(22px, 3vw, 32px); margin-bottom: 4px; }
.colophon .grid {
  margin-top: 28px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
}
.colophon dl {
  margin: 0;
  display: grid;
  grid-template-columns: 14ch 1fr;
  gap: 10px 16px;
  font-size: 12px;
  letter-spacing: 0.04em;
}
.colophon dt { color: var(--red); text-transform: uppercase; letter-spacing: 0.16em; font-size: 12px; }
.colophon dd { margin: 0; color: var(--fg); }
.colophon .signoff {
  margin-top: 48px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg2);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}
@media (max-width: 640px) {
  .colophon .grid { grid-template-columns: 1fr; gap: 28px; }
}

/* ==== 09 · DOCS: layout (sidebar + article + prev/next) ==== */
.doc-layout {
  padding: 48px 0 0;
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 48px;
  align-items: start;
}

.doc-sidebar {
  border: 1px solid var(--line);
  background: var(--bg1);
  align-self: start;
  position: sticky;
  top: 88px;
}
.doc-sidebar summary {
  cursor: pointer;
  padding: 12px 16px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
  list-style: none;
}
.doc-sidebar summary::-webkit-details-marker { display: none; }
.doc-sidebar nav { padding: 0 16px 16px; }
.doc-toc { list-style: none; margin: 0; padding: 0; }
.doc-toc-section { margin-top: 16px; }
.doc-toc-section:first-child { margin-top: 0; }
.doc-toc-label {
  display: block;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg3);
  margin-bottom: 6px;
}
.doc-toc-section ul { list-style: none; margin: 0; padding: 0; }
.doc-toc-section li { border-top: 1px solid var(--line); }
.doc-toc-section li:first-child { border-top: none; }
.doc-toc-section a {
  display: block;
  padding: 7px 0;
  font-size: 12.5px;
  color: var(--fg2);
  text-decoration: none;
}
.doc-toc-section a:hover { color: var(--fg); }
.doc-toc-section a.active { color: var(--red); }

@media (min-width: 900px) {
  .doc-sidebar summary { display: none; }
}
@media (max-width: 899px) {
  .doc-layout { grid-template-columns: 1fr; padding-top: 24px; }
  .doc-sidebar { position: static; }
}

/* ==== 10 · DOCS: article typography (markdown-rendered) ==== */
.doc-article {
  min-width: 0; /* let tables/pre shrink inside the grid track */
  font-size: 14px;
  line-height: 1.7;
  color: var(--fg);
  padding-bottom: 24px;
}
.doc-article h1 {
  font-size: clamp(30px, 4vw, 44px);
  margin: 20px 0 20px;
  max-width: 22ch;
}
.doc-article h2 {
  font-size: clamp(22px, 3vw, 30px);
  margin: 40px 0 16px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}
.doc-article h3 { font-size: 19px; margin: 28px 0 12px; }
.doc-article h4 { font-size: 15px; margin: 20px 0 8px; }
.doc-article p, .doc-article ul, .doc-article ol { margin: 0 0 16px; color: var(--fg2); max-width: 78ch; }
.doc-article li { margin-bottom: 6px; }
.doc-article ul ul, .doc-article ol ol, .doc-article ul ol, .doc-article ol ul { margin: 6px 0 0; }
.doc-article a { color: var(--fg); text-decoration: underline; text-underline-offset: 2px; }
.doc-article a:hover { color: var(--red); }
.doc-article strong { color: var(--fg); font-weight: 700; }
.doc-article code {
  font-family: var(--mono);
  background: var(--bg-void);
  border: 1px solid var(--line);
  padding: 1px 5px;
  font-size: 0.92em;
  /* Inline code (e.g. long ALL_CAPS env var names) has no natural break
     point and isn't inside a scrollable ancestor like <pre>, so on narrow
     viewports it can force page-level horizontal scroll. Break inside the
     token as a last resort — normal wrapping at spaces still wins first. */
  overflow-wrap: break-word;
}
.doc-article pre code { overflow-wrap: normal; } /* pre already scrolls its own overflow */
.doc-article pre {
  background: var(--bg-void);
  border: 1px solid var(--line);
  padding: 16px 18px;
  margin: 0 0 20px;
  overflow-x: auto;
}
.doc-article pre code { background: none; border: none; padding: 0; }
.doc-article blockquote {
  margin: 0 0 16px;
  padding: 4px 0 4px 18px;
  border-left: 2px solid var(--line-strong);
  color: var(--fg2);
}
.doc-article hr { border: none; border-top: 1px solid var(--line); margin: 32px 0; }
.doc-article .doc-table-wrap { overflow-x: auto; margin: 0 0 20px; }
.doc-article table { border-collapse: collapse; width: 100%; font-size: 13px; }
.doc-article th, .doc-article td { border: 1px solid var(--line); padding: 8px 12px; text-align: left; }
.doc-article th { background: var(--bg1); color: var(--fg); text-transform: uppercase; font-size: 11px; letter-spacing: 0.08em; }
.doc-article td { color: var(--fg2); }
.doc-article img { border: 1px solid var(--line); }

/* Untranslated-fallback notice (site-docs-i18n design D2): hairline box,
   existing palette, radius 0 — same visual family as other notice/strip
   surfaces, not a new component. Sits directly above the article body
   (right under where the page's own H1 renders) on any locale page whose
   translation is missing. */
.doc-notice {
  margin: 0 0 20px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: var(--bg1);
  color: var(--fg2);
  font-size: 13px;
  line-height: 1.5;
}

/* ==== 11 · DOCS: prev/next + index ==== */
.doc-prevnext {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  gap: 16px;
  font-size: 12.5px;
  letter-spacing: 0.04em;
}
.doc-prevnext a { color: var(--fg2); text-decoration: none; }
.doc-prevnext a:hover { color: var(--red); }
.doc-prevnext .doc-next { text-align: right; }

.doc-index { padding-top: 64px; }
.doc-index h1 { font-size: clamp(40px, 6vw, 72px); margin: 0 0 16px; max-width: 16ch; }
.doc-index-grid {
  margin-top: 32px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}
.doc-index-section {
  background: var(--bg1);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 20px 22px 24px;
}
.doc-index-section ul { list-style: none; margin: 12px 0 0; padding: 0; }
.doc-index-section li { border-top: 1px solid var(--line); }
.doc-index-section li:first-child { border-top: none; }
.doc-index-section a { display: block; padding: 7px 0; font-size: 13px; color: var(--fg2); text-decoration: none; }
.doc-index-section a:hover { color: var(--red); }

/* ==== self-hosted display / mono fonts (add @font-face rules here if
   license-clean local files are added under src/assets/fonts/). Absent
   files, the stacks above fall back to system mono/sans — spec-compliant
   per design D3. ==== */
