/* ═══════════════════════════════════════════════════════════════════════════
   site.css — the static pages: /about, /faq, /privacy

   Loaded AFTER style.css, which stays the single source of every token. Nothing
   here defines a colour, a shadow, or a type size of its own: if a value needed
   tuning it went into style.css's :root instead. Same constraints as the app —
   no literal hex, no px font-size, no box-shadow literal below the token block,
   no inline styles, every margin/padding/gap from the --s* scale.

   The header and footer markup is duplicated byte-for-byte into every static
   page rather than injected by JS, so it renders with JS disabled and is visible
   to crawlers. See the comment above the header in about.html.
   ═══════════════════════════════════════════════════════════════════════════ */

/* style.css makes <body> a two-row grid for the app shell. The static pages are
   ordinary flow documents. */
body.site-page {
  display: block;
  height: auto;
  min-height: 100%;
  font-size: var(--t-body);
  line-height: var(--lh-body);
}

/* ═══ Shared header ═══════════════════════════════════════════════════════ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--header-bg);
  -webkit-backdrop-filter: blur(var(--header-blur));
  backdrop-filter: blur(var(--header-blur));
  border-bottom: var(--hair) solid transparent;
  transition: border-color var(--dur), box-shadow var(--dur);
}

/* site.js adds .stuck once the page has scrolled past --header-shadow-at. */
.site-header.stuck {
  border-bottom-color: var(--rule);
  box-shadow: var(--e1);
}

.site-header-wrap {
  max-width: var(--site-max);
  margin: 0 auto;
  padding: var(--s3) var(--s5);
  display: flex;
  align-items: center;
  gap: var(--s5);
}

.site-brand {
  display: flex;
  align-items: center;
  gap: var(--s3);
  text-decoration: none;
}

.site-brand svg { width: var(--mark-size); height: var(--mark-size); flex: none; }

/* Same layer separation as the app's mark. */
.site-brand .l1,
.site-brand .l3 { transition: transform var(--dur-slow) var(--ease-out); }
.site-brand:hover .l1 { transform: translateY(calc(var(--layer-shift) * -1)); }
.site-brand:hover .l3 { transform: translateY(var(--layer-shift)); }

.site-brand span {
  font-family: var(--display);
  font-size: var(--t-wordmark-site);
  font-weight: 600;
  color: var(--navy);
  letter-spacing: var(--ls-wordmark);
}

.site-nav {
  margin-left: auto;
  display: flex;
  gap: var(--s5);
  align-items: center;
}

.site-nav a {
  color: var(--ink-mid);
  text-decoration: none;
  font-size: var(--t-small);
  transition: color var(--dur-fast);
}

.site-nav a:hover { color: var(--blue); }
.site-nav a[aria-current="page"] { color: var(--navy); }

.site-cta {
  background: var(--navy);
  color: var(--on-navy) !important;
  padding: var(--s2) var(--s4);
  border-radius: var(--r);
  box-shadow: var(--e1);
  transition:
    transform var(--dur-fast) var(--ease),
    box-shadow var(--dur-fast),
    background var(--dur-fast);
}

.site-cta:hover {
  transform: translateY(var(--lift-2));
  box-shadow: var(--e2);
  background: var(--navy-hover);
}

/* Elevated controls swallow the :focus-visible ring on specificity — same trap
   the app hit. Restate both shadows together. */
.site-cta:focus-visible,
.bigcta:focus-visible,
.faq-q:focus-visible { box-shadow: var(--e2), var(--e-focus); }

/* ═══ The spine ═══════════════════════════════════════════════════════════
   A fixed S-curve in the left margin, the same geometry as the channel cut
   through the mark. stroke-dashoffset is driven by scroll progress in site.js.
   Hidden below 1180px, where there is no margin to put it in. */

.spine {
  position: fixed;
  left: calc((100vw - var(--site-max)) / 2 + var(--s5));
  top: 0;
  height: 100vh;
  width: var(--spine);
  pointer-events: none;
  z-index: 1;
}

.spine svg { height: 100%; width: 100%; overflow: visible; }

.spine path {
  fill: none;
  stroke: var(--pale);
  stroke-width: var(--spine-w);
  stroke-linecap: round;
}

.spine path.spine-lead { stroke: var(--blue); }

/* --spine-len and --spine-progress are set by site.js. Until they exist the
   lead path draws at full length, so a JS-less or unmeasurable page shows the
   finished curve rather than an empty gutter. */
.spine path.spine-lead {
  stroke-dasharray: var(--spine-len, none);
  stroke-dashoffset: calc(var(--spine-len, 0) * (1 - var(--spine-progress, 1)));
}

@media (max-width: 1180px) { .spine { display: none; } }

/* Deep-linked headings and FAQ rows must clear the sticky header. */
.site-section[id],
.faq-item[id],
.faq-q[id] { scroll-margin-top: var(--anchor-offset); }

/* ═══ Page frame ══════════════════════════════════════════════════════════ */

.site-main {
  max-width: var(--site-max);
  margin: 0 auto;
  padding: 0 var(--s5) var(--s9);
  position: relative;
  z-index: 2;
}

.site-col { padding-left: 0; }

/* Content clears the spine only where the spine exists. */
@media (min-width: 1181px) {
  .site-col { padding-left: calc(var(--spine) + var(--s6)); }
}

/* ═══ Reveals ═════════════════════════════════════════════════════════════
   Same [data-rise] contract as the app — style.css owns the base and .in
   rules. Only the per-element --d delays are page-specific, and they are
   assigned here by selector rather than inline. */

.site-page [data-rise] { --d: 0ms; }

.hero h1                    { --d: 80ms; }
.hero .hero-lede            { --d: 170ms; }
.hero .scrollcue            { --d: 260ms; }

.site-section h2            { --d: 60ms; }
.site-section > p           { --d: 110ms; }
.site-section > p + p       { --d: 150ms; }
.story, .viz, .callout      { --d: 110ms; }
.viz                        { --d: 160ms; }
.bars                       { --d: 200ms; }

.grid2 .card:nth-child(1) { --d: 0ms; }
.grid2 .card:nth-child(2) { --d: calc(var(--stagger) * 1); }
.grid2 .card:nth-child(3) { --d: calc(var(--stagger) * 2); }
.grid2 .card:nth-child(4) { --d: calc(var(--stagger) * 3); }

.close p     { --d: 70ms; }
.close .bigcta { --d: 140ms; }

/* ═══ Hero ════════════════════════════════════════════════════════════════ */

.hero { padding: var(--s9) 0 var(--s8); position: relative; }

.eyebrow {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--blue);
  margin: 0 0 var(--s4);
}

.hero h1 {
  font-family: var(--display);
  font-size: var(--t-mega);
  line-height: 1.08;
  letter-spacing: var(--ls-hero);
  color: var(--navy);
  margin: 0 0 var(--s5);
  font-weight: 500;
  max-width: 15ch;
}

.hero h1 em { font-style: italic; color: var(--blue); }

.hero-lede {
  font-size: var(--t-hero-lede);
  color: var(--ink-mid);
  max-width: 54ch;
  margin: 0;
}

.scrollcue {
  margin-top: var(--s8);
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-cue);
  text-transform: uppercase;
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  gap: var(--s3);
}

.scrollcue i {
  display: block;
  width: var(--hair);
  height: var(--scrollcue-h);
  background: linear-gradient(var(--blue), transparent);
  animation: drop 2.1s var(--ease) infinite;
}

@keyframes drop {
  0%   { transform: scaleY(0); transform-origin: top; }
  55%  { transform: scaleY(1); transform-origin: top; }
  56%  { transform-origin: bottom; }
  100% { transform: scaleY(0); transform-origin: bottom; }
}

/* ═══ Sections ════════════════════════════════════════════════════════════ */

.site-section {
  padding: var(--s9) 0;
  border-top: var(--hair) solid var(--rule);
}

.site-section:first-of-type { border-top: none; }

.slabel {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 var(--s4);
  display: flex;
  align-items: center;
  gap: var(--s3);
}

.slabel::before {
  content: "";
  width: var(--slabel-rule);
  height: var(--hair);
  background: var(--blue);
  flex: none;
}

.site-page h2 {
  font-family: var(--display);
  font-size: var(--t-h2);
  line-height: 1.2;
  letter-spacing: var(--ls-hero);
  color: var(--navy);
  margin: 0 0 var(--s5);
  font-weight: 500;
  max-width: 20ch;
}

.site-page h3 {
  font-family: var(--display);
  font-size: var(--t-h3);
  color: var(--navy);
  margin: 0 0 var(--s2);
  font-weight: 600;
}

.site-page p {
  margin: 0 0 var(--s4);
  max-width: var(--measure);
}

.site-page p:last-child { margin-bottom: 0; }

.site-page a { color: var(--blue); }

.big {
  font-size: var(--t-big);
  line-height: 1.5;
  color: var(--navy);
  font-family: var(--display);
  max-width: 34ch;
}

/* ═══ Story pull-block ════════════════════════════════════════════════════ */

.story {
  background: var(--apparatus);
  border-radius: var(--r);
  padding: var(--s6);
  border-left: var(--bw-accent) solid var(--blue);
  max-width: var(--measure);
}

.sig {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-sig);
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-top: var(--s4);
}

/* ═══ The 41 → 6 filter ═══════════════════════════════════════════════════ */

.viz {
  margin: var(--s6) 0 0;
  background: var(--apparatus);
  border-radius: var(--r);
  padding: var(--s6);
  position: relative;
  overflow: hidden;
}

.vizhead {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s3);
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: var(--t-viz);
  color: var(--ink-soft);
  margin-bottom: var(--s5);
  letter-spacing: var(--ls-viz);
}

.vizhead b { color: var(--navy); font-weight: 500; }

.dots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--dot-min), 1fr));
  gap: var(--dot-gap);
}

.dot {
  aspect-ratio: 1;
  border-radius: var(--r-sm);
  background: var(--rule-strong);
  transform: rotate(45deg) scale(.72);
  opacity: .85;
  transition:
    background var(--dur-slow) var(--ease),
    opacity var(--dur-slow) var(--ease),
    transform var(--dur-slow) var(--ease-out);
}

.viz.run .dot { opacity: .16; transform: rotate(45deg) scale(.5); }

.viz.run .dot.keep {
  opacity: 1;
  background: var(--navy);
  transform: rotate(45deg) scale(1);
}

/* The stagger is a token multiple rather than an inline transition-delay, so
   the whole filter retunes from --dot-stagger. 41 steps, matching the 41
   candidates the visualization describes. */
.dot:nth-child(1)  { transition-delay: calc(var(--dot-stagger) * 0); }
.dot:nth-child(2)  { transition-delay: calc(var(--dot-stagger) * 1); }
.dot:nth-child(3)  { transition-delay: calc(var(--dot-stagger) * 2); }
.dot:nth-child(4)  { transition-delay: calc(var(--dot-stagger) * 3); }
.dot:nth-child(5)  { transition-delay: calc(var(--dot-stagger) * 4); }
.dot:nth-child(6)  { transition-delay: calc(var(--dot-stagger) * 5); }
.dot:nth-child(7)  { transition-delay: calc(var(--dot-stagger) * 6); }
.dot:nth-child(8)  { transition-delay: calc(var(--dot-stagger) * 7); }
.dot:nth-child(9)  { transition-delay: calc(var(--dot-stagger) * 8); }
.dot:nth-child(10) { transition-delay: calc(var(--dot-stagger) * 9); }
.dot:nth-child(11) { transition-delay: calc(var(--dot-stagger) * 10); }
.dot:nth-child(12) { transition-delay: calc(var(--dot-stagger) * 11); }
.dot:nth-child(13) { transition-delay: calc(var(--dot-stagger) * 12); }
.dot:nth-child(14) { transition-delay: calc(var(--dot-stagger) * 13); }
.dot:nth-child(15) { transition-delay: calc(var(--dot-stagger) * 14); }
.dot:nth-child(16) { transition-delay: calc(var(--dot-stagger) * 15); }
.dot:nth-child(17) { transition-delay: calc(var(--dot-stagger) * 16); }
.dot:nth-child(18) { transition-delay: calc(var(--dot-stagger) * 17); }
.dot:nth-child(19) { transition-delay: calc(var(--dot-stagger) * 18); }
.dot:nth-child(20) { transition-delay: calc(var(--dot-stagger) * 19); }
.dot:nth-child(21) { transition-delay: calc(var(--dot-stagger) * 20); }
.dot:nth-child(22) { transition-delay: calc(var(--dot-stagger) * 21); }
.dot:nth-child(23) { transition-delay: calc(var(--dot-stagger) * 22); }
.dot:nth-child(24) { transition-delay: calc(var(--dot-stagger) * 23); }
.dot:nth-child(25) { transition-delay: calc(var(--dot-stagger) * 24); }
.dot:nth-child(26) { transition-delay: calc(var(--dot-stagger) * 25); }
.dot:nth-child(27) { transition-delay: calc(var(--dot-stagger) * 26); }
.dot:nth-child(28) { transition-delay: calc(var(--dot-stagger) * 27); }
.dot:nth-child(29) { transition-delay: calc(var(--dot-stagger) * 28); }
.dot:nth-child(30) { transition-delay: calc(var(--dot-stagger) * 29); }
.dot:nth-child(31) { transition-delay: calc(var(--dot-stagger) * 30); }
.dot:nth-child(32) { transition-delay: calc(var(--dot-stagger) * 31); }
.dot:nth-child(33) { transition-delay: calc(var(--dot-stagger) * 32); }
.dot:nth-child(34) { transition-delay: calc(var(--dot-stagger) * 33); }
.dot:nth-child(35) { transition-delay: calc(var(--dot-stagger) * 34); }
.dot:nth-child(36) { transition-delay: calc(var(--dot-stagger) * 35); }
.dot:nth-child(37) { transition-delay: calc(var(--dot-stagger) * 36); }
.dot:nth-child(38) { transition-delay: calc(var(--dot-stagger) * 37); }
.dot:nth-child(39) { transition-delay: calc(var(--dot-stagger) * 38); }
.dot:nth-child(40) { transition-delay: calc(var(--dot-stagger) * 39); }
.dot:nth-child(41) { transition-delay: calc(var(--dot-stagger) * 40); }

.vizfoot {
  margin-top: var(--s5);
  font-size: var(--t-small);
  color: var(--ink-mid);
  max-width: 58ch;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease) var(--viz-delay);
}

.viz.run .vizfoot { opacity: 1; }

/* ═══ Coverage bars ═══════════════════════════════════════════════════════ */

.bars {
  display: grid;
  gap: var(--s4);
  margin: var(--s5) 0 0;
  max-width: var(--measure);
}

.bar b {
  font-family: var(--mono);
  font-size: var(--t-viz);
  color: var(--ink-mid);
  display: flex;
  justify-content: space-between;
  gap: var(--s3);
  flex-wrap: wrap;
  margin-bottom: var(--s1);
  font-weight: 400;
}

.bar b span { color: var(--navy); }

.track {
  height: var(--bar-h);
  background: var(--rule);
  border-radius: var(--bar-r);
  overflow: hidden;
}

.fill {
  height: 100%;
  background: var(--blue);
  border-radius: var(--bar-r);
  width: 0;
  transition: width var(--bar-fill-dur) var(--ease-out) var(--bd, 0ms);
}

.fill.soft { background: var(--pale); }

/* Widths and stagger come from tokens, not from inline styles. */
.bar:nth-child(1) .fill { --w: var(--cov-bio); }
.bar:nth-child(2) .fill { --w: var(--cov-adj); --bd: var(--bar-delay-2); }
.bar:nth-child(3) .fill { --w: var(--cov-gap); --bd: var(--bar-delay-3); }

.bars.filled .fill { width: var(--w); }

/* ═══ Cheating callout ════════════════════════════════════════════════════ */

.callout {
  border: var(--hair) solid var(--rule);
  border-radius: var(--r);
  box-shadow: var(--e2);
  padding: var(--s6);
  background: var(--surface);
  max-width: var(--measure);
  position: relative;
  overflow: hidden;
}

.callout::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--bw-accent);
  background: linear-gradient(var(--navy), var(--blue), var(--pale));
}

/* ═══ Cards ═══════════════════════════════════════════════════════════════ */

.grid2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: var(--s4);
  margin-top: var(--s5);
}

.site-page .card {
  background: var(--surface);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r);
  box-shadow: var(--e1);
  padding: var(--s5);
  display: block;
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

.site-page .card:hover { transform: translateY(var(--lift-3)); box-shadow: var(--e3); }

.site-page .card p { font-size: var(--t-small); color: var(--ink-mid); margin: 0; }

.site-page .card .num {
  font-family: var(--mono);
  font-size: var(--t-micro);
  color: var(--blue);
  letter-spacing: var(--ls-sig);
  margin-bottom: var(--s3);
}

/* ═══ Closing CTA ═════════════════════════════════════════════════════════ */

.close {
  text-align: left;
  padding: var(--s9) 0 0;
  border-top: var(--hair) solid var(--rule);
}

.close h2 { font-size: var(--t-close-h2); max-width: 16ch; }

.bigcta {
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  background: var(--navy);
  color: var(--on-navy);
  text-decoration: none;
  padding: var(--s4) var(--s5);
  border-radius: var(--r);
  box-shadow: var(--e2);
  font-size: var(--t-cta);
  margin-top: var(--s5);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur);
}

.bigcta:hover { transform: translateY(var(--lift-3)); box-shadow: var(--e3); }
.bigcta span { font-family: var(--display); font-weight: 600; }

/* ═══ FAQ accordion ═══════════════════════════════════════════════════════
   Real <button> elements with aria-expanded/aria-controls. Opens via
   grid-template-rows 1fr -> 0fr, the same technique as the rail's batch
   accordion — never max-height, which needs a magic number. */

.faq-list { border-top: var(--hair) solid var(--rule); max-width: var(--measure); }

/* The question is a heading for outline purposes; the button inside it is what
   is actually operable. The heading itself carries no visual weight of its own. */
.faq-heading { margin: 0; font-size: inherit; font-weight: inherit; }

.faq-item { border-bottom: var(--hair) solid var(--rule); }

.faq-q {
  width: 100%;
  display: flex;
  align-items: baseline;
  gap: var(--s4);
  text-align: left;
  background: none;
  border: none;
  padding: var(--s5) 0;
  cursor: pointer;
  font-family: var(--display);
  font-size: var(--t-h3);
  color: var(--navy);
  transition: color var(--dur-fast);
}

.faq-q:hover { color: var(--blue); }

.faq-num {
  font-family: var(--mono);
  font-size: var(--t-micro);
  color: var(--blue);
  letter-spacing: var(--ls-sig);
  flex: none;
}

.faq-qtext { flex: 1; min-width: 0; }

.faq-caret {
  flex: none;
  color: var(--blue);
  font-family: var(--body);
  transition: transform var(--dur) var(--ease-out);
}

.faq-item.open .faq-caret { transform: rotate(45deg); }

.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows var(--dur-slow) var(--ease-out), opacity var(--dur);
}

.faq-item.open .faq-a { grid-template-rows: 1fr; opacity: 1; }

.faq-a-inner { overflow: hidden; }

/* The padding lives on a child so a closed row collapses to nothing. */
.faq-item.open .faq-a-inner > :first-child { margin-top: 0; }
.faq-a-inner > * { color: var(--ink-mid); }
.faq-a-inner > :last-child { padding-bottom: var(--s5); }

/* Deep-linked entry gets a moment of emphasis so it is obvious which one the
   fragment opened. */
.faq-item.targeted .faq-q { color: var(--blue); }

/* ═══ Privacy / long-form prose ═══════════════════════════════════════════
   privacy.html keeps its existing copy; these give it the site's typography.
   (Its old .static-page rules were dropped when style.css was rewritten, so
   without this the page renders unstyled.) */

.prose { padding: var(--s8) 0 var(--s9); }
.prose h1 {
  font-family: var(--display);
  font-size: var(--t-h2);
  line-height: 1.2;
  letter-spacing: var(--ls-hero);
  color: var(--navy);
  margin: 0 0 var(--s5);
  font-weight: 500;
  max-width: 20ch;
}
.prose h2 { font-size: var(--t-h3); margin-top: var(--s6); }
.prose ul { max-width: var(--measure); padding-left: var(--s5); }
.prose li { margin-bottom: var(--s2); }

/* ═══ Footer ══════════════════════════════════════════════════════════════ */

.page-footer {
  border-top: var(--hair) solid var(--rule);
  margin-top: var(--s9);
  padding: var(--s6) var(--s5);
  background: var(--apparatus);
}

.page-footer-wrap {
  max-width: var(--site-max);
  margin: 0 auto;
  display: flex;
  gap: var(--s5);
  flex-wrap: wrap;
  align-items: center;
  font-size: var(--t-small);
  color: var(--ink-soft);
}

.page-footer-wrap a { color: var(--ink-mid); text-decoration: none; }
.page-footer-wrap a:hover { color: var(--blue); }

.page-footer-note {
  margin-left: auto;
  font-family: var(--mono);
  font-size: var(--t-micro);
}

/* ═══ Responsive ══════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  .site-nav a:not(.site-cta) { display: none; }
  .site-main { padding-left: var(--s4); padding-right: var(--s4); }
  .site-header-wrap { padding-left: var(--s4); padding-right: var(--s4); }
  .page-footer { padding-left: var(--s4); padding-right: var(--s4); }
  .page-footer-note { margin-left: 0; width: 100%; }
  .story, .viz, .callout { padding: var(--s5); }
}

/* ═══ Reduced motion ══════════════════════════════════════════════════════
   style.css already collapses every duration and delay. These are the pieces
   that would otherwise sit in a half-finished state rather than simply not
   animating: the scroll cue's looping pulse, and the hover lifts. The spine,
   the filter and the bars are landed in their final state by site.js. */

@media (prefers-reduced-motion: reduce) {
  .scrollcue i { animation: none; }
  .site-page .card:hover,
  .bigcta:hover,
  .site-cta:hover { transform: none; }
  .site-brand:hover .l1,
  .site-brand:hover .l3 { transform: none; }
}
