const updateDots = () => { dotsContainer.querySelectorAll('.photo-lightbox-dot').forEach((d, i) => { d.classList.toggle('is-active', i === current); }); }; const updateNav = () => { const multi = images.length > 1; prevBtn.classList.toggle('is-hidden', !multi); nextBtn.classList.toggle('is-hidden', !multi); updateDots(); }; const buildDots = () => { dotsContainer.innerHTML = images.length > 1 ? images.map((_, i) => ``).join('') : ''; }; const renderCurrentImage = () => { lightboxImg.src = images[current].url; lightboxImg.alt = images[current].alt || ''; preloadNearby(current); }; const open = (index) => { current = index || 0; renderCurrentImage(); buildDots(); updateNav(); overlay.classList.add('is-open'); document.body.style.overflow = 'hidden'; }; const close = () => { overlay.classList.remove('is-open'); document.body.style.overflow = ''; }; const navigate = async (dir) => { if (isNavigating) { return; } const nextIndex = (current + dir + images.length) % images.length; if (nextIndex === current) { return; } isNavigating = true; lightboxImg.style.opacity = '0.35'; try { await preloadImage(images[nextIndex].url); current = nextIndex; renderCurrentImage(); updateNav(); } finally { lightboxImg.style.opacity = '1'; isNavigating = false; } };