// Shared contract between the inline intro script, the preloader and // everything that waits for the intro to finish (smooth scroll, hero shader). export const INTRO_CLASS = "is-intro" export const INTRO_END_EVENT = "since3:intro-end" export const INTRO_STORAGE_KEY = "since3:intro-seen" // Runs synchronously before the first paint. Plays the intro once per session // and never for people who prefer reduced motion. The timeout is a failsafe in // case the JavaScript bundle never arrives. export const introScript = `(function(){try{var d=document.documentElement;if(!sessionStorage.getItem("${INTRO_STORAGE_KEY}")&&!matchMedia("(prefers-reduced-motion: reduce)").matches){d.classList.add("${INTRO_CLASS}");setTimeout(function(){d.classList.remove("${INTRO_CLASS}")},8000)}}catch(e){}})()` export function isIntroRunning() { return document.documentElement.classList.contains(INTRO_CLASS) } /** Calls `callback` once the intro is over (immediately if there is none). */ export function onIntroEnd(callback: () => void) { if (!isIntroRunning()) { callback() return () => {} } window.addEventListener(INTRO_END_EVENT, callback, { once: true }) return () => window.removeEventListener(INTRO_END_EVENT, callback) }