/* Roxabi — shared styles. Vanilla CSS, no preprocessor. */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  padding-bottom: 64px;
}
a { color: inherit; text-decoration: none; }
/* Prose links must be distinguishable from body text without relying on color
   (WCAG 1.4.1 A): accent + underline. */
.prose a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--accent-hover); }
img, svg, canvas { display: block; max-width: 100%; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-sm); }
#main:focus { outline: none; }

/* Skip link — first tab stop, jumps keyboard users past the nav to content. */
.skip-link {
  position: absolute; left: var(--s-sm); top: -60px; z-index: 100;
  background: var(--accent); color: var(--accent-on);
  font-weight: 600; font-size: .9rem; padding: 8px 14px; border-radius: var(--r-md);
  transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: var(--s-sm); }

/* ── Layout ───────────────────────────────────────────── */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--s-lg); }
.prose { max-width: var(--maxw-prose); }
section { padding-block: var(--s-2xl); }
.section-label {
  font-family: var(--font-mono); font-size: .75rem; font-weight: 500;
  letter-spacing: .15em; text-transform: uppercase; color: var(--accent);
  margin-bottom: var(--s-md);
}

/* ── Spacing utilities — replace inline styles so a strict CSP needs no
   style-src 'unsafe-inline' (set on Cloudflare deploy). ─────────────────── */
.mt-xl { margin-top: var(--s-xl); }
.mt-2xl { margin-top: var(--s-2xl); }
.pt-2xl { padding-top: var(--s-2xl); }
.footer-tagline { margin-top: var(--s-md); max-width: 280px; }
.footer-bottom--flush { border: 0; margin: 0; padding: 0; }

/* ── Typography ───────────────────────────────────────── */
h1, h2, h3 { line-height: 1.1; letter-spacing: -.03em; font-weight: 800; }
h1 { font-size: clamp(2.25rem, 6vw, 4rem); font-weight: 900; letter-spacing: -.04em; }
h2 { font-size: clamp(1.6rem, 3.5vw, 2.25rem); }
h3 { font-size: 1.25rem; font-weight: 600; letter-spacing: -.02em; }
p { color: var(--text-muted); }
.lead { font-size: 1.125rem; color: var(--text-muted); }
strong { color: var(--text); font-weight: 600; }
code, .mono { font-family: var(--font-mono); }
/* Inline code — subtle chip in running documentation prose. Block code
   (pre / .codeblock / .formula-box) opts out below and keeps its own surface. */
.prose code { font-size: .86em; background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-sm); padding: .08em .36em; color: var(--text); -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.prose pre code { font-size: 1em; background: none; border: none; padding: 0; border-radius: 0; color: inherit; -webkit-box-decoration-break: slice; box-decoration-break: slice; }
.codeblock pre code { color: var(--code-text); }
.formula-box pre code { color: var(--accent); font-size: .9em; }

/* ── Nav ──────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.nav-inner { position: relative; display: flex; align-items: center; gap: var(--s-lg); height: 60px; padding-inline: var(--s-lg); }
.nav-inner > *, .nav-actions > * { display: flex; align-items: center; }
.brand { gap: var(--s-sm); font-weight: 800; letter-spacing: -.02em; font-size: 1.05rem; line-height: 1; }
.brand svg, .brand img { width: 26px; height: 26px; }
.nav-links { gap: var(--s-lg); margin-left: var(--s-md); }
.nav-links a { display: inline-flex; align-items: center; line-height: 1; color: var(--text-muted); font-size: .925rem; font-weight: 500; transition: color var(--dur) var(--ease); }
.nav-links a:hover, .nav-links a[aria-current="page"] { color: var(--text); }
.nav-actions { display: flex; align-items: center; gap: var(--s-xs); margin-left: auto; }
.icon-btn {
  display: inline-grid; place-items: center; width: 36px; height: 36px;
  border: 1px solid transparent; border-radius: var(--r-md); background: transparent;
  color: var(--text-muted); cursor: pointer; transition: all var(--dur) var(--ease);
}
.icon-btn:hover { color: var(--text); background: var(--surface); border-color: var(--border); }
.icon-btn svg { width: 18px; height: 18px; }
.lang-toggle {
  font-family: var(--font-mono); font-size: .75rem; font-weight: 600; letter-spacing: .05em;
  width: auto; padding-inline: var(--s-sm); gap: 2px; line-height: 1;
}
.lang-toggle .on { color: var(--accent); }
.lang-toggle .sep { color: var(--text-dim); }

/* Mobile menu toggle (CSS-only, zero-JS): a hidden checkbox + label hamburger.
   Hidden on desktop where .nav-links shows inline; revealed under 820px. */
.nav-toggle-cb { display: none; }                 /* desktop: control unused, off the tab order */
.nav-toggle { display: none; }                    /* hamburger hidden on desktop */
.nav-toggle .i-close { display: none; }
.nav-toggle-cb:focus-visible ~ .nav-toggle { outline: 2px solid var(--accent); outline-offset: 2px; }
.nav-toggle-cb:checked ~ .nav-toggle .i-menu { display: none; }
.nav-toggle-cb:checked ~ .nav-toggle .i-close { display: block; }

/* ── Buttons ──────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: var(--s-sm);
  font-weight: 600; font-size: .95rem; padding: 10px 18px; border-radius: var(--r-md);
  border: 1px solid transparent; cursor: pointer; transition: all var(--dur) var(--ease);
  white-space: nowrap;
}
.btn-primary { background: var(--accent); color: var(--accent-on); }
.btn-primary:hover { background: var(--accent-hover); box-shadow: var(--glow-accent); transform: translateY(-1px); }
/* border is the ghost button's only affordance — must meet 1.4.11 (3:1).
   --border-hi is 1.56:1 (dark) / 1.86:1 (light); --text-muted is 6.24 / 7.02. */
.btn-ghost { background: transparent; color: var(--text); border-color: var(--text-muted); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn svg { width: 16px; height: 16px; }
.btn .star-count { font-family: var(--font-mono); font-size: .8rem; color: var(--text-muted); }
/* Tactile press feedback on all button variants. */
.btn:active { transform: translateY(0); filter: brightness(.92); }
.btn-primary:active { box-shadow: none; }
@media (prefers-reduced-motion: reduce) {
  .btn-primary:hover, .pillar:hover, a.card:hover, a.proj-card:hover, .kpi-item:hover { transform: none; }
}

/* ── Badge / eyebrow ──────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center; gap: var(--s-sm);
  font-family: var(--font-mono); font-size: .75rem; letter-spacing: .02em;
  color: var(--text-muted); padding: 5px 12px; border: 1px solid var(--border-hi);
  border-radius: var(--r-full); background: var(--surface);
}
.badge .dot { width: 6px; height: 6px; border-radius: var(--r-full); background: var(--accent); box-shadow: 0 0 8px var(--accent); }

/* ── Hero ─────────────────────────────────────────────── */
.hero { position: relative; overflow: hidden; min-height: 100vh; min-height: 100dvh; padding-block: clamp(64px, 12vw, 140px); text-align: center; }
/* Light: warm amber radial in from the right. */
:root[data-theme="light"] .hero { background: radial-gradient(ellipse 100% 120% at 100% 50%, rgba(37,99,235,.10), transparent 70%); }
/* Dark: subtle amber pool behind the hub diagram. */
:root[data-theme="dark"] .hero { background: radial-gradient(ellipse 78% 88% at 70% 42%, rgba(59,130,246,.10), transparent 72%); }
.hero::after { /* vignette: settle the diagram into the page with darker edges */
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(ellipse 72% 62% at 50% 44%, transparent 22%, var(--bg) 78%);
}
/* Kinetic-grid shader canvas — behind the vignette + content. Dark theme only:
   the shader carries its own near-black backdrop, so hide it in light to stop it
   bleeding dark over the right of the hero (also covers a runtime dark→light toggle). */
#hero-bg { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; opacity: .55; }
:root[data-theme="light"] #hero-bg { display: none; }
.hero .wrap { position: relative; z-index: 2; max-width: 1280px; }
.hero h1 { margin-block: var(--s-lg) var(--s-md); font-size: clamp(2rem, 4vw, 3.2rem); line-height: 1.07; text-wrap: balance; }
.hero .lead { font-size: 1.25rem; max-width: 620px; margin-inline: auto; }
.hero .sub { color: var(--accent); font-weight: 600; }
.hero-cta { display: flex; gap: var(--s-md); justify-content: center; margin-top: var(--s-xl); flex-wrap: wrap; }
.hero .rox-dia { width: 100%; max-width: 880px; height: auto; display: block; margin: var(--s-xl) auto 0; }
/* iso hub: depth-sorted dataflow scene built by app.js (initIso) */
#iso .grid-line { stroke: var(--border); stroke-width: 1; }
#iso .link { stroke: var(--border); stroke-opacity: .55; stroke-width: 1.2; fill: none; stroke-linecap: round; }
#iso .mlabel { font-family: var(--font-mono); font-size: 9.5px; fill: var(--text-muted); letter-spacing: .02em; }
#iso .clabel { font-family: var(--font-mono); font-size: 9px; fill: var(--accent); letter-spacing: .04em; }

/* Scroll cue — bottom-centre of the hero, gentle bob, jumps to the first section. */
.hero-scroll {
  /* Anchor to the first screen's bottom, NOT the hero's — the hero content can be
     taller than the viewport, pushing its bottom edge below the fold. Place the cue
     a fixed distance up from the fold: 100dvh − nav(60) − footer(~47) − cue/gap. */
  position: absolute; left: 50%; bottom: auto; transform: translateX(-50%); z-index: 3;
  top: calc(100vh - 185px); top: calc(100dvh - 185px);
  display: inline-flex; flex-direction: column; align-items: center; gap: 7px;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-muted); transition: color var(--dur) var(--ease);
}
.hero-scroll:hover { color: var(--accent); }
.hero-scroll-arrow { display: block; line-height: 0; }
.hero-scroll-arrow svg { width: 20px; height: 20px; display: block; }
@media (prefers-reduced-motion: no-preference) {
  .hero-scroll-arrow { animation: hero-bob 1.8s ease-in-out infinite; }
}
@keyframes hero-bob { 0%, 100% { transform: translateY(0); opacity: .7; } 50% { transform: translateY(5px); opacity: 1; } }
@media (max-width: 859px) { .hero-scroll { display: none; } }

/* Desktop: two-column hero — copy left, hub diagram right (the visual IS the message) */
@media (min-width: 860px) {
  .hero { text-align: left; }
  .hero .wrap { display: grid; grid-template-columns: .8fr 1.2fr; align-items: center; gap: 0; }
  .hero-copy { min-width: 0; }
  .hero .lead { margin-inline: 0; max-width: 46ch; }
  .hero-copy .hero-cta { justify-content: flex-start; }
  .hero .rox-dia { margin: 0; }
  /* Two-column: let the shader (and iso) read on the right, keep the copy column
     legible with a left-weighted scrim instead of a centred vignette. */
  #hero-bg { opacity: .85; }
  .hero::after {
    background:
      linear-gradient(95deg, var(--bg) 4%, color-mix(in srgb, var(--bg) 72%, transparent) 32%, transparent 64%),
      radial-gradient(ellipse 96% 96% at 52% 48%, transparent 60%, var(--bg) 100%);
  }
}

/* ── Code block (always dark terminal) ────────────────── */
.code {
  background: var(--code-bg); color: var(--code-text); border: 1px solid var(--border);
  border-radius: var(--r-lg); font-family: var(--font-mono); font-size: .875rem; line-height: 1.6;
  text-align: left; overflow: hidden; box-shadow: var(--shadow-md);
}
.code-head { display: flex; align-items: center; gap: 6px; padding: 10px 14px; border-bottom: 1px solid var(--border); }
.code-head .d { width: 11px; height: 11px; border-radius: var(--r-full); background: var(--border-hi); }
.code-head .name { margin-left: var(--s-sm); font-size: .75rem; color: var(--code-muted); }
.code pre { padding: var(--s-lg); overflow-x: auto; margin: 0; }
.code .k { color: var(--code-keyword); }
.code .s { color: var(--code-string); }
.code .c { color: var(--code-muted); }
.hero .code { max-width: 640px; margin: var(--s-xl) auto 0; }

/* ── Grid / cards ─────────────────────────────────────── */
.grid { display: grid; gap: var(--s-lg); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
/* Pillars: balanced 2×2 at desktop (auto-fit was collapsing 4 cards into an ugly 3 + 1). */
.grid-pillars { grid-template-columns: 1fr; }
@media (min-width: 680px) { .grid-pillars { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--s-lg); transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.card:hover { border-color: var(--border-hi); }
/* Cards that ARE links (stack page, doc cards): stronger affordance + arrow nudge. */
a.card { display: block; }
a.card:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: var(--shadow-md); }
.card .arrow { display: inline-block; transition: transform var(--dur) var(--ease); }
a.card:hover .arrow { transform: translateX(3px); }
.card h3 { margin-bottom: var(--s-sm); }
.card p { font-size: .95rem; }
/* mono-note: IBM Plex Mono + AA-legible muted (was Plex Sans / text-dim in cards). */
.mono-note { font-family: var(--font-mono); font-size: .75rem; color: var(--text-muted); }
.card .mono-note { font-size: .75rem; margin-top: var(--s-sm); }
.card .icon { width: 32px; height: 32px; color: var(--accent); margin-bottom: var(--s-md); }
.pillar .num { font-family: var(--font-mono); color: var(--accent); font-size: .8rem; }
.pillar:hover { transform: translateY(-2px); }

/* Project cards (portfolio) */
a.proj-card { display: block; }
a.proj-card:hover { transform: translateY(-2px); border-color: var(--accent); }
.proj-card .top { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s-md); }
.proj-card .tag { font-family: var(--font-mono); font-size: .7rem; color: var(--text-dim); border: 1px solid var(--border); border-radius: var(--r-full); padding: 3px 10px; }
.proj-card .tag.live { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.proj-card .arrow { color: var(--accent); transition: transform var(--dur) var(--ease); }
a.proj-card:hover .arrow { transform: translateX(3px); }
/* Roadmap card — replaces the old ghosted "More, soon" placeholder with a confident
   "what's next" list (full opacity, reads as momentum not an empty shelf). */
.proj-card.roadmap { display: flex; flex-direction: column; }
.roadmap-list { list-style: none; padding: 0; margin: var(--s-sm) 0 0; }
.roadmap-list li { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-md); padding: 10px 0; border-top: 1px solid var(--border); }
.roadmap-list li:first-child { border-top: 0; }
.roadmap-list .mono { color: var(--text); font-weight: 500; font-size: .95rem; }
.roadmap-list .mono-note { font-family: var(--font-mono); font-size: .78rem; color: var(--text-muted); }

/* Stat cards */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--s-md); }
.stat { text-align: center; padding: var(--s-lg); border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--panel); }
.stat .n { font-size: 1.75rem; font-weight: 900; color: var(--accent); font-family: var(--font-mono); }
.stat .l { font-size: .8rem; color: var(--text-muted); margin-top: 4px; }

/* ── Final CTA band ───────────────────────────────────── */
.cta-band { text-align: center; position: relative; overflow: hidden; border-top: 1px solid var(--border); padding-block: var(--s-xl) var(--s-2xl); }
.cta-band::before { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse 60% 80% at 50% 0%, rgba(59,130,246,.10), transparent 70%); pointer-events: none; }
.cta-band .wrap { position: relative; }
/* The band owns its padding-block + full-bleed border; the wrapping <section> must
   not add its own or it double-pads. :has targets only cta-band-only sections. */
section:has(> .cta-band) { padding-block: 0; }
.cta-band h2 { margin-bottom: var(--s-md); }
.cta-band .hero-cta { margin-top: var(--s-xl); }

/* ── Footer ───────────────────────────────────────────── */
.footer { border-top: 1px solid var(--border); padding-block: var(--s-2xl) 0; color: var(--text-muted); }
.footer-top { display: flex; flex-wrap: wrap; gap: var(--s-xl); justify-content: space-between; }
.footer-links { display: flex; gap: var(--s-xl); flex-wrap: wrap; }
.footer-col { display: flex; flex-direction: column; gap: var(--s-sm); }
.footer-col .h { color: var(--text); font-weight: 600; font-size: .85rem; margin-bottom: 2px; }
.footer-col a { color: var(--text-muted); font-size: .9rem; transition: color var(--dur) var(--ease); }
.footer-col a:hover { color: var(--accent); }
.footer-bottom { position: fixed; bottom: 0; left: 0; right: 0; z-index: 50; margin-top: 0; padding: 16px var(--s-lg) 8px; border-top: 1px solid var(--border); display: flex; flex-wrap: wrap; gap: var(--s-md); justify-content: space-between; font-size: .85rem; background: var(--bg); }
/* WCAG AA: --text-dim (#52606e) is 2.97:1 on --bg — too low for body copy. Footer
   notes use --text-muted (6.25:1). Keep --text-dim only for decorative/large text. */
.footer .mono-note { font-family: var(--font-mono); font-size: .75rem; color: var(--text-muted); }

/* ── Constitution / article layout ────────────────────── */
.doc-hero { border-bottom: 1px solid var(--border); text-align: center; padding-block: var(--s-2xl); }
.doc-hero .meta { font-family: var(--font-mono); font-size: .75rem; color: var(--text-dim); margin-top: var(--s-md); }
.constitution { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: var(--s-2xl); align-items: start; }
.const-body { min-width: 0; } /* grid item must shrink below content min-content, else wide code/figures pin the track open */
.const-body pre.code, pre.code { overflow-x: auto; max-width: 100%; } /* docs author <pre class="code">; long unwrappable lines scroll instead of overflowing the page */
.toc { position: sticky; top: 80px; font-size: .85rem; display: flex; flex-direction: column; gap: 6px; border-left: 1px solid var(--border); padding-left: var(--s-md); }
.toc a { color: var(--text-muted); padding: 2px 0; border-left: 2px solid transparent; margin-left: calc(-1 * var(--s-md) - 2px); padding-left: var(--s-md); transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.toc a:hover { color: var(--text); }
.toc a.active { color: var(--accent); font-weight: 600; border-left-color: var(--accent); }
.toc .t { color: var(--text); font-weight: 600; margin-top: var(--s-md); font-size: .8rem; }
.titre { margin-top: var(--s-2xl); }
.titre > .label { font-family: var(--font-mono); font-size: .75rem; letter-spacing: .15em; text-transform: uppercase; color: var(--accent); }
.titre > h2 { margin-top: var(--s-xs); margin-bottom: var(--s-lg); }
.article { padding: var(--s-lg) 0; border-top: 1px solid var(--border); }
.article h3 { margin-bottom: var(--s-sm); }
.article h3 .a-num { color: var(--accent); font-family: var(--font-mono); font-size: .85rem; margin-right: var(--s-sm); }
.article p + p { margin-top: var(--s-md); }
.preamble { font-size: 1.05rem; }
.preamble p { color: var(--text); }
.laws { list-style: none; counter-reset: law; padding: 0; display: grid; gap: var(--s-md); }
.laws li { counter-increment: law; padding-left: 2.5rem; position: relative; color: var(--text-muted); }
.laws li::before { content: counter(law, upper-roman); position: absolute; left: 0; top: 0; font-family: var(--font-mono); color: var(--accent); font-size: .85rem; font-weight: 600; }

/* ── Project detail page ──────────────────────────────── */
.proj-hero { border-bottom: 1px solid var(--border); padding-block: var(--s-2xl); }
.proj-hero .kicker { display: flex; align-items: center; gap: var(--s-md); margin-bottom: var(--s-md); }
.proj-hero .units { font-family: var(--font-mono); font-size: .8rem; color: var(--text-muted); }
.meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s-md); margin-top: var(--s-xl); }
.meta-grid .m { border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-md); background: var(--panel); }
.meta-grid .m .k { font-size: .72rem; text-transform: uppercase; letter-spacing: .1em; color: var(--text-dim); font-family: var(--font-mono); }
.meta-grid .m .v { color: var(--text); font-weight: 600; margin-top: 4px; }
.feature-list { list-style: none; padding: 0; display: grid; gap: var(--s-md); }
.feature-list li { padding-left: 1.75rem; position: relative; color: var(--text-muted); }
.feature-list li::before { content: ""; position: absolute; left: 0; top: .55em; width: 8px; height: 8px; background: var(--accent); border-radius: 2px; transform: rotate(45deg); }

/* ── Reveal animation (AI_Animation idiom, authored) ──── */
[data-reveal] { opacity: 0; transform: translateY(12px); transition: opacity .5s var(--ease), transform .5s var(--ease); }
[data-reveal].in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* ── Responsive ───────────────────────────────────────── */
@media (max-width: 820px) {
  /* Reveal the control to keyboards (visually hidden, still focusable) + the hamburger. */
  .nav-toggle-cb { display: block; position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
  .nav-toggle { display: inline-grid; }
  /* Primary links collapse into a dropdown panel anchored under the bar. */
  .nav-links {
    display: none; position: absolute; top: 100%; left: var(--s-lg);
    flex-direction: column; align-items: stretch; gap: 2px;
    margin: var(--s-sm) 0 0; padding: var(--s-sm); min-width: 190px;
    background: var(--surface); border: 1px solid var(--border-hi);
    border-radius: var(--r-md); box-shadow: var(--shadow-md);
  }
  .nav-toggle-cb:checked ~ .nav-links { display: flex; }
  .nav-links a { padding: 8px 10px; border-radius: var(--r-sm); }
  .nav-links a:hover, .nav-links a[aria-current="page"] { background: var(--panel); color: var(--text); }
  .constitution { grid-template-columns: 1fr; }
  .toc { display: none; }
}

/* Phones: the pinned footer bar overlaps content on short viewports — let it
   flow inline instead and drop the reserved gutter. */
@media (max-width: 600px) {
  .footer-bottom { position: static; }
  body { padding-bottom: 0; }
}
.portfolio-note { font-family: var(--font-mono); font-size: .8rem; color: var(--text-dim); margin-top: var(--s-lg); }

/* ── Documentation (collection index + tagged document pages) ───── */
.doc-cards { align-items: stretch; }
a.doc-card { display: flex; flex-direction: column; gap: var(--s-sm); }
a.doc-card:hover { transform: translateY(-2px); border-color: var(--accent); }
/* Tag chips — shared across doc cards, doc hero, and doc footer nav */
.tag { display: inline-block; font-family: var(--font-mono); font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: 2px 10px; line-height: 1.7; }
a.tag:hover { color: var(--accent); border-color: var(--accent); }
.doc-card-tags, .doc-hero-tags, .doc-nav-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.doc-hero-tags { justify-content: center; margin-top: var(--s-md); }
.doc-card h3 { margin-bottom: 0; }
.doc-card > p { font-size: .95rem; }
.doc-card .portfolio-note { margin-top: auto; padding-top: var(--s-sm); color: var(--accent); }
.doc-card .arrow { display: inline-block; transition: transform var(--dur) var(--ease); }
a.doc-card:hover .arrow { transform: translateX(3px); }

/* Document figures — schematic SVG diagrams in a framed panel (theme-aware) */
.doc-figure { margin: var(--s-xl) 0; padding: var(--s-lg); background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-lg); }
.doc-figure svg { width: 100%; height: auto; }
.doc-figure figcaption { margin-top: var(--s-md); font-family: var(--font-mono); font-size: .75rem; color: var(--text-dim); text-align: center; }

/* Key-insight callout */
.callout { margin: var(--s-lg) 0; padding: var(--s-md) var(--s-lg); border-left: 3px solid var(--accent); background: var(--surface); border-radius: 0 var(--r-md) var(--r-md) 0; }
.callout p { color: var(--text); margin: 0; }
.callout p + p { margin-top: var(--s-sm); }

/* ── Doc components — extended library ─────────────────────
   Tables, steps, KPI, timeline, compare, formula, caveat, codeblock.
   Ported from the forge visual system to Roxabi tokens (amber-only, no red/green).
   Live reference + authoring snippets: lab/docs-components.html */

/* Codeblock — labelled code panel (filename/lang header) over the always-dark code surface */
.codeblock { background: var(--code-bg); border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; margin: var(--s-lg) 0; box-shadow: var(--shadow-md); }
.codeblock-header { background: color-mix(in srgb, var(--code-text) 7%, var(--code-bg)); border-bottom: 1px solid var(--border); padding: 8px 14px; font-family: var(--font-mono); font-size: .7rem; letter-spacing: .06em; color: var(--code-muted); }
.codeblock pre { margin: 0; padding: var(--s-lg); overflow-x: auto; color: var(--code-text); font-family: var(--font-mono); font-size: .85rem; line-height: 1.6; }
.codeblock .k { color: var(--code-keyword); }
.codeblock .s { color: var(--code-string); }
.codeblock .c { color: var(--code-muted); }

/* Data table — scroll-wrapped, mono code cells */
.tbl-wrap { overflow-x: auto; margin: var(--s-lg) 0; border: 1px solid var(--border); border-radius: var(--r-md); }
table.data-table { width: 100%; border-collapse: collapse; }
.data-table th { background: var(--surface); color: var(--text-dim); font-family: var(--font-mono); font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; padding: 10px 14px; text-align: left; border-bottom: 1px solid var(--border-hi); }
.data-table td { padding: 10px 14px; border-bottom: 1px solid var(--border); color: var(--text-muted); font-size: .9rem; }
.data-table tr:last-child td { border-bottom: none; }
.data-table tr:hover td { background: var(--surface); }
.data-table td code, .data-table th code { font-family: var(--font-mono); font-size: .8rem; background: var(--surface); border: 1px solid var(--border); padding: 1px 6px; border-radius: var(--r-sm); color: var(--text); }

/* Steps — vertical numbered process with a connecting rail */
.steps { display: flex; flex-direction: column; margin: var(--s-lg) 0; }
.step { display: flex; gap: var(--s-md); position: relative; padding-bottom: var(--s-lg); }
.step:last-child { padding-bottom: 0; }
.step::after { content: ""; position: absolute; left: 14px; top: 32px; bottom: 0; width: 1px; background: var(--border); }
.step:last-child::after { display: none; }
.step-num { flex: none; width: 29px; height: 29px; display: grid; place-items: center; background: var(--surface); border: 2px solid var(--accent); border-radius: var(--r-full); font-family: var(--font-mono); font-size: .8rem; color: var(--accent); }
.step-body { flex: 1; padding-top: 2px; }
.step-title { font-weight: 600; color: var(--text); margin-bottom: 2px; }
.step-desc { font-size: .9rem; color: var(--text-muted); }

/* KPI — metric / stat row */
.kpi { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--s-md); margin: var(--s-xl) 0; }
.kpi-item { background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-md); text-align: center; transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease); }
.kpi-item:hover { border-color: var(--accent); transform: translateY(-2px); }
.kpi-value { display: block; font-size: 1.75rem; font-weight: 800; letter-spacing: -.02em; color: var(--accent); line-height: 1; margin-bottom: 6px; }
.kpi-label { display: block; font-family: var(--font-mono); font-size: .68rem; letter-spacing: .05em; color: var(--text-dim); }

/* Timeline — dated vertical list with an accent rail */
.timeline { position: relative; padding-left: var(--s-xl); margin: var(--s-lg) 0; }
.timeline::before { content: ""; position: absolute; left: 6px; top: 0; bottom: 0; width: 2px; background: linear-gradient(to bottom, var(--accent), var(--border)); }
.tl-item { position: relative; margin-bottom: var(--s-xl); }
.tl-item:last-child { margin-bottom: 0; }
.tl-item::before { content: ""; position: absolute; left: calc(-1 * var(--s-xl) + 1px); top: 5px; width: 10px; height: 10px; border-radius: var(--r-full); background: var(--accent); border: 2px solid var(--bg); }
.tl-label { font-family: var(--font-mono); font-size: .65rem; font-weight: 700; text-transform: uppercase; letter-spacing: .12em; color: var(--accent); margin-bottom: 4px; }
.tl-title { font-weight: 600; color: var(--text); margin-bottom: 4px; }
.tl-body { font-size: .9rem; color: var(--text-muted); }

/* Compare — two-column is/not (amber = affirmed, neutral = rejected; brand has no red/green) */
.compare-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-md); margin: var(--s-lg) 0; }
.compare-col { background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-lg); }
.compare-col.positive { border-top: 3px solid var(--accent); }
.compare-col.negative { border-top: 3px solid var(--border-hi); }
.compare-head { font-family: var(--font-mono); font-size: .65rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; margin-bottom: var(--s-md); color: var(--text-dim); }
.compare-col.positive .compare-head { color: var(--accent); }
.compare-item { margin-bottom: var(--s-sm); font-size: .9rem; color: var(--text-muted); }
.compare-item:last-child { margin-bottom: 0; }
.compare-item strong { display: block; color: var(--text); }

/* Formula box — math / notation panel (amber, left rule) */
.formula-box { background: var(--panel); border: 1px solid var(--border); border-left: 3px solid var(--accent); border-radius: var(--r-md); padding: var(--s-md) var(--s-lg); margin: var(--s-lg) 0; overflow-x: auto; }
.formula-box pre { margin: 0; }
.formula-box code { font-family: var(--font-mono); font-size: .9em; line-height: 1.8; color: var(--accent); }

/* Caveat grid — Q&A / objection cards */
.caveat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--s-md); margin: var(--s-lg) 0; }
.caveat-card { background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-lg); }
.caveat-q { font-weight: 600; color: var(--text); margin-bottom: var(--s-sm); }
.caveat-body { font-size: .9rem; color: var(--text-muted); }
.caveat-direction { margin-top: var(--s-sm); padding-top: var(--s-sm); border-top: 1px solid var(--border); font-size: .85rem; color: var(--text-dim); }
.caveat-direction strong { color: var(--accent); }

/* Trinity — three labelled cards (amber top rule) */
.trinity { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-md); margin: var(--s-lg) 0; }
.trinity-card { background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-lg); position: relative; }
.trinity-card::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--accent); border-radius: var(--r-md) var(--r-md) 0 0; opacity: .65; }
.trinity-label { font-family: var(--font-mono); font-size: .65rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--accent); margin-bottom: var(--s-sm); }
.trinity-title { font-weight: 600; color: var(--text); margin-bottom: 6px; }
.trinity-body { font-size: .9rem; color: var(--text-muted); }

/* Modcard — labelled section card */
.modcard { background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-lg); margin-bottom: var(--s-md); }
.modcard-label { font-family: var(--font-mono); font-size: .65rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--text-dim); margin-bottom: 6px; }
.modcard-title { font-weight: 600; color: var(--accent); margin-bottom: var(--s-sm); }
.modcard-body { font-size: .9rem; color: var(--text-muted); }
.modcard-body p + p { margin-top: var(--s-sm); }

/* ── Maxim — derived-reflexes structured maxim card ──────────
   Breaks the "Let … · C₁ … · C₂ …" prose runs into one-belief-per-line
   lists, and renders the derived-vs-naive pair as the accent/muted
   contrast the §1 figure already establishes. Ref: lab/docs-components. */
.maxim { background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-lg); padding: var(--s-lg) var(--s-xl); margin: var(--s-lg) 0; }
.maxim-head { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-xs) var(--s-md); margin-bottom: var(--s-sm); }
.maxim-id { font-family: var(--font-mono); font-size: .95rem; font-weight: 700; color: var(--accent); }
.maxim-name { font-weight: 600; color: var(--text); }
.maxim-domain { margin-left: auto; font-family: var(--font-mono); font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .12em; color: var(--text-dim); border: 1px solid var(--border); border-radius: 999px; padding: 2px 10px; }
.maxim-sub { font-family: var(--font-mono); font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--text-dim); margin: var(--s-md) 0 6px; }
.maxim-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.maxim-list li { font-size: .9rem; color: var(--text-muted); padding-left: 1.2rem; position: relative; }
.maxim-list li::before { content: "·"; position: absolute; left: .2rem; color: var(--accent); font-weight: 700; }
.maxim-list li.anti::before { content: "∉"; font-family: var(--font-mono); font-size: .72rem; top: .1em; }
.maxim-list .c { font-family: var(--font-mono); font-weight: 600; color: var(--text); margin-right: .2rem; }
.maxim-list .g { color: var(--text-dim); }
.maxim-list code { font-size: .82rem; }
/* derived-vs-naive reflex contrast */
.reflex { display: grid; gap: 6px; margin-top: var(--s-lg); }
.reflex-row { display: grid; grid-template-columns: max-content 1fr; gap: var(--s-md); align-items: baseline; padding: 8px var(--s-md); border-radius: 0 var(--r-sm) var(--r-sm) 0; background: var(--surface); }
.reflex-row .r-tag { font-family: var(--font-mono); font-size: .62rem; font-weight: 700; letter-spacing: .08em; white-space: nowrap; }
.reflex-row .r-body { font-size: .9rem; color: var(--text-muted); }
.reflex-row .r-body code { background: none; border: none; padding: 0; font-size: .85rem; }
.reflex-row.derived { border-left: 3px solid var(--accent); }
.reflex-row.derived .r-tag { color: var(--accent); }
.reflex-row.derived .r-body code { color: var(--text); }
.reflex-row.naive { border-left: 3px solid var(--border-hi); }
.reflex-row.naive .r-tag { color: var(--text-dim); }
.reflex-row.naive .r-body code { color: var(--text-dim); text-decoration: line-through; text-decoration-color: var(--text-dim); }

@media (max-width: 640px) { .compare-wrap, .trinity { grid-template-columns: 1fr; } .maxim { padding: var(--s-lg); } }

/* Per-document footer nav: the doc's tag chips + back-to-index (derived by build.py) */
.doc-nav { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-md); margin-top: var(--s-2xl); padding-top: var(--s-lg); border-top: 1px solid var(--border); }
.doc-nav .idx { font-family: var(--font-mono); font-size: .8rem; color: var(--text-dim); transition: color var(--dur) var(--ease); }
.doc-nav .idx:hover { color: var(--accent); }

/* Tag-filter bar on the docs index (revealed by app.js; JS-off shows every card) */
.doc-filter { display: flex; flex-wrap: wrap; gap: var(--s-sm); justify-content: center; margin-bottom: var(--s-xl); }
.tag-filter { font-family: var(--font-mono); font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); background: transparent; border: 1px solid var(--border); border-radius: 999px; padding: 6px 14px; cursor: pointer; transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), background var(--dur) var(--ease); }
.tag-filter:hover { color: var(--accent); border-color: var(--accent); }
.tag-filter.is-active { color: var(--accent-on); background: var(--accent); border-color: var(--accent); }
.doc-card[hidden] { display: none; }

/* bouly: subpage heroes are content-height, not full-viewport (the full-bleed hero is the home constellation only) */
.hero--page { min-height: auto; padding-block: clamp(72px, 10vh, 120px) clamp(32px, 5vh, 64px); }
/* Subpage hero shares the 1080px content measure (the 1280px hero is the home
   canvas only) — keeps the h1 left-edge aligned with the sections below it. */
.hero.hero--page .wrap { max-width: var(--maxw); }

/* bouly: decorative constellation in the right column of subpage heroes.
   Hidden below 860px (where the hero collapses to a single column). Mirrors the
   homepage graph (constellation.js) minus cards/interaction. */
.hero-graph { display: none; }
@media (min-width: 860px) {
  .hero-graph {
    display: block; position: relative;
    height: clamp(300px, 40vh, 460px);
    margin-inline-start: var(--s-lg);
  }
  /* pointer-events:auto so hover-highlight works; no wheel/drag handlers attached
     → the page still scrolls normally over the graph (no scroll-hijack). */
  .hero-graph canvas { display: block; width: 100%; height: 100%; pointer-events: auto; }
  .hero-graph-cta {
    position: absolute; right: 0; bottom: 0;
    display: inline-flex; align-items: center; gap: 0.4rem;
    font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--text-muted); text-decoration: none;
    padding: 0.32rem 0.6rem; border: 1px solid var(--border); border-radius: var(--r-sm);
    background: color-mix(in srgb, var(--panel) 72%, transparent);
    backdrop-filter: blur(4px);
    transition: color .15s, border-color .15s, background .15s;
  }
  .hero-graph-cta:hover { color: var(--accent); border-color: var(--border-hi); }
}
