/* Smart Pacts — the ONE shared component stylesheet (A7 design system).
 * Replaces the three parallel systems (index inline / event inline /
 * gallery.css). Every component is defined here exactly once and consumes
 * only tokens.css semantic tokens. Page-level <style> is reserved for true
 * one-offs (see docs/DESIGN.md).
 *
 * CONTROLLER CONTRACT: class names used by the TS controllers (.locked,
 * .entry.ok/.err, .tcard/.art/.meta/.id/.price, .mono, .muted, .num) and
 * every element id / data-act are load-bearing — renaming them silently
 * kills features. scripts/dom-contract.mjs enforces this at build time. */

/* ── base ── */
body {
  margin: 0;
  background: var(--bg-page);
  color: var(--color-text);
  font-family: var(--font-sans);
  line-height: var(--leading-body);
  -webkit-text-size-adjust: 100%;
}
::selection { background: var(--color-accent-soft); }
:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
a { color: var(--color-accent); }
a:hover { color: var(--color-accent-hover); }

h1, h2, h3, h4 { line-height: var(--leading-heading); }
h1 { font-size: var(--text-2xl); font-weight: var(--weight-semibold); letter-spacing: var(--tracking-wide); margin: var(--space-4) 0 var(--space-2); }
h2 { font-size: var(--text-lg); font-weight: var(--weight-semibold); margin: var(--space-5) 0 var(--space-3); }
h3 { font-size: var(--text-base); font-weight: var(--weight-semibold); margin: var(--space-4) 0 var(--space-2); }
h4 { font-size: var(--text-base); font-weight: var(--weight-medium); margin: var(--space-4) 0 var(--space-1); }

/* ── utilities ── */
.muted { color: var(--color-text-secondary); }
.small { font-size: var(--text-sm); }
.mono { font-family: var(--font-mono); }
.breakable { overflow-wrap: anywhere; }
.lede { color: var(--color-text-secondary); margin: 0 0 var(--space-5); font-size: var(--text-lg); }
.section-lede { color: var(--color-text-secondary); margin: 0 0 var(--space-5); }
.eyebrow {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-accent);
  margin: 0 0 var(--space-2);
}

/* ── layout containers ── */
.wrap { max-width: var(--container-md); margin: 0 auto; padding: 0 var(--gutter); }
.wrap.sm { max-width: var(--container-sm); }
.wrap.lg { max-width: var(--container-lg); }

/* ── top chrome: banner + header as ONE sticky unit ──
   Two separate sticky elements at top:0 overlap while scrolling (the nav
   slides under the banner and becomes unreachable) — the wrapper keeps the
   compliance banner permanent AND the nav always visible. */
html { scroll-padding-top: 7.5rem; }           /* anchors land below the chrome */
.top-chrome {
  position: sticky;
  top: 0;
  z-index: var(--z-banner);
}

/* ── banner (valueless / testnet) ── */
.banner {
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-size: var(--text-sm);
  text-align: center;
  padding: var(--space-2) var(--space-4);
}
.banner strong { font-weight: var(--weight-semibold); }

/* ── global header / nav ── */
.site-header {
  position: relative;                          /* anchors the mobile menu */
  background: color-mix(in srgb, var(--color-surface) 88%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: var(--border-w) solid var(--color-border);
}
.site-header .bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  max-width: var(--container-lg);
  margin: 0 auto;
  padding: var(--space-3) var(--gutter);
}
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;
}
.wordmark svg { width: 1.25rem; height: 1.25rem; display: block; }
.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  font-size: var(--text-sm);
}
.site-nav a {
  color: var(--color-text-secondary);
  text-decoration: none;
  font-weight: var(--weight-medium);
  padding: var(--space-1) 0;
  border-bottom: 2px solid transparent;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.site-nav a:hover { color: var(--color-accent); }
.site-nav a[aria-current="page"], .site-nav a.active {
  color: var(--color-text);
  border-bottom-color: var(--color-accent);
}
.menu-toggle {
  display: none;
  font: inherit;
  background: none;
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  padding: var(--space-1) var(--space-3);
  cursor: pointer;
}
@media (max-width: 48rem) {
  .menu-toggle { display: inline-block; }
  .site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: var(--z-menu);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--color-surface);
    border-bottom: var(--border-w) solid var(--color-border);
    box-shadow: var(--shadow-md);
    padding: var(--space-2) var(--gutter) var(--space-3);
  }
  .site-nav.open { display: flex; }
  .site-nav a { padding: var(--space-3) 0; border-bottom: var(--border-w) solid var(--color-border); }
  .site-nav a:last-child { border-bottom: none; }
  .site-nav a[aria-current="page"], .site-nav a.active { border-bottom-color: var(--color-border); color: var(--color-accent); }
}

/* ── sub-nav (gallery family, guide pages) ── */
.topnav {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  font-size: var(--text-sm);
  border-bottom: var(--border-w) solid var(--color-border);
  padding: var(--space-1) 0 var(--space-3);
  margin-bottom: var(--space-4);
}
.topnav a { text-decoration: none; font-weight: var(--weight-medium); }
.topnav a:hover { text-decoration: underline; }
.topnav a.here { color: var(--color-text); }

/* ── buttons ── */
.btn {
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border-w) solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  transition: border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.btn:hover { border-color: var(--color-accent); color: var(--color-text); transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.btn:active { transform: translateY(0); box-shadow: none; }
.btn.primary {
  background: linear-gradient(120deg, var(--color-accent), var(--color-accent-hover));
  color: var(--color-on-accent);
  border-color: transparent;
  box-shadow: 0 0 22px var(--color-accent-soft);
}
.btn.primary:hover { box-shadow: 0 0 30px var(--color-accent-soft), var(--shadow-sm); }
.btn.ghost { border-color: transparent; background: transparent; color: var(--color-text-secondary); }
.btn.ghost:hover { color: var(--color-accent); transform: none; box-shadow: none; }
.btn.small { padding: var(--space-1) var(--space-2); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }
.cta-row { display: flex; gap: var(--space-3); flex-wrap: wrap; margin: var(--space-4) 0 0; }

/* ── forms ── */
input, select, textarea {
  font: inherit;
  padding: var(--space-2) var(--space-2);
  border-radius: var(--radius-md);
  border: var(--border-w) solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  max-width: 100%;
}
input:focus, select:focus, textarea:focus { border-color: var(--color-accent); outline: none; }
input.wide { width: min(34rem, 100%); font-family: var(--font-mono); font-size: var(--text-sm); }
.row, .buyrow, .voterow { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin: var(--space-3) 0; }
/* WRAP, or a form row cannot fit a phone. These labels are flex rows holding
   their own text AND their control (`<label>Network <select>…</select></label>`),
   so without wrapping the label is as wide as both together — a long option such
   as "testnet06 — test tokens, full functionality" made /portal 542px and
   /gallery/create 486px wide, overflowing at EVERY phone width including 414px.
   Verify with: MOBILE_CHECK_ROUTES=… node ../pco-website/scripts/mobile-check.mjs */
.row label, .buyrow label { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; min-width: 0; }

/* `min-width: 0` above is load-bearing, not decoration. A flex item defaults to
   `min-width: auto`, which REFUSES to shrink below its content's intrinsic
   width — so wrapping alone did not help: the select's own min-content width
   (set by its longest option) still forced the row open. Both are needed.
   Form controls need the same treatment for the same reason. */
input, select, textarea, button { max-width: 100%; min-width: 0; }
details summary { cursor: pointer; color: var(--color-text-secondary); font-size: var(--text-sm); }

/* ── cards ── */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: var(--space-4);
}
.card {
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-4);
  background: var(--color-surface);
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md), var(--shadow-glow); border-color: var(--color-border-strong); }
.card h3 { font-size: var(--text-base); font-weight: var(--weight-semibold); margin: 0 0 var(--space-2); }
.card p { margin: 0; font-size: var(--text-sm); color: var(--color-text-secondary); }
.cards.accent .card h3 { color: var(--color-accent); }

/* gallery token cards — markup generated by src/gallery/ui.ts (tokenCard) */
.cards.fill { grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); }
.tcard {
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: var(--color-text);
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.tcard:hover { border-color: var(--color-accent); transform: translateY(-3px); box-shadow: var(--shadow-md), var(--shadow-glow); }
.tcard .art {
  aspect-ratio: 1;
  background: var(--color-surface-raised);
  display: grid;
  place-content: center;
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  overflow: hidden;
}
.tcard .art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tcard .meta { padding: var(--space-2) var(--space-3); }
.tcard .meta .id { font-family: var(--font-mono); font-size: var(--text-sm); overflow-wrap: anywhere; }
.tcard .meta .price { font-weight: var(--weight-semibold); margin-top: var(--space-1); }

/* ── panels & steps (interactive sections; .locked is toggled by controllers) ──
   Blueprint detail: violet corner ticks (top-left / bottom-right pseudo-elements). */
.panel, .step {
  position: relative;
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-5) var(--space-5);
  margin: var(--space-5) 0;
  background: var(--color-surface);
  transition: opacity var(--dur-base) var(--ease-out);
}
.panel::before, .step::before,
.panel::after, .step::after {
  content: '';
  position: absolute;
  width: 0.7rem;
  height: 0.7rem;
  pointer-events: none;
}
.panel::before, .step::before {
  top: -1px; left: -1px;
  border-top: 1px solid var(--tick-ink);
  border-left: 1px solid var(--tick-ink);
  border-top-left-radius: var(--radius-lg);
}
.panel::after, .step::after {
  bottom: -1px; right: -1px;
  border-bottom: 1px solid var(--tick-ink);
  border-right: 1px solid var(--tick-ink);
  border-bottom-right-radius: var(--radius-lg);
}
.panel.locked, .step.locked { opacity: 0.55; }
.panel.locked [data-act], .panel.locked input, .panel.locked select { pointer-events: none; }
.step.locked [data-act]:not([data-act="refresh-proposal"]),
.step.locked input { pointer-events: none; }
/* WalletConnect pairing panel (portal): the QR needs a light quiet zone on the dark brand,
   and must never be wider than the phone it is viewed on (rule 15b). */
#wc-pair canvas { display: block; max-width: 100%; height: auto; background: #fff; padding: var(--space-2); border-radius: var(--radius-sm); margin: var(--space-3) 0; }
#wc-pair .row { flex-wrap: wrap; }

.step h2 {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  margin: 0 0 var(--space-3);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.step h2 .n {
  display: inline-grid;
  place-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  flex-shrink: 0;
}

/* ── kv rows ── */
.kv {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin: var(--space-3) 0;
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-raised);
  border-radius: var(--radius-md);
}
.kv > span:first-child, .kv > .k {
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  min-width: 11rem;
}

/* ── operational notices (maintenance/status — NOT legal blocks; never use
      .disclaimer for these: the disclaimer gate requires those to be verbatim
      legal text) ── */
.notice {
  border: var(--border-w) solid color-mix(in srgb, var(--color-accent) 45%, var(--color-border));
  border-radius: var(--radius-md);
  background: var(--color-accent-soft);
  padding: var(--space-3) var(--space-4);
  margin: var(--space-5) 0;
  font-size: var(--text-sm);
}
.notice p { margin: var(--space-1) 0; }
.notice .lead { font-weight: var(--weight-semibold); color: var(--color-text); }
.notice .lead.err { color: var(--color-error); }

/* ── disclaimers (legal blocks — text is verbatim from the disclaimer set) ── */
.disclaimer {
  border: var(--border-w) solid var(--color-border);
  border-left: var(--border-w-accent) solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  padding: var(--space-3) var(--space-4);
  margin: var(--space-5) 0;
  font-size: var(--text-sm);
}
.disclaimer.inline { margin: var(--space-4) 0; }
.disclaimer p { margin: var(--space-1) 0; }
.disclaimer .tag {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  letter-spacing: var(--tracking-caps);
}

/* ── badges ── */
.badge {
  display: inline-block;
  font-size: var(--text-sm);
  padding: 0.1rem var(--space-2);
  border-radius: var(--radius-pill);
  border: var(--border-w) solid var(--color-border);
  color: var(--color-text-secondary);
}
.badge.on { border-color: var(--color-accent); color: var(--color-accent); }
.live-badge {
  display: inline-block;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-on-accent);
  background: var(--color-accent);
  border-radius: var(--radius-sm);
  padding: 0.1rem var(--space-2);
  margin-right: var(--space-2);
  vertical-align: 0.1rem;
}
.dot {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--color-accent);
  margin-right: 0.35rem;
  vertical-align: 0.05rem;
}
@media (prefers-reduced-motion: no-preference) {
  .dot.pulse { animation: sp-pulse 2.4s var(--ease-in-out) infinite; }
  @keyframes sp-pulse {
    0%, 100% { box-shadow: 0 0 0 0 var(--color-accent-soft); }
    50% { box-shadow: 0 0 0 5px var(--color-accent-soft); }
  }
}

/* ── tables ── */
.tablewrap { overflow-x: auto; margin: var(--space-2) 0; }
table.plain, .bychain table { border-collapse: collapse; width: 100%; font-size: var(--text-sm); }
table.plain th, table.plain td,
.bychain th, .bychain td {
  padding: var(--space-1) var(--space-2);
  border-bottom: var(--border-w) solid var(--color-border);
  text-align: left;
}
table.plain td.num, table.plain th.num,
.bychain th.num, .bychain td.num { text-align: right; font-family: var(--font-mono); }
.bychain tfoot td {
  border-bottom: none;
  border-top: 2px solid var(--color-border);
  font-weight: var(--weight-semibold);
}

/* ── tally bar (event vote) ── */
.tally { margin: var(--space-4) 0; }
.bar { display: flex; height: 0.75rem; border-radius: var(--radius-sm); overflow: hidden; background: var(--color-border); }
.bar .yes { background: var(--color-accent); transition: width var(--dur-slow) var(--ease-out); }
.bar .no { background: var(--sp-slate); transition: width var(--dur-slow) var(--ease-out); }
.tally-nums { display: flex; gap: var(--space-5); margin: var(--space-2) 0; font-size: var(--text-sm); flex-wrap: wrap; }

/* ── DOCKED activity log ──
   🔴 WHY THIS IS PINNED TO THE VIEWPORT. The log used to sit at the very bottom of a
   long page, so a refusal — "your balance covers at most 0" — was written where nobody
   was looking, and the action read as the button doing nothing. Feedback you have to
   go and find is not feedback. It now follows the reader.
   Controllers PREPEND entries, so the newest is at the top and no autoscroll is needed. */
.log-dock {
  position: fixed;
  right: var(--space-4);
  bottom: var(--space-4);
  z-index: var(--z-dock);
  width: min(24rem, calc(100vw - var(--space-8)));
  /* Load-bearing on phones: a flex item defaults to min-width:auto and refuses to
     shrink below its content, so a long <select> option sets the page's floor and the
     layout overflows every phone width. flex-wrap alone does not fix it. */
  min-width: 0;
}
.log-dock .log-panel {
  background: var(--color-surface-raised);
  border: var(--border-w) solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.log-dock summary {
  cursor: pointer;
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  user-select: none;
}
.log-dock summary:focus-visible { outline: var(--border-w-accent) solid var(--color-focus); }
.log-dock #log { margin: 0; max-height: 40vh; overflow-y: auto; padding: 0 var(--space-3) var(--space-3); }
.log-dock .log-hint { margin: 0 var(--space-3) var(--space-3); }
/* hide the placeholder as soon as there is anything real to read */
.log-dock .log-panel:has(#log .entry) .log-hint { display: none; }
/* keep the dock from sitting permanently on top of the footer */
body:has(.log-dock) { padding-bottom: var(--space-10); }

@media (max-width: 40rem) {
  .log-dock { left: var(--space-3); right: var(--space-3); bottom: var(--space-3); width: auto; }
  .log-dock #log { max-height: 30vh; }
}
@media (prefers-reduced-motion: no-preference) {
  .log-dock .log-panel { transition: box-shadow var(--dur-fast) ease; }
}

/* ── activity log (controllers prepend .entry nodes) ── */
#log { margin: var(--space-5) 0 0; font-family: var(--font-mono); font-size: var(--text-sm); }
#log .entry {
  padding: var(--space-2) var(--space-3);
  margin: var(--space-2) 0;
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  overflow-wrap: anywhere;
}
#log .entry.ok { border-left: var(--border-w-accent) solid var(--color-accent); }
#log .entry.err { border-left: var(--border-w-accent) solid var(--color-error); }
#log .entry a { color: var(--color-accent); }

/* ── code / teasers ── */
pre.teaser, .teaser {
  margin: var(--space-5) 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-raised);
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-md);
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.55;
}
.teaser code { font-family: var(--font-mono); font-size: var(--text-sm); }

/* ── toc (guide pages) ── */
.toc {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-2) var(--space-3);
  margin: var(--space-5) 0;
}

/* ── markdown bodies (guide pages) ── */
.mdbody h1 { font-size: var(--text-2xl); }
.mdbody h2 { font-size: var(--text-lg); margin: var(--space-5) 0 var(--space-2); }
.mdbody h3 { font-size: var(--text-base); }
.mdbody code { font-family: var(--font-mono); font-size: 0.92em; background: var(--color-surface-raised); padding: 0.08em 0.35em; border-radius: var(--radius-sm); overflow-wrap: anywhere; }
.mdbody pre { background: var(--color-surface-raised); border: var(--border-w) solid var(--color-border); border-radius: var(--radius-lg); padding: var(--space-3) var(--space-4); overflow-x: auto; }
.mdbody pre code { background: none; padding: 0; }
.mdbody table { border-collapse: collapse; width: 100%; font-size: var(--text-sm); margin: var(--space-3) 0; display: block; overflow-x: auto; }
.mdbody th, .mdbody td { padding: var(--space-1) var(--space-2); border: var(--border-w) solid var(--color-border); text-align: left; }
.mdbody blockquote { border-left: var(--border-w-accent) solid var(--color-accent); margin: var(--space-4) 0; padding: var(--space-1) var(--space-4); background: var(--color-surface-raised); border-radius: 0 var(--radius-md) var(--radius-md) 0; }
.mdbody blockquote p { margin: var(--space-1) 0; }
.mdbody li { margin: var(--space-1) 0; }
.mdbody img { width: 100%; height: auto; display: block; margin: var(--space-3) auto; border: var(--border-w) solid var(--color-border); border-radius: var(--radius-lg); }
.mdbody img.tall { width: min(100%, 340px); }
.mdbody img.photo { width: min(100%, 460px); }

/* ── token detail art ── */
.detail-art {
  max-width: 26rem;
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface-raised);
}
.detail-art img { width: 100%; display: block; }

/* ── experiments (event page) ── */
.exp { border-top: var(--border-w) solid var(--color-border); padding-top: var(--space-3); margin-top: var(--space-4); }
.exp h3 { margin: 0 0 var(--space-1); }
.exp ol { margin: var(--space-1) 0 var(--space-2) 1.2rem; padding: 0; }
.exp li { margin: var(--space-1) 0; }

/* ── strand divider (the braid at rest) ── */
.strand-rule {
  height: 14px;
  background: var(--strand-rule) repeat-x center / 220px 14px;
  margin: var(--space-8) 0 var(--space-5);
}

/* ── stat strip (count-up numbers; site-ui.ts animates [data-count]) ── */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: var(--space-4);
  margin: var(--space-6) 0;
  border-top: var(--border-w) solid var(--color-border);
  border-bottom: var(--border-w) solid var(--color-border);
  padding: var(--space-5) 0;
}
.stat { text-align: center; padding: var(--space-4) var(--space-2); }
.stat .num {
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  font-weight: var(--weight-medium);
  color: var(--color-accent);
  display: block;
  font-variant-numeric: tabular-nums;
}
.stat .label { font-size: var(--text-sm); color: var(--color-text-secondary); }

/* ── scroll reveal (site-ui.ts adds .pre off-screen, .in on entry) ── */
@media (prefers-reduced-motion: no-preference) {
  [data-reveal].pre { opacity: 0; transform: translateY(14px); }
  [data-reveal].in {
    opacity: 1;
    transform: none;
    transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
  }
}

/* ── global footer ── */
.site-footer {
  border-top: var(--border-w) solid var(--color-border);
  margin-top: var(--space-9);
  padding: var(--space-7) 0 var(--space-7);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  background: var(--color-surface-sunken);
}
.site-footer .cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: var(--space-5);
  max-width: var(--container-lg);
  margin: 0 auto var(--space-5);
  padding: 0 var(--gutter);
}
.site-footer .col .col-h {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-text);
  margin: 0 0 var(--space-2);
}
.site-footer .col ul { list-style: none; margin: 0; padding: 0; }
.site-footer .col li { margin: var(--space-2) 0; }
.site-footer .col a { color: var(--color-text-secondary); text-decoration: none; }
.site-footer .col a:hover { color: var(--color-accent); text-decoration: underline; }
.site-footer .legal {
  max-width: var(--container-lg);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.site-footer .legal .disclaimer { background: var(--color-surface-raised); }
.site-footer .fine { margin: var(--space-4) 0 0; }

/* ── legal / prose pages ── */
.prose h2 { margin-top: var(--space-6); }
.prose ul { padding-left: 1.2rem; }
.prose li { margin: var(--space-1) 0; }

/* ── misc ── */
.guide-link { color: var(--color-accent); font-weight: var(--weight-medium); text-decoration: none; }
.guide-link:hover { text-decoration: underline; }
.foot {
  margin-top: var(--space-7);
  border-top: var(--border-w) solid var(--color-border);
  padding-top: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.foot .mono { color: var(--color-text); }
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--color-surface);
  color: var(--color-accent);
  padding: var(--space-2) var(--space-3);
  z-index: 40;
}
.skip-link:focus { left: 0; }
