/* ==========================================================================
   Reset, font faces, typography and layout primitives.
   ========================================================================== */

@font-face {
  font-family: "Inter";
  src: url("/static/fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/static/fonts/Inter-SemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Space Grotesk";
  src: url("/static/fonts/SpaceGrotesk-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Space Grotesk";
  src: url("/static/fonts/SpaceGrotesk-Bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
}

p { margin: 0; }
a { color: inherit; text-decoration: none; }
img, svg, video { max-width: 100%; display: block; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 4px;
}

::selection { background: var(--accent-500); color: #050f22; }

/* ── Primitives ─────────────────────────────────────────────────────── */
.shell {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter-safe);
}

.section { padding-block: var(--section-y); }

/* Small uppercase metadata. The one job the mono face has. */
.eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 0;
}

.lede {
  font-size: var(--fs-lg);
  line-height: 1.5;
  color: var(--text-muted);
  max-width: var(--measure);
}

.rule { height: 1px; background: var(--hairline); border: 0; margin: 0; }

.skip-link {
  position: absolute;
  left: var(--sp-4);
  top: -5rem;
  z-index: 2000;
  padding: var(--sp-3) var(--sp-5);
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--hairline-strong);
  transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: var(--sp-4); }

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

/* ── Section heading pair ───────────────────────────────────────────── */
/* Eyebrow above, headline below, at a deliberate offset. Used throughout so
   every section opens with the same rhythm. */
.head { margin-bottom: clamp(1.75rem, 3vw, 3rem); }
.head__eyebrow { margin-bottom: var(--sp-5); }
.head__title { font-size: var(--fs-3xl); max-width: 18ch; }

/* ── Reveals ────────────────────────────────────────────────────────── */
/* The hidden state is gated on `.reveals`, which the reveal code adds as its
   first act. Nothing hides content until something is already watching to
   bring it back, so a missing or throwing script leaves the page visible. */
.reveals [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--dur-reveal) var(--ease),
              transform var(--dur-reveal) var(--ease);
}
.reveals [data-reveal].is-in { opacity: 1; transform: none; }

/* Staggered children, for lists and headline lines. */
.reveals [data-reveal-stagger] > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--dur-reveal) var(--ease),
              transform var(--dur-reveal) var(--ease);
}
.reveals [data-reveal-stagger].is-in > * { opacity: 1; transform: none; }
.reveals [data-reveal-stagger].is-in > *:nth-child(1) { transition-delay: 0ms; }
.reveals [data-reveal-stagger].is-in > *:nth-child(2) { transition-delay: 70ms; }
.reveals [data-reveal-stagger].is-in > *:nth-child(3) { transition-delay: 140ms; }
.reveals [data-reveal-stagger].is-in > *:nth-child(4) { transition-delay: 210ms; }
.reveals [data-reveal-stagger].is-in > *:nth-child(5) { transition-delay: 280ms; }
.reveals [data-reveal-stagger].is-in > *:nth-child(6) { transition-delay: 350ms; }

/* A line of type wiped upward from behind its own edge. Used on the big
   headlines only — it is the most expensive-feeling move here and loses that
   the moment it is applied to everything. */
.mask { display: block; overflow: hidden; }
.reveals .mask > span {
  display: block;
  transform: translateY(105%);
  transition: transform var(--dur-reveal) var(--ease);
}
.reveals .is-in .mask > span,
.reveals .mask.is-in > span { transform: none; }
.reveals .is-in .mask:nth-child(2) > span { transition-delay: 90ms; }
.reveals .is-in .mask:nth-child(3) > span { transition-delay: 180ms; }

/* ── Error pages ────────────────────────────────────────────────────── */
.error-page {
  min-height: 72vh;
  display: grid;
  align-content: center;
  justify-items: start;
  gap: var(--sp-5);
}
.error-page__code { font-family: var(--font-mono); font-size: var(--fs-2xs);
  letter-spacing: var(--track-wide); color: var(--accent-ink); }
.error-page__title { font-size: var(--fs-3xl); }
.error-page__body { color: var(--text-muted); max-width: 46ch; }

/* ── Legal ──────────────────────────────────────────────────────────── */
.legal { max-width: 68ch; display: grid; gap: var(--sp-5); }
.legal h1 { font-size: var(--fs-2xl); margin-bottom: var(--sp-4); }
.legal p { color: var(--text-muted); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveals [data-reveal],
  .reveals [data-reveal-stagger] > * { opacity: 1; transform: none; }
  .reveals .mask > span { transform: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── The hero reveal ────────────────────────────────────────────────────
   Each line rises from behind its own edge with a slight shear that settles
   as it lands, so the three words arrive in order rather than together. The
   gold stop lands last, which is the only moment it moves anywhere on the
   site. */
.reveals .hero__line > span {
  transform: translateY(110%) skewY(4deg);
  transform-origin: left top;
  transition: transform 820ms var(--ease);
}
.reveals .hero__line.is-in > span,
.reveals .is-in .hero__line > span { transform: none; }

.reveals .hero__line--1 > span { transition-delay: 60ms; }
.reveals .hero__line--2 > span { transition-delay: 190ms; }

.reveals .hero__line .stop {
  display: inline-block;
  transform: scale(0);
  transform-origin: center;
  transition: transform 520ms var(--ease);
}
.reveals .is-in .hero__line .stop,
.reveals .hero__line.is-in .stop { transform: none; }
.reveals .hero__line--1 .stop { transition-delay: 620ms; }
.reveals .hero__line--2 .stop { transition-delay: 750ms; }

/* ── Media reveal ───────────────────────────────────────────────────────
   A frame wipes open from its own top edge while the picture inside settles
   out of a slight scale. The two run at different rates, which reads as the
   image arriving rather than the box merely appearing. */
.reveals .frame {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 900ms var(--ease);
}
.reveals .frame.is-in,
.reveals .is-in .frame { clip-path: inset(0 0 0 0); }

.reveals .frame > picture > img {
  transform: scale(1.08);
  transition: transform 1200ms var(--ease);
}
.reveals .frame.is-in > picture > img,
.reveals .is-in .frame > picture > img { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveals .hero__line > span,
  .reveals .hero__line .stop,
  .reveals .frame > picture > img { transform: none; }
  .reveals .frame { clip-path: none; }
}
