/* ============================================================================
   theme-mozard.css — Mozard house-style documentation theme
   Bundled with the gen-docs-mozard skill. Applied VERBATIM on the common path;
   do not regenerate per run. Custom themes are a separate, on-request build.

   Layout language (see references/theme.md — the "Zaakdossier" direction):
     a sticky .doc-toolbar (a real SURFACE with a bottom border — the brand mark,
     a search box, and the language + theme controls grouped right) above the body.
     No dark masthead hero — the .sheet card carries the title (.headrow: eyebrow/
     title/lede/metadata stamp) and holds <main> of <section>s. A section may nest
     .topics — folder-style tabs switching .topic panels — when it genuinely has
     parallel sub-topics; most don't.

   Two layout modes share this stylesheet:
     * DEFAULT (standalone / single-file) — .wrap > .shell = [sticky chapters rail |
       .sheet], a single measure-capped column centered on the page.
     * APP-SHELL (<body class="docs-site"> — the mozard-docs hierarchy) — a three-pane
       shell: a persistent doc-tree .site-nav on the LEFT, the .sheet content column
       in the MIDDLE, and the on-page TOC (nav.chapters) moved to the RIGHT. The whole
       assembly is centered and width-capped so wide screens gain navigation, not
       empty margin. The toolbar aligns to it (logo over the nav rail, search + toggles
       over the content column). On mobile all three stack content-first. The .site-nav
       is injected per page by scripts/build_sidenav.py; it is chrome (outside <main
       data-doc>), so build_pager.py's extractor ignores it.

   Componentry rules (do not regress): no accent-rail callouts — a colored TOP
   rule marks category instead of a colored LEFT border; no shadow-lift cards
   on hover; no border-radius:999px pill badges (small-radius tags instead).
   Color marks STATE, not decoration: the chapters-rail / site-nav active item gets
   a fill (+ a 2px brand inset rail on site-nav), the active topic tab gets a 2px
   brand top rule, table headers get a 2px brand underline.
   Surfaces read as layers: the toolbar and both nav rails sit on --surface with a
   real border (and a faint lift on the rails) — never --bg-on-bg, which vanished in
   light mode. Labels/eyebrows are sans caps; monospace is reserved for code and
   identifiers (glossary terms, repo names).

   No external hosts: system font stack only, no @import, no remote url().
   Theme: docs open in LIGHT (<html data-theme="light">); the toggle flips
   light<->dark. The footer is the one instrument surface that stays dark in
   both themes, where the brand yellow reads well. prefers-color-scheme is a
   fallback only —
   the JS toggle never auto-follows the OS/browser preference on load.
   Language: docs open in ENGLISH (<html data-lang="en" lang="en">); the toggle
   flips en<->nl by hiding the inactive paired lang="" content.
   Brand yellow is used ONLY as fills / rules / borders / on-dark accents — never
   as text on light, where it fails contrast (use --link, the dark gold, instead).
   Logo swap: the SVGs have hard-coded fills, so we swap the FILE, never recolor.
   ============================================================================ */

/* ---- Brand + semantic tokens (light) ------------------------------------ */
:root {
  --brand:          #f6c900;   /* Mozard primary yellow (huisstijl $color-primary) */
  --brand-contrast: #1f2933;   /* dark ink for text ON a yellow fill */

  --text:           #3a3f45;
  --text-muted:     #6c6d6e;   /* Mozard house gray (huisstijl $color-3ggray) */
  --text-faint:     #9599a0;   /* captions, counters, eyebrow tags */
  --heading:        #1f2933;

  --bg:             #f5f6f8;   /* page ground (cards float on it) */
  --bg-alt:         #eceff3;   /* subtle tint (table zebra) */
  --surface:        #ffffff;   /* cards + panels */
  --surface-alt:    #f7f8fa;   /* callouts, thead, diagram surface */

  --border:         #e3e6e9;
  --border-strong:  #cbd0d6;

  --link:           #8a6d00;   /* dark gold — the accessible text-accent on light (~4.6:1) */
  --link-hover:     #5e4a00;
  --accent:         #f6c900;   /* primary yellow: rules, borders, active bars, fills */
  --accent-2:       #ceab0a;   /* Mozard secondary gold (huisstijl $color-secondary) */

  --code-bg:        #eceff3;
  --code-text:      #24292f;

  --callout-bg:     #f7f8fa;
  --note-bg:        #eef3f7;   --note-border:   #4f7ea8;
  --warn-bg:        #fdf4e6;   --warn-border:   #e08a00;
  --assume-bg:      #f4f0f8;   --assume-border: #8a72b0;

  /* Instrument surfaces — ALWAYS dark, in both themes (footer, dark diagrams) */
  --ink:        #17191c;
  --ink-2:      #23272d;
  --ink-line:   rgba(255,255,255,.14);
  --ink-text:   #c9cdd3;
  --ink-head:   #ffffff;
  --grid:       rgba(31,41,51,.045);   /* faint grid on the light instrument surface */

  --shadow:     0 1px 2px rgba(17, 24, 39, .06), 0 4px 16px rgba(17, 24, 39, .05);
  --shadow-rail:0 1px 2px rgba(17, 24, 39, .05), 0 10px 28px -14px rgba(17, 24, 39, .18);
  --radius:     10px;   --radius-sm: 6px;
  --measure:    66ch;   --content-max: 1180px;

  /* App-shell (docs-site mode) — fixed nav rails + a measure-capped content column,
     the whole assembly centered so wide screens gain navigation, not empty margin. */
  --sidebar-w:  240px;  --toc-w: 220px;  --shell-gap: 40px;  --content-w: 760px;
  --assembly-w: calc(var(--sidebar-w) + var(--content-w) + var(--toc-w) + 2 * var(--shell-gap));

  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", "Cascadia Code", "JetBrains Mono",
               Menlo, Consolas, "Liberation Mono", monospace;

  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; --space-7: 48px; --space-8: 64px;
}

/* ---- Dark tokens: auto, unless a manual light theme is forced ----------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --text:#e6e8ea; --text-muted:#9aa0a6; --text-faint:#767b82; --heading:#f2f4f6;
    --bg:#17191c; --bg-alt:#24272c; --surface:#1e2125; --surface-alt:#24272c;
    --border:#30343a; --border-strong:#3d424a;
    --link:#e8c33a; --link-hover:#f6c900; --accent:#f6c900; --accent-2:#d9b62e;
    --code-bg:#24272c; --code-text:#e6e8ea;
    --callout-bg:#22252a; --note-bg:#1a2530; --note-border:#5f92c0;
    --warn-bg:#2b2313; --warn-border:#e0a54f; --assume-bg:#241f2e; --assume-border:#a48fca;
    --grid:rgba(255,255,255,.05);
    --shadow:0 1px 2px rgba(0,0,0,.35), 0 6px 22px rgba(0,0,0,.35);
    --shadow-rail:0 1px 2px rgba(0,0,0,.4), 0 12px 30px -14px rgba(0,0,0,.6);
  }
}

/* ---- Manual toggle override (wins over the media query) ----------------- */
:root[data-theme="dark"] {
  --text:#e6e8ea; --text-muted:#9aa0a6; --text-faint:#767b82; --heading:#f2f4f6;
  --bg:#17191c; --bg-alt:#24272c; --surface:#1e2125; --surface-alt:#24272c;
  --border:#30343a; --border-strong:#3d424a;
  --link:#e8c33a; --link-hover:#f6c900; --accent:#f6c900; --accent-2:#d9b62e;
  --code-bg:#24272c; --code-text:#e6e8ea;
  --callout-bg:#22252a; --note-bg:#1a2530; --note-border:#5f92c0;
  --warn-bg:#2b2313; --warn-border:#e0a54f; --assume-bg:#241f2e; --assume-border:#a48fca;
  --grid:rgba(255,255,255,.05);
  --shadow:0 1px 2px rgba(0,0,0,.35), 0 6px 22px rgba(0,0,0,.35);
}

/* ---- Reset / base ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font-family: var(--font-sans); font-size: 17px; line-height: 1.55;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; overflow-wrap: break-word;
  transition: background .25s ease, color .25s ease;
}
img, svg, video { max-width: 100%; height: auto; }

/* The UA stylesheet hides [hidden] with a plain `display: none`, so ANY author rule
   that sets display beats it. .stamp does (inline-flex), which left every
   `<span class="stamp screen-stamp" hidden>` on screen showing its label with an
   empty value. Restore the attribute's meaning once, here, rather than teaching
   each component to guard with :not([hidden]). */
[hidden] { display: none !important; }

/* ---- Bilingual visibility (English default; Dutch shows under data-lang=nl) */
:root:not([data-lang="nl"]) [lang="nl"] { display: none; }
:root[data-lang="nl"] [lang="en"] { display: none; }

/* ---- Typography --------------------------------------------------------- */
h1, h2, h3, h4 { color: var(--heading); line-height: 1.18; font-weight: 700; letter-spacing: -.015em; margin: 2em 0 .5em; scroll-margin-top: 24px; }
h1 { font-size: clamp(2rem, 4.5vw, 2.9rem); margin-top: 0; font-weight: 750; }
h2 { font-size: clamp(1.5rem, 3vw, 1.95rem); font-weight: 720; }
h3 { font-size: 1.16rem; font-weight: 660; margin: 1.8em 0 .4em; }
h4 { font-size: .98rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
/* Paragraph gap routed onto the space scale and lifted so a break reads as a break
   (it used to be ~1.05em — smaller than the line leading, so paragraphs merged). */
p, ul, ol, dl { margin: 0 0 var(--space-5); max-width: var(--measure); }
ul, ol { padding-left: 1.3em; } li + li { margin-top: .35em; }
small { color: var(--text-muted); }
a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; text-underline-offset: 2px; }
strong { color: var(--heading); }
blockquote { margin: 1.3em 0; padding: .2em 1.1em; border-left: 3px solid var(--accent); color: var(--text-muted); font-style: italic; }
hr, hr.div { border: 0; border-top: 1px solid var(--border); margin: 0; }

/* ---- Code --------------------------------------------------------------- */
code, kbd, pre, samp { font-family: var(--font-mono); font-size: .88em; }
/* No border on inline code — the tint alone marks it; a border on every token
   made code-dense prose read as a field of boxes. */
:not(pre) > code { background: var(--code-bg); color: var(--code-text); padding: .07em .34em; border-radius: 4px; }
pre { background: var(--code-bg); color: var(--code-text); padding: var(--space-4); border-radius: var(--radius); border: 1px solid var(--border); overflow-x: auto; line-height: 1.5; margin: 0 0 1.3em; }
pre code { background: none; border: 0; padding: 0; }

/* ---- Wrap + shell (sticky TOC rail + centered content) ------------------ */
.wrap, .page { max-width: var(--content-max); margin: 0 auto; padding: 0 var(--space-5); }
.shell { display: grid; grid-template-columns: 1fr; gap: var(--space-6); padding: var(--space-5) 0 var(--space-8); }
@media (min-width: 60rem) {
  .shell { grid-template-columns: 248px minmax(0, 1fr); gap: 52px; align-items: start; }
  /* One right edge: prose fills the content column rather than stopping short of the
     code / tables / diagrams beside it (same ragged-edge fix as docs-site — Q6). Only
     once the two-column shell is active; below 60rem the single column stays measure-capped. */
  .shell .sheet :is(p, ul, ol, dl, .lede, .plain, .note) { max-width: none; }
}
main { min-width: 0; }
.doc { max-width: 860px; margin: 0 auto; padding: var(--space-6) var(--space-5) var(--space-8); }  /* one-column article */

/* ---- Doc toolbar (search + language + theme) — sticky, content-width ---- */
/* Search is a mandatory control alongside theme/language (not an optional
   enhancement) — it fills the bar; language + theme group at the right so
   the input can actually grow to use the space. */
.doc-toolbar {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; gap: 14px;
  /* Full-bleed surface, content centered to --content-max via padding (no wrapper,
     no 100vw). A real surface with a boundary — NOT the page ground: as a sticky bar
     it must read as a distinct layer once content scrolls under it; matching --bg made
     it vanish in light mode (bg-on-bg ≈ 1:1). Border + faint shadow separate it. */
  padding: 10px max(var(--space-5), calc((100% - var(--content-max)) / 2));
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 6px 18px -14px rgba(17, 24, 39, .18);
}
.toolbar-logo { flex: none; display: flex; align-items: center; }
/* 30px matches the height of the language toggle and theme button beside it, so the wordmark sits
   on the same optical line as the controls instead of floating small above them.
   NOTE this rule (0,1,1) outranks `.logo-light, .logo-dark { height: 34px }` (0,1,0) further down,
   which is why that one never applied in the toolbar. The two are now deliberately different
   sizes: 34px is for a logo placed in page CONTENT, 30px for the compact sticky bar. Keep both. */
.toolbar-logo img { height: 30px; width: auto; }
.doc-toolbar .search-wrap { position: relative; flex: 1 1 auto; min-width: 0; }
.doc-search {
  width: 100%; font: inherit; font-size: .92rem; padding: .5em .9em;
  border: 1px solid var(--border-strong); border-radius: var(--radius); background: var(--bg); color: var(--text);
}
.doc-search:focus-visible { outline: 2px solid var(--link); outline-offset: 1px; }
.doc-toolbar-right { flex: none; display: flex; align-items: center; gap: 10px; }
.lang-toggle {
  position: relative; display: inline-flex; width: 68px; height: 30px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--bg);
  cursor: pointer; padding: 2px;
}
.lang-toggle .indicator {
  position: absolute; top: 2px; left: 2px; width: calc(50% - 2px); height: calc(100% - 4px);
  background: var(--brand); border-radius: 3px; transition: transform .15s ease; z-index: 0;
}
.lang-toggle[data-lang-value="nl"] .indicator { transform: translateX(100%); }
.lang-toggle .opt {
  position: relative; z-index: 1; flex: 1; display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: var(--text-muted);
}
.lang-toggle[data-lang-value="en"] .opt:nth-child(2) { color: var(--brand-contrast); }
.lang-toggle[data-lang-value="nl"] .opt:nth-child(3) { color: var(--brand-contrast); }
/* The glyph is an emoji (moon / sun), which draws well inside its em box — at 14px in a 30px
   button it sat as a small mark in a lot of empty space. 18px fills the button without touching
   its footprint or the toolbar height. */
.theme-btn { border: 1px solid var(--border-strong); background: var(--bg); width: 30px; height: 30px; border-radius: var(--radius-sm); cursor: pointer; display: grid; place-items: center; font-size: 18px; line-height: 1; padding: 0; }
.doc-toolbar button:focus-visible, .doc-toolbar input:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }

/* ---- Sheet (the light content card — carries title/lede/metadata) ------- */
/* No dark masthead hero — the page title lives in the sheet's headrow,
   inside the same card as the section content, exactly like the approved
   Zaakdossier direction. The brand mark moved to the toolbar instead. */
.sheet { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-6) var(--space-5) var(--space-6); }
.headrow { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.eyebrow { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; font-weight: 700; color: var(--link); margin: 0 0 8px; display: block; }
.sheet h1 { font-size: clamp(1.7rem, 3.5vw, 2.3rem); margin: 0 0 10px; }
.lede { font-size: 1.02rem; color: var(--text-muted); max-width: 60ch; margin: 18px 0 8px; line-height: 1.5; }
.stamp-row { display: flex; flex-wrap: wrap; gap: 8px; }
.stamp { display: inline-flex; gap: 5px; font-size: 12px; font-weight: 700; color: var(--brand-contrast); padding: 4px 10px; border-radius: 4px; background: var(--brand); white-space: nowrap; }
.stamp b { font-weight: 800; }

/* ---- Sticky chapters rail (nav.chapters) -------------------------------- */
/* Same job the old numbered TOC rail did — one entry per top-level <section>,
   scroll-anchored, scales to any document length. A dot marks the active
   chapter (matching the approved Zaakdossier direction exactly) — not a
   number: the rail is a location indicator, not a sequence display. */
nav.chapters {
  position: sticky; top: 70px; align-self: start; font-size: 13.5px;
  max-height: calc(100vh - 92px); overflow-y: auto;
  /* Real surface + boundary so the rail reads as a card, not floating text. Was
     --surface-alt on --bg (≈1:1 in light mode); --surface + a strong border + a
     faint lift give it the same separation the sheet already earns. */
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 10px 6px;
  box-shadow: var(--shadow-rail);
}
nav.chapters .toc-title { font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint); margin: 4px 8px 10px; }
nav.chapters ol { list-style: none; margin: 0; padding: 0; max-width: none; display: grid; gap: 2px; }
nav.chapters li { margin: 0; }
nav.chapters a { display: flex; align-items: center; gap: 7px; padding: 7px 8px; border-radius: var(--radius-sm); color: var(--text-muted); line-height: 1.35; transition: background .15s, color .15s; }
nav.chapters a::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: transparent; flex: none; }
/* Trailing chevron only appears on hover — a "this navigates" cue that doesn't
   fall back to the accent-rail pattern this theme deliberately avoids. */
nav.chapters a::after { content: "\203a"; margin-left: auto; padding-left: 6px; color: var(--text-faint); opacity: 0; transition: opacity .15s; }
nav.chapters a:hover { color: var(--heading); background: var(--bg-alt); text-decoration: none; }
nav.chapters a:hover::after { opacity: 1; }
nav.chapters a[aria-current="true"] { color: var(--heading); background: var(--bg-alt); font-weight: 700; }
nav.chapters a[aria-current="true"]::before { background: var(--brand); }

/* ---- Sections ---------------------------------------------------------- */
/* Section separator is owned by CSS (a top rule on every section) so EVERY
   section — including the first — is delimited consistently; the authored
   <hr class="div"> between sections is hidden. `:not(.doc-section)` keeps the
   rule off the merged pager's route wrappers, which are also <section>s. */
main section:not(.doc-section) { border-top: 1px solid var(--border); margin: var(--space-6) 0 0; padding-top: var(--space-6); scroll-margin-top: 22px; }
main section:not(.doc-section):first-of-type { margin-top: var(--space-4); }
main hr.div { display: none; }
main section > h2 { margin: 0 0 12px; text-wrap: balance; }
/* Eyebrow-style label: sans caps with tracking — NOT monospace (mono is reserved for
   code + identifiers like glossary terms and repo names, so it keeps meaning something). */
.sec-num { font-size: 12px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--link); display: block; margin-bottom: 8px; }

/* ---- Topics (optional, nested tabs within a section) -------------------- */
/* Use only when a section genuinely has parallel sub-topics worth switching
   between — most sections don't need this. The section itself stays plain,
   scroll-anchored content (nav.chapters points at it normally); only the
   .topic panels inside show/hide via JS. Same-page links that land inside a
   hidden .topic are handled by the reveal-then-jump script in theme.md — a
   plain <a href="#id"> into a topic that isn't showing does NOT work on its
   own, since a display:none element has no layout box to scroll to. */
.topics { display: flex; gap: 4px; margin: 20px 0 -1px; flex-wrap: wrap; }
.topic-tab {
  font: inherit; font-size: 13px; font-weight: 700; padding: 8px 16px;
  background: var(--surface-alt); color: var(--text-muted);
  border: 1px solid var(--border); border-bottom: none; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  cursor: pointer;
}
.topic-tab[aria-selected="true"] {
  background: var(--surface); color: var(--heading); border-top: 2px solid var(--brand);
  margin-top: -1px; border-bottom: 1px solid var(--surface);
}
.topic-body { border: 1px solid var(--border); border-radius: 0 var(--radius) var(--radius) var(--radius); background: var(--surface); padding: 18px 20px; }
.topic { display: none; }
.topic[data-active] { display: block; }

/* ---- Callouts ----------------------------------------------------------- */
/* Plain-language summary (the reference-style ".plain"; ".callout callout-plain" is an alias).
   A flat bordered box with a colored TOP rule marks category — no colored
   left rail, no tint beyond the neutral surface every callout already shares. */
.plain, .callout-plain {
  border: 1px solid var(--border); border-top: 2px solid var(--brand); background: var(--surface-alt);
  padding: 14px 18px; border-radius: var(--radius-sm); margin: 16px 0 22px; max-width: var(--measure);
}
.plain > :first-child, .callout > :first-child { margin-top: 0; }
.plain p, .callout > :last-child { margin-bottom: 0; }
.plain .tag, .callout-label {
  font-size: 11px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--link); display: block; margin-bottom: 5px; font-weight: 700;
}
.plain p { max-width: none; }
.callout { border: 1px solid var(--border); border-top: 2px solid var(--accent); background: var(--callout-bg); border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4); margin: 0 0 1.3em; }
.callout-note  { border-top-color: var(--note-border);   background: var(--note-bg); }
.callout-warn  { border-top-color: var(--warn-border);   background: var(--warn-bg); }
.callout-assumption { border-top-color: var(--assume-border); background: var(--assume-bg); }
.note { font-size: 15px; color: var(--text-muted); border-left: 2px solid var(--border); padding-left: 15px; margin: 18px 0; max-width: var(--measure); }
.note b { color: var(--heading); }
/* Inline "assumption" marker for a single unverified claim */
.assumption { font-size: .8em; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--assume-border); border: 1px solid var(--assume-border); border-radius: 4px; padding: .05em .5em; margin-left: .35em; }

/* ---- Tables ------------------------------------------------------------- */
.table-wrap { overflow-x: auto; margin: 0 0 1.3em; border: 1px solid var(--border); border-radius: var(--radius); }
table { border-collapse: collapse; width: 100%; font-size: .95rem; }
th, td { text-align: left; padding: .6em .85em; border-bottom: 1px solid var(--border); vertical-align: top; }
thead th { background: var(--surface-alt); color: var(--heading); font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; border-bottom: 2px solid var(--brand); }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:nth-child(even) td { background: var(--bg-alt); }

/* ---- Figures / diagrams (light instrument surface with faint grid) ------ */
.figure, figure { margin: 24px 0; max-width: none; }
figcaption, .figure figcaption { font-size: 13px; color: var(--text-faint); margin-top: 12px; line-height: 1.5; }
figcaption .key { color: var(--text-muted); }
.fig-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.diagram {
  background: var(--bg); border: 1px solid var(--border); border-radius: 12px; padding: 22px 18px; overflow-x: auto;
  background-image: linear-gradient(var(--grid) 1px, transparent 1px), linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 24px 24px;
}
/* No width:100% / min-width here on purpose: a diagram renders at its own native
   width/height attributes (matching its viewBox), never stretched or shrunk to the
   container. max-width:none opts diagrams out of the img/svg/video shrink-to-fit
   rule above — a diagram wider than the pane overflows and scrolls via .diagram's
   own overflow-x:auto instead of being squeezed illegible. See theme.md's diagram
   sizing guidance for the target natural width. */
.diagram svg { display: block; width: auto; height: auto; max-width: none; }
.node { display: inline-block; padding: var(--space-2) var(--space-3); background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); box-shadow: var(--shadow); font-weight: 500; font-size: .9rem; }
.node--accent { border-color: var(--accent); }

/* ---- Card grid (repositories / section index) -------------------------- */
/* `grid-auto-rows: 1fr` makes every row the same height. Without it each row sizes to its own
   tallest card, so a row holding a two-line title stands visibly taller than the row above it —
   the cards read as randomly sized rather than as a grid. All rows here are implicit (only
   columns are declared), so this governs the whole grid. */
.cards { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); grid-auto-rows: 1fr; list-style: none; margin: 22px 0; padding: 0; max-width: none; }
.cards-hint { margin: calc(-1 * var(--space-2)) 0 var(--space-4); color: var(--text-muted); font-size: .95rem; }
.card {
  position: relative; display: flex; flex-direction: column; height: 100%; box-sizing: border-box;
  padding: 15px 18px; border: 1px solid var(--border); border-top: 2px solid var(--border); border-radius: var(--radius-sm); background: var(--surface);
  transition: border-color .12s ease;
}
.card:hover { border-top-color: var(--brand); text-decoration: none; }
/* Card titles come in two kinds and want different faces.
   `.rname` is an identifier — a repo or package name (`mozard-backend`) — so it stays monospace;
   that is what the mono was added for. `h3` is prose: a section name ("Technical reference") or,
   in a handleiding, a whole question ("Hoe voeg ik trefwoorden toe aan een medewerker?"). Set in
   mono those read as code, so they take the body face. */
.card h3, .card .rname { margin: 0 0 .3em; font-size: 15px; font-weight: 700; color: var(--heading); word-break: break-word; }
.card h3 { font-family: var(--font-sans); }
.card .rname { font-family: var(--font-mono); }
/* Reserve room on the right for the corner "go" tag ONLY on cards that actually carry one, so
   the two never collide. A blanket reserve wrapped every title 78px early — on the hundreds of
   cards with no badge that is dead gutter, and it forced question titles onto a second line,
   which is what made the row heights uneven in the first place. */
.card:has(.go) h3, .card:has(.go) .rname { padding-right: 78px; }
.card .kind { align-self: flex-start; font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; padding: 2px 8px; border-radius: 4px; margin: 4px 0 8px; background: var(--surface-alt); color: var(--text-muted); border: 1px solid var(--border); }
.card .kind.own { background: rgba(246,201,0,.16); color: var(--link); border-color: rgba(246,201,0,.5); }
.card p { margin: 0; color: var(--text-muted); font-size: 14px; max-width: none; }
/* "go" affordance sits in the top-right corner (filled brand tag) instead of a bottom
   row — the card is a link, so the corner arrow is a cue, and it keeps cards compact. */
.card .go { position: absolute; top: 13px; right: 14px; margin: 0; padding: .28em .6em; border-radius: 4px; background: var(--brand); color: var(--brand-contrast); font-size: .72rem; font-weight: 700; letter-spacing: .02em; line-height: 1; white-space: nowrap; transition: transform .12s ease; }
.card:hover .go { transform: translateX(3px); }

/* ---- Glossary ---------------------------------------------------------- */
/* Definition list, not a 50/50 split: the term column hugs its widest term
   (mono kept — terms are identifiers), the definition takes the rest of the row. */
.gloss { display: grid; grid-template-columns: minmax(130px, max-content) 1fr; gap: var(--space-3) var(--space-6); margin-top: 14px; max-width: none; align-items: baseline; }
.gloss dt { font-family: var(--font-mono); font-weight: 700; color: var(--heading); font-size: 14px; }
.gloss dd { margin: 0; font-size: 14.5px; color: var(--text-muted); }
@media (max-width: 34rem) { .gloss { grid-template-columns: 1fr; gap: 2px; } .gloss dt { margin-top: 12px; } }

/* ---- Inter-page navigation (multi-doc) --------------------------------- */
.breadcrumb { font-size: .84rem; color: var(--text-muted); margin: 0 0 var(--space-5); }
.breadcrumb a { color: var(--text-muted); }
.breadcrumb a:hover { color: var(--link); }
.breadcrumb .sep { margin: 0 .5em; opacity: .6; }
.pager { display: flex; justify-content: space-between; gap: var(--space-4); margin-top: var(--space-8); padding-top: var(--space-5); border-top: 1px solid var(--border); }
.pager a { flex: 1 1 0; padding: var(--space-3) var(--space-4); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.pager a:hover { border-color: var(--brand); text-decoration: none; }
.pager .dir { display: block; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--text-faint); }
.pager .next { text-align: right; }

/* ---- Footer (dark instrument bar) -------------------------------------- */
.site-footer { background: var(--ink); color: #8e949c; font-family: var(--font-mono); font-size: 12.5px; padding: 26px 0; border-top: 3px solid var(--brand); }
.site-footer .wrap { display: flex; flex-wrap: wrap; gap: 8px 20px; justify-content: space-between; }
/* Provenance line (optional, in-flow) */
.doc-footer { margin-top: var(--space-8); padding-top: var(--space-4); border-top: 1px solid var(--border); color: var(--text-muted); font-size: .82rem; }

/* ---- Logo file-swap (toolbar-logo swaps between the two; content that swaps uses these) */
.logo-light { display: inline-block; } .logo-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .logo-light { display: none; }
  :root:not([data-theme="light"]) .logo-dark  { display: inline-block; }
}
:root[data-theme="dark"]  .logo-light { display: none; }        :root[data-theme="dark"]  .logo-dark { display: inline-block; }
:root[data-theme="light"] .logo-light { display: inline-block; } :root[data-theme="light"] .logo-dark { display: none; }
.logo-light, .logo-dark { height: 34px; width: auto; }

/* ============================================================================
   HANDLEIDING MODE — end-user manual componentry
   Added for the handleiding mode (see references/handleiding-*.md). Everything
   below is ADDITIVE: two opt-in modifiers on existing components, two list/
   disclosure primitives the theme lacked, and the .ui mock-screenshot layer.
   No rule above this banner is modified.
   ============================================================================ */

/* ---- Numbered chapters rail (opt-in: nav.chapters.chapters--numbered) ----
   A manual numbers its sections 01, 02, … and the rail should mirror that so
   the TOC, the .sec-num eyebrow, the table pins, and the .ui-callout dots all
   read as one numbering. Neutralizes the base dot bullet; behaviour (scrollspy,
   hover chevron, aria-current) is untouched. */
nav.chapters.chapters--numbered ol { counter-reset: chap; }
nav.chapters.chapters--numbered li { counter-increment: chap; }
nav.chapters.chapters--numbered a::before {
  content: counter(chap, decimal-leading-zero);
  width: auto; height: auto; border-radius: 0; background: none;
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  color: var(--text-faint); min-width: 18px;
}
nav.chapters.chapters--numbered a[aria-current="true"]::before { color: var(--link); background: none; }

/* ---- Framed figure (opt-in: .figure--frame) ------------------------------
   .diagram without the grid backdrop. A faint grid behind a mock application
   window reads as noise; a plain surface frame does not. Same overflow-x
   contract, so a wide mock scrolls instead of breaking the page. */
.figure--frame { background: var(--surface-alt); border: 1px solid var(--border); border-radius: 12px; padding: 16px; overflow-x: auto; }

/* ---- Task steps (ol.steps) ----------------------------------------------
   The core pattern of a task-oriented manual ("1. Klik op Toepassen"). The
   theme had no counter-based list at all. */
ol.steps { list-style: none; counter-reset: step; padding-left: 0; }
ol.steps > li { position: relative; counter-increment: step; padding-left: 38px; margin: 12px 0; }
ol.steps > li::before {
  content: counter(step); position: absolute; left: 0; top: -1px;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--surface-alt); border: 1px solid var(--border-strong);
  color: var(--link); font-weight: 700; font-size: 13px;
  display: grid; place-items: center;
}

/* ---- FAQ disclosure (details.faq) ---------------------------------------
   A manual ends in a FAQ; the theme had no <details>/<summary> styling. The
   +/x marker rotates rather than swapping glyphs, so it needs no JS. */
details.faq { border: 1px solid var(--border); border-radius: var(--radius-sm); margin: 10px 0; background: var(--surface); overflow: hidden; }
details.faq summary { cursor: pointer; padding: 14px 16px; font-weight: 600; color: var(--heading); list-style: none; display: flex; justify-content: space-between; gap: 12px; align-items: center; }
details.faq summary::-webkit-details-marker { display: none; }
details.faq summary::after { content: "+"; font-family: var(--font-mono); font-size: 19px; color: var(--link); flex: none; transition: transform .2s; }
details.faq[open] summary::after { transform: rotate(45deg); }
details.faq summary:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
details.faq .faq-body { padding: 0 16px 14px; }
details.faq .faq-body > :last-child { margin-bottom: 0; }

/* ---- Mock Mozard UI (.ui scope) -----------------------------------------
   Faithful rebuilt views of Mozard screens, for manuals where a real
   screenshot is unavailable or only partly capturable (see
   references/handleiding-screenshots.md).

   DELIBERATELY THEME-INDEPENDENT. Every colour here is a literal hex declared
   on the .ui scope itself; nothing inside references --surface/--bg/--text or
   any :root colour token. A dark-theme flip on :root therefore cannot reach
   inside — which is correct: a mock screenshot of a light application must not
   invert, or it stops resembling what the reader sees on screen. The only two
   inherited tokens are --font-sans/--font-mono, which SHOULD inherit so the
   mock uses the document's type stack.

   Mock UI text is the product's own Dutch vocabulary and is NEVER translated
   or lang-paired — the reader has to match it against the real screen. */
.ui { --ubg:#fff; --uchrome:#fff; --uline:#e6e6e3; --uline2:#d3d3d0; --utext:#41403a; --umut:#8b8b87; --uink:#2a2722; --uyellow:#f6c900; --ugold:#a9820a; --usea:#a9cbe0; --uland:#eef2e6; --uforest:#c4d8a2; --ucluster:#f2a11c; --uzaak:#e0574d; --upin:#41586a; --upoly:#3f6fa0; --ured:#d24b3f; --ugood:#2e8b4f; --udanger:#c0392b; font-family: var(--font-sans); color: var(--utext); }
.ui, .ui * { box-sizing: border-box; }
.ui-shot { position:relative; width:100%; background:var(--ubg); border:1px solid var(--uline2); border-radius:10px; overflow:hidden; }
.ui-app { display:grid; grid-template-columns:132px 1fr; min-height:440px; }
.ui-topbar { grid-column:1/-1; display:flex; align-items:center; gap:10px; height:38px; padding:0 12px; border-bottom:1px solid var(--uline); background:var(--uchrome); }
.ui-topbar .ui-wm { display:flex; align-items:center; gap:7px; }
.ui-topbar .ui-wm b { color:var(--uyellow); font-weight:800; font-size:15px; letter-spacing:-.02em; }
.ui-topbar .ui-wm span { font-size:9px; color:var(--umut); }
.ui-topbar .ui-tb-right { margin-left:auto; display:flex; gap:12px; color:var(--umut); }
.ui-topbar .ui-tb-right svg { width:14px; height:14px; }
.ui-nav { min-width:0; border-right:1px solid var(--uline); padding:10px 0; background:var(--uchrome); font-size:11px; }
.ui-nav a { display:flex; align-items:center; gap:9px; padding:7px 12px; color:var(--utext); text-decoration:none; }
.ui-nav a svg { width:14px; height:14px; stroke:var(--umut); fill:none; stroke-width:1.6; flex:none; }
.ui-nav a.active { color:var(--uink); font-weight:600; }
.ui-mainarea { position:relative; min-width:0; }
.ui-crumb { display:flex; align-items:center; gap:6px; height:26px; padding:0 12px; font-size:11px; color:var(--umut); border-bottom:1px solid var(--uline); }
.ui-crumb b { color:var(--uink); font-weight:600; }
.ui-searchbar { position:relative; display:flex; align-items:center; gap:8px; height:30px; margin:8px 10px; padding:0 10px; border:1px solid var(--uline2); border-radius:4px; background:#fff; font-size:10.5px; color:var(--umut); }
.ui-searchbar svg { width:12px; height:12px; stroke:var(--umut); fill:none; stroke-width:1.8; }
.ui-searchbar .ui-sb-txt { overflow:hidden; white-space:nowrap; text-overflow:ellipsis; flex:1; }
.ui-map { position:relative; margin:0 10px 10px; border-radius:4px; overflow:hidden; background:var(--usea); }
.ui-map svg { display:block; width:100%; height:100%; }
.ui-mapimg { display:block; width:100%; max-width:100%; height:auto; }
.ui-zoom { position:absolute; top:10px; left:10px; display:flex; flex-direction:column; background:#fff; border:1px solid var(--uline2); border-radius:4px; overflow:hidden; }
.ui-zoom span { width:22px; height:20px; display:grid; place-items:center; font-size:14px; color:var(--utext); }
.ui-zoom span:first-child { border-bottom:1px solid var(--uline); }
.ui-ctrlbtn { position:absolute; left:10px; width:26px; height:26px; background:#fff; border:1px solid var(--uline2); border-radius:50%; display:grid; place-items:center; box-shadow:0 1px 2px rgba(0,0,0,.12); }
.ui-ctrlbtn svg { width:13px; height:13px; stroke:var(--utext); fill:none; stroke-width:1.7; }
.ui-legendbtn { position:absolute; bottom:10px; left:10px; background:#fff; border:1px solid var(--uline2); border-radius:4px; padding:5px 9px; font-size:10px; color:var(--utext); box-shadow:0 1px 2px rgba(0,0,0,.12); }
.mk { position:absolute; transform:translate(-50%,-100%); }
.mk-cluster { transform:translate(-50%,-50%); width:24px; height:24px; border-radius:50%; background:var(--ucluster); border:2px solid #fff; box-shadow:0 1px 3px rgba(0,0,0,.3); display:grid; place-items:center; color:#fff; font-weight:700; font-size:11px; }
.mk-zaak .b { width:26px; height:22px; border-radius:5px; background:var(--uzaak); display:grid; place-items:center; box-shadow:0 1px 3px rgba(0,0,0,.3); }
.mk-zaak .b svg { width:13px; height:13px; stroke:#fff; fill:none; stroke-width:1.7; }
.mk-zaak .p { width:8px; height:8px; background:var(--uzaak); transform:rotate(45deg); margin:-5px auto 0; }
.mk-search .b { width:26px; height:22px; border-radius:5px; background:var(--upin); display:grid; place-items:center; box-shadow:0 1px 3px rgba(0,0,0,.3); }
.mk-search .b svg { width:12px; height:12px; stroke:#fff; fill:none; stroke-width:2; }
.mk-search .p { width:8px; height:8px; background:var(--upin); transform:rotate(45deg); margin:-5px auto 0; }
.ui-callout { position:absolute; width:22px; height:22px; border-radius:50%; background:var(--uyellow); border:2px solid #fff; color:#2a2722; font-family:var(--font-mono); font-weight:700; font-size:11px; display:grid; place-items:center; box-shadow:0 1px 4px rgba(0,0,0,.3); z-index:5; }
.ui-panel { width:100%; max-width:360px; background:#fff; border:1px solid var(--uline2); border-radius:8px; overflow:hidden; font-size:12px; color:var(--utext); }
.ui-ph { display:flex; align-items:center; justify-content:space-between; padding:11px 14px; border-bottom:3px solid var(--uline); }
.ui-ph h4 { margin:0; font-size:15px; font-weight:700; color:var(--uink); }
.ui-ph .x { color:var(--umut); font-size:16px; line-height:1; }
.ui-pb { padding:12px 14px; }
.ui-sec-label { font-size:10.5px; color:var(--umut); margin:2px 0 6px; }
.ui-hr { height:1px; background:var(--uline); margin:12px 0; border:0; }
.ui-check { display:flex; align-items:center; gap:9px; padding:6px 8px; border-radius:4px; }
.ui-check .box { width:15px; height:15px; border-radius:3px; border:1px solid var(--uline2); flex:none; display:grid; place-items:center; }
.ui-check .box.on { background:var(--uyellow); border-color:var(--uyellow); }
.ui-check .box.on svg { width:10px; height:10px; stroke:#fff; fill:none; stroke-width:2.4; }
.ui-check.hl { background:#fbfae8; }
.ui-layer { display:flex; align-items:center; gap:9px; padding:8px 4px; border-bottom:1px solid #f0f0ee; }
.ui-layer .box { width:15px; height:15px; border-radius:3px; border:1px solid var(--uline2); flex:none; display:grid; place-items:center; }
.ui-layer .box.on { background:var(--uyellow); border-color:var(--uyellow); }
.ui-layer .box.on svg { width:10px; height:10px; stroke:#fff; fill:none; stroke-width:2.4; }
.ui-layer .nm { flex:1; }
.ui-layer .badge { font-size:9px; color:var(--ugood); border:1px solid rgba(46,139,79,.4); border-radius:9px; padding:1px 7px; }
.ui-layer .drag { color:var(--umut); letter-spacing:-2px; }
.ui-layer .chev { color:var(--umut); font-size:10px; }
.ui-slider { padding:8px 10px 10px 26px; }
.ui-slider .row { display:flex; align-items:center; gap:10px; }
.ui-slider .lbl { font-size:11px; color:var(--utext); }
.ui-slider .track { flex:1; height:4px; border-radius:2px; background:var(--uyellow); position:relative; }
.ui-slider .track .knob { position:absolute; right:-2px; top:50%; transform:translateY(-50%); width:12px; height:12px; border-radius:50%; background:var(--uyellow); border:2px solid #fff; box-shadow:0 1px 2px rgba(0,0,0,.3); }
.ui-slider .pct { font-size:10px; color:var(--ugold); font-family:var(--font-mono); }
.ui-field { margin:10px 0; }
.ui-field .fl { font-size:10.5px; color:var(--utext); margin-bottom:4px; }
.ui-input { height:28px; border:1px solid var(--uline2); border-radius:4px; display:flex; align-items:center; padding:0 9px; font-size:10.5px; color:var(--umut); background:#fff; gap:6px; }
.ui-input .car { margin-left:auto; color:var(--umut); font-size:9px; }
.ui-input.plus { width:28px; justify-content:center; margin-left:6px; }
.ui-row2 { display:flex; align-items:center; gap:8px; }
.ui-row2 .k { font-size:10.5px; color:var(--umut); }
.ui-radio { display:inline-flex; align-items:center; gap:6px; margin-right:16px; font-size:11px; }
.ui-radio .rr { width:13px; height:13px; border-radius:50%; border:1px solid var(--uline2); display:grid; place-items:center; }
.ui-radio .rr.on::after { content:""; width:6px; height:6px; border-radius:50%; background:var(--uyellow); }
.ui-btns { display:flex; gap:9px; margin-bottom:12px; }
.ui-btn { flex:1; text-align:center; padding:7px 0; border-radius:5px; font-weight:600; font-size:12px; background:#fff; }
.ui-btn.reset { border:1px solid var(--udanger); color:var(--udanger); }
.ui-btn.apply { border:1px solid var(--ugood); color:var(--ugood); }
.ui-btn.ghost { border:1px solid var(--uline2); color:var(--utext); font-weight:500; }
.ui-coords { display:flex; gap:10px; align-items:flex-start; margin:6px 0 12px; }
.ui-coords .cross svg { width:22px; height:22px; stroke:var(--utext); fill:none; stroke-width:1.6; }
.ui-coords .grid { display:grid; grid-template-columns:auto auto auto; gap:2px 16px; font-size:10.5px; }
.ui-coords .sys { color:var(--ugold); font-weight:600; }
.ui-list-title { font-size:12px; font-weight:700; color:var(--uink); border-bottom:3px solid var(--uline); padding-bottom:4px; margin:10px 0 8px; }
.ui-toolbar { display:inline-flex; gap:6px; padding:7px; background:#fff; border:1px solid var(--uline2); border-radius:8px; box-shadow:0 1px 3px rgba(0,0,0,.12); }
.ui-tool { width:34px; height:28px; border-radius:5px; border:1px solid var(--uline2); background:#fff; display:grid; place-items:center; }
.ui-tool.active { background:var(--uyellow); border-color:var(--uyellow); }
.ui-tool svg { width:15px; height:15px; stroke:var(--utext); fill:none; stroke-width:1.7; }
.ui-tool.del svg { stroke:var(--udanger); }

/* Mock UI narrows with the page; the left rail goes first, then disappears. */
@media (max-width: 56rem) { .ui-app { grid-template-columns:104px 1fr; } }
@media (max-width: 34rem) { .ui-app { grid-template-columns:0 1fr; } .ui-nav { display:none; } }

/* Print: a collapsed FAQ answer must still be on the page. Two mechanisms,
   because engines hide it two different ways — older ones via display:none on
   the non-summary children, Chrome 131+ via the ::details-content pseudo. Both
   are harmless where unsupported. */
@media print {
  details.faq { break-inside: avoid; }
  details.faq > :not(summary) { display: block !important; }
  details.faq::details-content { content-visibility: visible !important; block-size: auto !important; }
  details.faq summary::after { display: none; }
  .ui-shot, .figure--frame { break-inside: avoid; }
}

/* ---- Utilities --------------------------------------------------------- */
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.muted { color: var(--text-muted); }

/* ---- Optional enhancements (see references/interactions.md) ------------- */
.code-wrap { position: relative; }
.code-wrap .copy-btn { position: absolute; top: var(--space-2); right: var(--space-2); padding: .2em .55em; font: inherit; font-size: .74rem; cursor: pointer; color: var(--text-muted); background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); opacity: 0; transition: opacity .12s; }
.code-wrap:hover .copy-btn, .code-wrap:focus-within .copy-btn { opacity: 1; }
.permalink { margin-left: .35em; color: var(--text-muted); text-decoration: none; opacity: 0; transition: opacity .12s; font-weight: 400; }
h1:hover .permalink, h2:hover .permalink, h3:hover .permalink, .permalink:focus { opacity: 1; }
.doc-filter { width: 100%; padding: .5em .8em; margin: 0 0 var(--space-4); font: inherit; color: var(--text); background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius); }
.doc-filter:focus { outline: 2px solid var(--link); outline-offset: 1px; }
.filter-hide { display: none !important; }
/* Base .search-results is in-flow (pager sidebar); .doc-toolbar's copy floats
   under the mandatory search box instead — see references/interactions.md. */
.search-results { list-style: none; margin: 0 0 var(--space-4); padding: 0; max-width: none; }
.search-results a { display: block; padding: var(--space-2) var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
.search-results a:hover { border-color: var(--brand); text-decoration: none; }
.sr-title { display: block; font-weight: 600; font-size: .9rem; }
.sr-snip { display: block; color: var(--text-muted); font-size: .82rem; margin-top: .15em; }
.sr-empty { padding: var(--space-2) var(--space-3); color: var(--text-muted); font-size: .9rem; }
.doc-toolbar .search-results {
  position: absolute; top: calc(100% + 8px); left: 0; width: 100%; z-index: 5;
  max-height: 320px; overflow-y: auto; margin: 0; padding: var(--space-2);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow);
}
.doc-toolbar .search-results li + li { margin-top: 2px; }
.doc-toolbar .search-results a { border: 0; border-radius: var(--radius-sm); }
mark { background: var(--brand); color: var(--brand-contrast); padding: 0 .12em; border-radius: 2px; }

/* ============================================================================
   APP-SHELL — docs-site mode (the mozard-docs hierarchy)
   Opt in with <body class="docs-site">. A persistent doc-tree sidebar (.site-nav)
   on the left, a measure-capped content column (.sheet) in the middle, and the
   on-page TOC (nav.chapters) moved to the RIGHT. The whole assembly is centered and
   width-capped so wide monitors gain navigation, not empty margin. A standalone
   single-file doc OMITS the class and keeps the centered-card layout above, intact.
   ============================================================================ */

/* Persistent documentation tree — chrome, so it lives OUTSIDE <main data-doc> and
   the merged-pager extractor ignores it. Injected per page by build_sidenav.py. */
.site-nav { font-size: 13.5px; }
.site-nav .home { display: block; font-weight: 800; color: var(--heading); padding: 4px 10px 12px; letter-spacing: -.01em; }
.site-nav .home:hover { color: var(--link); text-decoration: none; }
.site-nav .home .kicker { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 2px; }
.site-nav ul { list-style: none; margin: 0; padding: 0; max-width: none; }
.site-nav li { margin: 0; }
.site-nav a { display: block; padding: 6px 10px; border-radius: var(--radius-sm); color: var(--text-muted); line-height: 1.35; }
.site-nav a:hover { color: var(--heading); background: var(--bg-alt); text-decoration: none; }
.site-nav a[aria-current="page"] { color: var(--heading); background: var(--bg-alt); font-weight: 700; box-shadow: inset 2px 0 0 var(--brand); }
.site-nav ul ul { margin: 1px 0 5px; padding-left: 10px; border-left: 1px solid var(--border); }
.site-nav ul ul a { font-size: 12.5px; padding: 5px 10px; color: var(--text-faint); }

/* Full-bleed toolbar, content centered to the wider assembly (applies at all widths). */
body.docs-site .doc-toolbar { padding: 10px max(var(--space-5), calc((100% - var(--assembly-w)) / 2)); }

/* .shell dissolves so its children (.sheet, nav.chapters) place directly in the
   .wrap layout — one flat [nav | content | toc] set on desktop, a single
   reorderable column on mobile. */
body.docs-site .shell { display: contents; }
body.docs-site .sheet { max-width: var(--content-w); }

/* ---- Mobile / narrow: content first, then on-page TOC, then the tree ------ */
@media (max-width: 63.999rem) {
  body.docs-site .wrap:has(.site-nav) { display: flex; flex-direction: column; padding-top: var(--space-4); padding-bottom: var(--space-7); }
  body.docs-site .sheet       { order: 1; }
  body.docs-site nav.chapters { order: 2; }
  body.docs-site .site-nav    { order: 3; }
  body.docs-site .site-nav, body.docs-site nav.chapters { position: static; max-height: none; overflow: visible; margin-top: var(--space-5); }
  body.docs-site .site-nav { background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 12px 10px; box-shadow: var(--shadow-rail); }
}

/* ---- Desktop: three-pane grid; assembly centered + width-capped ----------- */
@media (min-width: 64rem) {
  body.docs-site .doc-toolbar { gap: var(--shell-gap); }
  body.docs-site .toolbar-logo { flex: 0 0 var(--sidebar-w); }
  body.docs-site .doc-toolbar .search-wrap { flex: 0 1 var(--content-w); }
  body.docs-site .doc-toolbar-right { flex: none; }

  body.docs-site .wrap:has(.site-nav) {
    max-width: none; margin: 0;
    padding-inline: max(var(--space-5), calc((100% - var(--assembly-w)) / 2));
    padding-top: var(--space-5); padding-bottom: var(--space-8);
    display: grid; column-gap: var(--shell-gap); align-items: start;
    grid-template-columns: var(--sidebar-w) minmax(0, 1fr) var(--toc-w);
  }
  /* All three panes sit in row 1 — without an explicit row, non-dense auto-flow
     places the DOM-later .sheet on row 2 (a tall empty gap) once nav.chapters
     has taken col 3 on row 1. */
  body.docs-site .site-nav {
    grid-column: 1; grid-row: 1; position: sticky; top: 70px; align-self: start;
    max-height: calc(100vh - 92px); overflow-y: auto;
    background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius);
    padding: 12px 8px; box-shadow: var(--shadow-rail);
  }
  body.docs-site .sheet       { grid-column: 2; grid-row: 1; justify-self: start; }
  body.docs-site nav.chapters { grid-column: 3; grid-row: 1; }

  /* Stub pages (no on-page TOC): two panes; content still capped and left-aligned. */
  body.docs-site .wrap:has(.site-nav):not(:has(nav.chapters)) {
    grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  }

  /* One right edge: prose fills the measure-capped column rather than stopping
     short of the cards / tables / diagrams beside it (fixes the ragged edge — Q6). */
  body.docs-site .sheet :is(p, ul, ol, dl, .lede, .plain, .note) { max-width: none; }
}

/* ---- Motion / print ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } * { animation: none !important; transition: none !important; } }
@media print {
  .doc-toolbar, nav.chapters, .site-nav, .pager, .copy-btn, .doc-filter, .topics { display: none !important; }
  .topic { display: block !important; }
  .shell { grid-template-columns: 1fr; }
  body.docs-site .wrap:has(.site-nav) { display: block; padding: 0; }
  .sheet { border: 0; padding: 0; max-width: none; }
  body { background: #fff; color: #000; font-size: 11pt; }
  a { color: #000; text-decoration: underline; }
  .diagram, pre, .table-wrap { break-inside: avoid; }
}
