// Smooth scroll for nav links document.querySelectorAll('a[href^="#"]').forEach((anchor) => { anchor.addEventListener("click", function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute("href")); if (target) { target.scrollIntoView({ behavior: "smooth" }); } }); }); // ─── Parallax ─── function initParallax() { const sections = document.querySelectorAll(".bg-image-section:not(#hero)"); const heroLayer = document.getElementById("hero-slideshow"); function update() { sections.forEach((section) => { const rect = section.getBoundingClientRect(); const yPos = -(rect.top * 0.4); section.style.backgroundPositionY = `${yPos}px`; }); if (heroLayer) { const hero = document.getElementById("hero"); if (hero) { const rect = hero.getBoundingClientRect(); const yPos = -(rect.top * 0.4); heroLayer.style.transform = `translateY(${yPos}px) scale(1.1)`; } } } window.addEventListener("scroll", update, { passive: true }); update(); } // ─── Hero Slideshow ─── let currentBackdrop = null; const NEAR_TOP_THRESHOLD = 1800; function checkDestructiveTheme() { if (!currentBackdrop) return; const nearTop = window.scrollY < NEAR_TOP_THRESHOLD; if (currentBackdrop.destructive && nearTop) { document.body.classList.add("destructive-mode"); } else { document.body.classList.remove("destructive-mode"); } } function initHeroSlideshow(allBackdrops, usedNames) { const hero = document.getElementById("hero"); const layer = document.getElementById("hero-slideshow"); if (!hero || !layer) return; const slides = allBackdrops.filter((b) => !usedNames.includes(b.name)); if (slides.length === 0) { console.warn("No unused backdrops for hero slideshow"); return; } let idx = 0; function pickRandomSlide(exclude) { if (slides.length === 1) return slides[0]; let pick; do { pick = slides[Math.floor(Math.random() * slides.length)]; } while (pick.name === exclude?.name); return pick; } function showSlide() { const backdrop = pickRandomSlide(currentBackdrop); currentBackdrop = backdrop; layer.style.opacity = "0"; setTimeout(() => { layer.style.backgroundImage = `url('/assets/${backdrop.name}.png')`; layer.style.opacity = "1"; checkDestructiveTheme(); }, 600); const delayMs = (backdrop.time || 6) * 1000; setTimeout(showSlide, delayMs); } const first = pickRandomSlide(); currentBackdrop = first; layer.style.backgroundImage = `url('/assets/${first.name}.png')`; layer.style.opacity = "1"; checkDestructiveTheme(); setTimeout(showSlide, (first.time || 6) * 1000); } // ─── Load Backdrops ─── async function loadBackdrops() { try { const response = await fetch("/api/backdrops.json"); const backdrops = await response.json(); const safeBackdrops = backdrops.filter((b) => !b.destructive); const sections = document.querySelectorAll(".bg-image-section:not(#hero)"); const used = []; sections.forEach((section) => { let pick; let safety = 0; do { pick = safeBackdrops[Math.floor(Math.random() * safeBackdrops.length)]; safety++; } while ( used.includes(pick.name) && used.length < safeBackdrops.length && safety < 50 ); used.push(pick.name); section.style.backgroundImage = `url('/assets/${pick.name}.png')`; }); initParallax(); initHeroSlideshow(backdrops, used); window.addEventListener("scroll", checkDestructiveTheme, { passive: true }); } catch (err) { console.error("Failed to load backdrops:", err); } } // ─── Load Staff ─── async function loadStaff() { try { const response = await fetch("/api/staff.json"); const staff = await response.json(); const container = document.getElementById("staff-grid"); if (!container) return; container.innerHTML = staff .map( (member) => `
${team.description}
${ hasDiscord ? ` Discord ` : "" }