/* =========================================================================
   Nomos — Civic Futurism
   Hand-written CSS. No build step, no framework. Server-less static site.
   Tokens → base → layout → components → sections → responsive → motion.
   ========================================================================= */

/* ---- Tokens ------------------------------------------------------------- */
:root {
  /* Core neutrals */
  --ink: #141413;
  --archive: #faf9f5;
  --stone: #e8e6dc;
  /* Secondary text. Darkened from the original #b0aea5 (≈2.2:1 on white — failed
     WCAG body-text contrast) to ≈4.9:1. Same warm-gray hue, actually readable. */
  --ash: #6e6c63;
  /* Truly faint warm gray for decorative-only uses (muted dots, dashed edges). */
  --ash-faint: #b0aea5;
  --card: #ffffff;

  /* Brand */
  --paleblue: #dde6ea;
  --civic: #4e7c9b;
  --civic-ink: #3a5e76;     /* darker civic for hover / on-light text */
  --civic-btn: #3a5e76;     /* button fill — 6.9:1 on white, passes WCAG AA */
  --civic-btn-hover: #2e4d61;
  --slate-deep: #23313a;

  /* Functional severity (status + evidence only; always paired with a label) */
  --verdict: #6f8a63;
  --breach: #b65a50;
  --warning: #c08a45;

  /* Type — one grotesque sitewide (Hanken Grotesk, the b7-prototype face,
     unified across home + sub-pages) with IBM Plex Mono carrying the
     machine-readable evidence/label register (genuinely earned). */
  --font-display: "Hanken Grotesk", system-ui, "Segoe UI", Arial, sans-serif;
  --font-sans: "Hanken Grotesk", system-ui, "Segoe UI", Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* Rhythm */
  --maxw: 72rem;
  --maxw-narrow: 54rem;
  --gutter: clamp(1.15rem, 4vw, 2.25rem);
  --radius: 12px;
  --radius-sm: 8px;
  --border: 1px solid var(--stone);

  /* Elevation — soft, hue-tinted shadows (toward ink, never pure black; blur
     kept modest). Used for real grouping/depth, never paired with a border on
     the same element (pick one). */
  /* Top specular edge — the b7 "lit edge", promoted sitewide. Reads as a
     precision-machined surface even on opaque white cards. */
  --edge-spec: inset 0 1px 0 rgba(255, 255, 255, 0.72);
  --shadow-sm: 0 1px 2px rgba(20, 20, 19, 0.05), 0 1px 1px rgba(20, 20, 19, 0.04);
  --shadow-md: 0 6px 18px -8px rgba(20, 20, 19, 0.18), 0 2px 6px -4px rgba(20, 20, 19, 0.10);
  --shadow-lg: 0 18px 44px -16px rgba(20, 20, 19, 0.24), 0 6px 14px -10px rgba(35, 49, 58, 0.16);
  --shadow-civic: 0 14px 40px -18px rgba(78, 124, 155, 0.42);

  /* Motion (Emil: strong custom curves, never weak CSS defaults) */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);   /* confident, decisive */
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
}

/* ---- Reset / base ------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--archive);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.025em;
  color: var(--ink);
  text-wrap: balance;
}

p { text-wrap: pretty; }

p { margin: 0; }

a { color: var(--civic-ink); text-decoration: none; }
a:hover { color: var(--ink); }

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

::selection { background: var(--paleblue); color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--civic);
  outline-offset: 2px;
  border-radius: 2px;
}
/* On the civic-blue primary button, a civic outline has too little contrast —
   switch to ink so the focus ring is always visible. */
.btn--primary:focus-visible { outline-color: var(--ink); }
/* On dark slate surfaces (cta-card), the civic ring is low-contrast — use archive. */
.cta-card :focus-visible,
.btn--ghost-dark:focus-visible { outline-color: var(--archive); }

/* Skip link — visible only when focused, for keyboard users. */
.skip-link {
  position: absolute;
  left: 0.75rem;
  top: -3rem;
  z-index: 100;
  background: var(--ink);
  color: var(--archive);
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  transition: top 160ms var(--ease-out);
}
.skip-link:focus { top: 0.75rem; color: var(--archive); }

/* ---- Layout primitives -------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: clamp(3.75rem, 8vw, 7.5rem);
  /* Thinner rule than the card border — sections separate, cards contain. */
  border-top: 1px solid color-mix(in srgb, var(--stone) 70%, transparent);
  /* clear the 66px sticky nav when jumped to via an in-page anchor */
  scroll-margin-top: 78px;
}
.section--wash { background: var(--paleblue); }
.section--flush { border-top: none; }

.measure { max-width: 65ch; }

/* Eyebrow — used sparingly (≈ 1 per 3 sections), never above every header */
.eyebrow {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
  margin: 0 0 1.1rem;
}

.section-head { max-width: 46rem; margin-bottom: clamp(2rem, 4vw, 3rem); }

/* Chip eyebrow — the b7 hero chip promoted as a shared page-hero treatment.
   Opaque tint on light sub-pages (no blur needed); b7 re-skins it to glass. */
.eyebrow--chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.36rem 0.8rem;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--paleblue) 55%, transparent);
  border: 1px solid color-mix(in srgb, var(--civic) 22%, var(--stone));
  color: var(--civic-ink);
  margin-bottom: 1.25rem;
}
.section-head h2 {
  font-size: clamp(1.85rem, 3.8vw, 2.8rem);
}
.section-head .lede {
  margin-top: 1rem;
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  color: var(--ash);
  max-width: 60ch;
}
.section-head .lede strong { color: var(--ink); font-weight: 500; }

/* ---- Buttons ------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1;
  padding: 0.8rem 1.25rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: transform 160ms var(--ease-out), background-color 160ms var(--ease-out),
    border-color 160ms var(--ease-out), color 160ms var(--ease-out);
}
.btn:active { transform: scale(0.97); }

.btn--primary {
  background: var(--civic-btn);
  color: #fff;
  box-shadow: var(--shadow-sm);
}
.btn--primary:hover { background: var(--civic-btn-hover); color: #fff; }
@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover { transform: translateY(-1px); box-shadow: var(--shadow-civic); }
  .btn--primary:active { transform: scale(0.97); box-shadow: var(--shadow-sm); }
}

.btn--secondary {
  background: transparent;
  color: var(--ink);
  border-color: var(--stone);
}
.btn--secondary:hover { border-color: var(--civic); color: var(--civic-ink); }

.btn--ghost-dark {
  background: transparent;
  color: var(--archive);
  border-color: rgba(250, 249, 245, 0.28);
}
.btn--ghost-dark:hover { border-color: var(--archive); }

.btn .arrow { transition: transform 200ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover .arrow { transform: translateX(3px); }
}

/* ---- Cards -------------------------------------------------------------- */
.card {
  background: var(--card);
  border: var(--border);
  border-radius: var(--radius);
  padding: 1.6rem;
  box-shadow: var(--edge-spec);
  transition: transform 220ms var(--ease-out), box-shadow 220ms var(--ease-out),
    border-color 220ms var(--ease-out);
}
.card h3 { font-size: 1.12rem; margin-bottom: 0.5rem; transition: color 200ms var(--ease-out); }
.card p { color: var(--ash); font-size: 0.95rem; }
@media (hover: hover) and (pointer: fine) {
  .card:hover { transform: translateY(-3px); box-shadow: var(--edge-spec), var(--shadow-md); border-color: color-mix(in srgb, var(--civic) 35%, var(--stone)); }
  .card:hover h3 { color: var(--civic-ink); }
}

/* ---- Severity badge (color ALWAYS paired with a text label) ------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.5rem;
  border-radius: 3px;
  border: 1px solid;
}
.badge::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.badge--breach  { color: var(--breach);  border-color: color-mix(in srgb, var(--breach) 40%, transparent);  background: color-mix(in srgb, var(--breach) 7%, transparent); }
.badge--warning { color: var(--warning); border-color: color-mix(in srgb, var(--warning) 40%, transparent); background: color-mix(in srgb, var(--warning) 7%, transparent); }
.badge--verdict { color: var(--verdict); border-color: color-mix(in srgb, var(--verdict) 40%, transparent); background: color-mix(in srgb, var(--verdict) 8%, transparent); }

/* =========================================================================
   Site chrome — nav + footer
   ========================================================================= */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--archive) 86%, transparent);
  backdrop-filter: blur(14px) saturate(1.15);
  -webkit-backdrop-filter: blur(14px) saturate(1.15);
  border-bottom: var(--border);
}
.nav__inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: 66px;
}
/* Nav condenses once the page is scrolled — a slightly deeper edge so it reads
   as lifted above the content it now overlaps. */
.nav { transition: box-shadow 220ms var(--ease-out); }
.nav.is-scrolled { box-shadow: var(--shadow-sm); }

/* Scroll-progress rule along the nav's lower edge. Width tracks reading progress
   exactly (set by main.js); no easing so it stays an honest position indicator. */
.nav__progress {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  transform: scaleX(var(--sp, 0));
  transform-origin: left center;
  background: linear-gradient(90deg, var(--civic), color-mix(in srgb, var(--civic) 55%, var(--paleblue)));
  z-index: 1;
}
.brand { display: inline-flex; align-items: center; gap: 0.55rem; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); }
.brand:hover { color: var(--ink); }
.brand__mark { width: 26px; height: 26px; flex: none; }
.brand__name { font-size: 1.08rem; }

.nav__links {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  margin-left: 0.5rem;
  list-style: none;
  padding: 0;
}
.nav__links a {
  position: relative;
  font-size: 0.9rem;
  color: var(--ink);
  opacity: 0.78;
  padding-block: 0.4rem;
  transition: opacity 150ms var(--ease-out);
}
.nav__links a:hover { opacity: 1; color: var(--ink); }
/* Scrollspy active state — a small civic underline tracks the section in view. */
.nav__links a.is-active { opacity: 1; }
.nav__links a.is-active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background: var(--civic);
  border-radius: 1px;
}

.nav__cta { margin-left: auto; display: flex; align-items: center; gap: 0.65rem; }

.nav__toggle {
  display: none;
  margin-left: auto;
  background: transparent;
  border: var(--border);
  border-radius: var(--radius-sm);
  width: 42px; height: 38px;
  cursor: pointer;
  align-items: center;
  justify-content: center;
}
.nav__toggle svg { width: 20px; height: 20px; }

.nav__mobile {
  display: none;
  border-top: var(--border);
  background: var(--archive);
  padding: 0.5rem var(--gutter) 1.25rem;
}
.nav__mobile a {
  display: block;
  padding: 0.7rem 0;
  font-size: 1rem;
  color: var(--ink);
  border-bottom: var(--border);
}
.nav__mobile .btn { margin-top: 1rem; width: 100%; justify-content: center; }
.nav__mobile[data-open="true"] { display: block; }

.footer {
  background: var(--archive);
  border-top: var(--border);
  padding-block: clamp(2.5rem, 5vw, 4rem) 2rem;
}
.footer__grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: 2.5rem;
}
.footer__brand p { color: var(--ash); font-size: 0.9rem; margin-top: 0.9rem; max-width: 30ch; }
.footer__col h4 {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
  font-weight: 500;
  margin-bottom: 0.9rem;
}
.footer__col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.footer__col a { font-size: 0.92rem; color: var(--ink); opacity: 0.8; }
.footer__col a:hover { opacity: 1; }
.footer__base {
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  margin-top: 3rem; padding-top: 1.5rem; border-top: var(--border);
  font-size: 0.82rem; color: var(--ash);
}

/* =========================================================================
   Hero
   ========================================================================= */
.hero {
  padding-block: clamp(3rem, 6vw, 5.5rem) clamp(3.5rem, 7vw, 6rem);
  position: relative;
  isolation: isolate;
}
/* Distinctive moment: a faint archival "margin rule" runs down the page edge of
   the hero — the civic rulebook's ruled margin, barely there. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 100%;
  z-index: -1;
  background-image: linear-gradient(to right, color-mix(in srgb, var(--civic) 22%, transparent) 0, transparent 1px);
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-position: var(--gutter) 0;
  opacity: 0.6;
}
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.hero h1 {
  font-size: clamp(2.5rem, 5.6vw, 4.25rem);
  letter-spacing: -0.04em;
  line-height: 1.02;
}
.hero__sub {
  margin-top: 1.4rem;
  font-size: clamp(1.08rem, 1.7vw, 1.3rem);
  line-height: 1.5;
  color: var(--ash);
  max-width: 40ch;
}
.hero__sub strong { color: var(--ink); font-weight: 500; }
.hero__cta { margin-top: 2rem; display: flex; gap: 0.75rem; flex-wrap: wrap; }
.hero__note {
  margin-top: 1.6rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ash);
  letter-spacing: 0.01em;
}

/* System-map diagram wrapper — the hero's signature visual. Given a real
   surface (subtle card + soft shadow) so it reads as a live control plane
   panel, not a flat inline drawing. */
.systemmap {
  width: 100%;
  background: linear-gradient(180deg, color-mix(in srgb, var(--card) 100%, transparent), color-mix(in srgb, var(--paleblue) 22%, var(--card)));
  border: 1px solid color-mix(in srgb, var(--civic) 14%, var(--stone));
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: clamp(0.75rem, 2vw, 1.25rem);
}
.systemmap svg { width: 100%; height: auto; display: block; }
.systemmap__fallback { display: none; } /* shown on small screens (see media query) */

/* Travelling packets — small civic dots that ride the connector paths to make
   the control plane feel "quietly alive". Injected by main.js as <circle> on
   the flow group; the offset-path is set inline per path. Pure decoration in
   service of the product story; removed under reduced motion. */
.systemmap__packet {
  fill: var(--civic);
  opacity: 0;
  animation: packet-travel 3.4s var(--ease-in-out) infinite;
}
@keyframes packet-travel {
  0%   { offset-distance: 0%;   opacity: 0; }
  12%  { opacity: 0.9; }
  82%  { opacity: 0.9; }
  100% { offset-distance: 100%; opacity: 0; }
}

/* Signature moment: the control-plane connectors draw themselves in on load —
   a "live, quietly alive" control plane, not a static diagram. */
.systemmap__flow path {
  stroke-dasharray: 320;
  stroke-dashoffset: 320;
  animation: flow-draw 1.1s var(--ease-out) forwards;
}
.systemmap__flow:first-of-type path { animation-delay: 0.25s; }
.systemmap__flow:last-of-type path { animation-delay: 0.7s; }
.systemmap__flow path:nth-child(2) { animation-delay: 0.06s; }
.systemmap__flow path:nth-child(3) { animation-delay: 0.12s; }
.systemmap__flow path:nth-child(4) { animation-delay: 0.18s; }
.systemmap__flow path:nth-child(5) { animation-delay: 0.24s; }
.systemmap__flow path:nth-child(6) { animation-delay: 0.30s; }
.systemmap__flow path:nth-child(7) { animation-delay: 0.36s; }
@keyframes flow-draw { to { stroke-dashoffset: 0; } }

/* Live stage status — each stage's civic dot lights in sequence, so the Nomos
   panel reads as a control plane processing, not a static list. The last stage
   (Publish) confirms with an expanding ring. Labels stay full-opacity for
   legibility; only the small status dots animate. */
.systemmap__stagedot {
  fill: var(--civic);
  opacity: 0.28;
  animation: stage-dot 3.4s var(--ease-in-out) infinite;
  animation-delay: calc(var(--s, 0) * 0.32s);
}
@keyframes stage-dot {
  0%   { opacity: 0.28; }
  7%   { opacity: 1; }
  20%  { opacity: 0.55; }
  30%  { opacity: 0.28; }
  100% { opacity: 0.28; }
}
/* Publish "confirm" — a civic ring pulses out just after Publish's dot lights
   (its --s is 3, so ~0.96s into the 3.4s cycle → ~28%). */
.systemmap__stagepulse {
  fill: none;
  stroke: var(--civic);
  stroke-width: 1.4;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: stage-confirm 3.4s var(--ease-out) infinite;
  animation-delay: 0.96s;
}
@keyframes stage-confirm {
  0%, 22% { transform: scale(1); opacity: 0; }
  30%     { transform: scale(1); opacity: 0.85; }
  55%     { transform: scale(3.4); opacity: 0; }
  100%    { transform: scale(3.4); opacity: 0; }
}

/* =========================================================================
   Problem — numbered pain list
   ========================================================================= */
.pains {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem 2.5rem;
  counter-reset: pain;
  margin-top: 0.5rem;
}
.pains li {
  list-style: none;
  display: flex;
  gap: 0.9rem;
  padding: 1rem 0.75rem 1rem 0.6rem;
  border-top: var(--border);
  align-items: baseline;
  border-radius: var(--radius-sm);
  transition: background-color 200ms var(--ease-out);
}
.pains li::before {
  counter-increment: pain;
  content: counter(pain, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--civic);
  flex: none;
  font-variant-numeric: tabular-nums;
}
.pains li span { font-size: 1rem; }
@media (hover: hover) and (pointer: fine) {
  .pains li:hover { background: color-mix(in srgb, var(--paleblue) 40%, transparent); }
}
.problem__kicker {
  margin-top: 2.5rem;
  font-size: clamp(1.1rem, 1.8vw, 1.35rem);
  max-width: 54ch;
}
.problem__kicker strong { font-weight: 600; }

/* =========================================================================
   Core claim — editorial / serif moment
   ========================================================================= */
.claim { text-align: left; }
.claim__big {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.1rem, 4.8vw, 3.6rem);
  line-height: 1.1;
  letter-spacing: -0.025em;
  max-width: 18ch;
}
/* Emphasis: a true Hanken italic carries the one emphasized phrase. */
.claim__big em { font-family: inherit; font-style: italic; font-weight: 500; color: var(--civic-ink); }
.claim__body {
  margin-top: 1.75rem;
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  color: var(--ash);
  max-width: 56ch;
}
.claim__body strong { color: var(--ink); font-weight: 500; }

/* =========================================================================
   How it works — horizontal stepped flow → vertical timeline on mobile
   ========================================================================= */
.flow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0;
  margin-top: 1rem;
}
.flow__step { padding: 1.4rem 1.1rem 1.4rem 0; position: relative; }
.flow__step:not(:last-child) { border-right: var(--border); padding-inline: 0 1.1rem; }
.flow__step + .flow__step { padding-left: 1.1rem; }
/* A small civic tick at each step head — flow cue, not an AI "01/02" index. */
.flow__step h3 { font-size: 1.02rem; margin: 0.2rem 0 0.5rem; }
.flow__step h3::before {
  content: "";
  display: block;
  width: 18px;
  height: 2px;
  background: var(--civic);
  margin-bottom: 0.7rem;
}
.flow__step p { font-size: 0.85rem; color: var(--ash); line-height: 1.45; }

/* =========================================================================
   Govern deep dive — the wedge (two columns)
   ========================================================================= */
.govern__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.govern__col h3 { font-size: 1.15rem; margin-bottom: 1.1rem; }

/* example violations — evidence-style rows */
.violations { display: grid; gap: 0.6rem; }
.violation {
  display: flex; align-items: center; gap: 0.9rem;
  padding: 0.85rem 1rem;
  background: var(--card);
  border: var(--border);
  border-radius: var(--radius-sm);
  transition: transform 200ms var(--ease-out), box-shadow 200ms var(--ease-out),
    border-color 200ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .violation:hover { transform: translateX(3px); box-shadow: var(--shadow-sm); border-color: color-mix(in srgb, var(--breach) 25%, var(--stone)); }
}
.violation__text { font-size: 0.92rem; }
.violation .badge { margin-left: auto; flex: none; }

/* vocabulary translation — definition grid */
.lexicon { display: grid; gap: 0; }
.lexicon__row {
  display: grid;
  grid-template-columns: 8.5rem 1fr;
  gap: 1rem;
  padding: 0.85rem 0;
  border-top: var(--border);
  align-items: baseline;
}
.lexicon__term {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink);
  font-weight: 500;
}
.lexicon__def { font-size: 0.92rem; color: var(--ash); }

/* govern pipeline strip */
.pipeline {
  margin-top: 2.75rem;
  padding: 1.5rem;
  background: var(--card);
  border: var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-mono);
  font-size: 0.82rem;
}
.pipeline__node {
  padding: 0.4rem 0.7rem;
  border: var(--border);
  border-radius: 5px;
  color: var(--ink);
  white-space: nowrap;
  background: var(--card);
}
.pipeline__node--state {
  border-color: color-mix(in srgb, var(--civic) 45%, var(--stone));
  color: var(--civic-ink);
  background: color-mix(in srgb, var(--paleblue) 50%, var(--card));
}
.pipeline__arrow { color: var(--ash); transition: color 300ms var(--ease-out); }

/* Pipeline draws itself node-by-node when scrolled into view (it IS a process —
   motion is motivated). main.js adds .is-drawn; each node/arrow staggers in. */
.js .pipeline.reveal--pipeline .pipeline__node,
.js .pipeline.reveal--pipeline .pipeline__arrow {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 360ms var(--ease-out), transform 360ms var(--ease-out);
}
.pipeline.reveal--pipeline.is-drawn .pipeline__node,
.pipeline.reveal--pipeline.is-drawn .pipeline__arrow {
  opacity: 1;
  transform: none;
  transition-delay: calc(var(--n, 0) * 90ms);
}
.pipeline.reveal--pipeline.is-drawn .pipeline__arrow { color: var(--civic); }

/* =========================================================================
   Reconcile / Reporting — split text + visual
   ========================================================================= */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.split--reverse .split__media { order: -1; }
.split__copy .lede { margin-top: 1rem; }
.evidence__grid .lede { margin-top: 1rem; }

/* tiny reconciliation ledger visual */
.ledger {
  background: var(--card);
  border: var(--border);
  border-radius: var(--radius);
  padding: 0.4rem 0;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  box-shadow: var(--shadow-md);
}
.ledger__row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 1rem;
  padding: 0.7rem 1.2rem;
  align-items: center;
}
.ledger__row + .ledger__row { border-top: var(--border); }
.ledger__row--head { color: var(--ash); font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; }
.ledger__label { color: var(--ink); }
.ledger__num { color: var(--ink); font-variant-numeric: tabular-nums; }
.ledger__delta { font-variant-numeric: tabular-nums; }
.ledger__delta--ok { color: var(--verdict); }
.ledger__delta--off { color: var(--breach); }

/* reporting outputs grid */
.outputs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem; }
.output {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.9rem 1rem;
  border: var(--border);
  border-radius: var(--radius-sm);
  background: var(--card);
  font-size: 0.92rem;
}
.output svg { width: 18px; height: 18px; color: var(--civic); flex: none; }

/* =========================================================================
   Use cases — card grid
   ========================================================================= */
.usecases { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.usecase__tag {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--civic);
}
.usecase h3 { font-size: 1.06rem; margin: 0.7rem 0 0.5rem; }

/* =========================================================================
   Evidence / proof — the mono audit card
   ========================================================================= */
.evidence__grid { display: grid; grid-template-columns: 1fr 1.1fr; gap: clamp(2rem, 5vw, 4rem); align-items: start; }
.evidence-card {
  background: var(--card);
  border: var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  box-shadow: var(--edge-spec), var(--shadow-md);
}
.evidence-card__head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.85rem 1.15rem;
  background: var(--paleblue);
  border-bottom: var(--border);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  color: var(--ink);
}
.evidence-row {
  display: flex; justify-content: space-between; gap: 1.5rem;
  padding: 0.7rem 1.15rem;
  border-bottom: var(--border);
}
.evidence-row:last-child { border-bottom: none; }
.evidence-key { color: var(--ash); }
.evidence-val { color: var(--ink); text-align: right; word-break: break-word; }

/* Determinism proof — the card's signature moment. When it scrolls into view a
   faint civic "verify" band sweeps down the card, both read figures count up
   (via main.js), and on landing identically the two read rows resolve to the
   verdict colour — motion that PROVES "same as-at → same number". */
.evidence-card[data-proof] { position: relative; }
.js .evidence-card[data-proof]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 42%;
  background: linear-gradient(180deg,
    transparent,
    color-mix(in srgb, var(--civic) 14%, transparent) 70%,
    color-mix(in srgb, var(--civic) 28%, transparent));
  opacity: 0;
  pointer-events: none;
  transform: translateY(-100%);
}
.evidence-card[data-proof].is-proving::after {
  animation: proof-sweep 1.15s var(--ease-out) 0.15s 1;
}
@keyframes proof-sweep {
  0%   { transform: translateY(-100%); opacity: 0; }
  28%  { opacity: 1; }
  100% { transform: translateY(250%); opacity: 0; }
}
.evidence-row--read { transition: background-color 0.5s var(--ease-out); }
.evidence-row--read .evidence-val { transition: color 0.5s var(--ease-out); }
.evidence-card[data-proof].is-proven .evidence-row--read {
  background: color-mix(in srgb, var(--verdict) 8%, transparent);
}
.evidence-card[data-proof].is-proven .evidence-row--read .evidence-val {
  color: var(--verdict);
}
.evidence-card[data-proof].is-proven .badge--verdict {
  animation: badge-settle 0.5s var(--ease-out) 1;
}
@keyframes badge-settle {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.09); }
  100% { transform: scale(1); }
}

/* =========================================================================
   Final CTA
   ========================================================================= */
.finalcta { text-align: center; }
.finalcta h2 { font-size: clamp(2rem, 4.4vw, 3.2rem); max-width: 18ch; margin-inline: auto; }
.finalcta p { margin: 1.25rem auto 0; max-width: 52ch; color: var(--ash); font-size: 1.1rem; }
.finalcta .hero__cta { justify-content: center; margin-top: 2rem; }

/* =========================================================================
   Operator characters ("Nomos Marginalia")
   ========================================================================= */
.op {
  width: 84px;
  height: 84px;
  display: block;
  color: var(--ink);
  flex: none;
  overflow: visible;
}
.op--float {
  position: absolute;
  opacity: 0.92;
  pointer-events: none;
}
.op-tag {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ash);
  border: var(--border);
  background: var(--card);
  border-radius: 5px;
  padding: 0.35rem 0.6rem;
  display: inline-block;
  box-shadow: var(--shadow-sm);
}
.marginalia {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin-top: 2.5rem;
}

/* ---- Operator animations -------------------------------------------------
   Each operator is visibly DOING the work. Animations run only after main.js
   adds .is-animating when the marginalia scrolls into view (so they fire when
   seen, not silently at load), and are fully disabled under reduced motion.
   The static art is complete on its own. transform/opacity/clip-path only. */

/* op-pen: nib writes a clause line, then the line redraws on loop */
.op .op-ink {
  stroke-dasharray: 22;
  stroke-dashoffset: 22;
}
.op.is-animating .op-ink {
  animation: op-write 3.2s var(--ease-out) infinite;
}
.op.is-animating .op-pen-hand {
  transform-box: fill-box;
  transform-origin: 20% 80%;
  animation: op-nib 3.2s var(--ease-in-out) infinite;
}
@keyframes op-write {
  0%   { stroke-dashoffset: 22; }
  35%  { stroke-dashoffset: 0; }
  85%  { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: 22; }
}
@keyframes op-nib {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  20%      { transform: translate(-1px, 1px) rotate(-3deg); }
  35%      { transform: translate(1px, 0) rotate(2deg); }
}

/* op-tile: held tile drops into the empty slot, stamp ring pulses on landing */
.op.is-animating .op-tile-drop {
  transform-box: fill-box;
  animation: op-drop 3s var(--ease-out) infinite;
}
.op.is-animating .op-stamp {
  transform-box: fill-box;
  transform-origin: center;
  animation: op-stamp 3s var(--ease-out) infinite;
}
@keyframes op-drop {
  0%   { transform: translate(6px, -12px); opacity: 0; }
  25%  { transform: translate(0, 0); opacity: 1; }
  100% { transform: translate(0, 0); opacity: 1; }
}
@keyframes op-stamp {
  0%, 24% { transform: scale(0.4); opacity: 0; }
  30%     { transform: scale(1); opacity: 0.8; }
  48%     { transform: scale(1.5); opacity: 0; }
  100%    { transform: scale(1.5); opacity: 0; }
}

/* op-look: magnifier sweeps the source thread, ✓ confirms at the end */
.op.is-animating .op-scan {
  transform-box: fill-box;
  animation: op-sweep 3.4s var(--ease-in-out) infinite;
}
.op.is-animating .op-check {
  transform-box: fill-box;
  transform-origin: center;
  animation: op-confirm 3.4s var(--ease-out) infinite;
}
@keyframes op-sweep {
  0%, 100% { transform: translate(0, 0); }
  45%      { transform: translate(16px, -12px); }
  60%      { transform: translate(16px, -12px); }
}
@keyframes op-confirm {
  0%, 55% { transform: scale(0.9); opacity: 0.5; }
  68%     { transform: scale(1.12); opacity: 1; }
  80%     { transform: scale(1); opacity: 1; }
  100%    { transform: scale(1); opacity: 1; }
}

/* op-plain: pushes the document cart forward, then resets */
.op.is-animating .op-roll {
  transform-box: fill-box;
  animation: op-cart 3.6s var(--ease-in-out) infinite;
}
@keyframes op-cart {
  0%   { transform: translateX(-6px); }
  40%  { transform: translateX(4px); }
  100% { transform: translateX(-6px); }
}

/* =========================================================================
   Wedge homepage — status badges, capability cards, roadmap tiers, FAQ
   All reuse .card / .badge / .expect-list so the b7 theme re-skins them free.
   ========================================================================= */

/* Status badges — reuse the .badge base; colour is ALWAYS paired with a label. */
.badge--now   { color: var(--verdict);   border-color: color-mix(in srgb, var(--verdict) 45%, transparent); background: color-mix(in srgb, var(--verdict) 8%, transparent); }
.badge--next  { color: var(--civic-ink); border-color: color-mix(in srgb, var(--civic) 45%, transparent);   background: color-mix(in srgb, var(--civic) 8%, transparent); }
.badge--later { color: var(--ash);       border-color: color-mix(in srgb, var(--ash) 45%, transparent);     background: color-mix(in srgb, var(--ash) 8%, transparent); }

/* "Available now" reads as LIVE: its status dot gives a slow, calm heartbeat.
   Only the now/live badge pulses — roadmap badges (next/later) stay static,
   because they aren't live yet. Quietly alive, never busy. */
.badge--now::before {
  transform-box: fill-box;
  animation: badge-live 2.6s var(--ease-in-out) infinite;
}
@keyframes badge-live {
  0%, 100% { opacity: 0.5;  transform: scale(0.8); }
  50%      { opacity: 1;    transform: scale(1); }
}

/* Capability cards (What ships) + roadmap tiers */
.caps  { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }
.tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; position: relative; }
/* Govern rail — the connector that draws Policy → Posture → Action plan
   together. Rendered only in the full motion tier (see motion.css); GSAP
   scrubs its scaleX as the section scrolls in. Decorative, aria-hidden. */
.tiers__rail { display: none; }
.cap__head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem 0.75rem; margin-bottom: 0.6rem; flex-wrap: wrap; }
.cap__head h3 { margin: 0; font-size: 1.08rem; }
/* Availability chip (Connect card): honest connector status, mono like other data labels. */
.cap__chip {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.02em;
  color: var(--civic-ink);
  background: color-mix(in srgb, var(--paleblue) 45%, transparent);
  border: 1px solid color-mix(in srgb, var(--civic) 28%, transparent);
  border-radius: 999px;
  padding: 0.18rem 0.55rem;
  white-space: nowrap;
}
.cap p, .tier p { color: var(--ash); font-size: 0.92rem; }
.who__list { margin-top: 1.75rem; max-width: 52ch; }

/* Pricing bracket table — mono ledger register, cumulative fee column. */
.bracket-scroll { overflow-x: auto; }
.bracket-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
  font-family: var(--font-mono);
}
.bracket-table th {
  text-align: right;
  padding: 0.6rem 0.9rem;
  border-bottom: 2px solid var(--civic);
  white-space: nowrap;
  font-weight: 600;
}
.bracket-table th:first-child { text-align: left; }
.bracket-table td {
  text-align: right;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--stone);
}
.bracket-table td:first-child { text-align: left; }
.bracket-table tbody tr:nth-child(odd) { background: var(--card); }
.bracket-table__note { color: var(--ash); font-size: 0.82em; }

@media (max-width: 1024px) { .caps { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 880px)  { .tiers { grid-template-columns: 1fr; } }
@media (max-width: 560px)  { .caps { grid-template-columns: 1fr; } }

/* FAQ list */
.faq { display: grid; gap: 0.75rem; max-width: 52rem; }
.faq__item {
  background: var(--card);
  border: var(--border);
  border-radius: var(--radius);
  padding: 1.25rem 1.4rem;
  box-shadow: var(--edge-spec);
  transition: border-color 200ms var(--ease-out), box-shadow 200ms var(--ease-out),
    transform 200ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .faq__item:hover {
    border-color: color-mix(in srgb, var(--civic) 32%, var(--stone));
    box-shadow: var(--edge-spec), var(--shadow-sm);
    transform: translateY(-2px);
  }
}
.faq__item h3 { font-size: 1.05rem; margin-bottom: 0.5rem; }
.faq__item p { color: var(--ash); font-size: 0.95rem; }
.faq__item p a { text-decoration: underline; }

/* Platform page: availability sub-headers + muted (roadmap) platform grid */
.platform-subhead {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ash);
  margin: 0 0 0.9rem;
}
.platform-grid--muted .platform { color: var(--ash); font-weight: 400; }
.platform-grid--muted .platform::before { background: var(--ash-faint); }

/* Prose page (pricing / security intros, generic content) */
.prose { max-width: 46rem; }
.prose p { color: color-mix(in srgb, var(--ink) 86%, var(--archive)); margin-bottom: 1rem; }
.prose p.lede { color: var(--ash); font-size: clamp(1.05rem, 1.6vw, 1.2rem); }
.prose p.lede strong, .prose p strong { color: var(--ink); font-weight: 500; }

/* =========================================================================
   Sub-page components (platforms / contact / privacy)
   ========================================================================= */

/* Page hero (sub-pages) */
.page-hero h1 { font-size: clamp(2.25rem, 4.8vw, 3.45rem); max-width: 20ch; }
.page-hero__lede {
  margin-top: 1.25rem;
  font-size: clamp(1.05rem, 1.7vw, 1.25rem);
  color: var(--ash);
  max-width: 58ch;
}
.page-hero__lede strong { color: var(--ink); font-weight: 500; }
.page-hero .hero__cta { margin-top: 1.75rem; }

/* Platform grid */
.platform-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.6rem;
}
.platform {
  display: flex;
  align-items: center;
  min-height: 56px;
  padding: 0.75rem 1rem;
  background: var(--card);
  border: var(--border);
  border-radius: var(--radius-sm);
  font-size: 0.95rem;
  font-weight: 500;
  transition: border-color 150ms var(--ease-out), transform 150ms var(--ease-out);
}
.platform::before {
  content: "";
  width: 7px; height: 7px;
  margin-right: 0.7rem;
  border-radius: 2px;
  background: var(--civic);
  flex: none;
}
@media (hover: hover) {
  .platform:hover { border-color: var(--civic); transform: translateY(-1px); }
}

/* CTA card (full-width section closer) */
.cta-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  background: var(--slate-deep);
  color: var(--archive);
  border-radius: var(--radius);
}
.cta-card h2 { color: var(--archive); font-size: clamp(1.4rem, 2.6vw, 1.9rem); }
.cta-card p { margin-top: 0.6rem; color: color-mix(in srgb, var(--archive) 78%, transparent); max-width: 56ch; }
.cta-card .btn--primary { background: var(--civic); }
.cta-card .btn--primary:hover { background: #fff; color: var(--slate-deep); }

/* Contact */
.contact__grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.contact-form { margin-top: 2rem; display: grid; gap: 1.1rem; max-width: 32rem; }
.field { display: grid; gap: 0.4rem; }
.field label { font-size: 0.85rem; font-weight: 500; color: var(--ink); }
.field input,
.field textarea {
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--stone);
  border-radius: var(--radius-sm);
  padding: 0.65rem 0.8rem;
  width: 100%;
}
.field input::placeholder,
.field textarea::placeholder { color: var(--ash); }
.field input:focus,
.field textarea:focus { outline: 2px solid var(--civic); outline-offset: 1px; border-color: var(--civic); }
.contact-form .btn { justify-self: start; margin-top: 0.25rem; }
.contact-form__note { font-size: 0.85rem; color: var(--ash); }

.expect-card {
  background: var(--card);
  border: var(--border);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 4vw, 2rem);
  box-shadow: var(--edge-spec);
}
.expect-card h2 { font-size: 1.25rem; margin-bottom: 1.1rem; }
.expect-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.9rem; }
.expect-list li {
  position: relative;
  padding-left: 1.4rem;
  font-size: 0.95rem;
  color: var(--ash);
  line-height: 1.5;
}
.expect-list li strong { color: var(--ink); font-weight: 600; }
.expect-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.55em;
  width: 8px; height: 8px;
  border-radius: 2px;
  background: var(--civic);
}

/* Legal / privacy prose */
.legal { max-width: 48rem; }
.legal__head { margin-bottom: 2.5rem; }
.legal__head h1 { font-size: clamp(2rem, 4vw, 2.8rem); }
.legal__meta { margin-top: 0.9rem; font-family: var(--font-mono); font-size: 0.82rem; color: var(--ash); }
.legal__body { font-size: 1rem; line-height: 1.7; color: var(--ink); }
.legal__body h2 {
  font-size: 1.2rem;
  margin: 2.4rem 0 0.8rem;
  padding-top: 1.6rem;
  border-top: var(--border);
  scroll-margin-top: 90px;
}
.legal__body p { margin-bottom: 1rem; color: color-mix(in srgb, var(--ink) 86%, var(--archive)); }
.legal__body ul { margin: 0 0 1rem; padding-left: 1.3rem; display: grid; gap: 0.5rem; }
.legal__body li { color: color-mix(in srgb, var(--ink) 86%, var(--archive)); }
.legal__body a { text-decoration: underline; }
.legal__contact {
  font-style: normal;
  background: var(--paleblue);
  border-radius: var(--radius);
  padding: 1.2rem 1.4rem;
  line-height: 1.7;
  margin: 1rem 0;
}
.legal__placeholder-note {
  font-size: 0.88rem;
  color: var(--ash);
  background: var(--card);
  border: 1px dashed var(--stone);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1.1rem;
  margin-top: 2rem;
}

/* =========================================================================
   Responsive
   ========================================================================= */
@media (max-width: 1024px) {
  .nav__links { gap: 1.1rem; }
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 2rem; }
}

@media (max-width: 880px) {
  .hero__grid { grid-template-columns: 1fr; }
  .hero__media { order: 2; }
  .systemmap svg { display: none; }
  /* SVG is hidden here, so drop the panel chrome (its border/shadow/padding
     would otherwise render as an empty card above the text fallback). */
  .systemmap { background: none; border: none; box-shadow: none; padding: 0; }
  .systemmap__fallback { display: block; }

  .govern__grid,
  .split,
  .evidence__grid,
  .contact__grid { grid-template-columns: 1fr; }
  .split--reverse .split__media { order: 0; }

  .usecases { grid-template-columns: 1fr 1fr; }
  .outputs { grid-template-columns: 1fr; }

  /* nav → hamburger */
  .nav__links, .nav__cta { display: none; }
  .nav__toggle { display: inline-flex; }

  /* how-it-works → vertical timeline */
  .flow { grid-template-columns: 1fr; }
  .flow__step { padding: 1rem 0 1rem 1.25rem; border-right: none !important; border-left: var(--border); }
  .flow__step + .flow__step { padding-left: 1.25rem; }

  .pains { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
  .usecases { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: 1fr; }
  .hero__cta .btn, .finalcta .btn { flex: 1 1 auto; justify-content: center; }
  .lexicon__row { grid-template-columns: 1fr; gap: 0.2rem; }
}

