// 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 with Destructive Theme ─── 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 showSlide(index) { const backdrop = slides[index]; 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; idx = (index + 1) % slides.length; setTimeout(() => showSlide(idx), delayMs); } currentBackdrop = slides[0]; layer.style.backgroundImage = `url('/assets/${slides[0].name}.png')`; layer.style.opacity = "1"; checkDestructiveTheme(); idx = 1; const initialDelay = (slides[0].time || 6) * 1000; setTimeout(() => showSlide(idx), initialDelay); } // ─── 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 Team ─── async function loadTeam() { try { const response = await fetch("/api/team.json"); const team = await response.json(); team.sort((a, b) => a.priority - b.priority); const container = document.getElementById("team-grid"); if (!container) return; container.innerHTML = team .map( (member) => `
${ member.icon ? `${member.name}` : '
' }
${member.name}
${member.role}
`, ) .join(""); } catch (err) { console.error("Failed to load team:", err); } } // ─── Load Posts ─── async function loadPosts() { try { const response = await fetch("/api/posts.json"); const posts = await response.json(); const container = document.getElementById("posts-grid"); if (!container) return; container.innerHTML = posts .map( (post) => `
${post.date}
${post.title}
${post.description}
`, ) .join(""); } catch (err) { console.error("Failed to load posts:", err); } } // ─── Video Play/Pause ─── function initVideo() { const playBtn = document.getElementById("play-btn"); const video = document.getElementById("trailer-video"); const container = document.querySelector(".video-container"); if (!playBtn || !video || !container) return; playBtn.addEventListener("click", () => { if (video.paused) { video.play(); container.classList.add("playing"); } else { video.pause(); container.classList.remove("playing"); } }); video.addEventListener("ended", () => { container.classList.remove("playing"); }); } // ─── Scroll Effects ─── function initScrollEffects() { const header = document.querySelector("header"); const footer = document.querySelector("footer"); const scrollThreshold = 200; function update() { const scrollY = window.scrollY; const docHeight = document.documentElement.scrollHeight; const winHeight = window.innerHeight; const nearBottom = scrollY + winHeight >= docHeight - 80; const shortPage = docHeight <= winHeight + 100; if (scrollY > 10) { header.classList.add("scrolled"); } else { header.classList.remove("scrolled"); } if (scrollY < scrollThreshold && !shortPage) { footer.classList.remove("visible"); } else { footer.classList.add("visible"); if (nearBottom || shortPage) { footer.classList.remove("glass"); footer.classList.add("solid"); } else { footer.classList.add("glass"); footer.classList.remove("solid"); } } } window.addEventListener("scroll", update, { passive: true }); update(); } // ─── Initialize ─── document.addEventListener("DOMContentLoaded", () => { loadBackdrops(); loadTeam(); loadPosts(); initVideo(); initScrollEffects(); });