/**
 * base.css — fonts, reset, typography, layout primitives, reveal system.
 * Fonts are self-hosted (SIL OFL 1.1 — see assets/fonts/OFL-*.txt).
 */

/* ---------- Fonts ---------- */
@font-face {
  font-family: 'Inter';
  src: url('../assets/fonts/inter-latin-wght.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('../assets/fonts/jetbrains-mono-latin-wght.woff2') format('woff2-variations');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
img, video, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: none; padding: 0; cursor: pointer; }
input { font: inherit; }

html {
  /* Smooth anchor scrolling for "How it works ↓" etc. (interaction-spec §0.4) */
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 1rem; /* 16px web root — see DECISIONS.md */
  line-height: 1.6;
  font-weight: 400;
  color: var(--text-primary);
  background: var(--bg-primary);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Anchor targets clear the sticky nav (interaction-spec §0.4) */
[id] { scroll-margin-top: calc(var(--nav-height) + 1rem); }

/* ---------- Typography ---------- */
h1, h2, h3, h4 { font-weight: 550; line-height: 1.15; letter-spacing: -0.02em; text-wrap: balance; }
h1 { font-size: clamp(2.25rem, 5vw, 3.75rem); }   /* hero ≈56–72px per spec §0 */
h2 { font-size: clamp(1.75rem, 3.4vw, 2.5rem); }
h3 { font-size: 1.25rem; }

p { text-wrap: pretty; }

.mono {
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 0.875em;
}

a { color: inherit; }

/* Text links: underline slides in (interaction-spec §0.3, optional flourish) */
.link {
  color: var(--primary-dark);
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size var(--dur-fast) var(--ease-out);
}
.link:hover, .link:focus-visible { background-size: 100% 1px; }

/* ---------- Focus (design-system contract: 2px accent ring) ---------- */
:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ---------- Layout primitives ---------- */
.container {
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
}
.section { padding-block: calc(var(--section-gap) / 2); }
.section-title { text-align: center; margin-bottom: var(--space-12); }

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

.skip-link {
  position: absolute; top: 0; left: 0; z-index: var(--z-tooltip);
  background: var(--primary); color: #fff;
  padding: var(--space-2) var(--space-4);
  transform: translateY(-110%);
}
.skip-link:focus { transform: none; }

/* ---------- Scroll reveal system (interaction-spec §0.2) ----------
   Hidden state only applies when JS is running (html.js) AND motion is OK —
   content is always visible with JS disabled or reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(16px);
  }
  .js .reveal.is-visible {
    opacity: 1;
    transform: none;
    transition:
      opacity var(--dur-slow) var(--ease-out),
      transform var(--dur-slow) var(--ease-out);
    transition-delay: var(--reveal-delay, 0ms);
  }
  /* Above-the-fold guard: revealed without transition at init */
  .js .reveal.is-visible.no-anim { transition: none; }

  /* Media side of feature rows additionally slides 12px inward */
  .js .reveal .row-media { transform: translateX(var(--slide-from, 12px)); transition: transform var(--dur-slow) var(--ease-out); transition-delay: var(--reveal-delay, 0ms); }
  .js .reveal.is-visible .row-media { transform: none; }
}

/* ---------- Reduced motion: global kill (interaction-spec §0.5) ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
