const MOTION_QUERY = '(prefers-reduced-motion: reduce)'; function prefersReducedMotion() { return window.matchMedia(MOTION_QUERY).matches; } function enableEnhancement() { if (prefersReducedMotion() || typeof IntersectionObserver !== 'function') { document.documentElement.removeAttribute('data-motion'); return false; } document.documentElement.dataset.motion = 'enhance'; return true; } function activatePageOpen(enhance) { document.querySelectorAll('[data-motion="page-open"]').forEach((node) => { if (!enhance) { node.classList.add('is-active'); return; } requestAnimationFrame(() => { requestAnimationFrame(() => node.classList.add('is-active')); }); }); } function initializeMotionDelays() { const beatOrder = new Map([ ['seal', 0], ['heading', 0], ['title', 1], ['media', 2], ['cta', 3], ]); document.querySelectorAll('[data-motion="page-open"]').forEach((page) => { page.querySelectorAll('[data-motion-beat]').forEach((beat, index) => { const namedIndex = beatOrder.get(beat.dataset.motionBeat); beat.style.setProperty('--motion-index', String(Math.min(namedIndex ?? index, 3))); }); }); document.querySelectorAll('[data-reveal-group]').forEach((group) => { const nodes = Array.from(group.querySelectorAll('[data-reveal]')) .filter((node) => node.closest('[data-reveal-group]') === group); nodes.forEach((node, index) => { node.style.setProperty('--motion-index', String(Math.min(index, 3))); }); }); } function observeReveals(enhance) { const nodes = Array.from(document.querySelectorAll('[data-reveal]')); if (nodes.length === 0) { return; } if (!enhance || typeof IntersectionObserver !== 'function') { nodes.forEach((node) => node.classList.add('is-revealed')); return; } const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (!entry.isIntersecting) { return; } entry.target.classList.add('is-revealed'); observer.unobserve(entry.target); }); }, { rootMargin: '0px 0px -12% 0px', threshold: 0.2, }, ); nodes.forEach((node) => observer.observe(node)); } function bootMotion() { initializeMotionDelays(); const enhance = enableEnhancement(); activatePageOpen(enhance); observeReveals(enhance); window.matchMedia(MOTION_QUERY).addEventListener('change', (event) => { if (event.matches) { document.documentElement.removeAttribute('data-motion'); document.querySelectorAll('[data-motion="page-open"]').forEach((node) => { node.classList.add('is-active'); }); document.querySelectorAll('[data-reveal]').forEach((node) => { node.classList.add('is-revealed'); }); return; } document.documentElement.dataset.motion = 'enhance'; }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', bootMotion, { once: true }); } else { bootMotion(); }