document.addEventListener("DOMContentLoaded", function(){ function initCarousel(){ const cards = document.querySelectorAll('.coverflow-card'); const dots = document.querySelectorAll('.dot'); const carousel = document.querySelector('.apple-coverflow'); const nextBtn = document.querySelector('.next'); const prevBtn = document.querySelector('.prev'); /* WAIT UNTIL CARDS EXIST (important for Experience Cloud) */ if(!cards.length || !carousel){ setTimeout(initCarousel, 100); return; } let index = 0; let autoRotate = null; let startX = 0; let isDragging = false; /* --------------------------- MAIN COVERFLOW UPDATE ----------------------------*/ function updateCoverflow(){ cards.forEach(card => { card.classList.remove('far-left','left','center','right','far-right'); }); cards[index].classList.add('center'); cards[(index - 1 + cards.length) % cards.length].classList.add('left'); cards[(index + 1) % cards.length].classList.add('right'); cards[(index - 2 + cards.length) % cards.length].classList.add('far-left'); cards[(index + 2) % cards.length].classList.add('far-right'); dots.forEach(dot => dot.classList.remove('active')); if (dots[index]) { dots[index].classList.add('active'); } } /* --------------------------- AUTO ROTATE ----------------------------*/ function startAutoRotate(){ if (autoRotate) return; autoRotate = setInterval(() => { index = (index + 1) % cards.length; updateCoverflow(); }, 5000); } function stopAutoRotate(){ if (autoRotate) { clearInterval(autoRotate); autoRotate = null; } } /* --------------------------- ARROW CONTROLS ----------------------------*/ if (nextBtn) { nextBtn.onclick = () => { stopAutoRotate(); index = (index + 1) % cards.length; updateCoverflow(); }; } if (prevBtn) { prevBtn.onclick = () => { stopAutoRotate(); index = (index - 1 + cards.length) % cards.length; updateCoverflow(); }; } /* --------------------------- DOT NAVIGATION ----------------------------*/ dots.forEach(dot => { dot.addEventListener("click", function(e){ e.stopPropagation(); stopAutoRotate(); index = parseInt(dot.dataset.index, 10); updateCoverflow(); }); }); /* --------------------------- DRAG / SWIPE NAVIGATION ----------------------------*/ function beginDrag(x){ isDragging = true; startX = x; } function endDrag(x){ if (!isDragging) return; const diff = x - startX; if (Math.abs(diff) > 50) { stopAutoRotate(); if (diff < 0) { index = (index + 1) % cards.length; } else { index = (index - 1 + cards.length) % cards.length; } updateCoverflow(); } isDragging = false; } /* Pointer events */ carousel.addEventListener("pointerdown", function(e){ beginDrag(e.clientX); }); document.addEventListener("pointerup", function(e){ endDrag(e.clientX); }); /* Touch fallback for mobile */ carousel.addEventListener("touchstart", function(e){ if (e.touches && e.touches.length > 0) { beginDrag(e.touches[0].clientX); } if (!autoRotate) { startAutoRotate(); } }, { passive: true }); carousel.addEventListener("touchend", function(e){ if (e.changedTouches && e.changedTouches.length > 0) { endDrag(e.changedTouches[0].clientX); } }, { passive: true }); /* --------------------------- INIT ----------------------------*/ updateCoverflow(); startAutoRotate(); /* Restart if the tab becomes active again */ document.addEventListener("visibilitychange", function(){ if (!document.hidden) { updateCoverflow(); startAutoRotate(); } }); } initCarousel(); /* --------------------------- WATCH FOR LWR PAGE NAVIGATION ----------------------------*/ const observer = new MutationObserver(() => { const carousel = document.querySelector('.apple-coverflow'); if (carousel && !carousel.dataset.carouselInitialized) { carousel.dataset.carouselInitialized = "true"; initCarousel(); } }); observer.observe(document.body, { childList: true, subtree: true }); });