/** * Godspark Refined — Zensical Light JS * - Scroll reveal for `.gp-reveal` * - Cursor glow via `[gp-glow]` attribute * - Reduced-motion safe */ ;(function () { "use strict"; const prefersReducedMotion = window.matchMedia( "(prefers-reduced-motion: reduce)" ).matches; function initScrollReveal() { if (prefersReducedMotion) return; const nodes = document.querySelectorAll(".gp-reveal"); if (!nodes.length) return; const thresholdRaw = getComputedStyle(document.documentElement) .getPropertyValue("--gp-reveal-threshold") .trim(); const threshold = Number.isFinite(parseFloat(thresholdRaw)) ? parseFloat(thresholdRaw) : 0.12; const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { entry.target.classList.add("is-visible"); observer.unobserve(entry.target); } }); }, { threshold, rootMargin: "0px 0px -16px 0px" } ); nodes.forEach((el) => observer.observe(el)); } function initCursorGlow() { const el = document.documentElement; const enabled = el.hasAttribute("gp-glow") || el.classList.contains("gp-glow-active"); if (!enabled) return; if (prefersReducedMotion) return; el.classList.add("gp-glow-active"); let raf = false; function setGlow(x, y) { el.style.setProperty("--gp-cursor-x", x + "px"); el.style.setProperty("--gp-cursor-y", y + "px"); } function onMove(e) { if (raf) return; raf = true; requestAnimationFrame(() => { const cx = e.touches ? e.touches[0].clientX : e.clientX; const cy = e.touches ? e.touches[0].clientY : e.clientY; setGlow(cx, cy); raf = false; }); } function onHide() { el.style.setProperty("--gp-glow-opacity", "0"); } function onShow() { el.style.setProperty("--gp-glow-opacity", "1"); } const passive = { passive: true }; document.addEventListener("mousemove", onMove, passive); document.addEventListener("touchmove", onMove, passive); document.addEventListener("mouseleave", onHide); document.addEventListener("mouseenter", onShow); } function boot() { initScrollReveal(); initCursorGlow(); initCusdisReload(); } /** * Re-initialize Cusdis comment widget after Zensical instant-navigation * page transitions (XHR-based SPA navigation). Without this, the widget * only renders on hard-refresh / initial page load. */ function initCusdisReload() { if (typeof document$ === "undefined") return; // not in Zensical context document$.subscribe(function () { var el = document.getElementById("cusdis_thread"); if (!el) return; // Clear stale Cusdis iframe from previous page render el.innerHTML = ""; // Re-create Cusdis widget for the new page if (window.CUSDIS && typeof window.CUSDIS.renderTo === "function") { window.CUSDIS.renderTo(el); } }); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", boot); } else { boot(); } })();