/* Tokens for the story site: fonts, modes, type, spacing, motion.
   Values travel with the site for the pilot (spec §10); once the design-system
   PR merges they are checked against color.json. */

@font-face {
  font-family: "Geist";
  src: url("/story/fonts/geist-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("/story/fonts/plex-mono-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("/story/fonts/plex-mono-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

:root {
  --sans: "Geist", system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, monospace;
  --phosphor: #00E6A0; /* fill only, never text */

  /* motion.json: existing tokens only */
  --instant: 80ms;
  --fast: 120ms;
  --standard: 200ms;
  --dramatic: 400ms;
  --ease-out: cubic-bezier(0, 0, .2, 1);
  --ease-in-out: cubic-bezier(.4, 0, .2, 1);

  /* layout: a 1200px content column (the platform's width); the gutters sit outside it */
  --content: 1200px;
  --gutter: 16px;
  --container: calc(var(--content) + 2 * var(--gutter));
  --grid-gap: 24px;
}
/* side gutters: 16px on phones, 32px on tablets, 48px from 1024px */
@media (min-width: 760px) { :root { --gutter: 32px; } }
@media (min-width: 1024px) { :root { --gutter: 48px; } }

/* light is the default; without JS (no data-mode) the system preference applies below */
:root,
[data-mode="light"] {
  color-scheme: light;
  --bg: #FFFFFF;
  --rule: #D6D9DF;
  --rule-strong: #0B1120;
  --fg: #0B1120;
  --fg-2: #1E293B;
  --fg-3: #334155;
  --link: #0066B8;
  --mark-fg: #0B1120;
}
[data-mode="dark"] {
  color-scheme: dark;
  --bg: #06090F;
  --rule: #1B2332;
  --rule-strong: #F5F5F4;
  --fg: #F5F5F4;
  --fg-2: #C4BEB7;
  --fg-3: #A09A93;
  --link: #00D4FF;
  --mark-fg: #06090F;
}

/* no-JS fallback: same dark values, only while no data-mode is set */
@media (prefers-color-scheme: dark) {
  :root:not([data-mode]) {
    color-scheme: dark;
    --bg: #06090F;
    --rule: #1B2332;
    --rule-strong: #F5F5F4;
    --fg: #F5F5F4;
    --fg-2: #C4BEB7;
    --fg-3: #A09A93;
    --link: #00D4FF;
    --mark-fg: #06090F;
  }
}

/* type roles, spec §4 */
.poster { font: 800 128px/.9 var(--sans); letter-spacing: -.05em; }
.data-display { font: 600 88px/1 var(--mono); letter-spacing: 0; }
.h-xl { font: 600 36px/1.2 var(--sans); letter-spacing: -.02em; }
.h-lg { font: 500 20px/1.4 var(--sans); letter-spacing: -.01em; }
.body-lg { font: 400 16px/1.6 var(--sans); }
.data-lg { font: 600 16px/1.2 var(--mono); letter-spacing: 0; }
.label { font: 500 12px/1.4 var(--mono); letter-spacing: 0; }
.caps { font: 500 10px/1.4 var(--mono); letter-spacing: .04em; text-transform: uppercase; }

@media (max-width: 1100px) {
  .poster { font-size: clamp(52px, 11vw, 128px); }
  .data-display { font-size: clamp(44px, 7vw, 88px); }
}
@media (max-width: 759.98px) {
  .poster { font-size: 52px; }
  .data-display { font-size: 44px; }
  .h-xl { font-size: 28px; }
}

/* Layout and components. Motion only ever adds rules under html.motion (end of file). */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-size-adjust: 100%; }
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  min-height: 100vh;
}
a { color: inherit; }
ol { list-style: none; }

/* every focusable element: 2px link-colour ring, 2px offset */
:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }

.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.skip {
  position: absolute; left: var(--gutter); top: 8px; z-index: 10;
  padding: 8px 12px; background: var(--bg); color: var(--link);
  font: 500 12px/1.4 var(--mono);
  transform: translateY(calc(-100% - 16px));
}
.skip:focus-visible, .skip:focus { transform: none; }

.wrap { max-width: var(--container); margin: 0 auto; padding-left: var(--gutter); padding-right: var(--gutter); }
.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--grid-gap); }

/* the page is the width query container, so the 2px rules can run edge to edge */
/* note: container-type also makes .page the containing block for any position:fixed descendant */
.page { container-type: inline-size; }

/* strong 2px rules are pseudo-elements so they can animate. They run the full
   page width: the element sits centred in the column, so it extends half the
   page width either side of its own centre. cqw is the page's width without a
   scrollbar (100vw would include it and overflow); without cqw support both
   offsets drop and the rule falls back to the column width. */
.rule-b, .rule-t { position: relative; }
.rule-b::after, .rule-t::after {
  content: ""; position: absolute; left: 0; right: 0; height: 2px;
  left: calc(50% - 50cqw); right: calc(50% - 50cqw);
  background: var(--rule-strong); transform-origin: left center;
}
.rule-b::after { bottom: -2px; }
.rule-t::after { top: -2px; }

/* header */
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 20px 0; border-bottom: 2px solid transparent; color: var(--fg); }
.wordmark { font-weight: 600; text-decoration: none; }
/* shown only in draft builds; the markup is absent otherwise */
.draft-marker { display: inline-block; margin-left: 12px; padding: 2px 6px; border: 1px solid var(--fg-3); color: var(--fg); }

.topbar-end { display: flex; align-items: center; gap: 16px; }
/* reader mode toggle: caps role, 1px --fg-3 border (3:1 on both modes); hover and focus-visible share one rule.
   32px tall so the 18px Bloch sphere fits beside the word. */
.mode-toggle { display: inline-flex; flex-shrink: 0; align-items: center; gap: 8px; height: 32px; padding: 0 10px 0 8px; background: transparent; color: var(--fg-3); border: 1px solid var(--fg-3); border-radius: 0; cursor: pointer; transition: color var(--fast) var(--ease-out), border-color var(--fast) var(--ease-out); }
/* until toggle.js reveals it the button keeps its slot, so the reveal shifts nothing (CLS 0) */
.mode-toggle[hidden] { display: inline-flex; visibility: hidden; }
.mode-toggle svg { width: 18px; height: 18px; flex-shrink: 0; overflow: visible; }
/* Bloch sphere: the state arrow points up in dark (|0>) and down in light (|1>) */
.bloch .arrow { transform-origin: 9px 9px; }
[data-mode="light"] .bloch .arrow { transform: rotate(180deg); }
/* both words share one grid cell, so the slot is always the wider word ("Light") */
.mode-word { display: inline-grid; }
.mode-word > span { grid-area: 1 / 1; justify-self: center; }
/* opposite offsets, so each change is a one-way slide: to dark both words rise, to light both fall */
[data-mode="dark"] .mode-light { opacity: 0; transform: translateY(-6px); }
[data-mode="light"] .mode-dark { opacity: 0; transform: translateY(6px); }
/* the turn and the slide run only on a change of mode: on load the end state is the first style */
@media (prefers-reduced-motion: no-preference) {
  .bloch .arrow { transition: transform var(--dramatic) var(--ease-in-out); }
  .mode-word > span { transition: opacity var(--standard) var(--ease-in-out), transform var(--standard) var(--ease-in-out); }
}
.mode-toggle:focus-visible { color: var(--fg); border-color: var(--fg); }
@media (hover: hover) { .mode-toggle:hover { color: var(--fg); border-color: var(--fg); } }

/* mode crossfade: a View Transition, 200ms (150ms with reduced motion) */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--standard); animation-timing-function: var(--ease-in-out); }
@media (prefers-reduced-motion: reduce) { ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 150ms; } }

/* hero */
.hero { padding-top: 128px; padding-bottom: 96px; }
.eyebrow { color: var(--fg-3); margin-bottom: 28px; }
.hero h1 { grid-column: 1 / -1; }
.hl { display: inline-block; line-height: .8; position: relative; isolation: isolate; color: var(--mark-fg); padding: .04em .06em .1em; }
.hl::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--phosphor); transform-origin: left center; }
.lede { grid-column: 1 / span 6; margin-top: 40px; color: var(--fg-2); }
.lede strong { color: var(--fg); font-weight: 600; }

/* a word or digit that rises out of its own line (motion moves the inner span) */
.mask { display: inline-block; clip-path: inset(-.2em -.12em -.22em -.12em); }
.mask > span { display: inline-block; }

/* stats */
.stats { border-top: 2px solid transparent; border-bottom: 1px solid var(--rule); display: grid; grid-template-columns: repeat(3, 1fr); }
.stat { padding: 32px 24px 32px 0; border-right: 1px solid var(--rule); }
.stat + .stat { padding-left: 24px; }
.stat:last-child { border-right: 0; }
.stat .data-display { display: block; }
.stat p { color: var(--fg-2); margin-top: 16px; max-width: 22ch; }
.stat .label { display: block; color: var(--fg-3); margin-top: 8px; }

/* contents */
.contents { padding-top: 96px; padding-bottom: 128px; }
.contents-h { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 8px 24px; border-bottom: 2px solid transparent; padding-bottom: 16px; }
.contents-h .caps, .part, .row .caps, .row .data-lg { color: var(--fg-3); }
.part { padding: 40px 0 12px; border-bottom: 1px solid transparent; position: relative; }
.row { display: grid; grid-template-columns: 64px minmax(0, 1fr) 120px; gap: 24px; align-items: baseline; padding: 16px 0; border-bottom: 1px solid transparent; position: relative; }
.row::after, .part::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: var(--rule); transform-origin: left center;
}
.row .caps { text-align: right; }

/* footer */
footer { border-top: 2px solid transparent; padding: 24px 0 48px; display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 16px; }
footer .caps { color: var(--fg-3); }
.footer-links { display: flex; gap: 16px; }
footer a {
  color: var(--link); font: 500 12px/1.4 var(--mono);
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--link) 40%, transparent);
  transition: text-decoration-color var(--fast) var(--ease-out);
}
footer a:focus-visible { text-decoration-color: var(--link); }
@media (hover: hover) { footer a:hover { text-decoration-color: var(--link); } }

/* phones (below 760px) */
@media (max-width: 759.98px) {
  .hero { padding-top: 64px; padding-bottom: 64px; }
  .lede { grid-column: 1 / -1; }
  /* the three stats stack */
  .stats { grid-template-columns: 1fr; }
  .stat, .stat + .stat { padding-left: 0; padding-right: 0; border-right: 0; }
  .stat + .stat { border-top: 1px solid var(--rule); }
  .contents { padding-top: 64px; padding-bottom: 96px; }
  .row { grid-template-columns: 40px minmax(0, 1fr); }
  .row .caps { display: none; }
  .topbar-right { display: none; }
  /* the draft marker drops under the wordmark, aligned with it */
  .draft-marker { display: block; width: max-content; margin-left: 0; margin-top: 8px; }
}

/* Ported unchanged from the v5 reference render (2026-10-26-ledger-opening-v5.html).
   Start states exist only under html.motion: without it every element is final. */
/* ---------- motion (only when html.motion) ---------- */
html.motion .rule-b::after,html.motion .rule-t::after{transform:scaleX(0);transition:transform var(--dramatic) var(--ease-out) var(--d,0ms)}
html.motion .in.rule-b::after,html.motion .in.rule-t::after{transform:none}

html.motion .mask>span{transform:translateY(135%);transition:transform var(--dramatic) var(--ease-out) var(--d,0ms)}
html.motion .mask.in>span{transform:none}

html.motion .hl{color:var(--fg);transition:color var(--standard) var(--ease-in-out) calc(var(--d,0ms) + var(--standard))}
html.motion .hl::before{transform:scaleX(0);transition:transform var(--dramatic) var(--ease-out) var(--d,0ms)}
html.motion .hl.in{color:var(--mark-fg)}
html.motion .hl.in::before{transform:none}

html.motion .row::after,html.motion .part::after{transform:scaleX(0);transition:transform var(--dramatic) var(--ease-out) var(--d,0ms)}
html.motion .row.in::after,html.motion .part.in::after{transform:none}
html.motion .row.in .mask>span,html.motion .contents-h.in .mask>span{transform:none}
html.motion .row .rv-in{opacity:0;transition:opacity var(--dramatic) var(--ease-out) var(--d,0ms)}
html.motion .row.in .rv-in{opacity:1}
html.motion .rv{opacity:0;transform:translateY(16px);transition:opacity var(--dramatic) var(--ease-out) var(--d,0ms),transform var(--dramatic) var(--ease-out) var(--d,0ms)}
html.motion .rv.in{opacity:1;transform:none}

/* motion.js resets the load set without a transition before retrying (see reveal()) */
html.still *, html.still *::before, html.still *::after { transition: none !important; }
