/* ---------------------------------------------------------------
   Adeia — motion states

   Resting positions for the page-wide reveal system, plus the Lenis
   and ground-transition hooks. Everything animated lives here; the
   animation itself is driven by motion.js.

   The .js-reveal / .js-split selectors are deliberately global — they
   are the contract every section uses. They are also the only place
   on the page where content starts invisible, so all of them are
   gated behind html.motion-ready, a class motion.js adds on start and
   removes on any failure. If the script never runs, never loads, or
   throws, none of these rules apply and the page renders plainly.
   --------------------------------------------------------------- */

/* ---------- smooth scroll (Lenis) ---------- */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

.lenis.lenis-stopped {
  overflow: clip;
}

.lenis.lenis-smooth iframe {
  pointer-events: none;
}

/* ---------- resting states ---------- */

/* Fade and rise. data-delay="<ms>" on the element offsets the start. */
html.motion-ready .js-reveal {
  opacity: 0;
  transform: translateY(24px);
  will-change: opacity, transform;
}

/* Split headings hold at zero only until the lines exist and have
   been parked below their masks; motion.js then adds .is-split in the
   same frame, so there is no visible flash either way. */
html.motion-ready .js-split {
  opacity: 0;
}

html.motion-ready .js-split.is-split {
  opacity: 1;
}

/* SplitText writes these: one element per line, each wrapped in a
   mask that it gives overflow:clip inline. */
.splitline {
  display: block;
  will-change: transform;
}

.splitline-mask {
  display: block;
}

/* ---------- ground transitions ----------
   With the driver live the body carries the ground colour and eases
   between them, so the page moves through ink, bone, paper and forest
   as one surface. Sections keep their own background otherwise. */
@media (prefers-reduced-motion: no-preference) {
  html.ground-driven .ground {
    background-color: transparent;
  }
}

/* ---------- reduced motion ----------
   Everything above is neutralised: content is visible, static, and
   motion.js binds no scroll or pointer listeners at all. */
@media (prefers-reduced-motion: reduce) {
  html.motion-ready .js-reveal,
  html.motion-ready .js-split,
  html.motion-ready .js-split.is-split {
    opacity: 1 !important;
    transform: none !important;
    will-change: auto !important;
  }

  .splitline,
  .splitline-mask {
    transform: none !important;
    will-change: auto !important;
  }

  html {
    scroll-behavior: auto !important;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}
