/* Cinematic scroll motion — every page.
   Progressive enhancement: nothing here applies until assets/js/motion.js adds
   `motion-ready` to <html>, so with JS off (or prefers-reduced-motion) every
   element is static and fully visible. The script also adds `motion-native`
   when the browser runs scroll-driven animations itself (animation-timeline),
   or `motion-js` when it feeds --progress from a requestAnimationFrame loop.
   Rules: only pseudo-elements move inside overflow-hidden boxes; DOM transforms
   stay small and inside their parent's box so the runtime layout check
   (clipping / section scrollWidth) keeps passing with motion on. */

:root { --m-ease: cubic-bezier(.22, 1, .36, 1); --m-dur: 900ms; --m-slide: clamp(24px, 4vw, 60px); }
body { overflow-x: clip; }

/* ---------- Entrances ---------- */
.motion-ready .reveal, .motion-ready .reveal-stagger > * {
  opacity: 0;
  transform: translate3d(0, 40px, 0);
  transition: opacity var(--m-dur) var(--m-ease), transform var(--m-dur) var(--m-ease), filter var(--m-dur) var(--m-ease);
}
.motion-ready .reveal--left { transform: translate3d(calc(var(--m-slide) * -1), 0, 0); }
.motion-ready .reveal--right { transform: translate3d(var(--m-slide), 0, 0); }
.motion-ready .reveal--blur { filter: blur(12px); }
.motion-ready .reveal-stagger > * { transform: translate3d(0, 30px, 0); transition-delay: calc(var(--i, 0) * 120ms); }
.motion-ready .reveal.is-visible, .motion-ready .reveal-stagger.is-visible > * { opacity: 1; transform: none; filter: none; }

/* ---------- Scroll-linked: hero content eases away as the band leaves ---------- */
.motion-ready [data-motion="hero"] { transform-origin: 50% 100%; }
.motion-js [data-motion="hero"] {
  transform: translate3d(0, calc(var(--progress, 0) * 120px), 0) scale(calc(1 - var(--progress, 0) * .06));
  opacity: calc(1 - var(--progress, 0) * .9);
}
@supports (animation-timeline: scroll()) {
  .motion-native [data-motion="hero"] { animation: m-hero-leave linear both; animation-timeline: scroll(root block); animation-range: 0 70vh; }
}
@keyframes m-hero-leave { to { transform: translate3d(0, 120px, 0) scale(.94); opacity: .1; } }

/* ---------- Scroll-linked: parallax photo layers ----------
   The section keeps its own background; a taller pseudo-element inherits it,
   sits behind the content and drifts as the section crosses the viewport. */
.motion-ready [data-motion="parallax"] { position: relative; isolation: isolate; overflow: hidden; view-timeline-name: --m-section; view-timeline-axis: block; }
.motion-ready [data-motion="parallax"]::before {
  content: ""; position: absolute; inset: -10% 0; z-index: -1;
  background: inherit; background-attachment: scroll;
  transform: translate3d(0, -8%, 0);
}
.motion-js [data-motion="parallax"]::before { transform: translate3d(0, calc((var(--progress, 0) - .5) * 16%), 0); }
@supports (animation-timeline: view()) {
  .motion-native [data-motion="parallax"]::before { animation: m-parallax linear both; animation-timeline: --m-section; animation-range: entry 0% exit 100%; }
}
@keyframes m-parallax { from { transform: translate3d(0, -8%, 0); } to { transform: translate3d(0, 8%, 0); } }

/* ---------- Scroll-linked: photo strip drift (each photo at its own speed) ---------- */
.motion-ready [data-motion="drift"] { view-timeline-name: --m-strip; view-timeline-axis: block; }
.motion-ready [data-motion="drift"] .photo-strip-item { position: relative; overflow: hidden; isolation: isolate; }
.motion-ready [data-motion="drift"] .photo-strip-item::before {
  content: ""; position: absolute; inset: -7.5% 0; z-index: -1;
  background-image: inherit; background-size: cover; background-position: center;
  transform: translate3d(0, calc(-6.5% - var(--amp)), 0);
}
.motion-ready [data-motion="drift"] .photo-strip-item:nth-child(1) { --amp: 2.5%; }
.motion-ready [data-motion="drift"] .photo-strip-item:nth-child(2) { --amp: 4.5%; }
.motion-ready [data-motion="drift"] .photo-strip-item:nth-child(3) { --amp: 6.5%; }
.motion-js [data-motion="drift"] .photo-strip-item::before { transform: translate3d(0, calc(-6.5% + (var(--progress, 0) - .5) * 2 * var(--amp)), 0); }
@supports (animation-timeline: view()) {
  .motion-native [data-motion="drift"] .photo-strip-item::before { animation: m-drift linear both; animation-timeline: --m-strip; animation-range: entry 0% exit 100%; }
}
@keyframes m-drift { from { transform: translate3d(0, calc(-6.5% - var(--amp)), 0); } to { transform: translate3d(0, calc(-6.5% + var(--amp)), 0); } }

/* ---------- Scroll-linked: one section warms from grey to white as it arrives ---------- */
.motion-js [data-motion="shift"] { background-color: color-mix(in srgb, #e6e6e6, #fff calc(var(--progress, 0) * 100%)); }
.motion-ready [data-motion="shift"] { view-timeline-name: --m-shift; }
@supports (animation-timeline: view()) {
  .motion-native [data-motion="shift"] { animation: m-shift linear both; animation-timeline: --m-shift; animation-range: entry 0% entry 100%; }
}
@keyframes m-shift { from { background-color: #e6e6e6; } to { background-color: #fff; } }

/* ---------- Phones: entrances stay (vertical only); heavy scroll-linked effects off ---------- */
@media (max-width: 767px) {
  .motion-ready .reveal--left, .motion-ready .reveal--right { transform: translate3d(0, 40px, 0); }
  .motion-ready [data-motion="hero"] { animation: none; transform: none; opacity: 1; }
  .motion-ready [data-motion="drift"] .photo-strip-item::before { animation: none; transform: translate3d(0, -6.5%, 0); }
  .motion-ready [data-motion="shift"] { animation: none; background-color: #fff; }
}

/* ---------- Reduced motion: the script never adds motion-ready, but belt and braces ---------- */
@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal-stagger > * { opacity: 1 !important; transform: none !important; filter: none !important; }
  [data-motion]::before, [data-motion] { animation: none !important; }
}
