/* ==========================================================================
   Base layer: reset, fonts, typography, grain, focus, motion defaults
   ========================================================================== */

/* Generated by tools/fetch_fonts.py — carries the correct unicode-range,
   style and weight for every subset. Never edit by hand; re-run the script. */
@import url("../assets/fonts/fonts.css");

/* --- reset --- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, picture, video, canvas { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; }
p, h1, h2, h3, h4 { overflow-wrap: break-word; }
ul[class] { list-style: none; padding: 0; }
a { color: inherit; }

/* --- display type ---
   Anton ships a single static weight (400) and no width axis: it is already
   condensed and heavy by design. font-weight is pinned to 400 (not 900) so
   no browser ever synthesizes a fake bold against the one face we have. */
.display {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 0.86;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.eyebrow {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* --- layout helpers --- */
.shell {
  width: min(100% - (var(--gutter) * 2), var(--max-width));
  margin-inline: auto;
}
.section { padding-block: var(--space-3xl); position: relative; }

/* --- a11y --- */
.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: var(--space-s); left: var(--space-s);
  z-index: var(--z-skip);
  padding: var(--space-xs) var(--space-s);
  background: var(--accent-fill); color: var(--on-accent);
  font-weight: 700; text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--dur-fast) var(--ease-out-expo);
}
.skip-link:focus { transform: translateY(0); }
:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* --- reveal primitives. JS adds .is-revealed. --- */
.reveal-line { display: block; overflow: hidden; }
.reveal-line > span {
  display: block;
  transform: translateY(105%);
  transition:
    transform var(--dur-slow) var(--ease-out-expo),
    opacity var(--dur-base) linear;
  opacity: 0;
}
.is-revealed .reveal-line > span { transform: translateY(0); opacity: 1; }

.reveal-media {
  overflow: hidden;
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--dur-slow) var(--ease-out-expo);
}
.reveal-media img { transform: scale(1.12); transition: transform var(--dur-slower) var(--ease-out-expo); }
.is-revealed.reveal-media { clip-path: inset(0 0 0 0); }
.is-revealed.reveal-media img { transform: scale(1); }

/* --- film grain: unifies photos shot at different events on different cameras --- */
.grain {
  position: fixed; inset: 0;
  /* A canvas is a replaced element: `inset: 0` alone leaves it at its
     intrinsic 180x180, which rendered the grain as a small grey square in
     the top-left corner instead of a full-page texture. */
  width: 100%; height: 100%;
  z-index: var(--z-grain);
  pointer-events: none;
  /* multiply, not overlay: on a light page overlay washes out and reads as
     haze rather than film grain. */
  opacity: 0.035;
  mix-blend-mode: multiply;
}

/* --- viewfinder cursor: desktop, fine pointer only --- */
.cursor { display: none; }
@media (hover: hover) and (pointer: fine) {
  .cursor {
    display: block; position: fixed; top: 0; left: 0;
    width: 4.5rem; height: 4.5rem;
    z-index: var(--z-cursor); pointer-events: none;
    border: 1px solid var(--award); border-radius: 50%;
    transform: translate(-50%, -50%) scale(0);
    transition: transform var(--dur-fast) var(--ease-out-expo);
  }
  .cursor.is-active { transform: translate(-50%, -50%) scale(1); }
}

/* --- motion off --- */
@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;
  }
  .reveal-line > span { transform: none; opacity: 1; }
  .reveal-media { clip-path: none; }
  .reveal-media img { transform: none; }
  .grain, .cursor { display: none; }
}
