/* ==========================================================================
   MOTION — shared keyframes, scroll reveals and the reduced-motion rules.

   Rules of the house: shapes move slowly and never bounce; ambient motion
   pauses when its section is off screen; everything settles.
   Ambient loops use the individual translate / rotate / scale properties,
   so they compose with the transforms that js/parallax.js writes.
   ========================================================================== */

@keyframes drift-a {
  0%, 100% { translate: 0 0; }
  50%      { translate: 22px -26px; }
}
@keyframes drift-b {
  0%, 100% { translate: 0 0; }
  50%      { translate: -26px 18px; }
}
@keyframes spin { to { rotate: 360deg; } }
@keyframes spin-back { to { rotate: -360deg; } }
@keyframes breathe {
  0%, 100% { scale: 1; }
  50%      { scale: 1.06; }
}

.motion .amb-a    { animation: drift-a 26s var(--ease-io) infinite; }
.motion .amb-b    { animation: drift-b 32s var(--ease-io) infinite; }
.motion .amb-spin { animation: spin 60s linear infinite; }
.motion .amb-orbit{ animation: spin 22s linear infinite; }
.motion .amb-breathe { animation: breathe 14s var(--ease-io) infinite; }

/* Ambient motion rests while its section is out of view (js/inview.js) */
.motion [data-inview]:not(.is-inview) :is(.amb-a, .amb-b, .amb-spin, .amb-orbit, .amb-breathe) {
  animation-play-state: paused;
}

/* ── Scroll reveals (js/reveal.js adds .is-in once) ─────────── */
.motion [data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity 1s var(--ease),
    transform 1.1s var(--ease);
  transition-delay: var(--d, 0ms);
}
.motion [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Titles rise word by word (js/split.js wraps the words) */
.split .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: .24em;       /* keeps descenders (g, y, p) inside the mask */
  margin-bottom: -.24em;
}
.split .w > span { display: inline-block; }
.motion .split .w > span {
  transform: translateY(110%);
  transition: transform 1.1s var(--ease);
  transition-delay: calc(var(--wi, 0) * 55ms + var(--d, 0ms));
}
.motion .split.is-in .w > span { transform: none; }

/* Photos open from the bottom edge */
.motion [data-reveal="mask"] {
  opacity: 1;
  transform: none;
  clip-path: inset(100% 0 0 0);
  transition: clip-path 1.2s var(--ease);
  transition-delay: var(--d, 0ms);
}
.motion [data-reveal="mask"].is-in { clip-path: inset(0 0 0 0); }

/* ── Reduced motion: everything is simply there ─────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0ms !important;
  }
}
