/* ==========================================================================
   BASE — reset, typography, utilities
   Copied verbatim from System/02-Components/snippets/base.css — do not
   hardcode raw values here, everything reads through tokens.css.
   ========================================================================== */

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

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

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

a { color: inherit; text-decoration: none; }

h1, h2, h3, h4, p, figure { margin: 0; }

.u-container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.u-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--size-label);
  font-weight: 500;
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--color-accent);
}

.u-eyebrow::before {
  content: "";
  width: 28px;
  height: 1px;
  background: currentColor;
  opacity: 0.7;
}

.u-section-lead {
  margin-top: var(--space-sm);
  max-width: 52ch;
  font-size: var(--size-lead);
  color: var(--color-ink-dim);
}

.u-visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Reveal primitives — toggled by IntersectionObserver in main.js. */
.r-fade,
.r-mask > * ,
.r-rise {
  opacity: 1;
  transform: none;
}

html.is-ready .r-fade { opacity: 0; transition: opacity var(--dur-slow) var(--ease-out); }
html.is-ready .r-fade.in-view { opacity: 1; }

html.is-ready .r-rise { opacity: 0; transform: translateY(2.5rem); transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out); }
html.is-ready .r-rise.in-view { opacity: 1; transform: none; }

html.is-ready .r-slide-left { opacity: 0; transform: translateX(-4.5rem); transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out); }
html.is-ready .r-slide-left.in-view { opacity: 1; transform: none; }

html.is-ready .r-mask { overflow: hidden; }
html.is-ready .r-mask > * { transform: translateY(110%); transition: transform var(--dur-slow) var(--ease-out); }
html.is-ready .r-mask.in-view > * { transform: none; }

@media (prefers-reduced-motion: reduce) {
  html.is-ready .r-fade,
  html.is-ready .r-rise,
  html.is-ready .r-slide-left,
  html.is-ready .r-mask > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

.split-word { display: inline-block; overflow: hidden; vertical-align: top; }
.split-word-inner { display: inline-block; will-change: transform, opacity; }

/* Overlay push hand-off (.c-hgallery exit phase in main.js) — forces the
   next section's reveals to their shown end-state for the duration of the
   push overlay only. See ANIMATION-PLAYBOOK.md §7. */
.is-push-revealed .split-word-inner { transform: none !important; opacity: 1 !important; }
.is-push-revealed .u-section-lead { opacity: 1 !important; }
.is-push-revealed .c-mockup-grid__list > * { transform: none !important; opacity: 1 !important; }
.is-push-revealed .c-gallery__list > * { transform: none !important; opacity: 1 !important; }
