/* ============================================================
   OATH LIGHT — WEBSITE SURFACE STYLES
   The website's half of the design system. tokens.css is the data
   (loaded first, byte-identical to design-system/tokens.css);
   this file is the component layer built on top of it, the same
   role design-system/preview.html's .ol-* block plays for the app.

   RULES THIS FILE KEEPS
   ---------------------
   1. No hardcoded colour. Every colour resolves to an --ol-* token.
      The only literals below are alpha-compositing helpers written
      as color-mix() over a token, never a hex.
   2. No second typeface. --ol-font-ui (Manrope) everywhere; the one
      exception is --site-mono, used strictly inside <code> where a
      terminal transcript has to align. The design system has no code
      surface, so this is a website-only addition, declared here and
      nowhere else.
   3. Every size, gap, radius, shadow, duration and easing comes from
      a token or a calc() on one. The display sizes a marketing page
      needs and an app UI doesn't are derived below, in one block, as
      multiples of the token scale.

   THEME MODEL — THE INVERSION
   ---------------------------
   The page is Noir dark: <html> carries no data-theme, so :root's
   dark values apply and the whole site sits on --ol-bg-0 (#0a0a0a).
   Bands that need to read as the opposite pole carry
   data-theme="light" — which flips every --ol-* colour token inside
   that subtree to the light theme. So an inverted band is not a
   hand-painted white section; it is the same components rendering
   against the other half of the same palette. Nothing inside a band
   needs to know which side it is on.
   ============================================================ */

/* ============================================================
   1. DERIVED SCALE — website-only, all calc()'d off tokens
   ============================================================ */
:root {
  /* Display sizes. The token scale tops out at 42px because it was cut
     for app chrome; a landing page headline needs more. Rather than
     inventing numbers, these are multiples of the top of the scale, so
     retuning --ol-size-4xl retunes the whole site. */
  --site-display-1: clamp(var(--ol-size-3xl), 6.2vw, calc(var(--ol-size-4xl) * 1.62));
  --site-display-2: clamp(var(--ol-size-2xl), 4.4vw, calc(var(--ol-size-4xl) * 1.12));
  --site-display-3: clamp(var(--ol-size-xl), 3vw, calc(var(--ol-size-3xl) * 0.95));

  /* Optical letter-spacing for large type. Not a token: the system has
     no display tier, so tracking is a website concern. */
  --site-track-display: -0.028em;
  --site-track-title: -0.018em;

  /* Page rhythm */
  --site-container: 1200px;
  --site-container-narrow: 900px;
  --site-container-prose: 820px;
  --site-gutter: var(--ol-space-6);
  --site-section-y: clamp(var(--ol-space-8), 9vh, calc(var(--ol-space-8) * 2.4));
  --site-section-y-tight: clamp(var(--ol-space-7), 7vh, calc(var(--ol-space-8) * 1.7));

  /* Code is the one place a second family is allowed — see header. */
  --site-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* ============================================================
   2. RESET + PAGE GROUND
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  scroll-behavior: smooth;
  background: var(--ol-bg-0);
}

body {
  background: var(--ol-bg-0);
  color: var(--ol-text-1);
  font-family: var(--ol-font-ui);
  font-size: var(--ol-size-md);
  font-weight: var(--ol-weight-regular);
  line-height: var(--ol-leading-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { max-width: 100%; display: block; }

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

a {
  color: var(--ol-text-1);
  text-decoration: none;
  transition: color var(--ol-duration-base) var(--ol-ease-standard);
}

:focus-visible {
  outline: 2px solid var(--ol-focus-ring);
  outline-offset: 3px;
  border-radius: var(--ol-radius-sm);
}

details > summary { list-style: none; cursor: pointer; }
details > summary::-webkit-details-marker { display: none; }

.skip-link {
  position: absolute;
  left: var(--ol-space-4);
  top: calc(var(--ol-space-4) * -6);
  z-index: 100;
  background: var(--ol-accent);
  color: var(--ol-accent-ink);
  font-weight: var(--ol-weight-bold);
  font-size: var(--ol-size-sm);
  padding: var(--ol-space-2) var(--ol-space-4);
  border-radius: var(--ol-radius-sm);
  transition: top var(--ol-duration-base) var(--ol-ease-standard);
}
.skip-link:focus-visible { top: var(--ol-space-4); }

/* ============================================================
   3. THE INVERSION BAND
   data-theme="light" already flips the tokens (tokens.css). All this
   class does is paint the band's own ground with the now-flipped
   token and re-establish the text colour, so children inherit the
   right pole without knowing it.
   ============================================================ */
.band {
  background: var(--ol-bg-0);
  color: var(--ol-text-1);
}
.band-raised { background: var(--ol-bg-1); }

/* A band boundary is always a hairline in the *incoming* theme, so the
   seam reads as a fold rather than a gap. */
.band-edge-top { border-top: 1px solid var(--ol-border); }
.band-edge-bottom { border-bottom: 1px solid var(--ol-border); }

/* ============================================================
   4. LAYOUT
   ============================================================ */
.container {
  width: 100%;
  max-width: var(--site-container);
  margin-inline: auto;
  padding-inline: var(--site-gutter);
}
.container-narrow { max-width: var(--site-container-narrow); }
.container-prose { max-width: var(--site-container-prose); }

.section { padding-block: var(--site-section-y); }
.section-tight { padding-block: var(--site-section-y-tight); }
.section-top-only { padding-block: var(--site-section-y) 0; }

.grid { display: grid; gap: var(--ol-space-5); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.split {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
  gap: calc(var(--ol-space-8) + var(--ol-space-2));
  align-items: center;
}

.stack { display: flex; flex-direction: column; gap: var(--ol-space-4); }
.stack-tight { display: flex; flex-direction: column; gap: var(--ol-space-3); }
.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ol-space-3);
  align-items: center;
}
.row-between {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ol-space-5);
  align-items: flex-end;
  justify-content: space-between;
}
.center { text-align: center; }
.mx-auto { margin-inline: auto; }

/* ============================================================
   5. TYPOGRAPHY
   ============================================================ */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--ol-space-2);
  font-size: var(--ol-size-sm);
  font-weight: var(--ol-weight-bold);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ol-text-3);
  margin-bottom: var(--ol-space-4);
}
/* The mark: a token-coloured square rotated 45°. Replaces the old
   three-stop gradient diamond — same silhouette, one colour. */
.eyebrow::before {
  content: '';
  width: 7px;
  height: 7px;
  flex: 0 0 7px;
  background: var(--ol-accent);
  transform: rotate(45deg);
}
.eyebrow-plain::before { display: none; }

.display-1 {
  font-size: var(--site-display-1);
  font-weight: var(--ol-weight-bold);
  line-height: var(--ol-leading-tight);
  letter-spacing: var(--site-track-display);
  color: var(--ol-text-1);
}
.display-2 {
  font-size: var(--site-display-2);
  font-weight: var(--ol-weight-bold);
  line-height: var(--ol-leading-tight);
  letter-spacing: var(--site-track-display);
  color: var(--ol-text-1);
}
.display-3 {
  font-size: var(--site-display-3);
  font-weight: var(--ol-weight-bold);
  line-height: var(--ol-leading-snug);
  letter-spacing: var(--site-track-title);
  color: var(--ol-text-1);
}
.title {
  font-size: var(--ol-size-xl);
  font-weight: var(--ol-weight-semibold);
  line-height: var(--ol-leading-snug);
  letter-spacing: var(--site-track-title);
  color: var(--ol-text-1);
}
.title-sm {
  font-size: var(--ol-size-lg);
  font-weight: var(--ol-weight-semibold);
  line-height: var(--ol-leading-snug);
  color: var(--ol-text-1);
}

.lead {
  font-size: var(--ol-size-lg);
  line-height: var(--ol-leading-relaxed);
  color: var(--ol-text-2);
}
.body { font-size: var(--ol-size-md); line-height: var(--ol-leading-normal); color: var(--ol-text-2); }
.body-sm { font-size: var(--ol-size-base); line-height: var(--ol-leading-normal); color: var(--ol-text-2); }
.muted { color: var(--ol-text-3); }
.strong { color: var(--ol-text-1); font-weight: var(--ol-weight-semibold); }

.measure { max-width: 60ch; }
.measure-tight { max-width: 52ch; }
.measure-wide { max-width: 68ch; }

.mono {
  font-family: var(--site-mono);
  font-size: 0.9em;
  color: var(--ol-text-2);
}

.prose a, .link {
  color: var(--ol-text-1);
  font-weight: var(--ol-weight-semibold);
  text-decoration: underline;
  text-decoration-color: var(--ol-border-strong);
  text-underline-offset: 3px;
}
.prose a:hover, .link:hover { text-decoration-color: var(--ol-accent); }

/* ============================================================
   6. BUTTONS — the .ol-btn contract, web-sized
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ol-space-2);
  padding: var(--ol-space-3) var(--ol-space-5);
  border: 1px solid transparent;
  border-radius: var(--ol-radius-sm);
  font-family: var(--ol-font-ui);
  font-size: var(--ol-size-base);
  font-weight: var(--ol-weight-bold);
  line-height: var(--ol-leading-snug);
  cursor: pointer;
  transition: transform var(--ol-duration-fast) var(--ol-ease-standard),
              box-shadow var(--ol-duration-base) var(--ol-ease-standard),
              background var(--ol-duration-base) var(--ol-ease-standard),
              border-color var(--ol-duration-base) var(--ol-ease-standard),
              color var(--ol-duration-base) var(--ol-ease-standard);
}
.btn:active { transform: scale(.97); }

.btn-primary {
  background: var(--ol-accent);
  color: var(--ol-accent-ink);
  box-shadow: var(--ol-shadow-sm);
}
.btn-primary:hover {
  background: var(--ol-accent-2);
  color: var(--ol-accent-ink);
  box-shadow: var(--ol-shadow-md);
}

.btn-ghost {
  background: var(--ol-bg-2);
  border-color: var(--ol-border);
  color: var(--ol-text-1);
}
.btn-ghost:hover { border-color: var(--ol-border-strong); background: var(--ol-bg-3); color: var(--ol-text-1); }

.btn-lg {
  padding: var(--ol-space-4) var(--ol-space-6);
  font-size: var(--ol-size-md);
  border-radius: var(--ol-radius-md);
}
.btn-sm {
  padding: var(--ol-space-2) var(--ol-space-4);
  font-size: var(--ol-size-sm);
}

/* ============================================================
   7. SURFACES
   ============================================================ */
.card {
  background: var(--ol-bg-1);
  border: 1px solid var(--ol-border);
  border-radius: var(--ol-radius-lg);
  padding: var(--ol-space-5);
  box-shadow: var(--ol-shadow-sm);
  position: relative;
}
/* The lit top edge that makes a panel read as physical rather than as a
   lighter rectangle (see --ol-hairline in tokens.css). */
.card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  border-radius: inherit;
  background: var(--ol-hairline);
  pointer-events: none;
}
.card-lg { padding: clamp(var(--ol-space-5), 3vw, var(--ol-space-7)); }
.card-flat { box-shadow: none; background: var(--ol-bg-2); }
.card-flat::before { display: none; }
.card-dashed {
  background: transparent;
  border-style: dashed;
  border-color: var(--ol-border-strong);
  box-shadow: none;
}
.card-dashed::before { display: none; }
.card-accent {
  border-color: var(--ol-accent-3);
  box-shadow: var(--ol-shadow-md);
}

.lift {
  transition: transform var(--ol-duration-base) var(--ol-ease-standard),
              box-shadow var(--ol-duration-base) var(--ol-ease-standard),
              border-color var(--ol-duration-base) var(--ol-ease-standard);
}
.lift:hover {
  transform: translateY(-3px);
  box-shadow: var(--ol-shadow-md);
  border-color: var(--ol-border-strong);
}

/* ============================================================
   8. CHIPS, PILLS, STATUS
   ============================================================ */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--ol-space-2);
  font-size: var(--ol-size-sm);
  font-weight: var(--ol-weight-semibold);
  padding: 5px var(--ol-space-3);
  border-radius: var(--ol-radius-pill);
  background: var(--ol-bg-2);
  border: 1px solid var(--ol-border);
  color: var(--ol-text-2);
}
.chip-solid {
  background: var(--ol-bg-3);
  border-color: var(--ol-border-strong);
  color: var(--ol-text-1);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: var(--ol-space-2);
  font-size: var(--ol-size-xs);
  font-weight: var(--ol-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 5px var(--ol-space-3);
  border-radius: var(--ol-radius-pill);
  border: 1px solid transparent;
}
.status::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.status-ok {
  color: var(--ol-ok);
  background: color-mix(in oklab, var(--ol-ok) 14%, transparent);
  border-color: color-mix(in oklab, var(--ol-ok) 40%, transparent);
}
.status-live {
  color: var(--ol-accent);
  background: color-mix(in oklab, var(--ol-accent) 12%, transparent);
  border-color: color-mix(in oklab, var(--ol-accent) 34%, transparent);
}
.status-warn {
  color: var(--ol-warn);
  background: color-mix(in oklab, var(--ol-warn) 14%, transparent);
  border-color: color-mix(in oklab, var(--ol-warn) 40%, transparent);
}
.status-planned {
  color: var(--ol-text-3);
  background: var(--ol-bg-2);
  border-color: var(--ol-border);
}

.yes { color: var(--ol-ok); font-weight: var(--ol-weight-black); }
.partial { color: var(--ol-warn); font-weight: var(--ol-weight-black); }
.no { color: var(--ol-text-3); font-weight: var(--ol-weight-black); }

/* ============================================================
   9. NOTICE / BANNER — the .ol-banner contract
   ============================================================ */
.notice {
  display: flex;
  gap: var(--ol-space-4);
  align-items: flex-start;
  padding: var(--ol-space-5);
  border-radius: var(--ol-radius-md);
  border: 1px solid transparent;
}
.notice-warn {
  background: color-mix(in oklab, var(--ol-warn) 10%, transparent);
  border-color: color-mix(in oklab, var(--ol-warn) 34%, transparent);
}
.notice-warn .notice-title { color: var(--ol-warn); }
.notice-title {
  font-size: var(--ol-size-lg);
  font-weight: var(--ol-weight-bold);
  line-height: var(--ol-leading-snug);
  margin-bottom: var(--ol-space-2);
}
.notice-mark {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: var(--ol-radius-sm);
  font-size: var(--ol-size-lg);
  font-weight: var(--ol-weight-black);
  color: var(--ol-warn);
  background: color-mix(in oklab, var(--ol-warn) 16%, transparent);
}

/* ============================================================
   10. ANNOUNCEMENT BAR + HEADER
   The header is one of the bands that inverts: it was solid black in
   the previous design, so it is the light pole now.
   ============================================================ */
.announce {
  background: var(--ol-bg-1);
  border-bottom: 1px solid var(--ol-border);
  text-align: center;
}
.announce-inner {
  padding-block: var(--ol-space-2);
  font-size: var(--ol-size-sm);
  color: var(--ol-text-3);
}
.announce strong {
  color: var(--ol-text-1);
  font-weight: var(--ol-weight-bold);
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--ol-bg-0);
  border-bottom: 1px solid var(--ol-border-strong);
}
.site-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ol-space-5);
  padding-block: var(--ol-space-3);
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--ol-space-3);
}
.brand img { width: 28px; height: 28px; }
.brand span {
  font-size: var(--ol-size-lg);
  font-weight: var(--ol-weight-bold);
  letter-spacing: var(--site-track-title);
  color: var(--ol-text-1);
}
.nav-links {
  display: flex;
  align-items: center;
  gap: var(--ol-space-6);
}
.nav-link {
  font-size: var(--ol-size-base);
  font-weight: var(--ol-weight-medium);
  color: var(--ol-text-2);
}
.nav-link:hover { color: var(--ol-text-1); }
.nav-link.is-active {
  color: var(--ol-text-1);
  font-weight: var(--ol-weight-bold);
}

/* ============================================================
   11. HERO
   The ground is the dot field from tokens.css — the static texture
   that replaced the old animated colour blobs system-wide.
   ============================================================ */
.hero {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--ol-border);
}
.hero-ground {
  position: absolute;
  inset: -80px 0;
  pointer-events: none;
  background-image: radial-gradient(var(--ol-ground-dot) 1px, transparent 1px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(120% 90% at 50% 0%, #000 0%, transparent 72%);
  mask-image: radial-gradient(120% 90% at 50% 0%, #000 0%, transparent 72%);
}
.hero-inner {
  position: relative;
  padding-block: var(--site-section-y);
}

/* ============================================================
   12. BLOCK-SCREEN MOCK (home hero)
   ============================================================ */
.mock {
  background: var(--ol-bg-1);
  border: 1px solid var(--ol-border);
  border-radius: var(--ol-radius-lg);
  box-shadow: var(--ol-shadow-md);
  overflow: hidden;
}
.mock-bar {
  display: flex;
  align-items: center;
  gap: var(--ol-space-2);
  padding: var(--ol-space-3) var(--ol-space-4);
  border-bottom: 1px solid var(--ol-border);
  background: var(--ol-bg-2);
}
.mock-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ol-border-strong);
}
.mock-url {
  margin-left: var(--ol-space-2);
  flex: 1;
  height: 24px;
  border-radius: var(--ol-radius-sm);
  background: var(--ol-bg-3);
  display: flex;
  align-items: center;
  gap: var(--ol-space-2);
  padding-inline: var(--ol-space-3);
  font-family: var(--site-mono);
  font-size: var(--ol-size-xs);
  color: var(--ol-text-3);
}
.mock-body {
  padding: var(--ol-space-7) var(--ol-space-6);
  text-align: center;
}
.mock-body img {
  width: 42px;
  height: 42px;
  margin: 0 auto var(--ol-space-4);
}
.mock-float {
  position: absolute;
  left: calc(var(--ol-space-4) * -1);
  bottom: calc(var(--ol-space-4) * -1);
  display: flex;
  align-items: center;
  gap: var(--ol-space-3);
  background: var(--ol-bg-2);
  border: 1px solid var(--ol-border-strong);
  border-radius: var(--ol-radius-md);
  padding: var(--ol-space-3) var(--ol-space-4);
  box-shadow: var(--ol-shadow-md);
}
.mock-float-num {
  font-size: var(--ol-size-xl);
  font-weight: var(--ol-weight-black);
  font-variant-numeric: tabular-nums;
  color: var(--ol-text-1);
  line-height: var(--ol-leading-tight);
}
.mock-float-label {
  font-size: var(--ol-size-xs);
  line-height: var(--ol-leading-snug);
  color: var(--ol-text-3);
}

/* ============================================================
   13. STAT BAR
   ============================================================ */
.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.stat {
  padding: var(--ol-space-6) var(--ol-space-4);
  text-align: center;
  border-right: 1px solid var(--ol-border);
}
.stat:last-child { border-right: 0; }
.stat-num {
  font-size: clamp(var(--ol-size-2xl), 3.2vw, var(--ol-size-4xl));
  font-weight: var(--ol-weight-black);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--site-track-title);
  line-height: var(--ol-leading-tight);
  color: var(--ol-text-1);
}
.stat-label {
  font-size: var(--ol-size-base);
  color: var(--ol-text-3);
  margin-top: var(--ol-space-2);
}

/* ============================================================
   14. NUMBERED LAYER CARDS
   ============================================================ */
.layer-num {
  font-family: var(--site-mono);
  font-size: var(--ol-size-sm);
  font-weight: var(--ol-weight-bold);
  letter-spacing: 0.1em;
  color: var(--ol-text-3);
}
.layer-head {
  display: flex;
  align-items: baseline;
  gap: var(--ol-space-4);
  margin-bottom: var(--ol-space-3);
}
.layer-head .layer-num { font-size: var(--ol-size-lg); color: var(--ol-accent-3); }

.step-num {
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  display: grid;
  place-items: center;
  border-radius: var(--ol-radius-sm);
  background: var(--ol-accent);
  color: var(--ol-accent-ink);
  font-size: var(--ol-size-md);
  font-weight: var(--ol-weight-black);
}

/* ============================================================
   15. TABLE — the comparison matrix
   ============================================================ */
.table-scroll { overflow-x: auto; }
.table-wrap {
  min-width: 860px;
  border: 1px solid var(--ol-border);
  border-radius: var(--ol-radius-lg);
  overflow: hidden;
  box-shadow: var(--ol-shadow-sm);
}
.cmp {
  width: 100%;
  border-collapse: collapse;
  background: var(--ol-bg-1);
}
.cmp th, .cmp td {
  padding: var(--ol-space-4);
  text-align: center;
  border-bottom: 1px solid var(--ol-border);
  font-size: var(--ol-size-base);
  vertical-align: middle;
}
.cmp tbody tr:last-child td { border-bottom: 0; }
.cmp thead th {
  background: var(--ol-bg-2);
  font-weight: var(--ol-weight-bold);
  color: var(--ol-text-1);
  border-bottom: 1px solid var(--ol-border-strong);
}
.cmp .row-label {
  text-align: left;
  font-weight: var(--ol-weight-semibold);
  color: var(--ol-text-1);
  min-width: 15rem;
}
.cmp td:not(.row-label) { color: var(--ol-text-2); }
/* The Oath Light column is the inverted one — it takes the accent as its
   ground, so it reads as the answer rather than as one of five options. */
.cmp .col-us {
  background: color-mix(in oklab, var(--ol-accent) 8%, transparent);
}
.cmp thead .col-us {
  background: var(--ol-accent);
  color: var(--ol-accent-ink);
  border-bottom-color: var(--ol-accent);
}
.cmp thead .col-us .col-sub { color: var(--ol-accent-ink); opacity: .7; }
.col-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--ol-space-2);
  font-size: var(--ol-size-md);
  font-weight: var(--ol-weight-bold);
}
.col-head img { width: 20px; height: 20px; }
.col-sub {
  display: block;
  margin-top: 2px;
  font-size: var(--ol-size-xs);
  font-weight: var(--ol-weight-medium);
  color: var(--ol-text-3);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}
.cell-note {
  display: block;
  font-size: var(--ol-size-xs);
  color: var(--ol-text-3);
  margin-top: 2px;
}
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ol-space-5);
  margin-top: var(--ol-space-4);
  font-size: var(--ol-size-base);
  color: var(--ol-text-3);
}

/* Ledger (does / does not) */
.ledger-head {
  display: flex;
  align-items: center;
  gap: var(--ol-space-3);
  padding: var(--ol-space-4) var(--ol-space-5);
  border-bottom: 1px solid var(--ol-border);
  font-size: var(--ol-size-lg);
  font-weight: var(--ol-weight-bold);
  color: var(--ol-text-1);
}
.ledger-list { padding: var(--ol-space-2) var(--ol-space-5) var(--ol-space-4); }
.ledger-list li {
  list-style: none;
  padding-block: var(--ol-space-3);
  border-bottom: 1px solid var(--ol-border);
  font-size: var(--ol-size-base);
  color: var(--ol-text-2);
}
.ledger-list li:last-child { border-bottom: 0; }

/* ============================================================
   16. TIMELINE (roadmap)
   ============================================================ */
.timeline {
  position: relative;
  padding-left: calc(var(--ol-space-8) - var(--ol-space-2));
}
.timeline::before {
  content: '';
  position: absolute;
  left: 7px;
  top: var(--ol-space-2);
  bottom: var(--ol-space-2);
  width: 1px;
  background: var(--ol-border-strong);
}
.tl-item { position: relative; margin-bottom: var(--ol-space-5); }
.tl-item:last-child { margin-bottom: 0; }
.tl-item::before {
  content: '';
  position: absolute;
  left: calc((var(--ol-space-8) - var(--ol-space-2)) * -1 + 1px);
  top: var(--ol-space-6);
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--ol-bg-0);
  border: 2px solid var(--ol-border-strong);
}
.tl-item.is-done::before { background: var(--ol-ok); border-color: var(--ol-ok); }
.tl-item.is-now::before {
  background: var(--ol-accent);
  border-color: var(--ol-accent);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--ol-accent) 22%, transparent);
}

/* ============================================================
   17. CODE BLOCK
   Previously the only dark element on a light page; now the only
   light element on a dark one — it carries data-theme="light".
   ============================================================ */
.codeblock {
  background: var(--ol-bg-1);
  border: 1px solid var(--ol-border);
  border-radius: var(--ol-radius-md);
  overflow: hidden;
}
.codeblock-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ol-space-3);
  padding: var(--ol-space-2) var(--ol-space-4);
  border-bottom: 1px solid var(--ol-border);
  background: var(--ol-bg-2);
  font-family: var(--site-mono);
  font-size: var(--ol-size-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ol-text-3);
}
.codeblock pre {
  margin: 0;
  padding: var(--ol-space-4);
  overflow-x: auto;
}
.codeblock code {
  font-family: var(--site-mono);
  font-size: var(--ol-size-base);
  line-height: var(--ol-leading-relaxed);
  color: var(--ol-text-1);
  white-space: pre;
}
.copy-btn {
  font-family: var(--ol-font-ui);
  font-size: var(--ol-size-xs);
  font-weight: var(--ol-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ol-text-2);
  background: var(--ol-bg-3);
  border: 1px solid var(--ol-border);
  border-radius: var(--ol-radius-pill);
  padding: 4px var(--ol-space-3);
  cursor: pointer;
  transition: color var(--ol-duration-base) var(--ol-ease-standard),
              border-color var(--ol-duration-base) var(--ol-ease-standard);
}
.copy-btn:hover { color: var(--ol-text-1); border-color: var(--ol-border-strong); }

/* ============================================================
   18. FAQ
   ============================================================ */
.faq-item {
  background: var(--ol-bg-1);
  border: 1px solid var(--ol-border);
  border-radius: var(--ol-radius-md);
  padding-inline: var(--ol-space-5);
  transition: border-color var(--ol-duration-base) var(--ol-ease-standard);
}
.faq-item[open] { border-color: var(--ol-border-strong); }
.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ol-space-4);
  padding-block: var(--ol-space-4);
  font-size: var(--ol-size-md);
  font-weight: var(--ol-weight-semibold);
  color: var(--ol-text-1);
}
.faq-plus {
  flex: 0 0 auto;
  font-size: var(--ol-size-xl);
  line-height: 1;
  color: var(--ol-text-3);
  transition: transform var(--ol-duration-base) var(--ol-ease-standard),
              color var(--ol-duration-base) var(--ol-ease-standard);
}
.faq-item[open] .faq-plus { transform: rotate(45deg); color: var(--ol-accent); }
.faq-item > p { padding-bottom: var(--ol-space-5); }

/* ============================================================
   19. FOOTER
   ============================================================ */
.site-footer { background: var(--ol-bg-0); }
.cta-panel {
  border-radius: var(--ol-radius-xl);
  padding: clamp(var(--ol-space-6), 5vw, var(--ol-space-8));
  background: var(--ol-bg-0);
  border: 1px solid var(--ol-border);
  box-shadow: var(--ol-shadow-md);
}
.cta-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: var(--ol-space-7);
  align-items: center;
}
.footer-cols {
  display: grid;
  grid-template-columns: 1.7fr 1fr 1fr 1fr;
  gap: var(--ol-space-7);
  padding-block: var(--ol-space-8) var(--ol-space-6);
}
.footer-heading {
  font-size: var(--ol-size-xs);
  font-weight: var(--ol-weight-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ol-text-3);
  margin-bottom: var(--ol-space-4);
}
.footer-links {
  display: flex;
  flex-direction: column;
  gap: var(--ol-space-3);
  font-size: var(--ol-size-base);
}
.footer-links a { color: var(--ol-text-2); }
.footer-links a:hover { color: var(--ol-text-1); }
.footer-base { border-top: 1px solid var(--ol-border); }
.footer-base-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ol-space-2) var(--ol-space-5);
  align-items: center;
  justify-content: space-between;
  padding-block: var(--ol-space-4);
  font-size: var(--ol-size-sm);
  color: var(--ol-text-3);
}

/* ============================================================
   20. MOTION — entrance + scroll reveals
   Durations here are longer than --ol-duration-slow on purpose: those
   tokens size UI feedback, and a scroll reveal is a different job.
   They are still expressed as multiples of the token so Serious Mode's
   snappier timings carry through.
   ============================================================ */
@keyframes olRise {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: none; }
}
.pp-anim .hero-el {
  opacity: 0;
  animation: olRise calc(var(--ol-duration-slow) * 2) var(--ol-ease-spring) both;
}
.pp-anim .hero-el:nth-child(2) { animation-delay: calc(var(--ol-duration-fast) * 0.75); }
.pp-anim .hero-el:nth-child(3) { animation-delay: calc(var(--ol-duration-fast) * 1.5); }
.pp-anim .hero-el:nth-child(4) { animation-delay: calc(var(--ol-duration-fast) * 2.25); }

@supports (animation-timeline: view()) {
  .pp-anim .reveal {
    opacity: 0;
    animation: olRise linear both;
    animation-timeline: view();
    animation-range: entry 5% cover 20%;
  }
  .pp-anim .reveal-stagger > * {
    opacity: 0;
    animation: olRise linear both;
    animation-timeline: view();
    animation-range: entry 2% cover 16%;
  }
  .pp-anim .reveal-stagger > *:nth-child(2) { animation-range: entry 5% cover 19%; }
  .pp-anim .reveal-stagger > *:nth-child(3) { animation-range: entry 8% cover 22%; }
  .pp-anim .reveal-stagger > *:nth-child(4) { animation-range: entry 11% cover 25%; }
  .pp-anim .reveal-stagger > *:nth-child(5) { animation-range: entry 14% cover 28%; }
  .pp-anim .reveal-stagger > *:nth-child(6) { animation-range: entry 17% cover 31%; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .pp-anim .hero-el,
  .pp-anim .reveal,
  .pp-anim .reveal-stagger > * {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .lift:hover { transform: none; }
}

/* ============================================================
   21. RESPONSIVE
   ============================================================ */
@media (max-width: 960px) {
  .nav-links { display: none; }
  .split { grid-template-columns: minmax(0, 1fr); gap: var(--ol-space-7); }
  .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stat:nth-child(2n) { border-right: 0; }
  .stat:nth-child(-n+2) { border-bottom: 1px solid var(--ol-border); }
  .cta-grid { grid-template-columns: minmax(0, 1fr); }
  .footer-cols { grid-template-columns: 1fr 1fr; row-gap: var(--ol-space-7); }
}

@media (max-width: 640px) {
  :root { --site-gutter: var(--ol-space-4); }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); }
  .footer-cols { grid-template-columns: 1fr; }
  .row-between { align-items: flex-start; }
  .mock-float { position: static; margin-top: var(--ol-space-4); }
}
