/* llmwiki — god-level docs style */
:root {
  --bg: #ffffff;
  --bg-alt: #f8fafc;
  --bg-card: #ffffff;
  --bg-code: #edf0f5;                      /* v1.0 #119: slightly darker for better contrast */
  --text: #0f172a;
  --text-secondary: #475569;
  --text-muted: #6b7280;                   /* WCAG AA: 4.84:1 on white, 4.63:1 on --bg-alt */
  --border: #d1d5db;                       /* v1.0 #119: stronger card borders (was #e2e8f0) */
  --border-subtle: #e2e8f0;                /* for less prominent separators */
  --accent: #7C3AED;
  --accent-light: #a78bfa;
  --accent-bg: #f5f3ff;
  --radius: 8px;
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', 'SF Mono', 'Fira Code', monospace;
  --shadow: 0 10px 25px -5px rgba(15, 23, 42, 0.1), 0 8px 10px -6px rgba(15, 23, 42, 0.04);
  --shadow-card: 0 1px 3px rgba(15, 23, 42, 0.08), 0 1px 2px rgba(15, 23, 42, 0.04);  /* v1.0 #119: card shadow */
  --shadow-card-hover: 0 4px 12px rgba(15, 23, 42, 0.12), 0 2px 4px rgba(15, 23, 42, 0.06);
  --section-y: 16px 0 24px;
  --block-gap: 16px;
  /* Vertical rhythm of the page masthead, in one place so every page
     family (hero, hero-sm, project hero) scales from the same tokens.
     The hero is a title + one subtitle line; it does not need to cost
     ~150px of chrome before the first row of real content. */
  --hero-y: 28px 0 22px;
  --hero-y-sm: 20px 0 16px;
  --hero-gap: 0px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0c0a1d;
    --bg-alt: #110f26;
    --bg-card: #16142d;
    --bg-code: #1a1836;
    --text: #e2e8f0;
    --text-secondary: #94a3b8;
    --text-muted: #8b9bb5;  /* WCAG AA: 6.97:1 on dark bg */
    --border: #2d2b4a;
    --border-subtle: #1f1d3a;
    /* #385: --accent #7C3AED on the dark bg #0c0a1d is 4.63:1 — axe
       flags it as borderline. The lighter shade #a78bfa is 8.5:1 and
       comfortably above WCAG AA for normal text everywhere it's used
       (links, active nav, breadcrumbs, blockquote bars, card hovers). */
    --accent: #a78bfa;
    --accent-light: #c4b5fd;
    --accent-bg: #1e1a3a;
    --shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.3);
    --shadow-card: 0 2px 6px rgba(0, 0, 0, 0.35);
    --shadow-card-hover: 0 6px 16px rgba(0, 0, 0, 0.45);
  }
}
:root[data-theme="dark"] {
  --bg: #0c0a1d;
  --bg-alt: #110f26;
  --bg-card: #16142d;
  --bg-code: #1a1836;
  --text: #e2e8f0;
  --text-secondary: #94a3b8;
  --text-muted: #8b9bb5;
  --border: #2d2b4a;
  --border-subtle: #1f1d3a;
  --accent: #a78bfa;        /* #385: bump for AA contrast on dark bg */
  --accent-light: #c4b5fd;  /* one step lighter for hover states */
  --accent-bg: #1e1a3a;
  --shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.3);
  --shadow-card: 0 2px 6px rgba(0, 0, 0, 0.35);
  --shadow-card-hover: 0 6px 16px rgba(0, 0, 0, 0.45);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }
body { font-family: var(--font); background: var(--bg); color: var(--text); line-height: 1.7; -webkit-font-smoothing: antialiased; overflow-wrap: break-word; word-wrap: break-word; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
/* Skip-to-content link — visible only on keyboard focus */
.skip-link { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; z-index: 999; padding: 8px 16px; background: var(--accent); color: #fff; font-weight: 600; font-size: 0.9rem; border-radius: 0 0 6px 0; text-decoration: none; }
/* #ui-h1 (#565): explicit focus styles. Reset overflow + width on focus
   so the link's content actually paints, and add a visible outline so
   the keyboard-focus ring isn't ambiguous against the accent bg. */
.skip-link:focus,
.skip-link:focus-visible { position: fixed; top: 0; left: 0; width: auto; height: auto; overflow: visible; outline: 3px solid #fff; outline-offset: 0; box-shadow: 0 0 0 6px var(--accent); }
.container { max-width: 1080px; margin: 0 auto; padding: 0 24px; }
.muted { color: var(--text-muted); }
kbd { display: inline-block; padding: 2px 6px; font-family: var(--mono); font-size: 0.72rem; color: var(--text-secondary); background: var(--bg-code); border: 1px solid var(--border); border-radius: 4px; line-height: 1; }

/* Reading progress bar */
/* Decorative only — never let the strip eat clicks (or the start of a
   mouse gesture) aimed at the nav underneath it. */
.progress-bar { position: fixed; top: 0; left: 0; height: 3px; width: 0%; background: var(--accent); z-index: 200; pointer-events: none; transition: width 0.1s; }

/* Nav */
/* v1.0 #119: add a subtle shadow + stronger blur so the nav stays grounded on light backgrounds */
.nav { position: sticky; top: 0; z-index: 100; background: var(--bg); border-bottom: 1px solid var(--border); box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); }
.nav-inner { max-width: 1080px; margin: 0 auto; padding: 0 24px; height: 56px; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.nav-brand { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 0.95rem; color: var(--text); text-decoration: none; flex-shrink: 0; }
.nav-brand:hover { text-decoration: none; }
.nav-links { display: flex; align-items: center; gap: 16px; }
.nav-links a { color: var(--text-secondary); font-size: 0.86rem; font-weight: 500; text-decoration: none; }
.nav-links a:hover { color: var(--text); text-decoration: none; }
/* #385 S3: --accent is already bumped to #a78bfa in dark mode so the active
   nav has 8.5:1 contrast there. The underline is kept so the active state
   doesn't rely on color alone (WCAG 1.4.1 "Use of Color"). */
.nav-links a.active { color: var(--accent); text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 2px; }

.nav-search-btn { display: flex; align-items: center; gap: 8px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; font-family: var(--font); color: var(--text-secondary); cursor: pointer; font-size: 0.82rem; transition: all 0.15s; }
.nav-search-btn:hover { border-color: var(--accent); color: var(--accent); }
.nav-search-btn svg { flex-shrink: 0; }
@media (max-width: 767px) { .nav-search-btn span, .nav-search-btn kbd { display: none; } }
/* Tablet + mobile: the desktop text anchors (Home/Raw/Candidates/Graph/Projects/Sessions/Analytics/Docs)
   overflow a 768px viewport at 0.9rem/gap-20, so collapse them below the
   1024 desktop breakpoint. Users still have Search + Theme in the top nav,
   the command palette via Cmd+K, and the mobile bottom nav below 767. */
@media (max-width: 1023px) { .nav-links > a { display: none; } }

/* #ui-m3 (#573): bump touch target from 36×36 to 44×44 (Apple HIG +
   WCAG 2.5.5 minimum). Visual icon stays the same; padding grows. */
.theme-toggle { background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--text-secondary); transition: all 0.2s; padding: 0; flex-shrink: 0; }
.theme-toggle:hover { border-color: var(--accent); color: var(--accent); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-sun { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .icon-moon { display: none; }
}

/* Hero */
.hero { padding: var(--hero-y); margin-bottom: var(--hero-gap); background: var(--bg-alt); border-bottom: 1px solid var(--border); }
.hero-sm { padding: var(--hero-y-sm); margin-bottom: var(--hero-gap); }
.hero h1 { font-size: 2rem; font-weight: 700; letter-spacing: -0.02em; color: var(--text); margin-bottom: 8px; overflow-wrap: break-word; }
.hero .hero-sub { color: var(--text-secondary); font-size: 0.9rem; line-height: 1.6; overflow-wrap: break-word; }
.hero .hero-sub code { font-family: var(--mono); background: var(--bg-card); padding: 1px 6px; border-radius: 4px; font-size: 0.82rem; border: 1px solid var(--border); }
.hero .hero-sub a { color: var(--accent); font-weight: 500; }

/* Breadcrumbs */
.breadcrumbs { font-size: 0.82rem; color: var(--text-muted); margin-bottom: 16px; }
.breadcrumbs a { color: var(--text-secondary); text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 2px; text-decoration-color: var(--border); }
.breadcrumbs a:hover { color: var(--accent); text-decoration: underline; }
.breadcrumbs .crumb-sep { margin: 0 6px; color: var(--text-muted); }
.breadcrumbs [aria-current="page"] { color: var(--text); font-weight: 500; }

/* Section */
.section { padding: var(--section-y); }
.section h2 { font-size: 1.5rem; font-weight: 700; margin: 24px 0 16px; color: var(--text); }
.section h3 { font-size: 1.15rem; font-weight: 600; margin: 20px 0 10px; color: var(--text); }
/* #27: the Analytics page stacks several stat sections; tighten the vertical
   rhythm so they read as one dashboard rather than distant blocks. */
.analytics-page { --section-y: 12px 0; }
.analytics-page .section h2 { margin-top: 8px; }

.meta-tools { font-size: 0.82rem; margin-bottom: 12px; overflow-wrap: break-word; }

/* Actions strip */
.session-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; margin-bottom: 24px; padding-bottom: 16px; border-bottom: 1px solid var(--border); }

/* #36: copyable `cd … && claude --resume …` one-liner on session pages */
.resume-command {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  margin: -8px 0 24px; padding: 10px 12px;
  background: var(--bg-alt);
  border: 1px solid var(--border); border-radius: 8px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
}
/* Explicit fg/bg so we beat `.content code` (--bg-code) and keep WCAG AA. */
.content .resume-command .resume-cmd-text,
.resume-command .resume-cmd-text {
  flex: 1 1 240px; font-size: 0.82rem; word-break: break-all;
  background: var(--bg-alt); border: 0; padding: 0; color: var(--text);
}
.resume-command .resume-copy-btn { flex: 0 0 auto; }
.resume-command .resume-hint { flex: 1 1 100%; font-size: 0.75rem; font-family: Inter, system-ui, sans-serif; }
/* Stale: mute with color, not opacity — axe treats opacity-diluted
   text as a color-contrast failure even when the base pair is AA. */
.resume-command.resume-stale .resume-cmd-text {
  color: var(--text-muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.resume-command.resume-stale .resume-hint { color: var(--text-muted); }

.project-disk-path { font-size: 0.9rem; margin: 0 0 8px; }
.project-disk-path code, .card-path code, .card-title code {
  font-size: 0.85em; word-break: break-all;
}
.card-path { font-size: 0.78rem; margin-top: 4px; line-height: 1.35; }
.hero h1 { overflow-wrap: anywhere; word-break: break-word; }
.session-id { word-break: break-all; }

/* #36 follow-up: project pages stack many thin strips (topics, disk
   paths, heatmap, charts, sessions) — tighten via --section-y once. */
.project-page { --section-y: 8px 0 12px; }
.project-page > .hero { --hero-y: 20px 0 14px; }
.project-page .section h2 { margin: 12px 0 10px; }
.project-page .project-topics-section { padding-top: 4px; padding-bottom: 4px; }
.project-page .project-topics-section .container { padding-top: 4px; padding-bottom: 0; }
.project-page .project-disk-section { padding-top: 0; padding-bottom: 4px; }
.project-page .sub-section { margin-top: 16px; }
.project-page .breadcrumbs { margin-bottom: 8px; }
.btn { display: inline-flex; align-items: center; padding: 6px 14px; font-size: 0.82rem; font-weight: 500; background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; color: var(--text-secondary); cursor: pointer; text-decoration: none; transition: all 0.15s; font-family: var(--font); }
.btn:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.btn-primary { background: var(--accent); color: #ffffff; border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-light); border-color: var(--accent-light); color: #ffffff; }
.btn.copied { background: var(--accent-bg); color: var(--accent); border-color: var(--accent); }

/* Code copy button */
.code-wrap { position: relative; }
/* #ui-m4 (#574) + axe color-contrast follow-up: copy-code-btn was
   opacity: 0 by default; touch + keyboard users couldn't see it. The
   first fix used opacity: 0.6 by default but axe flagged the resulting
   blend (text color × 0.6 over page bg) as 4.5:1 borderline-failing.
   Switched to full opacity always-visible — no hover/focus state to
   reveal — and de-emphasised the button via lower-contrast neutral
   border + muted text instead of opacity. WCAG-clean. #ui-m3 (#573):
   padding bumped so the hit area lands at the 44×44 minimum. */
.copy-code-btn { position: absolute; top: 8px; right: 8px; padding: 8px 12px; min-width: 44px; min-height: 44px; font-size: 0.72rem; font-weight: 500; background: var(--bg); border: 1px solid var(--border); border-radius: 4px; color: var(--text); cursor: pointer; font-family: var(--font); transition: border-color 0.15s, color 0.15s; z-index: 2; }
.copy-code-btn:hover, .copy-code-btn:focus-visible { border-color: var(--accent); color: var(--accent); }
.copy-code-btn.copied { background: var(--accent-bg); color: var(--accent); border-color: var(--accent); }

/* Content */
.content { color: var(--text); font-size: 0.95rem; max-width: 100%; overflow-wrap: break-word; word-wrap: break-word; min-width: 0; }
.content h1, .content h2, .content h3, .content h4 { margin: 28px 0 12px; font-weight: 600; color: var(--text); scroll-margin-top: 72px; overflow-wrap: break-word; }
.content h1 { font-size: 1.6rem; }
.content h2 { font-size: 1.3rem; border-bottom: 1px solid var(--border); padding-bottom: 6px; margin-top: 36px; }
.content h3 { font-size: 1.08rem; color: var(--accent); }
.content h4 { font-size: 0.98rem; color: var(--text-secondary); }
.content p { margin: 12px 0; color: var(--text); overflow-wrap: break-word; }
.content ul, .content ol { margin: 12px 0 12px 24px; }
.content li { margin: 4px 0; overflow-wrap: break-word; word-wrap: break-word; }
.content li code { word-break: break-all; }
.content code { font-family: var(--mono); background: var(--bg-code); padding: 2px 6px; border-radius: 4px; font-size: 0.82em; word-break: break-word; overflow-wrap: anywhere; }
.content pre { background: var(--bg-code); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; overflow-x: auto; overflow-y: hidden; margin: 16px 0; font-size: 0.82rem; line-height: 1.5; max-width: 100%; white-space: pre; }
.content pre code { background: none; padding: 0; font-size: inherit; word-break: normal; white-space: pre; overflow-wrap: normal; }
.content blockquote { border-left: 3px solid var(--accent); padding: 8px 16px; color: var(--text-secondary); background: var(--accent-bg); margin: 16px 0; border-radius: 0 var(--radius) var(--radius) 0; }
.content table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 0.88rem; display: block; overflow-x: auto; }
.content th, .content td { border: 1px solid var(--border); padding: 8px 12px; text-align: left; overflow-wrap: break-word; }
.content th { background: var(--bg-alt); font-weight: 600; }
.content tr:nth-child(even) { background: var(--bg-alt); }
.content strong { font-weight: 600; }
.content hr { border: none; border-top: 1px solid var(--border); margin: 32px 0; }
.content .headerlink { opacity: 0; margin-left: 8px; color: var(--text-muted); font-weight: 400; text-decoration: none; }
.content h1:hover .headerlink, .content h2:hover .headerlink, .content h3:hover .headerlink, .content h4:hover .headerlink { opacity: 1; }

/* v0.5: highlight.js owns token colours (see hljs-light / hljs-dark <link>
   tags in page_head). We only style the code block container so it matches
   the rest of the wiki's visual language. */
.article pre,
.article pre code.hljs {
  background: var(--bg-code);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin: 16px 0;
  overflow-x: auto;
}
.article pre code.hljs { padding: 14px 16px; display: block; }
.article pre { padding: 0; }
.article :not(pre) > code.hljs { background: transparent; padding: 0; }
/* a11y (#385 S2): the GitHub hljs theme uses several token colors that fail
   WCAG AA 4.5:1 contrast against our --bg-code background:
     hljs-keyword     #d73a49 → 4.17:1 (light) → #c23a40 (4.82:1)
     hljs-built_in    #005cc5 → 4.34:1 (light) → #0050a8 (4.78:1)
     hljs-number      #005cc5 → 4.34:1 (light) → #0050a8 (4.78:1)
     hljs-literal     #005cc5 → 4.34:1 (light) → #0050a8 (4.78:1)
     hljs-title       #6f42c1 → 4.40:1 (light) → #5c34a3 (4.65:1)
     hljs-attr        #005cc5 → 4.34:1 (light) → #0050a8 (4.78:1)
     hljs-symbol      #e36209 → 4.05:1 (light) → #c8530a (4.51:1)
   Dark-theme tokens stay on the hljs-dark stylesheet which already passes. */
:root:not([data-theme="dark"]) .hljs-keyword,
:root:not([data-theme="dark"]) .hljs-type { color: #c23a40; }
:root:not([data-theme="dark"]) .hljs-built_in,
:root:not([data-theme="dark"]) .hljs-number,
:root:not([data-theme="dark"]) .hljs-literal,
:root:not([data-theme="dark"]) .hljs-attr { color: #0050a8; }
:root:not([data-theme="dark"]) .hljs-title,
:root:not([data-theme="dark"]) .hljs-title.function_,
:root:not([data-theme="dark"]) .hljs-class .hljs-title { color: #5c34a3; }
:root:not([data-theme="dark"]) .hljs-symbol,
:root:not([data-theme="dark"]) .hljs-bullet { color: #c8530a; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hljs-keyword,
  :root:not([data-theme="light"]) .hljs-type,
  :root:not([data-theme="light"]) .hljs-built_in,
  :root:not([data-theme="light"]) .hljs-number,
  :root:not([data-theme="light"]) .hljs-literal,
  :root:not([data-theme="light"]) .hljs-attr,
  :root:not([data-theme="light"]) .hljs-title,
  :root:not([data-theme="light"]) .hljs-symbol,
  :root:not([data-theme="light"]) .hljs-bullet { color: unset; }
}

/* Cards */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; margin: 16px 0; }
.card { display: block; padding: 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); text-decoration: none; color: var(--text); transition: all 0.15s; box-shadow: var(--shadow-card); }
.card:hover { border-color: var(--accent); text-decoration: none; transform: translateY(-1px); box-shadow: var(--shadow-card-hover); }
.card-title { font-weight: 600; font-size: 0.95rem; margin-bottom: 4px; color: var(--text); }
.card-meta { font-size: 0.82rem; color: var(--text-secondary); }
/* #455: small muted activity date range under the meta line. */
.card-date-range { font-size: 0.72rem; color: var(--text-muted); margin-top: 2px; font-variant-numeric: tabular-nums; }
/* #471: human-readable session description rendered as a subtitle on
   session detail pages and as a small line beneath the slug in the
   sessions index table. */
.session-description { font-size: 0.95rem; color: var(--text-secondary); margin: -8px 0 16px; line-height: 1.5; }
.session-cell-desc { font-size: 0.78rem; color: var(--text-muted); margin-top: 2px; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* #476: richer tool-result collapsible card. Renders as
   `[badge] preview · N lines · X chars` so the user knows what's
   inside without expanding. The badge tints by outcome. */
.collapsible-result { margin: 12px 0; border: 1px solid var(--border); border-radius: 6px; padding: 0; background: var(--bg-card); }
.collapsible-result > summary { padding: 8px 12px; cursor: pointer; list-style: none; font-size: 0.85rem; line-height: 1.5; }
.collapsible-result > summary::-webkit-details-marker { display: none; }
.collapsible-result > summary:hover { background: var(--bg-alt); }
.collapsible-result[open] > summary { border-bottom: 1px solid var(--border); }
.collapsible-result > *:not(summary) { padding: 8px 12px; }
.tool-result-badge { display: inline-block; font-size: 0.7rem; font-weight: 600; padding: 1px 6px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.04em; }
.tool-result-ok    { background: rgba(5,150,105,0.12); color: #047857; }
.tool-result-error { background: rgba(220,38,38,0.12); color: #991B1B; }
:root[data-theme="dark"] .tool-result-ok    { background: rgba(52,211,153,0.18); color: #34D399; }
:root[data-theme="dark"] .tool-result-error { background: rgba(248,113,113,0.18); color: #F87171; }
.tool-result-preview { color: var(--text); font-family: var(--mono); font-size: 0.82rem; }
.tool-result-meta    { font-size: 0.78rem; }
.collapsible-result.outcome-error { border-color: rgba(220,38,38,0.4); }
.card-stats { font-size: 0.78rem; margin-top: 6px; }
.card-badge { margin-top: 8px; }

/* Content-freshness badge (#57) */
.freshness {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 10px; border-radius: 999px;
  font-size: 0.72rem; font-weight: 600; white-space: nowrap;
  border: 1px solid;
}
.freshness::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
}
.fresh-green   { color: #15803d; background: #dcfce7; border-color: #86efac; }
.fresh-yellow  { color: #92400e; background: #fef3c7; border-color: #fcd34d; }
.fresh-red     { color: #b91c1c; background: #fee2e2; border-color: #fca5a5; }
.fresh-unknown { color: #6b7280; background: #f3f4f6; border-color: #d1d5db; }
:root[data-theme="dark"] .fresh-green   { color: #86efac; background: #052e16; border-color: #065f46; }
:root[data-theme="dark"] .fresh-yellow  { color: #fcd34d; background: #3a2a06; border-color: #78350f; }
:root[data-theme="dark"] .fresh-red     { color: #fca5a5; background: #3a0a0a; border-color: #7f1d1d; }
:root[data-theme="dark"] .fresh-unknown { color: #9ca3af; background: #1f2937; border-color: #374151; }
@media print {
  .freshness { background: #fff !important; color: #000 !important; border-color: #ccc !important; }
  .freshness::before { background: #000 !important; }
}

/* Sub-agent collapsible */
.sub-section { margin-top: 32px; }
.sub-section summary { font-size: 1.15rem; font-weight: 600; cursor: pointer; padding: 8px 0; color: var(--text-secondary); }
.sub-section summary:hover { color: var(--accent); }

/* Sessions table */
/* #ui-h10 (#569): isolation: isolate creates a stacking context so
   the sticky thead doesn't lose z-order against the page nav blur on
   iOS Safari.
   Do NOT put overflow-x: auto here — any non-visible overflow makes
   .table-wrap the sticky containing block, so top:56px (nav clearance)
   offsets the thead into the first body row on initial paint, and
   page-scroll stickiness is lost. Horizontal scroll is opt-in below
   for narrow viewports only. */
.table-wrap { max-width: 100%; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-card); isolation: isolate; }
/* #452: table-layout: fixed pins column widths from <colgroup> so sticky <thead>
   columns stay aligned with <tbody> as the user scrolls. String columns wrap so
   the table can stay inside the card without a horizontal scrollport (Msgs/Tools
   stay narrow + nowrap). */
.sessions-table { width: 100%; max-width: 100%; border-collapse: collapse; font-size: 0.88rem; table-layout: fixed; }
.sessions-table td { overflow: hidden; }
/* String content: Session, Project, Cwd, Model — wrap instead of ellipsis crush. */
.sessions-table td:nth-child(1),
.sessions-table td:nth-child(3),
.sessions-table td:nth-child(5),
.sessions-table td:nth-child(6) {
  white-space: normal; overflow-wrap: anywhere; word-break: break-word;
}
.sessions-table td a { display: inline; max-width: 100%; overflow-wrap: anywhere; word-break: break-word; }
/* Date is always YYYY-MM-DD — never ellipsize; keep on one line. */
.sessions-table td:nth-child(4) { overflow: visible; text-overflow: clip; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sessions-table td.session-cwd code { font-size: 0.78em; word-break: break-all; }
.sessions-table td.num { white-space: nowrap; }
/* #ui-h10 (#569): iOS Safari needs -webkit-sticky and a stacking
   context (isolation: isolate) on the table parent so the sticky
   thead doesn't lose its z-axis ordering against the nav blur. The
   `transform: translateZ(0)` gives older WebKit a hardware layer so
   the sticky cells don't get repainted as plain rows during scroll.
   top: 56px clears the sticky site nav while the thead sticks to the
   viewport (only valid when .table-wrap has no overflow scrollport). */
.sessions-table thead {
  position: -webkit-sticky;
  position: sticky;
  top: 56px;
  background: var(--bg-alt);
  z-index: 1;
  transform: translateZ(0);
}
/* Narrow viewports: allow horizontal pan. That reintroduces a scrollport,
   so drop nav-offset sticky (top:0) to avoid the overlap bug; page-scroll
   stickiness cannot survive an overflow ancestor either way. */
@media (max-width: 900px) {
  .table-wrap { overflow-x: auto; }
  .sessions-table thead { top: 0; }
}
/* (.table-wrap isolation rule moved up to the main definition above) */
.sessions-table th, .sessions-table td { padding: 8px 12px; text-align: left; border-bottom: 1px solid var(--border); }
.sessions-table th { background: var(--bg-alt); font-weight: 600; color: var(--text-secondary); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; }
.sessions-table tr:last-child td { border-bottom: none; }
.sessions-table tr:hover { background: var(--bg-alt); }
.sessions-table tr.selected { background: var(--accent-bg); }
.sessions-table td.num { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-secondary); }
.sessions-table code { font-family: var(--mono); font-size: 0.82em; color: var(--text-secondary); }
.sessions-table tr[hidden] { display: none; }

.mcp-usage-table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 0.88rem; }
.mcp-usage-table th, .mcp-usage-table td { padding: 8px 12px; text-align: left; border-bottom: 1px solid var(--border); }
.mcp-usage-table th { background: var(--bg-alt); font-weight: 600; color: var(--text-secondary); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; }
.mcp-usage-table tr:last-child td { border-bottom: none; }

/* #52 Wiki value / Wiki usage */
.wiki-value-section h3, .wiki-usage-section h3 { margin: 20px 0 8px; font-size: 1rem; }
.wiki-usage-mcp { margin-top: 16px; }
.wiki-value-cost { margin: 0 0 16px; font-size: 0.82rem; }
.wiki-value-list { margin: 6px 0 0; padding-left: 1.2em; font-size: 0.86rem; }
.wiki-value-list li { margin: 2px 0; }
.wiki-value-mix, .wiki-value-top, .wiki-value-dead { margin: 12px 0 8px; }

/* Filter bar */
.filter-bar { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; margin-bottom: 16px; padding: 12px 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); }
.filter-bar label { display: flex; flex-direction: column; gap: 4px; font-size: 0.72rem; color: var(--text-muted); font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; }
.filter-bar select, .filter-bar input { padding: 6px 10px; font-size: 0.85rem; background: var(--bg); border: 1px solid var(--border); border-radius: 4px; color: var(--text); font-family: var(--font); min-width: 140px; }
.filter-bar input[type="text"] { min-width: 180px; }
.filter-bar .btn { align-self: end; }
.filter-count { font-size: 0.78rem; margin-left: auto; align-self: end; }

/* Synthesis block */
.synthesis { background: var(--accent-bg); border: 1px solid var(--accent-light); border-radius: var(--radius); padding: 20px 24px; margin-bottom: 24px; }
.synthesis h2, .synthesis h3 { color: var(--accent); margin-top: 0; }
.synthesis p { margin: 10px 0; }

/* Command palette */
/* #478: was gated by `[aria-hidden="false"]`. axe-core flags that as
   `aria-hidden-focus` because focusable children inside an aria-hidden
   element are unreachable to AT users. Now toggled via `.open` class
   that JS sets when the dialog is active; aria-hidden is removed
   entirely while open and `inert` is applied to sibling chrome to
   keep AT focus inside the dialog (#479). */
.palette { position: fixed; inset: 0; z-index: 300; display: none; }
.palette.open { display: block; }
.palette-backdrop { position: absolute; inset: 0; background: rgba(15, 23, 42, 0.5); backdrop-filter: blur(4px); }
.palette-modal { position: relative; max-width: 600px; margin: 10vh auto 0; background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow); overflow: hidden; }
.palette-header { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.palette-header svg { color: var(--text-muted); flex-shrink: 0; }
.palette-header input { flex: 1; background: transparent; border: none; outline: none; font-family: var(--font); font-size: 0.95rem; color: var(--text); }
.palette-header input::placeholder { color: var(--text-muted); }
.palette-results { list-style: none; max-height: 50vh; overflow-y: auto; padding: 6px 0; }
.palette-results li { padding: 10px 16px; cursor: pointer; border-left: 3px solid transparent; }
.palette-results li.active { background: var(--accent-bg); border-left-color: var(--accent); }
.palette-results li:hover { background: var(--bg-alt); }
.palette-results .result-title { font-weight: 500; font-size: 0.9rem; color: var(--text); }
.palette-results .result-meta { font-size: 0.75rem; color: var(--text-muted); margin-top: 2px; }
.palette-results .result-type { display: inline-block; padding: 1px 6px; background: var(--bg-code); border-radius: 3px; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; margin-right: 6px; color: var(--accent); }
/* #20: shown when the search data itself failed to load, so a broken index
   doesn't masquerade as "no matches". Not selectable — it isn't a result. */
.palette-results li.palette-note { cursor: default; border-left-color: #b91c1c; color: #b91c1c; font-size: 0.85rem; }
.palette-results li.palette-note:hover { background: transparent; }
.palette-footer { display: flex; gap: 16px; padding: 10px 16px; border-top: 1px solid var(--border); font-size: 0.75rem; background: var(--bg-alt); }

/* Help dialog */
/* #478: same .open class swap as the palette — aria-hidden gating
   was an axe-core violation for any focusable child. */
/* #ui-l8 (#581): hint + example paragraphs in the help dialog moved
   from inline style="" to these classes so the dialog stays
   strict-CSP-friendly. */
.help-dialog-hint { font-size: 0.82rem; margin: 4px 0 8px; }
.help-dialog-example { font-size: 0.82rem; margin-top: 6px; }
/* 404 page link list — was inline style="list-style:disc;...". */
.not-found-links { list-style: disc; padding-left: 24px; margin: 12px 0; }
.help-dialog { position: fixed; inset: 0; z-index: 250; display: none; }
.help-dialog.open { display: block; }
.help-modal { position: relative; max-width: 420px; margin: 15vh auto 0; background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; padding: 24px; box-shadow: var(--shadow); }
.help-modal h2 { font-size: 1.1rem; margin-bottom: 16px; }
.help-modal table { width: 100%; font-size: 0.88rem; margin-bottom: 16px; }
.help-modal td { padding: 6px 0; }
.help-modal td:first-child { width: 130px; }

/* Footer */
.footer { padding: 24px 0; border-top: 1px solid var(--border); margin-top: 32px; background: var(--bg-alt); }
.footer p { font-size: 0.85rem; color: var(--text-muted); text-align: center; }
.footer a { text-decoration: underline; text-underline-offset: 2px; }

.container.narrow { max-width: 860px; }

/* Documents tree browser (Home + documents/ pages) */
.doctree-section { padding: 16px 0 48px; }
.doctree-layout { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: 32px; align-items: start; }
.doctree-sidebar { position: sticky; top: 88px; max-height: calc(100vh - 120px); overflow-y: auto; padding: 14px 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.88rem; }
.doctree-title { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); font-weight: 600; margin-bottom: 8px; }
.doctree-sidebar ul { list-style: none; margin: 0; padding: 0; }
.doctree-sidebar ul ul { padding-left: 14px; }
.doctree-sidebar li { margin: 1px 0; }
.doctree-sidebar summary { cursor: pointer; padding: 3px 6px; border-radius: 4px; font-weight: 600; color: var(--text-secondary); }
.doctree-sidebar summary:hover { background: var(--bg-alt); color: var(--text); }
.doctree-sidebar a { display: block; padding: 3px 6px; border-radius: 4px; color: var(--text-secondary); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.doctree-sidebar a:hover { background: var(--bg-alt); color: var(--text); text-decoration: none; }
.doctree-sidebar a.active { color: var(--accent); background: var(--bg-alt); font-weight: 500; }
.doctree-main h2 { margin-bottom: 12px; }
.doctree-main .recent-docs-mini { list-style: none; margin: 12px 0; padding: 0; }
.doctree-main .recent-docs-mini li { padding: 5px 0; border-bottom: 1px solid var(--border); }
.doctree-main .recent-docs-mini li:last-child { border-bottom: none; }
.doc-article { min-width: 0; }
.queue-widget { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; box-shadow: var(--shadow-card); }
.queue-widget-content { margin: 14px 0; }
.state-widget { margin: 14px 0; }
/* #234: lint failure note under Candidates / knowledge table; stage stamps in Timeline. */
.state-table-wrap .state-lint-banner {
  margin-top: 10px;
  margin-bottom: 0;
}
.state-lint-banner {
  white-space: pre-wrap;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.82rem;
  line-height: 1.4;
  margin: 0 0 14px;
  max-height: calc(1.4em * 7);
  overflow: auto;
}
.state-table-wrap { overflow-x: auto; margin-bottom: 14px; }
.state-pipeline-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; min-width: 520px; }
.state-pipeline-table th, .state-pipeline-table td { border: 1px solid var(--border); padding: 10px 12px; vertical-align: top; text-align: left; }
.state-pipeline-table th { background: var(--bg-alt); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); }
.state-pipeline-table .state-cell-count { font-weight: 700; font-variant-numeric: tabular-nums; }
.state-pipeline-table .state-cell-cost { font-size: 0.85em; color: var(--text-muted); white-space: nowrap; }
.state-pipeline-table .state-queue-meta { font-weight: 400; font-size: 0.85em; }
.state-pipeline-table .state-row-label { font-weight: 600; }
.state-pipeline-table .state-source-docs { font-weight: 600; color: var(--text); }
.automation-panel { margin-bottom: 18px; padding-bottom: 14px; border-bottom: 1px solid var(--border); }
.automation-panel h2 { margin: 0 0 8px; font-size: 1.1rem; }
.automation-panel ul { margin: 8px 0; padding-left: 18px; }
.state-pipeline-table tfoot td { background: var(--bg-alt); font-weight: 600; }
.collapse-sections { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.collapse-section { border: 1px solid var(--border); border-radius: 8px; background: var(--bg-alt); }
.collapse-section > summary { cursor: pointer; list-style: none; padding: 10px 12px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.collapse-section > summary::-webkit-details-marker { display: none; }
.collapse-section > summary::before { content: "▸"; color: var(--text-muted); font-size: 0.85rem; }
.collapse-section[open] > summary::before { content: "▾"; }
.collapse-section-count { margin-left: auto; font-size: 0.78rem; font-weight: 600; color: var(--text-muted); background: var(--bg-card); border: 1px solid var(--border); border-radius: 999px; padding: 1px 8px; }
.collapse-section-body { padding: 0 12px 12px; border-top: 1px solid var(--border); }
.collapse-section-body ul,
.collapse-section-list { margin: 8px 0 0 18px; }
.collapse-section-body .queue-commands-table { margin-top: 10px; }
.queue-stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin-bottom: 12px; }
.queue-stat { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; background: var(--bg-alt); }
.queue-stat-label { font-size: 0.74rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.queue-stat-value { font-size: 1.2rem; font-weight: 700; }
.queue-meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 6px 12px; margin-bottom: 10px; font-size: 0.9rem; }
.queue-type-list { margin: 6px 0 0 18px; }
.queue-commands-table { width: 100%; border-collapse: collapse; margin: 10px 0 14px; font-size: 0.88rem; }
.queue-commands-table th, .queue-commands-table td { border: 1px solid var(--border); padding: 8px 10px; vertical-align: top; }
.queue-commands-table th { background: var(--bg-alt); text-align: left; }
.queue-copy-btn { white-space: nowrap; }
/* #97 candidates review page — per-row decisions + the batch Apply assembles.
   The Apply bar sticks under the 56px site nav so it stays reachable while the
   reviewer scrolls the tables below it. */
.cand-apply-panel { position: sticky; top: 56px; z-index: 90; background: var(--bg); padding: 8px 0; border-bottom: 1px solid var(--border); }
.cand-apply-bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.cand-apply-spacer { flex: 1 1 auto; }
.cand-apply-btn {
  font: inherit; font-size: 0.9rem; padding: 6px 14px;
  border: 1px solid var(--border); border-radius: 4px; background: var(--bg-alt); color: var(--text); cursor: pointer;
}
.cand-apply-btn:hover { border-color: var(--accent); }
.cand-apply-primary { border-color: var(--accent); font-weight: 600; }
.cand-output { margin: 12px 0 4px; }
.cand-cli {
  margin: 8px 0 12px; padding: 12px; overflow-x: auto;
  background: var(--bg-alt); border: 1px solid var(--border); border-radius: 6px;
  font-size: 0.85rem; white-space: pre-wrap;
}
.cand-batch { max-height: 45vh; overflow-y: auto; }
.cand-intent { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; }
.cand-intent label { display: inline-flex; gap: 6px; align-items: center; font-size: 0.82rem; }
/* An authored display beats the hidden attribute, which only works through
   the UA stylesheet. Without this the conditional Into and Reason fields
   render on every row whatever the decision is. */
.cand-intent label[hidden] { display: none; }
.cand-decision, .cand-merge-into, .cand-discard-reason {
  font: inherit; font-size: 0.85rem; padding: 4px 6px; color: var(--text);
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 4px;
}
.cand-intent[data-decided="yes"] { font-weight: 600; }
.cand-intent[data-decided="yes"] .cand-decision { border-color: var(--accent); }
/* The merge wrap is a span, not a label, because it holds a combobox whose
   listbox is not phrasing content — so it needs the same [hidden] guard. */
.cand-intent .cand-merge-wrap { display: inline-flex; gap: 6px; align-items: center; font-size: 0.82rem; }
.cand-intent .cand-merge-wrap[hidden] { display: none; }
.cand-combo { position: relative; display: inline-flex; align-items: center; gap: 3px; }
.cand-combo-open {
  font: inherit; font-size: 0.7rem; line-height: 1; padding: 6px 7px; cursor: pointer;
  color: var(--text); background: var(--bg-alt);
  border: 1px solid var(--border); border-radius: 4px;
}
.cand-combo-open:hover { border-color: var(--accent); }
/* The dropdown escapes its cell, so the candidates tables must not clip it;
   the review table has three wrapping columns and fits narrow screens. */
.cand-table-wrap { overflow: visible; }
.cand-review-table { min-width: 0; }
.cand-combo-list, .cand-combo-empty {
  position: absolute; top: calc(100% + 3px); left: 0; z-index: 95;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 4px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.22);
}
.cand-combo-list {
  margin: 0; padding: 3px; list-style: none;
  min-width: 200px; max-width: 320px; max-height: 220px; overflow-y: auto;
}
.cand-combo-empty { padding: 6px 9px; font-size: 0.8rem; color: var(--text-muted); }
.cand-combo-list[hidden], .cand-combo-empty[hidden] { display: none; }
.cand-combo-option { padding: 4px 8px; border-radius: 3px; font-size: 0.85rem; font-weight: 400; white-space: nowrap; cursor: pointer; }
.cand-combo-option:hover { background: var(--bg-alt); }
.cand-combo-option[aria-selected="true"] { background: var(--accent); color: var(--bg); }
.cand-merge-into[data-invalid="yes"], .cand-discard-reason[data-invalid="yes"] {
  border-color: var(--danger, #b91c1c);
  box-shadow: 0 0 0 1px var(--danger, #b91c1c);
}
.error-banner { color: var(--danger, #b91c1c); background: color-mix(in srgb, var(--danger, #b91c1c) 12%, transparent); border: 1px solid var(--danger, #b91c1c); padding: 10px 12px; border-radius: 6px; margin: 12px 0; }
@media (max-width: 860px) {
  .doctree-layout { grid-template-columns: 1fr; }
  .doctree-sidebar { position: static; max-height: none; }
}

/* Recent documents page */
.recent-docs { list-style: none; margin: 0; padding: 0; counter-reset: none; }
.recent-doc { padding: 14px 0; border-bottom: 1px solid var(--border); }
.recent-doc:last-child { border-bottom: none; }
.recent-doc > a { font-weight: 600; font-size: 1.02rem; }
.recent-doc-meta { margin-top: 4px; font-size: 0.85rem; overflow-wrap: anywhere; }

/* v0.4: Related pages panel */
.related-pages { margin-top: 48px; padding-top: 24px; border-top: 1px solid var(--border); }
.related-pages h3 { font-size: 1.05rem; color: var(--text-secondary); margin-bottom: 12px; }
.related-pages ul { list-style: none; margin: 0; padding: 0; }
.related-pages li { padding: 6px 0; font-size: 0.9rem; border-bottom: 1px solid var(--border); }
.related-pages li:last-child { border-bottom: none; }

/* v0.8 (#64, #72): GitHub-style 365-day activity heatmap. Rendered as a
   build-time SVG in build.py (see llmwiki/viz_heatmap.py). The CSS custom
   properties below get picked up by the inlined SVG via its own <style>
   block so the colors swap with the page theme. The pre-v0.8 JS-based
   tiny-strip heatmap is gone. */
:root {
  --heatmap-0: #dde1e6;        /* v1.0 #119: darker level-0 for visibility on white */
  --heatmap-1: #9be9a8;
  --heatmap-2: #40c463;
  --heatmap-3: #30a14e;
  --heatmap-4: #216e39;
}
:root[data-theme="dark"] {
  --heatmap-0: #161b22;
  --heatmap-1: #0e4429;
  --heatmap-2: #006d32;
  --heatmap-3: #26a641;
  --heatmap-4: #39d353;
}
.heatmap-section { padding-top: 16px; padding-bottom: 16px; }
.activity-heatmap {
  display: flex; flex-direction: column; align-items: center;
  margin-bottom: var(--block-gap); padding: 14px 16px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius); overflow-x: auto; width: 100%;
  box-sizing: border-box;
}
.heatmap-label { font-size: 0.78rem; margin-bottom: 8px; text-align: center; width: 100%; }
.heatmap-totals { font-size: 0.78rem; margin: 8px 0 0; text-align: center; width: 100%; }
.heatmap-svg { display: block; max-width: 100%; margin-inline: auto; }
.heatmap-svg rect { transition: stroke 0.1s; }
.heatmap-svg rect:hover { stroke: var(--accent); stroke-width: 1; }

/* v0.8 (#65): Tool-call bar chart — rendered as pure SVG by
   llmwiki/viz_tools.py. CSS custom properties drive the category
   colors so the page theme can override them; dark-mode variants
   use saturated fills that read against the dark card background. */
:root {
  /* v1.0 #119: slightly less saturated in light mode — bars read cleaner on white card background */
  --tool-cat-io: #2563eb;
  --tool-cat-search: #9333ea;
  --tool-cat-exec: #ea580c;
  --tool-cat-network: #059669;
  --tool-cat-plan: #475569;
  --tool-cat-other: #6b7280;
}
:root[data-theme="dark"] {
  --tool-cat-io: #60a5fa;
  --tool-cat-search: #c084fc;
  --tool-cat-exec: #fb923c;
  --tool-cat-network: #34d399;
  --tool-cat-plan: #94a3b8;
  --tool-cat-other: #9ca3af;
}
.tool-chart-section { padding-top: 8px; padding-bottom: 16px; }
.tool-chart-card { margin: 16px 0 24px; padding: 14px 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); overflow-x: auto; }
.tool-chart-label { font-size: 0.78rem; margin-bottom: 8px; }
.tool-chart-svg { display: block; max-width: 100%; }
.tool-chart-svg rect { transition: opacity 0.1s; stroke: rgba(15, 23, 42, 0.08); stroke-width: 1; }  /* v1.0 #119: thin stroke for bar definition */
:root[data-theme="dark"] .tool-chart-svg rect { stroke: rgba(255, 255, 255, 0.05); }
.tool-chart-svg rect:hover { opacity: 0.85; }

/* v0.8 (#66): Token usage card — stacked bars for four token categories
   plus a cache hit ratio badge. Rendered as plain HTML by
   llmwiki/viz_tokens.py. Colors follow the same category convention as
   the tool chart (blue = input, amber = cache_creation, green = cache_read,
   purple = output). */
:root {
  --token-input: #3b82f6;
  --token-cache-creation: #f59e0b;
  --token-cache-read: #10b981;
  --token-output: #a855f7;
  --token-area-fill: rgba(59, 130, 246, 0.22);
  --token-area-stroke: #3b82f6;
}
:root[data-theme="dark"] {
  --token-input: #60a5fa;
  --token-cache-creation: #fbbf24;
  --token-cache-read: #34d399;
  --token-output: #c084fc;
  --token-area-fill: rgba(96, 165, 250, 0.22);
  --token-area-stroke: #60a5fa;
}
.token-card { margin: 16px 0 24px; padding: 14px 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); }
.token-card-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
.token-card-title { font-weight: 600; font-size: 0.9rem; }
.token-card-total { font-size: 0.78rem; }
.token-row { display: grid; grid-template-columns: 120px 1fr 64px; gap: 10px; align-items: center; margin: 4px 0; font-size: 0.82rem; }
.token-label { color: var(--text-secondary); }
.token-bar-wrap { height: 10px; background: var(--bg-alt); border-radius: 3px; overflow: hidden; }
.token-bar { display: block; height: 100%; border-radius: 3px; }
.token-bar-input { background: var(--token-input); }
.token-bar-cache_creation { background: var(--token-cache-creation); }
.token-bar-cache_read { background: var(--token-cache-read); }
.token-bar-output { background: var(--token-output); }
.token-value { text-align: right; font-family: 'JetBrains Mono', monospace; font-size: 0.78rem; color: var(--text-secondary); }
.token-ratio { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border); font-size: 0.8rem; display: flex; gap: 8px; align-items: baseline; }
.token-ratio-label { color: var(--text-secondary); }
.token-ratio-value { font-weight: 600; font-size: 0.95rem; }
.token-ratio-value.tier-green   { color: #15803d; }
.token-ratio-value.tier-yellow  { color: #92400e; }
.token-ratio-value.tier-red     { color: #b91c1c; }
.token-ratio-value.tier-unknown { color: var(--text-secondary); }
:root[data-theme="dark"] .token-ratio-value.tier-green  { color: #86efac; }
:root[data-theme="dark"] .token-ratio-value.tier-yellow { color: #fcd34d; }
:root[data-theme="dark"] .token-ratio-value.tier-red    { color: #fca5a5; }
.token-ratio.tier-green   { background: rgba(34, 197, 94, 0.08); }
.token-ratio.tier-yellow  { background: rgba(234, 179, 8, 0.08); }
.token-ratio.tier-red     { background: rgba(239, 68, 68, 0.08); }
.token-ratio { padding: 8px 10px; border-radius: 4px; }
.token-timeline-svg { display: block; max-width: 100%; }

/* Site-wide token stats on the home page */
.token-stats-section { padding-top: 8px; padding-bottom: 16px; }
.token-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin: 8px 0 24px; }
.token-stat { padding: 14px 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); text-decoration: none; color: var(--text); display: block; }
a.token-stat:hover { border-color: var(--accent); }
.token-stat-label { font-size: 0.76rem; margin-bottom: 4px; }
.token-stat-value { font-size: 1.4rem; font-weight: 600; font-family: 'JetBrains Mono', monospace; }
.token-stat-sub { font-size: 0.75rem; margin-top: 4px; }

/* v0.7 (#55): Model entity info card + /models/ sortable table. The
   `.model-card` is rendered by llmwiki/models_page.py.render_model_info_card;
   the `.models-table` is inside render_models_index. Both reuse existing
   theme vars — no new custom properties. */
.model-card { margin: 20px 0; padding: 18px 22px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); }
.model-card-header { display: flex; gap: 10px; align-items: baseline; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.model-card-title { font-size: 1.25rem; font-weight: 700; }
.model-card-provider { font-size: 0.95rem; }
.model-card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px 18px; margin-bottom: 14px; }
.model-card-kv { display: flex; flex-direction: column; gap: 2px; font-size: 0.88rem; }
.model-card-kv .muted { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; }
.model-card-row { display: flex; gap: 12px; align-items: baseline; font-size: 0.88rem; margin: 8px 0; }
.model-card-row-label { min-width: 80px; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; }
.model-price-cell { margin-right: 14px; font-family: 'JetBrains Mono', monospace; }
.model-card-section-title { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; margin-top: 14px; margin-bottom: 8px; }
.model-card-benches { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.model-bench-row { display: grid; grid-template-columns: 140px 1fr 52px; gap: 10px; align-items: center; margin: 4px 0; font-size: 0.85rem; }
.model-bench-label { color: var(--text-secondary); }
.model-bench-bar { height: 10px; background: var(--bg-alt); border-radius: 3px; overflow: hidden; }
.model-bench-fill { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
.model-bench-value { text-align: right; font-family: 'JetBrains Mono', monospace; font-size: 0.78rem; color: var(--text-secondary); }
.model-warnings { margin: 12px 0; padding: 10px 14px; background: rgba(234, 179, 8, 0.08); border: 1px solid #f59e0b; border-radius: 4px; font-size: 0.85rem; }
.model-warnings summary { cursor: pointer; font-weight: 600; color: #b45309; }
:root[data-theme="dark"] .model-warnings { background: rgba(234, 179, 8, 0.12); }
:root[data-theme="dark"] .model-warnings summary { color: #fcd34d; }
.models-table-wrap { overflow-x: auto; margin: 20px 0; }
.models-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.models-table th, .models-table td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--border); }
.models-table th { font-weight: 600; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-secondary); background: var(--bg-alt); }
.models-table td { font-family: 'JetBrains Mono', monospace; }
.models-table td:first-child { font-family: inherit; }
.models-table tr:hover td { background: var(--bg-alt); }
.models-table a { color: var(--accent); text-decoration: none; font-weight: 500; }
.models-table a:hover { text-decoration: underline; }

/* v0.7 (#56): Changelog timeline + inline pricing sparkline + home
   "Recently updated" card. All rendered by llmwiki/changelog_timeline.py.
   Timeline is a vertical list with a connecting line on the left,
   newest entry first, numeric deltas colored by direction. */
.timeline-card { margin: 20px 0; padding: 18px 22px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); }
.timeline-card-title { font-size: 0.88rem; font-weight: 600; margin-bottom: 12px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; }
.timeline-sparkline { display: flex; align-items: center; gap: 12px; padding: 6px 0 12px; font-size: 0.78rem; }
.timeline-sparkline .price-sparkline { flex: 0 0 auto; }
.changelog-timeline { list-style: none; margin: 0; padding: 0 0 0 18px; position: relative; border-left: 2px solid var(--border); }
.timeline-item { position: relative; padding: 8px 0 8px 16px; font-size: 0.88rem; }
.timeline-date { display: block; font-size: 0.76rem; color: var(--text-secondary); font-family: 'JetBrains Mono', monospace; margin-bottom: 2px; }
.timeline-dot { position: absolute; left: -23px; top: 14px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); border: 2px solid var(--bg-card); }
.timeline-body { display: block; }
.timeline-event { font-weight: 500; }
.timeline-detail { font-size: 0.82rem; color: var(--text-secondary); margin-top: 4px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.timeline-field { font-size: 0.78rem; padding: 1px 6px; background: var(--bg-alt); border-radius: 3px; }
.timeline-delta { display: inline-flex; gap: 6px; align-items: baseline; font-family: 'JetBrains Mono', monospace; }
.timeline-from { color: var(--text-secondary); text-decoration: line-through; text-decoration-thickness: 1px; }
.timeline-to { font-weight: 600; color: var(--text); }
.timeline-arrow { color: var(--text-secondary); }
.timeline-arrow-down { color: #15803d; }
.timeline-arrow-up { color: #b91c1c; }
:root[data-theme="dark"] .timeline-arrow-down { color: #86efac; }
:root[data-theme="dark"] .timeline-arrow-up { color: #fca5a5; }

.recently-updated-section { padding-top: 8px; padding-bottom: 16px; }
.recently-updated-card { margin: 8px 0 24px; padding: 14px 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); }
.recently-updated-title { font-size: 0.78rem; margin-bottom: 10px; }
.recently-updated-list { list-style: none; margin: 0; padding: 0; }
.recently-updated-item { display: grid; grid-template-columns: 180px 100px 1fr; gap: 10px; align-items: baseline; padding: 6px 0; border-bottom: 1px solid var(--border); font-size: 0.88rem; min-width: 0; }
.recently-updated-item:last-child { border-bottom: none; }
.recently-updated-item > * { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recently-updated-item a { color: var(--accent); text-decoration: none; font-weight: 500; }
.recently-updated-item a:hover { text-decoration: underline; }
.recently-updated-date { font-family: 'JetBrains Mono', monospace; font-size: 0.78rem; }
/* Below 640px the 180+100+1fr grid is too wide — collapse to a single
   column so each item stacks vertically instead of overflowing. */
@media (max-width: 639px) {
  .recently-updated-item { grid-template-columns: 1fr; gap: 2px; padding: 8px 0; }
  .recently-updated-item > * { white-space: normal; }
}

/* Project topics — GitHub-style tag chips on project cards, project
   detail pages, and the home-page grid. Rendered by
   llmwiki/project_topics.py. Tag colors are theme-neutral so the
   same style reads on both project cards (light background) and
   the project hero strip. */
.project-topics { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.topic-chip {
  display: inline-block;
  padding: 3px 10px;
  background: var(--bg-alt);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 500;
  line-height: 1.4;
  text-decoration: none;
  transition: all 0.1s;
}
a.topic-chip:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--bg-card);
}
.topic-chip-more { opacity: 0.7; }
.card-topics { margin-top: 8px; }
.card-topics .topic-chip { font-size: 0.68rem; padding: 2px 8px; }
/* Topic-page identity line (#108) — the chip naming what kind of thing
   the topic is. Same pill shape as .topic-chip, sized for the hero
   subtitle it sits in. A topic no wiki page describes still renders a
   chip, reading `Unclassified topic` — see topics_page.KIND_OTHER_LABEL. */
.topic-kind-chip {
  display: inline-block;
  padding: 2px 9px;
  background: var(--bg-card);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: baseline;
}
/* Two different facts, two different labels: "Active" is derived from the
   sessions that mention the topic, "Reviewed" is the backing page's own
   date. Either is dropped entirely when its dates are absent. */
.topic-activity, .topic-reviewed { font-variant-numeric: tabular-nums; }
.topic-reviewed { font-style: italic; }
/* The backing page's rendered markdown is wrapped in `.content` so it gets
   the site-wide prose rules — notably the overflow guards on tables and
   code blocks. The topic page's own `Connected topics` / `Sessions`
   headings sit outside that wrapper, so they repeat `.content h2` here and
   the page reads as one heading family rather than two. */
.topic-page > h2 {
  margin: 36px 0 12px;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--text);
  border-bottom: 1px solid var(--border);
  padding-bottom: 6px;
}
.topic-page-content { margin-bottom: 8px; }

.project-topics-section { padding-top: 12px; padding-bottom: 8px; }
.project-topics-section .container { padding-top: 16px; padding-bottom: 4px; }
.project-description { margin: 0 0 10px; font-size: 0.92rem; line-height: 1.5; max-width: 680px; }
.project-hero-topics { margin-bottom: 6px; }
.project-homepage { display: inline-block; margin-top: 6px; font-size: 0.82rem; color: var(--accent); text-decoration: none; }
.project-homepage:hover { text-decoration: underline; }

/* Agent badge — shows which AI agent produced the session */
.agent-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  border: 1px solid;
  vertical-align: middle;
}
/* #459: light-theme agent text colors darkened to clear WCAG AA on the
   alpha-blended backgrounds. Originals (codex #059669, copilot #2563EB,
   cursor #D97706, gemini #DC2626) measured 2.86–4.49:1 on the effective
   10%-alpha tint, all under the 4.5:1 small-text threshold. The border
   tint is decorative so its rgba(color, 0.3) value is unchanged. */
.agent-claude   { color: #7C3AED; background: rgba(124,58,237,0.1); border-color: rgba(124,58,237,0.3); }
.agent-codex    { color: #047857; background: rgba(5,150,105,0.1); border-color: rgba(5,150,105,0.3); }
.agent-copilot  { color: #1E40AF; background: rgba(37,99,235,0.1); border-color: rgba(37,99,235,0.3); }
.agent-cursor   { color: #92400E; background: rgba(217,119,6,0.1); border-color: rgba(217,119,6,0.3); }
.agent-gemini   { color: #991B1B; background: rgba(220,38,38,0.1); border-color: rgba(220,38,38,0.3); }
.agent-obsidian { color: #7E22CE; background: rgba(126,34,206,0.1); border-color: rgba(126,34,206,0.3); }
.agent-openclaw { color: #0F766E; background: rgba(15,118,110,0.1); border-color: rgba(15,118,110,0.3); }
.agent-opencode { color: #0369A1; background: rgba(3,105,161,0.1); border-color: rgba(3,105,161,0.3); }
.agent-docs     { color: #4B5563; background: rgba(75,85,99,0.1); border-color: rgba(75,85,99,0.3); }
/* Simplification sweep removed the PDF adapter — agent-pdf rule deleted. */
.agent-unknown  { color: #6B7280; background: rgba(107,114,128,0.1); border-color: rgba(107,114,128,0.3); }
:root[data-theme="dark"] .agent-claude   { color: #A78BFA; background: rgba(167,139,250,0.15); border-color: rgba(167,139,250,0.3); }
:root[data-theme="dark"] .agent-codex    { color: #34D399; background: rgba(52,211,153,0.15); border-color: rgba(52,211,153,0.3); }
:root[data-theme="dark"] .agent-copilot  { color: #60A5FA; background: rgba(96,165,250,0.15); border-color: rgba(96,165,250,0.3); }
:root[data-theme="dark"] .agent-cursor   { color: #FBBF24; background: rgba(251,191,36,0.15); border-color: rgba(251,191,36,0.3); }
:root[data-theme="dark"] .agent-gemini   { color: #F87171; background: rgba(248,113,113,0.15); border-color: rgba(248,113,113,0.3); }
:root[data-theme="dark"] .agent-openclaw { color: #5EEAD4; background: rgba(94,234,212,0.15); border-color: rgba(94,234,212,0.3); }
:root[data-theme="dark"] .agent-opencode { color: #7DD3FC; background: rgba(125,211,252,0.15); border-color: rgba(125,211,252,0.3); }
:root[data-theme="dark"] .agent-docs     { color: #D1D5DB; background: rgba(209,213,219,0.12); border-color: rgba(209,213,219,0.3); }
.sessions-table .agent-badge { font-size: 0.65rem; padding: 1px 6px; }

/* v0.4: Deep-link icon next to headings */
.content h2 .deep-link, .content h3 .deep-link, .content h4 .deep-link { margin-left: 8px; font-size: 0.8em; opacity: 0; text-decoration: none; transition: opacity 0.15s; }
.content h2:hover .deep-link, .content h3:hover .deep-link, .content h4:hover .deep-link { opacity: 0.7; }
.content h2 .deep-link:hover, .content h3 .deep-link:hover { opacity: 1; text-decoration: none; }

/* v0.4: Mark highlighting in search results */
mark { background: var(--accent-bg); color: var(--accent); padding: 0 2px; border-radius: 3px; font-weight: 500; }

/* Hover-to-preview wikilinks */
.wikilink-preview { position: fixed; max-width: 360px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow); padding: 12px 14px; z-index: 250; pointer-events: auto; font-size: 0.85rem; animation: fadeIn 0.1s ease-out; }
.wikilink-preview .wl-title { font-weight: 600; color: var(--text); margin-bottom: 6px; }
.wikilink-preview .wl-body { color: var(--text-secondary); font-size: 0.8rem; line-height: 1.5; max-height: 140px; overflow: hidden; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }

/* Timeline block on sessions index */
.timeline-block { margin-bottom: 16px; padding: 12px 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); }
.timeline-label { font-size: 0.78rem; margin-bottom: 6px; }
.timeline-block svg rect { transition: opacity 0.15s; }
.timeline-block svg rect:hover { opacity: 1 !important; }

/* TOC sidebar (session pages, desktop only, injected by JS) */
.toc-sidebar { position: fixed; top: 88px; left: max(16px, calc((100vw - 1080px) / 2 - 240px)); width: 220px; max-height: calc(100vh - 120px); overflow-y: auto; padding: 12px 14px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.82rem; z-index: 50; display: none; }
.toc-sidebar .toc-title { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); font-weight: 600; margin-bottom: 8px; }
.toc-sidebar ul { list-style: none; padding: 0; margin: 0; }
.toc-sidebar li { margin: 0; }
.toc-sidebar li.toc-h3 { padding-left: 12px; }
.toc-sidebar li.toc-h4 { padding-left: 24px; }
.toc-sidebar .toc-link { display: block; padding: 4px 8px; color: var(--text-secondary); border-left: 2px solid transparent; line-height: 1.4; text-decoration: none; border-radius: 0 4px 4px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.toc-sidebar .toc-link:hover { color: var(--text); background: var(--bg-alt); text-decoration: none; }
.toc-sidebar .toc-link.active { color: var(--accent); border-left-color: var(--accent); background: var(--bg-alt); font-weight: 500; }
@media (min-width: 1340px) { .toc-sidebar { display: block; } }

/* #460: Hamburger button + slide-down drawer for tablet/mobile.
   Desktop nav-links row hides at <1024 (existing rule), so without
   this drawer Graph / Docs / Changelog were unreachable on mobile. */
.nav-hamburger {
  display: none;  /* shown only when nav-links row is hidden */
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 6px; width: 44px; height: 44px;
  align-items: center; justify-content: center;
  cursor: pointer; color: var(--text-secondary);
  padding: 0; margin-left: auto;
  transition: all 0.15s;
}
.nav-hamburger:hover { border-color: var(--accent); color: var(--accent); }
@media (max-width: 1023px) { .nav-hamburger { display: inline-flex; } }
/* #v1378-review: forced-colors (Windows High Contrast) mode overrides
   our custom palette with the system one. Without this, the hamburger
   button's border (var(--border)) is ignored and the button visually
   disappears against the nav background. Use system-named colors so
   it stays visible. */
@media (forced-colors: active) {
  .nav-hamburger { border: 2px solid ButtonText; }
  .nav-hamburger:focus-visible { outline: 3px solid Highlight; outline-offset: 2px; }
}
.nav-drawer {
  display: none;
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--bg); border-bottom: 1px solid var(--border);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
  flex-direction: column; padding: 8px 16px 12px;
  z-index: 99;
}
.nav-drawer:not([hidden]) { display: flex; }
.nav-drawer-link {
  display: block; padding: 12px 12px;
  color: var(--text); font-size: 0.95rem; font-weight: 500;
  text-decoration: none; border-radius: 6px;
}
.nav-drawer-link:hover, .nav-drawer-link:focus-visible { background: var(--bg-alt); text-decoration: none; }
.nav-drawer-link.active { color: var(--accent); }

/* Mobile bottom navigation */
.mobile-bottom-nav { display: none; }
/* Mobile bottom nav breakpoint at 767 matches the common 768 tablet cutoff
   (Bootstrap/Tailwind). At 767 and below we show the bottom nav; at 768+
   we assume the user has enough horizontal room for the top-nav controls. */
@media (max-width: 767px) {
  .mobile-bottom-nav {
    display: flex; position: fixed; bottom: 0; left: 0; right: 0;
    background: var(--bg-card); border-top: 1px solid var(--border);
    padding: 6px 0 calc(6px + env(safe-area-inset-bottom, 0px));
    justify-content: space-around; align-items: center;
    z-index: 150; backdrop-filter: saturate(1.5) blur(8px);
    -webkit-backdrop-filter: saturate(1.5) blur(8px);
  }
  .mbn-link {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    background: none; border: none; color: var(--text-secondary);
    padding: 4px 10px; font-size: 0.66rem; font-weight: 500;
    text-decoration: none; cursor: pointer; font-family: inherit;
    min-width: 52px; transition: color 0.15s;
  }
  .mbn-link svg { width: 20px; height: 20px; stroke-width: 2; }
  .mbn-link:hover, .mbn-link:active { color: var(--accent); text-decoration: none; }
  .mbn-link.active { color: var(--accent); }
  body { padding-bottom: 76px; }
  .nav-links .nav-search-btn, .nav-links .theme-toggle { display: none; }
}

/* Print */
@media print {
  :root {
    --bg: #fff; --bg-alt: #fff; --bg-card: #fff; --bg-code: #f5f5f5;
    --text: #000; --text-secondary: #333; --text-muted: #555;
    --border: #ccc; --accent: #000;
  }
  /* #ui-l1 (#578): keep breadcrumbs in print so a printed page
     retains its location context. #ui-l3 (#579): keep activity
     heatmap + token charts + related-pages too — useful when an
     offline reader needs to follow a hardcopy. Removed from the
     hide-list. */
  .nav, .footer, .palette, .help-dialog, .session-actions, .filter-bar,
  .progress-bar, .nav-search-btn, .theme-toggle, .copy-code-btn,
  .wikilink-preview, .timeline-block, .toc-sidebar, .mobile-bottom-nav,
  .deep-link,
  .meta-tools { display: none !important; }
  /* Breadcrumbs + heatmap + charts kept on print, but rendered
     monochrome to save ink. */
  .breadcrumbs { color: #333; }
  .activity-heatmap { filter: grayscale(100%); }
  .related-pages { border-top: 1px solid #ccc; padding-top: 8pt; margin-top: 12pt; page-break-inside: avoid; }
  body { background: #fff; color: #000; font-size: 11pt; padding-bottom: 0; }
  .hero { padding: 12px 0 8px; background: #fff; border: none; }
  .hero h1 { font-size: 18pt; color: #000; }
  .hero .hero-sub { color: #333; font-size: 10pt; }
  .container { max-width: 100%; padding: 0 12pt; }
  .content { font-size: 11pt; }
  .content h1, .content h2, .content h3, .content h4 { page-break-after: avoid; break-after: avoid; color: #000; }
  .content pre, .content blockquote, .content table, .content img, .content figure { page-break-inside: avoid; break-inside: avoid; }
  .content pre { border: 1px solid #ccc; background: #f8f8f8; font-size: 9pt; }
  .content code { font-size: 9pt; }
  .content a { color: #000; text-decoration: underline; }
  .content a[href^="http"]:after { content: " (" attr(href) ")"; font-size: 8pt; color: #555; word-break: break-all; }
  .content img, .content svg { max-width: 100%; height: auto; }
  article { max-width: 100% !important; }
  .section { padding: 0 !important; }
}

/* --- Reader shell (v1.2.0 · #112) --- */
.reader-shell {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr) 280px;
  gap: 32px;
  max-width: 1440px;
  margin: 0 auto;
  padding: 32px 24px;
  align-items: start;
}
.reader-shell__drawer,
.reader-shell__rail {
  position: sticky;
  top: 24px;
  align-self: start;
  background: var(--bg-alt);
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  padding: 16px;
  font-size: 0.85rem;
}
.reader-shell__drawer h2,
.reader-shell__rail h2 {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin: 0 0 10px 0;
}
.reader-shell__drawer ul,
.reader-shell__rail ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.reader-shell__drawer li,
.reader-shell__rail li { padding: 4px 0; }

.reader-shell__drawer-empty {
  color: var(--text-muted);
  font-size: 0.78rem;
  margin: 0;
}

.reader-shell__header {
  border-bottom: 1px solid var(--border-subtle);
  padding-bottom: 16px;
  margin-bottom: 24px;
}
.reader-shell__crumbs {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.reader-shell__crumbs .sep { margin: 0 6px; }
.reader-shell__subtitle {
  color: var(--text-muted);
  margin-top: 4px;
}

.reader-shell__utility {
  display: flex;
  gap: 8px;
  margin-top: 14px;
  flex-wrap: wrap;
}
.reader-shell__util-btn {
  padding: 4px 10px;
  font-size: 0.78rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-secondary);
  text-decoration: none;
  transition: border-color 0.15s;
}
.reader-shell__util-btn:hover { border-color: var(--accent); }

.reader-shell__body { line-height: 1.7; }

.reader-shell__infobox dl {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 10px;
  font-size: 0.82rem;
}
.reader-shell__infobox-row { display: contents; }
.reader-shell__infobox dt { color: var(--text-muted); }
.reader-shell__infobox dd { margin: 0; }

.reader-shell__revisions,
.reader-shell__see-also,
.reader-shell__references {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border-subtle);
}

@media (max-width: 1100px) {
  .reader-shell {
    grid-template-columns: minmax(0, 1fr) 280px;
  }
  .reader-shell__drawer { display: none; }
}
@media (max-width: 760px) {
  .reader-shell {
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
  }
  .reader-shell__rail {
    position: static;
    margin-top: 24px;
  }
}


/* --- Docs shell (v1.2.0 · #265) --- */
.docs-shell {
  max-width: 760px;
  margin: 0 auto;
  padding: 28px 32px 96px;
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.75;
  color: var(--text);
  letter-spacing: -0.01em;
}

.docs-shell > h1,
.docs-shell > header h1 {
  font-size: 2.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 8px 0 20px;
  color: var(--text);
}

.docs-shell h2 {
  font-size: 1.75rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.25;
  margin: 48px 0 20px;
  padding-top: 24px;
  border-top: 1px solid var(--border-subtle);
  color: var(--text);
}

.docs-shell h2:first-of-type {
  border-top: none;
  padding-top: 0;
  margin-top: 32px;
}

.docs-shell h3 {
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
  margin: 48px 0 16px;
  color: var(--text);
}

.docs-shell h4 {
  font-size: 1rem;
  font-weight: 600;
  margin: 32px 0 12px;
  color: var(--text);
}

.docs-shell p,
.docs-shell ul,
.docs-shell ol {
  margin: 0 0 20px;
}

.docs-shell ul,
.docs-shell ol {
  padding-left: 1.6em;
}

.docs-shell li {
  margin: 8px 0;
}

.docs-shell li > p {
  margin: 0 0 8px;
}

/* Inline code */
.docs-shell p code,
.docs-shell li code,
.docs-shell td code,
.docs-shell th code {
  font-family: var(--mono);
  font-size: 0.875em;
  padding: 2px 6px;
  background: var(--bg-code);
  border: 1px solid var(--border-subtle);
  border-radius: 4px;
  color: var(--text);
  letter-spacing: 0;
}

/* Code blocks */
.docs-shell pre {
  font-family: var(--mono);
  font-size: 0.9rem;
  line-height: 1.65;
  background: var(--bg-code);
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  padding: 20px 24px;
  margin: 28px 0;
  overflow-x: auto;
  color: var(--text);
}

.docs-shell pre code {
  font-family: inherit;
  background: transparent;
  border: none;
  padding: 0;
  font-size: inherit;
  color: inherit;
}

/* Links */
.docs-shell a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
  transition: text-decoration-color 0.12s ease;
}

.docs-shell a:hover {
  text-decoration-color: var(--accent);
}

/* Blockquote — used for the "Trusted" / "Warning" / "Result" callouts */
.docs-shell blockquote {
  margin: 28px 0;
  padding: 16px 24px;
  background: var(--accent-bg);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  color: var(--text);
}

.docs-shell blockquote p {
  margin: 0;
}

/* Horizontal rules — editorial dividers */
.docs-shell hr {
  margin: 72px auto;
  width: 56px;
  height: 1px;
  background: var(--border);
  border: none;
}

/* Tables — clean editorial look */
.docs-shell table {
  width: 100%;
  border-collapse: collapse;
  margin: 32px 0;
  font-size: 0.96rem;
}

.docs-shell thead th {
  text-align: left;
  font-weight: 600;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.docs-shell tbody td {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border-subtle);
  vertical-align: top;
  color: var(--text);
}

.docs-shell tbody tr:last-child td {
  border-bottom: none;
}

/* Frontmatter strip — "Time: 5 min · You'll need: …" stacked below the
   title as a hairline rule with one row per field. Grid keeps labels in
   a narrow left column so values align across fields + wrap cleanly. */
.docs-shell .docs-meta {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 8px 20px;
  padding: 20px 0;
  margin: 0 0 56px;
  border-top: 1px solid var(--border-subtle);
  border-bottom: 1px solid var(--border-subtle);
  font-size: 0.93rem;
  color: var(--text-secondary);
}

.docs-shell .docs-meta dt {
  color: var(--text-muted);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  align-self: start;
  padding-top: 3px;
}

.docs-shell .docs-meta dd {
  margin: 0;
  line-height: 1.55;
  color: var(--text);
}

.docs-shell .docs-meta code {
  font-family: var(--mono);
  font-size: 0.85em;
  padding: 1px 6px;
  background: var(--bg-code);
  border: 1px solid var(--border-subtle);
  border-radius: 4px;
}

.docs-shell .docs-meta a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

/* Tutorial lead-in — the first paragraph after the meta strip. The
   heading after it gives just enough rhythm; we lift the paragraph to
   a slightly larger size + calmer color so the "Why this matters"
   section header reads as a proper divider. */
.docs-shell > .docs-meta + hr + h2 + p,
.docs-shell > h1 + p {
  font-size: 1.15rem;
  line-height: 1.65;
  color: var(--text-secondary);
}

/* Emphasis for bold inline — a touch darker than regular body */
.docs-shell strong {
  font-weight: 600;
  color: var(--text);
}

/* Responsive */
@media (max-width: 760px) {
  .docs-shell {
    padding: 40px 20px 96px;
    font-size: 1rem;
    line-height: 1.7;
  }
  .docs-shell > h1 {
    font-size: 2.25rem;
  }
  .docs-shell h2 {
    font-size: 1.4rem;
    margin-top: 56px;
  }
  .docs-shell pre {
    padding: 16px 18px;
    border-radius: 6px;
  }
  .docs-shell table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }
}

/* Dark mode — inherit all tokens, no overrides needed; just nudge blockquote */
:root[data-theme="dark"] .docs-shell blockquote {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .docs-shell blockquote {
    background: color-mix(in srgb, var(--accent) 10%, transparent);
  }
}

/* Hub index hero — applied to docs/index.md h1 only. Stays a full step
   bigger than tutorial h1 (2.75 rem) so the hub is unmistakably the
   landing page. */
.docs-shell.docs-hub > h1 {
  font-size: 3.5rem;
  letter-spacing: -0.03em;
  margin-bottom: 12px;
}

.docs-shell.docs-hub > h1 + p {
  font-size: 1.25rem;
  line-height: 1.55;
  color: var(--text-secondary);
  max-width: 620px;
  margin-bottom: 72px;
}

/* Passthrough pages (reference docs, adapter guides, deploy guides)
   get a gentler wrapper — same column width + typography, but the
   meta-strip / hub-hero accents don't apply. */
.docs-shell.docs-passthrough > h1 {
  font-size: 2.4rem;
}

@media (max-width: 760px) {
  .docs-shell.docs-hub > h1 {
    font-size: 2.5rem;
  }
  .docs-shell.docs-hub > h1 + p {
    font-size: 1.0625rem;
    margin-bottom: 48px;
  }
}

/* #282: tutorial table of contents + prev/next footer + edit-on-GitHub.
   Scoped under `.docs-shell`. */

.docs-shell .tutorial-toc {
  margin: 24px 0 40px 0;
  padding: 14px 18px;
  background: var(--bg-alt);
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  font-size: 0.92rem;
}
.docs-shell .tutorial-toc summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.78rem;
}
.docs-shell .tutorial-toc ul {
  list-style: none;
  padding: 0;
  margin: 10px 0 0 0;
}
.docs-shell .tutorial-toc li {
  padding: 2px 0;
}
.docs-shell .tutorial-toc a {
  color: var(--text);
  text-decoration: none;
}
.docs-shell .tutorial-toc a:hover {
  text-decoration: underline;
}

/* #387 U9: on the docs hub, keep in-page navigation visible while scrolling
   80+ enumerated editorial pages. The earlier `position: sticky` made the
   full-width TOC paint over the prose beneath it (a stuck full-width box in
   a single column overlaps the content that scrolls under it). Instead, on
   wide screens we lift the TOC out of the 760px reading column entirely and
   pin it in the right-hand gutter, anchored to the column's right edge so it
   stays attached to the content at any viewport width. Below 1280px (gutter
   too narrow) it falls back to the inline boxed TOC defined above. */
@media (min-width: 1280px) {
  .docs-shell.docs-hub .tutorial-toc {
    position: fixed;
    top: 96px;
    /* right edge of the centred 760px column is at `50% + 380px`; add a
       20px gap, then a 220px panel — fits within the gutter from 1280px up. */
    left: calc(50% + 400px);
    width: 220px;
    max-height: calc(100vh - 140px);
    overflow-y: auto;
    margin: 0;
    z-index: 5;
  }
  .docs-shell.docs-hub .tutorial-toc summary {
    /* On the hub, the TOC is the primary nav — surface it open by default
       (the <details open> already does this) and use a clearer label. */
    color: var(--accent);
  }
}

.docs-shell .tutorial-footer-rule {
  margin-top: 48px;
  border: 0;
  border-top: 1px solid var(--border-subtle);
}
.docs-shell .tutorial-footer {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 24px;
}
.docs-shell .tutorial-footer .prev-tut,
.docs-shell .tutorial-footer .next-tut {
  display: flex;
  flex-direction: column;
  padding: 14px 18px;
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  text-decoration: none;
  color: var(--text);
  transition: border-color 0.15s, transform 0.15s;
}
.docs-shell .tutorial-footer .prev-tut:hover,
.docs-shell .tutorial-footer .next-tut:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
}
.docs-shell .tutorial-footer .next-tut {
  text-align: right;
}
.docs-shell .tutorial-footer .placeholder {
  visibility: hidden;
}
.docs-shell .tutorial-footer .tut-nav-dir {
  color: var(--text-muted);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.docs-shell .tutorial-footer .tut-nav-title {
  font-weight: 600;
  margin-top: 4px;
}

.docs-shell .tutorial-edit {
  text-align: center;
  margin: 20px 0 8px 0;
  font-size: 0.85rem;
}
.docs-shell .tutorial-edit a {
  color: var(--text-muted);
  text-decoration: none;
}
.docs-shell .tutorial-edit a:hover {
  color: var(--accent);
  text-decoration: underline;
}

@media (max-width: 760px) {
  .docs-shell .tutorial-footer {
    grid-template-columns: 1fr;
  }
}
