/* ==========================================================================
   base.css — reset, self-hosted fonts, typography, layout primitives, a11y
   Depends on tokens.css. Load order: tokens → base → components → pages.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. FONTS — self-hosted, no Google CDN (render-blocking round trip + GDPR).
   Subset: latin + latin-ext (Spanish accents are needed).
   Run `python tools/fetch_fonts.py` to populate site/fonts/.
   If the files are absent the stack falls back to system-ui and the site
   still renders correctly — nothing here is load-bearing.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Nunito";
  src: url("../fonts/nunito-800.woff2") format("woff2");
  font-weight: 800; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2192, U+2212, U+2215;
}
@font-face {
  font-family: "Nunito";
  src: url("../fonts/nunito-900.woff2") format("woff2");
  font-weight: 900; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2192, U+2212, U+2215;
}
@font-face {
  font-family: "Nunito Sans";
  src: url("../fonts/nunito-sans-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2192, U+2212, U+2215;
}
@font-face {
  font-family: "Nunito Sans";
  src: url("../fonts/nunito-sans-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2192, U+2212, U+2215;
}
@font-face {
  font-family: "Nunito Sans";
  src: url("../fonts/nunito-sans-700.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2192, U+2212, U+2215;
}

/* --------------------------------------------------------------------------
   2. RESET
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Sticky nav is 86px; keep anchored sections clear of it. */
  scroll-padding-top: 110px;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Guards against any child blowing out the viewport at 375px. */
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: var(--lh-display);
  letter-spacing: -.01em;
  color: var(--purple-deep);
  margin: 0 0 var(--s-4);
  text-wrap: balance;
}
h1 { font-size: var(--h1); font-weight: 800; }
h2 { font-size: var(--h2); font-weight: 800; }
h3 { font-size: var(--h3); font-weight: 800; color: var(--ink); }

p { margin: 0 0 var(--s-4); }
p:last-child { margin-bottom: 0; }

/* Long-form paragraphs get a comfortable measure. Quote blocks share this
   width so the two align — the review asked for that repeatedly. */
.lede { font-size: var(--lede); color: var(--ink-soft); max-width: var(--maxw-read); }

ul, ol { margin: 0 0 var(--s-4); padding-left: 1.15em; }
li { margin-bottom: var(--s-2); }
li::marker { color: var(--purple); }

a { color: var(--purple); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--purple-deep); }

img, picture, svg, video { max-width: 100%; display: block; }
img { height: auto; }

strong, b { font-weight: 600; color: var(--ink); }

/* --------------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: clamp(20px, 5vw, 40px);
}

/* .measure is the alignment contract from review slides 9, 10, 12, 16:
   a paragraph and the quote box beneath it share max-width AND left edge. */
.measure { max-width: var(--maxw-read); }

.band { padding-block: var(--band-y); }
.band--alt  { background: var(--paper-alt); }
.band--tint { background: var(--purple-tint); }
.band--ink  { background: var(--purple-ink); color: rgba(255,255,255,.86); }
.band--ink h1, .band--ink h2, .band--ink h3 { color: var(--white); }
.band--ink a { color: var(--white); }

.grid { display: grid; gap: var(--s-5); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 900px) { .grid--3 { grid-template-columns: 1fr; } }
@media (max-width: 720px) { .grid--2 { grid-template-columns: 1fr; } }

.stack > * + * { margin-top: var(--s-4); }

/* Section eyebrow — purple, uppercase, letter-spaced. Used site-wide. */
.eyebrow {
  font-family: var(--font-body);
  font-size: var(--micro);
  font-weight: 600;
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--purple);
  margin: 0 0 var(--s-3);
}
.band--ink .eyebrow { color: var(--orange); }

/* --------------------------------------------------------------------------
   4. ACCESSIBILITY
   -------------------------------------------------------------------------- */

/* Skip link — visible only on focus, first focusable element on every page. */
.skip {
  position: absolute; left: var(--s-4); top: -100px;
  z-index: 999;
  background: var(--purple); color: var(--white);
  padding: var(--s-3) var(--s-5);
  border-radius: var(--radius-sm);
  font-weight: 600; text-decoration: none;
  transition: top var(--dur-fast) var(--ease);
}
.skip:focus { top: var(--s-4); color: var(--white); }

/* One consistent focus ring everywhere. Never remove without replacing. */
:focus-visible {
  outline: 2px solid var(--purple);
  outline-offset: 2px;
  border-radius: 3px;
}
.band--ink :focus-visible,
.footer :focus-visible { outline-color: var(--orange); }

/* Screen-reader-only text that stays in the accessibility tree. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* Every interactive target clears 44px. */
a.btn, button, [role="button"], input, select, textarea, summary {
  min-height: 44px;
}

/* --------------------------------------------------------------------------
   5. MOTION BASELINE
   reveal.js adds .is-visible once, on first scroll into view. CSS does the
   rest. Elements are authored in their FINAL state and offset from it here,
   so that if JS never runs the content is still fully visible.
   -------------------------------------------------------------------------- */
/* Content is hidden ONLY once reveal.js has confirmed it is running and has
   stamped .reveal-ready on <html>. Hiding by default and un-hiding from JS is
   the fragile order: if this file loads and the script does not, the page is
   silently blank. This way a failed script costs the animation, not the
   content. */
.reveal-ready .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.reveal-ready .reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   6. PRINT
   -------------------------------------------------------------------------- */
@media print {
  .nav, .footer, .skip, .cta-band { display: none; }
  body { color: #000; background: #fff; }
  .reveal { opacity: 1; transform: none; }
}
