/* obversa.ai, base v2. Tokens first, one accent per mode, no orange, no purple. */

/* Self-hosted Typography */
/* Self-hosted fonts, two subsets each: the latin file carries the basic Latin
   letters, digits and punctuation; the latin-ext file the accented letters.
   Each subset declares its unicode-range so the browser loads what the text
   needs and never falls back to a system face for a missing letter. */

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/ibm-plex-mono-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('assets/fonts/ibm-plex-mono-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('assets/fonts/ibm-plex-mono-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/schibsted-grotesk-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('assets/fonts/schibsted-grotesk-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('assets/fonts/schibsted-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('assets/fonts/schibsted-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg: #F4F8F0;
  --surface: #FBFDF9;
  --ink: #12331F;
  --ink-2: #44604D;
  --line: #D3E2D1;
  --line-strong: #B9D0BA;
  --accent: #1C7C54;
  --accent-ink: #F2FBF4;
  --accent-soft: #DEF4C6;
  --ledger-bg: #1B512D;
  --ledger-ink: #DDEFE0;
  --ledger-muted: #9EC8AA;
  --ledger-mark: #73E2A7;
  --relief: #12331F;
  --focus: #1C7C54;
  --font-sans: "Schibsted Grotesk", "Helvetica Neue", Arial, sans-serif;
  --font-mono: "IBM Plex Mono", "SFMono-Regular", Menlo, Consolas, monospace;
  --radius: 4px;
  --measure: 62ch;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0E1F15;
    --surface: #142A1C;
    --ink: #E8F3E9;
    --ink-2: #A9C4B0;
    --line: #23422F;
    --line-strong: #2F5A3F;
    --accent: #73E2A7;
    --accent-ink: #0E1F15;
    --accent-soft: #1B512D;
    --ledger-bg: #071209;
    --ledger-ink: #D6EBD9;
    --ledger-muted: #6E9A7B;
    --ledger-mark: #73E2A7;
    --relief: #1B512D;
    --focus: #73E2A7;
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --bg: #0E1F15;
  --surface: #142A1C;
  --ink: #E8F3E9;
  --ink-2: #A9C4B0;
  --line: #23422F;
  --line-strong: #2F5A3F;
  --accent: #73E2A7;
  --accent-ink: #0E1F15;
  --accent-soft: #1B512D;
  --ledger-bg: #071209;
  --ledger-ink: #D6EBD9;
  --ledger-muted: #6E9A7B;
  --ledger-mark: #73E2A7;
  --relief: #1B512D;
  --focus: #73E2A7;
  color-scheme: dark;
}

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

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

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

h1, h2, h3 {
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.1;
  text-wrap: balance;
}

p { margin: 0; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

::selection { background: var(--ledger-mark); color: #12331F; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: 1rem;
  top: -3rem;
  padding: 0.5rem 0.75rem;
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: var(--radius);
}
.skip:focus { top: 1rem; }

/* Header */

.site-header {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 1.1rem var(--gutter);
  border-bottom: 1px solid var(--line);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.16em;
  perspective: 400px;
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: -0.02em;
  text-decoration: none;
}

/* The mark: a coin with two faces. Its disc is 28 of a 32 grid, set to the
   cap height of the word (0.703em in Schibsted Grotesk), so the box is
   0.703em * 32 / 28. The
   wordmark turns it on hover and on keyboard focus, once, and turns it back;
   under reduced motion the reverse shows without the spin. */
.coin {
  position: relative;
  width: 0.8036em;
  height: 0.8036em;
  transform-style: preserve-3d;
  transition: transform 640ms cubic-bezier(0.2, 0.75, 0.25, 1);
}
.mark { position: absolute; inset: 0; width: 100%; height: 100%; fill: var(--accent); color: var(--accent); backface-visibility: hidden; }
.mark.back { transform: rotateY(180deg); }
.mark-face { fill: var(--relief); }
.wordmark:hover .coin, .wordmark:focus-visible .coin { transform: rotateY(180deg); }
@media (prefers-reduced-motion: reduce) { .coin { transition: none; } }

.site-nav {
  display: flex;
  gap: 1.35rem;
  margin-left: 1rem;
  font-size: 0.95rem;
  font-weight: 500;
}
.site-nav a { text-decoration: none; color: var(--ink-2); }
.site-nav a:hover { color: var(--ink); }

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-left: auto;
}

.theme-toggle {
  font: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--ink-2);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 0.45rem 0.7rem;
  cursor: pointer;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--ink-2); }

/* Buttons */

.button {
  display: inline-flex;
  align-items: center;
  padding: 0.7rem 1.1rem;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: transform 120ms ease, background-color 120ms ease;
}
.button:active { transform: translateY(1px); }
.button-primary { background: var(--accent); color: var(--accent-ink); }
.button-primary:hover { filter: brightness(1.06); }
.button-quiet { border-color: var(--line-strong); color: var(--ink); }
.button-quiet:hover { border-color: var(--ink-2); }

.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* Hero */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
  padding: clamp(3rem, 8vw, 6rem) var(--gutter) clamp(3rem, 7vw, 5rem);
}

.hero h1 {
  font-size: clamp(2rem, 1.1rem + 2.9vw, 3rem);
  font-weight: 800;
  letter-spacing: -0.025em;
}

.lede {
  margin-top: 1.25rem;
  max-width: 44ch;
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.3rem);
  color: var(--ink-2);
  text-wrap: pretty;
}

.hero .actions { margin-top: 2rem; }

/* The ledger: the real run output as the hero visual */

.ledger {
  margin: 0;
  background: var(--ledger-bg);
  color: var(--ledger-ink);
  border-radius: var(--radius);
  box-shadow: 0 24px 60px -30px rgba(18, 51, 31, 0.55);
  overflow: hidden;
}

.ledger-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.9rem 1.1rem 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.ledger-cmd { color: var(--ledger-ink); }
.ledger-stamp {
  color: var(--ledger-mark);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
}

.ledger-lines {
  margin: 0;
  padding: 0.75rem 0 0.9rem;
  list-style: none;
  counter-reset: line;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  line-height: 1.7;
  overflow-x: auto;
}
.ledger-lines li {
  counter-increment: line;
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.ledger-lines li::before {
  content: counter(line);
  text-align: right;
  padding-right: 0.9rem;
  color: var(--ledger-muted);
  font-size: 0.7rem;
}
.ledger-lines code { font: inherit; padding-right: 1.1rem; }
.ledger-lines .is-mark code {
  color: var(--ledger-mark);
  position: relative;
}
.ledger-lines .is-mark { background: rgba(115, 226, 167, 0.08); }

.ledger figcaption {
  padding: 0.85rem 1.1rem 1rem;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--ledger-muted);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* Motion. Every move below is a function of scroll position: a view timeline
   on the root scroller drives it, so the same scroll position always paints
   the same frame. Nothing here runs on the clock and nothing loops.
   The initial hidden state lives only inside this block, next to the
   animation that resolves it, so a browser without scroll timelines
   (or a reader who asked for reduced motion) gets the finished page. */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    @keyframes arrive {
      from { opacity: 0; transform: translateY(0.6rem); }
      to { opacity: 1; transform: none; }
    }
    @keyframes drift {
      from { transform: translateY(1.25rem); }
      to { transform: translateY(-1.25rem); }
    }

    /* The hero ledger: the lines arrive in order as the record scrolls into
       place. The ledger names its own view timeline so its lines can follow
       it; their own timelines would attach to the list, which scrolls
       sideways. Line n occupies a 6% slice of the ledger's travel, starting
       3% after line n-1. On a phone the ledger sits under the copy and
       enters from below, so its lines start earlier and spread a little
       wider: the first few are readable at rest, the rest are written as
       the record climbs the screen. */
    .ledger { view-timeline-name: --ledger; --from: 18%; --step: 3%; }
    .ledger-lines li {
      animation: arrive linear both;
      animation-timeline: --ledger;
      animation-range: cover calc(var(--from) + var(--i) * var(--step)) cover calc(var(--from) + 6% + var(--i) * var(--step));
    }
    .ledger-lines li:nth-child(1) { --i: 1; }
    .ledger-lines li:nth-child(2) { --i: 2; }
    .ledger-lines li:nth-child(3) { --i: 3; }
    .ledger-lines li:nth-child(4) { --i: 4; }
    .ledger-lines li:nth-child(5) { --i: 5; }
    .ledger-lines li:nth-child(6) { --i: 6; }
    .ledger-lines li:nth-child(7) { --i: 7; }
    .ledger-lines li:nth-child(8) { --i: 8; }
    .ledger-lines li:nth-child(9) { --i: 9; }
    .ledger-lines li:nth-child(10) { --i: 10; }
    .ledger-lines li:nth-child(11) { --i: 11; }
    .ledger-lines li:nth-child(12) { --i: 12; }
    .ledger-lines li:nth-child(13) { --i: 13; }
    .ledger-lines li:nth-child(14) { --i: 14; }
    .ledger-lines li:nth-child(15) { --i: 15; }
    .ledger-lines li:nth-child(16) { --i: 16; }

    /* Section reveals: each block of a section arrives as its own top edge
       crosses the lower part of the viewport. Quiet by construction: the
       same short rise as a ledger line, finished 16rem after the block's
       top edge enters, whatever the block's height. */
    section:not(.hero) > * {
      animation: arrive linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 16rem;
    }

    /* The two diagram cards drift a little slower than the page while they
       cross the viewport. The card's own overflow does not matter: as the
       subject of a view timeline it still measures against the root. The
       selector outranks the section reveal above so the card drifts
       instead of fading. */
    section:not(.hero) > .process-visual-card {
      animation: drift linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }
  }
}

/* Process Visual Diagram Component */
.process-visual-card {
  margin-top: 2.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 16px 40px rgba(18, 51, 31, 0.08);
}

.process-visual-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 1.1rem 1.5rem;
  border-bottom: 1px solid var(--line);
}

.process-visual-title {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--ink);
  letter-spacing: -0.015em;
}

.graph-stage {
  padding: 1.5rem 1.25rem 1rem;
  background: var(--surface);
  position: relative;
}

/* On a wide screen the record wraps into rows and nothing scrolls sideways;
   on a phone it keeps its single row inside its own scroller. */
@media (min-width: 900px) {
  .record-strip { flex-wrap: wrap; overflow-x: visible; }
}

.record-verdict.pass {
  color: var(--ledger-mark);
}

.record-verdict.hold {
  border: 1px solid rgba(255, 255, 255, 0.35);
  padding: 1px 4px;
  border-radius: 2px;
}

.record-verdict.fail {
  background: var(--ink);
  color: var(--bg);
  padding: 1px 4px;
  border-radius: 2px;
}

/* Sections */

section:not(.hero) {
  padding: clamp(3rem, 7vw, 5.5rem) var(--gutter);
  border-top: 1px solid var(--line);
}

section h2 {
  font-size: clamp(1.6rem, 1.1rem + 1.6vw, 2.4rem);
  max-width: 24ch;
}

.section-lede {
  margin-top: 0.75rem;
  color: var(--ink-2);
  max-width: var(--measure);
}

/* Value */

.value { padding-top: 0; border-top: 0; }

.value-grid {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2rem clamp(2rem, 6vw, 5rem);
  border-top: 1px solid var(--line);
  padding-top: 2rem;
}

.value-item dt {
  font-weight: 700;
  font-size: 1.2rem;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.value-item dd {
  margin: 0.5rem 0 0;
  color: var(--ink-2);
  max-width: 48ch;
}

/* How it works */

.steps {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 4vw, 3rem);
}

.steps li {
  border-top: 2px solid var(--ink);
  padding-top: 1rem;
}

.step-label {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--accent);
}

.steps h3 {
  margin-top: 0.6rem;
  font-size: 1.2rem;
}

.steps p {
  margin-top: 0.6rem;
  color: var(--ink-2);
}

/* Layers */

.layer-list {
  margin: 2.5rem 0 0;
  display: grid;
  gap: 0;
}

.layer {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: 1rem clamp(1.5rem, 4vw, 3rem);
  padding: 1.35rem 0;
  border-top: 1px solid var(--line);
}
.layer:last-child { border-bottom: 1px solid var(--line); }

.layer dt {
  display: grid;
  gap: 0.15rem;
}
.layer-known {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-2);
}
.layer-ours {
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: -0.01em;
}
.layer dd {
  margin: 0;
  color: var(--ink-2);
  max-width: var(--measure);
}

/* Engines */

.engines {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: start;
}

.engines-copy p {
  margin-top: 1rem;
  color: var(--ink-2);
  max-width: 44ch;
}

.engines-copy .pull {
  margin-top: 1.5rem;
  padding-left: 1rem;
  border-left: 3px solid var(--accent);
  color: var(--ink);
  font-weight: 500;
  max-width: 34ch;
}

.engine-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--line);
}

.engine-list li {
  display: grid;
  gap: 0.15rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--line);
}
.engine-list li:nth-child(odd) { padding-right: 1.5rem; }
.engine-list li:nth-child(even) { padding-left: 1.5rem; border-left: 1px solid var(--line); }

.engine-list strong { font-weight: 700; }
.engine-list span {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-2);
}

/* Status */

.status-columns {
  margin-top: 2rem;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2rem, 6vw, 5rem);
}

.status-columns h3 {
  font-size: 1rem;
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--accent);
}

.status-columns ul {
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.75rem;
  color: var(--ink-2);
  max-width: 44ch;
}

/* Closing */

.closing {
  background: var(--surface);
}
.closing h2 { max-width: 20ch; }
.closing .actions { margin-top: 2rem; }

/* Footer */

.site-footer {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  padding: 1.5rem var(--gutter) 2.5rem;
  border-top: 1px solid var(--line);
  font-size: 0.9rem;
  color: var(--ink-2);
}
.site-footer span { font-weight: 700; color: var(--ink); }
.site-footer a { text-decoration: none; }
.site-footer a:hover { color: var(--ink); text-decoration: underline; }

/* Phones and narrow windows: one column, nothing wider than the viewport */

@media (max-width: 900px) {
  .hero { grid-template-columns: minmax(0, 1fr); }
  .ledger { --from: 6.5%; --step: 3.5%; }
  .engines { grid-template-columns: minmax(0, 1fr); }
  .steps { grid-template-columns: minmax(0, 1fr); }
  .layer { grid-template-columns: minmax(0, 1fr); gap: 0.5rem; }
}

@media (max-width: 720px) {
  .site-nav { display: none; }
  .site-header .button { display: none; }
  .value-grid, .status-columns, .engine-list { grid-template-columns: minmax(0, 1fr); }
  .engine-list li:nth-child(odd) { padding-right: 0; }
  .engine-list li:nth-child(even) { padding-left: 0; border-left: 0; }
}

/* The flow card: the workflow and its record, replayed as the card scrolls into place. */
.flow { --mark: var(--ledger-mark, #73E2A7); --tint-1: color-mix(in srgb, var(--accent) 6%, transparent); --tint-2: color-mix(in srgb, var(--accent) 11%, transparent); }
    .flow .ground { fill: var(--bg); }
    .flow .sans { font-family: "Schibsted Grotesk", "Helvetica Neue", Arial, sans-serif; }
    .flow .mono { font-family: "IBM Plex Mono", Menlo, monospace; }
    .flow .title { font-size: 15px; font-weight: 700; fill: var(--ink); }
    .flow .kicker { font-size: 11px; fill: var(--ink-2); letter-spacing: 0.04em; }
    .flow .box { fill: var(--tint-1); stroke: var(--line-strong); stroke-width: 1; }
    .flow .box2 { fill: var(--tint-2); stroke: var(--line-strong); stroke-width: 1; }
    .flow .boxlabel { font-size: 10.5px; fill: var(--ink-2); letter-spacing: 0.04em; }
    .flow .station { fill: var(--surface); stroke: var(--line-strong); stroke-width: 1.25; }
    .flow .station-lit { fill: var(--accent-soft); stroke: var(--accent); }
    .flow .name { font-size: 12.5px; font-weight: 700; fill: var(--ink); text-anchor: middle; }
    .flow .sub { font-size: 9.5px; fill: var(--ink-2); text-anchor: middle; }
    .flow .edge { fill: none; stroke: var(--line-strong); stroke-width: 1.25; }
    .flow .edge-lit { fill: none; stroke: var(--accent); stroke-width: 1.5; }
    .flow .arc { fill: none; stroke: var(--line); stroke-width: 1; }
    .flow .gate { fill: var(--bg); stroke: var(--accent); stroke-width: 1.75; }
    .flow .gate-fill { fill: var(--accent); }
    .flow .gatelabel { font-size: 9.5px; fill: var(--ink-2); text-anchor: middle; }
    .flow .return { fill: none; stroke: var(--accent); stroke-width: 1.25; }
    .flow .returnlabel { font-size: 9.5px; fill: var(--ink-2); text-anchor: middle; }
    .flow .strip { fill: var(--ledger-bg); }
    .flow .striplabel { font-size: 9.5px; fill: var(--ledger-muted); letter-spacing: 0.08em; }
    .flow .block { fill: rgba(255,255,255,0.05); stroke: rgba(255,255,255,0.14); stroke-width: 1; }
    .flow .pass .block { stroke: var(--mark); }
    .flow .hold .block { stroke: var(--ledger-ink); stroke-dasharray: 3 2; }
    .flow .fail .block { fill: var(--ledger-ink); stroke: var(--ledger-ink); }
    .flow .btime { font-size: 8.5px; fill: var(--ledger-muted); }
    .flow .btext { font-size: 9.5px; fill: var(--ledger-ink); }
    .flow .fail .btext, .flow .fail .btime { fill: var(--ledger-bg); }
    .flow .pass .btext { fill: var(--mark); }
    .flow .cursor { fill: var(--mark); }
    .flow .caption { font-size: 11px; fill: var(--ink-2); }
    /* The rest state is the finished record. The page adds the replay, scroll-driven. */
    .flow .step, .flow .station-lit, .flow .edge-lit, .flow .gate-fill { opacity: 1; }
    .flow .cursor { opacity: 0; }
.flow-card .graph-stage { overflow-x: auto; }
/* The review loop's three stations start at the left edge so a phone's first slice shows Draft and the
   return edge; from 900 px up the group is centred in its container (240 user units to the right). */
@media (min-width: 900px) { .flow-card .loop-group { transform: translate(240px, 0); } }
.flow-card .graph-stage .flow { width: 100%; min-width: 860px; height: auto; display: block; overflow: visible; }
.process-visual-meta { font-family: var(--font-mono); font-size: 0.8rem; color: var(--ink-2); }
.flow-card figcaption { padding: 0.9rem 1.5rem 1.1rem; border-top: 1px solid var(--line); font-size: 0.9rem; line-height: 1.5; color: var(--ink-2); }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .flow-card { view-timeline-name: --flow; --from: 22%; --span: 42%; --slice: 4%; }
    .flow-card .flow .step { animation: flow-arrive linear both; animation-timeline: --flow; animation-range: cover calc(var(--from) + var(--p) * var(--span)) cover calc(var(--from) + var(--p) * var(--span) + var(--slice)); }
    .flow-card .flow .station-lit, .flow-card .flow .edge-lit, .flow-card .flow .gate-fill { animation: flow-lit linear both; animation-timeline: --flow; animation-range: cover calc(var(--from) + var(--p) * var(--span)) cover calc(var(--from) + var(--p) * var(--span) + var(--slice)); }
    .flow-card .flow .cursor { animation: flow-pulse linear both; animation-timeline: --flow; animation-range: cover calc(var(--from) + var(--p) * var(--span)) cover calc(var(--from) + var(--p) * var(--span) + 2.5 * var(--slice)); }
    @keyframes flow-arrive { from { opacity: 0.28; } to { opacity: 1; } }
    @keyframes flow-lit { from { opacity: 0; } to { opacity: 1; } }
    @keyframes flow-pulse { from { opacity: 0; } 35% { opacity: 1; } to { opacity: 0; } }
  }
}


/* The GitHub mark: an icon-only link in the header, and the mark beside the
   word in the closing button. Sized to the header's other controls so the
   row keeps one baseline. */
.icon-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 999px;
  color: var(--ink-muted, currentColor);
  transition: color 120ms ease, background-color 120ms ease;
}
.icon-link svg { width: 1.25rem; height: 1.25rem; display: block; }
.icon-link:hover, .icon-link:focus-visible { color: var(--ink, currentColor); }
.button-with-mark { display: inline-flex; align-items: center; gap: 0.5rem; }
.button-with-mark svg { width: 1.05rem; height: 1.05rem; }
@media (prefers-reduced-motion: reduce) { .icon-link { transition: none; } }
