(function () { "use strict"; var prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; function setActiveNav() { var current = window.location.pathname.split("/").pop() || "index.html"; var links = document.querySelectorAll(".site-menu a[href], .site-mobile-menu a[href]"); links.forEach(function (link) { var href = link.getAttribute("href"); if (!href || href.charAt(0) === "#" || href.indexOf("mailto:") === 0) { return; } var page = href.split("#")[0]; if (page === current) { link.classList.add("is-active"); } }); } function setupScrollProgress() { var progress = document.createElement("span"); progress.className = "gtml-scroll-progress"; progress.setAttribute("aria-hidden", "true"); document.body.appendChild(progress); function updateProgress() { var scrollTop = window.pageYOffset || document.documentElement.scrollTop; var maxScroll = document.documentElement.scrollHeight - window.innerHeight; var percent = maxScroll > 0 ? Math.min(100, Math.max(0, (scrollTop / maxScroll) * 100)) : 0; progress.style.width = percent + "%"; } updateProgress(); window.addEventListener("scroll", updateProgress, { passive: true }); window.addEventListener("resize", updateProgress); } function setupReveal() { var elements = document.querySelectorAll([ ".about-panel", ".box-with-humber", ".srv-col", ".profile-card", ".person", ".simple-card", ".collab-card", ".text-card", ".gallery-item" ].join(",")); elements.forEach(function (element) { element.classList.add("gtml-reveal"); }); if (!("IntersectionObserver" in window) || prefersReducedMotion) { elements.forEach(function (element) { element.classList.add("is-visible"); }); return; } var observer = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { entry.target.classList.add("is-visible"); observer.unobserve(entry.target); } }); }, { threshold: 0.12, rootMargin: "0px 0px -48px 0px" }); elements.forEach(function (element, index) { element.style.transitionDelay = Math.min(index % 8, 5) * 45 + "ms"; if (element.getBoundingClientRect().top < window.innerHeight * 1.05) { element.classList.add("is-visible"); } else { observer.observe(element); } }); } function setupTilt() { if (prefersReducedMotion || window.matchMedia("(pointer: coarse)").matches) { return; } var cards = document.querySelectorAll([ ".box-with-humber", ".srv-col", ".profile-card", ".person", ".simple-card", ".collab-card", ".text-card", ".gallery-item" ].join(",")); cards.forEach(function (card) { card.classList.add("tilt-card"); card.addEventListener("mousemove", function (event) { var rect = card.getBoundingClientRect(); var x = (event.clientX - rect.left) / rect.width - 0.5; var y = (event.clientY - rect.top) / rect.height - 0.5; card.style.setProperty("--tilt-x", (-y * 4).toFixed(2) + "deg"); card.style.setProperty("--tilt-y", (x * 4).toFixed(2) + "deg"); }); card.addEventListener("mouseleave", function () { card.style.setProperty("--tilt-x", "0deg"); card.style.setProperty("--tilt-y", "0deg"); }); }); } function setupKeyboardLightbox() { var lightbox = document.getElementById("galleryLightbox"); if (!lightbox) { return; } lightbox.setAttribute("role", "dialog"); lightbox.setAttribute("aria-modal", "true"); } document.addEventListener("DOMContentLoaded", function () { document.documentElement.classList.add("gtml-enhanced"); setupScrollProgress(); setActiveNav(); setupReveal(); setupTilt(); setupKeyboardLightbox(); }); })();