(() => { const hero = document.querySelector("[data-circuit-hero]"); if (!hero) return; const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; const sequence = [ ["projects", 180], ["articles", 320], ["blog", 460], ["github", 820], ["gitea", 930], ["linkedin", 1040], ["twitch", 1150], ["youtube", 1260], ["kofi", 1370], ]; let run = 0; let timers = []; const clearTimers = () => { timers.forEach(window.clearTimeout); timers = []; }; const revealAll = () => { hero.querySelectorAll(".circuit-node").forEach((node) => node.classList.add("is-ready")); hero.querySelectorAll(".circuit-live path").forEach((path) => path.classList.add("is-live")); }; const start = () => { run += 1; const token = run; clearTimers(); hero.classList.remove("is-glitching"); hero.querySelectorAll(".circuit-node").forEach((node) => node.classList.remove("is-ready")); hero.querySelectorAll(".circuit-live path").forEach((path) => path.classList.remove("is-live")); if (reducedMotion) { revealAll(); return; } sequence.forEach(([name, delay]) => { timers.push(window.setTimeout(() => { if (token !== run) return; hero.querySelector(`[data-route-node="${name}"]`)?.classList.add("is-ready"); hero.querySelector(`#route-${name}`)?.classList.add("is-live"); }, delay)); }); }; hero.querySelector("[data-circuit-replay]")?.addEventListener("click", start); start(); })();