// Lightbox Array.from(document.querySelectorAll("[data-lightbox]")).forEach(element => { element.onclick = (e) => { e.preventDefault(); basicLightbox.create(``).show(); }; }); let lastPointerType = "mouse"; window.addEventListener("pointerdown", event => { lastPointerType = event.pointerType || "mouse"; }); // Central magnetic menu const menuContainer = document.querySelector("[data-magnetic-menu]"); if (menuContainer) { const menuItems = Array.from(menuContainer.querySelectorAll(".magnetic-menu__item")); const hoverRadius = 240; const shiftStrength = 45; const spread = 18; const isHome = document.body.classList.contains("is-home"); const applySpreadOnly = () => { menuItems.forEach((item, index) => { const neighborSpread = (index - (menuItems.length - 1) / 2) * spread; item.style.transform = `translate(${neighborSpread}px, 0px)`; }); }; const handleMenuPointer = event => { const pointerX = event?.clientX ?? null; const pointerY = event?.clientY ?? null; menuItems.forEach((item, index) => { const rect = item.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; let offsetX = 0; let offsetY = 0; if (pointerX !== null) { const dx = pointerX - centerX; const dy = pointerY - centerY; const distance = Math.hypot(dx, dy); if (distance < hoverRadius && distance > 0.001) { const force = 1 - distance / hoverRadius; offsetX = -(dx / distance) * force * shiftStrength; offsetY = -(dy / distance) * force * shiftStrength; } } const neighborSpread = (index - (menuItems.length - 1) / 2) * spread; item.style.transform = `translate(${offsetX + neighborSpread}px, ${offsetY}px)`; }); }; menuContainer.addEventListener("pointermove", handleMenuPointer); menuContainer.addEventListener("pointerleave", applySpreadOnly); applySpreadOnly(); if (isHome) { const pinMenu = () => { document.body.classList.add("has-top-menu"); }; menuItems.forEach(item => { item.addEventListener("pointerdown", pinMenu, { once: true }); item.addEventListener("click", pinMenu, { once: true }); item.addEventListener("touchstart", pinMenu, { once: true }); }); } } // Footer magnet hover const footer = document.querySelector(".footer"); const footerMagnets = footer ? Array.from(footer.querySelectorAll("[data-footer-magnet]")) : []; if (footer && footerMagnets.length) { const radius = 240; const maxOffset = 60; let pointerX = null; let pointerY = null; let rafId = null; const updateFooterMagnets = () => { footerMagnets.forEach(item => { if (pointerX === null || pointerY === null) { item.style.transform = ""; return; } const rect = item.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const dx = centerX - pointerX; const dy = centerY - pointerY; const distance = Math.hypot(dx, dy); if (distance < radius && distance > 0.001) { const force = 1 - distance / radius; const offsetX = (dx / distance) * force * maxOffset; const offsetY = (dy / distance) * force * maxOffset; item.style.transform = `translate(${offsetX}px, ${offsetY}px)`; } else { item.style.transform = ""; } }); rafId = null; }; const requestFooterUpdate = () => { if (rafId === null) { rafId = requestAnimationFrame(updateFooterMagnets); } }; footer.addEventListener("pointermove", event => { pointerX = event.clientX; pointerY = event.clientY; requestFooterUpdate(); }); footer.addEventListener("pointerleave", () => { pointerX = null; pointerY = null; footerMagnets.forEach(item => { item.style.transform = ""; }); }); } // Footer image brightness cycle const footerDimImage = document.querySelector(".footer-dim-image"); if (footerDimImage) { const brightnessSteps = [1, 0.75, 0.5, 0.25]; let brightnessIndex = Number(footerDimImage.dataset.brightnessIndex || 0); footerDimImage.style.filter = `brightness(${brightnessSteps[brightnessIndex]})`; footerDimImage.addEventListener("click", () => { brightnessIndex = (brightnessIndex + 1) % brightnessSteps.length; footerDimImage.dataset.brightnessIndex = String(brightnessIndex); footerDimImage.style.filter = `brightness(${brightnessSteps[brightnessIndex]})`; if (!document.body.classList.contains("is-blackout") && Math.random() < 0.15) { document.body.classList.add("is-blackout"); } }); } // Blackout toggle based on click const blackoutOverlay = document.querySelector("[data-blackout-overlay]"); document.addEventListener("pointerdown", () => { if (document.body.classList.contains("is-blackout")) { document.body.classList.remove("is-blackout"); } }, true);