/** * Scroll-reveal for [data-motion] (theme-wide; do not duplicate in header/blocks). * * @package Trafium_AI */ (function () { 'use strict'; function reveal(el) { el.classList.add('is-inview'); } function initMotion() { if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { return; } // Long-form articles: do not hide blocks behind scroll-reveal. if (document.body.classList.contains('trf-single-article')) { document.querySelectorAll('[data-motion], [data-motion-stagger] [data-motion-item]').forEach(reveal); return; } var motionEls = document.querySelectorAll('[data-motion]'); var staggerContainers = document.querySelectorAll('[data-motion-stagger]'); if (!motionEls.length && !staggerContainers.length) { return; } document.body.classList.add('trf-motion'); staggerContainers.forEach(function (container) { var items = container.querySelectorAll(':scope > [data-motion-item]'); items.forEach(function (item, index) { item.style.setProperty('--motion-i', String(index)); }); }); var targets = []; motionEls.forEach(function (el) { targets.push(el); }); staggerContainers.forEach(function (container) { container.querySelectorAll(':scope > [data-motion-item]').forEach(function (el) { targets.push(el); }); }); function revealAll() { targets.forEach(reveal); } if (!window.IntersectionObserver) { revealAll(); return; } var io = new IntersectionObserver( function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { reveal(entry.target); io.unobserve(entry.target); } }); }, { threshold: 0.12, rootMargin: '0px 0px -5% 0px' } ); targets.forEach(function (el) { io.observe(el); }); // Above-the-fold: reveal after layout without waiting for scroll. requestAnimationFrame(function () { requestAnimationFrame(function () { targets.forEach(function (el) { if (el.classList.contains('is-inview')) { return; } var rect = el.getBoundingClientRect(); if (rect.top < window.innerHeight && rect.bottom > 0) { reveal(el); io.unobserve(el); } }); }); }); // Safety fallback if IO never fires (broken inline scripts, layout shifts). window.setTimeout(function () { targets.forEach(function (el) { if (!el.classList.contains('is-inview')) { reveal(el); try { io.unobserve(el); } catch (e) { // ignore } } }); }, 2500); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initMotion); } else { initMotion(); } })();