/* ═══════════════════════════════════════════════════════════════
   D4D Site Platform — base layer
   Reset, fonts, body type, prose, rhythm classes, container,
   accessibility primitives, print. Requires tokens.css first.
   All colors are tokens — see tokens.css.
   ═══════════════════════════════════════════════════════════════ */

/* ── Self-hosted variable fonts ──────────────────────────────────
   Fraunces carries the SOFT/WONK axes DESIGN.md requires (verified
   in the shipped files: opsz 9–144, wght 100–900, SOFT 0–100,
   WONK 0–1). Inter: opsz 14–32, wght 100–900 (covers G's weight-550
   nav voice with no extra file). woff2 preferred, ttf fallback.
   No font CDN at runtime — all four reference sites violate this;
   the platform self-hosts from day one. */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('assets/fonts/Fraunces-VF.woff2') format('woff2-variations'),
       url('assets/fonts/Fraunces-VF.ttf') format('truetype-variations');
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('assets/fonts/Fraunces-Italic-VF.woff2') format('woff2-variations'),
       url('assets/fonts/Fraunces-Italic-VF.ttf') format('truetype-variations');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('assets/fonts/Inter-VF.woff2') format('woff2-variations'),
       url('assets/fonts/Inter-VF.ttf') format('truetype-variations');
}
@font-face {
  font-family: 'Inter';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('assets/fonts/Inter-Italic-VF.woff2') format('woff2-variations'),
       url('assets/fonts/Inter-Italic-VF.ttf') format('truetype-variations');
}

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

/* must beat any display:grid/flex a component sets on its block */
[hidden] { display: none !important; }

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

/* clip (not hidden) preserves position:sticky while killing the
   sideways drag that reveal transforms can otherwise cause */
html, body { overflow-x: clip; }

html { scroll-behavior: smooth; }

/* Anchored sections land clear of the sticky header everywhere:
   header height + 8px cushion, on every element an anchor can hit. */
:where([id]) { scroll-margin-top: calc(var(--head-h) + 8px); }

body {
  margin: 0;
  background: var(--paper-100);
  color: var(--ink-800);
  /* rem, not px — px ignores the reader's browser font-size setting
     (G's commented rationale, adopted as law) */
  font: 400 1.0625rem/1.65 var(--ff-b);
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

/* break-word on body protects against long URLs, but display type
   must never split mid-word — a candidate's surname breaking in half
   is not acceptable */
h1, h2, h3, h4, .display {
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}

img, svg, picture, video { max-width: 100%; }
img { height: auto; display: block; }  /* height:auto — never distort a real photo */
a { color: inherit; }

button, input, select, textarea { font: inherit; }

/* ── Container ─────────────────────────────────────────────────── */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--pad-inline);
}

/* ── Section rhythm ────────────────────────────────────────────────
   .sec  — standard full-width section band
   .band — interstitial (donate band, quote band, marquee dressing):
           tighter vertical rhythm, a real editorial distinction.
   Surface modifiers keep the print flattener honest; components may
   add their own backgrounds but dark grounds must carry --dark so
   print and on-dark text tokens apply. */
.sec  { padding: var(--rhythm-section) 0; position: relative; }
.band { padding: var(--rhythm-interstitial) 0; position: relative; }

.sec--alt  { background: var(--paper-200); }
.sec--dark, .band--dark {
  background: var(--ink-950);
  color: var(--on-dark-body);
}

/* Section header block (kicker + h2 + optional sub live inside;
   their own specs belong to the section-header component) */
.sec__head { margin-bottom: var(--rhythm-headgap); }

/* ── Prose ─────────────────────────────────────────────────────────
   54ch lands at ~68 real characters (Inter's "0" is wider than its
   average glyph) and, being font-relative, holds the measure at
   every breakpoint (G's commented math, kept). */
.prose { max-width: 54ch; }
.prose p { margin: 0 0 1.05em; }
.prose b, .prose strong { font-weight: 650; color: var(--ink-700); }

/* Measure utilities — DESIGN.md: 52ch for section subs and hero
   ledes, 44ch for donate copy. */
.measure-lede   { max-width: 52ch; }
.measure-narrow { max-width: 44ch; }

/* ── Accessibility primitives ──────────────────────────────────── */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: var(--z-skip);
  background: var(--accent);
  color: var(--white);
  padding: var(--sp-3) var(--sp-4);
  border-radius: 0 0 var(--r-surface) 0;
  text-decoration: none;
  font: 650 0.9375rem/1 var(--ff-b);
}
.skip:focus { left: 0; }

/* Two-layer focus indicator — survives EVERY ground (a gold-only
   outline is 2.15:1 on --paper-100 / 1.97:1 on --paper-200 — a
   WCAG 1.4.11 failure on light sections). The 6px --ink-950 shadow
   fills the 3px outline offset, so the composite reads inner 3px
   ink ring → outer 3px gold ring. The two layers are 8.01:1 against
   EACH OTHER, so whichever layer matches the ground, the other
   still carries the indicator at ≥3:1.
   Computed ratios (WCAG relative luminance, this file's tokens):
     ink-950 layer: 17.26:1 vs --paper-100 · 15.81:1 vs --paper-200
                    · 8.01:1 vs --gold bands (1:1 on --ink-950
                    grounds, where the gold layer carries at 8.01:1)
     gold layer:     8.01:1 vs --ink-950 grounds · 8.01:1 vs the ink
                    ring (2.15:1 / 1.97:1 vs paper-100/200 and 1:1
                    on gold bands — the ink layer carries those)
   No explicit radius: outline and shadow both follow each element's
   own corner shape. The skip link inherits this same two-layer ring
   when focused — its accent chip + white text sit inside it
   unchanged, so the variant stays coherent with the house ring. */
:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  box-shadow: 0 0 0 6px var(--ink-950);
}

/* ── Reduced motion (global floor) ─────────────────────────────────
   The reveal system's animation styles live in motion.css inside
   @media (prefers-reduced-motion: no-preference) — hidden states are
   applied by JS only, so no extra un-hiding is needed here. This
   block is the belt-and-suspenders floor for everything else. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Body type responsive tiers (G verbatim) ───────────────────── */
@media (max-width: 620px) {
  body { font-size: 1.0312rem; }
}
@media (min-width: 1700px) {
  body { font-size: 1.125rem; }
}
@media (min-width: 2300px) {
  body { font-size: 1.1875rem; }
}

/* ── Print ─────────────────────────────────────────────────────────
   A volunteer printing the priorities page gets readable paper:
   chrome and motion hidden, dark bands flattened to white.
   Foundation-level flatten: the --on-dark-* ramp itself goes black,
   so EVERY on-dark consumer (formcard heads, stat labels, footer
   legal, hairlines, ghost rings…) flattens at once — no component
   needs its own print rules. */
@media print {
  :root {
    --on-dark-heading:   var(--black);
    --on-dark-body:      var(--black);
    --on-dark-secondary: var(--black);
    --on-dark-caption:   var(--black);
    --on-dark-legal:     var(--black);
    --on-dark-hairline:  var(--black);
    --on-dark-ring:      var(--black);
  }
  /* .dmodal removed — Decision 27 killed the donate popup; --z-modal stays reserved in tokens.css */
  .site-head, .mobile-nav, .skip, .marquee,
  .tex-grain, .hero__scroll, .lb {
    display: none !important;
  }
  body { background: var(--white); color: var(--black); }
  .sec--dark, .band--dark, .stats, .foot {
    background: var(--white) !important;
    color: var(--black) !important;
  }
}
