document.addEventListener('DOMContentLoaded', () => { const toastElement = document.getElementById('pageToast'); const toastBody = document.getElementById('pageToastBody'); const pageToast = toastElement ? new bootstrap.Toast(toastElement, { delay: 2200 }) : null; const showToast = (message) => { if (!pageToast || !toastBody || !message) return; toastBody.textContent = message; pageToast.show(); }; document.querySelectorAll('[data-toast-message]').forEach((link) => { link.addEventListener('click', () => showToast(link.getAttribute('data-toast-message'))); }); const revealItems = document.querySelectorAll('.reveal'); if ('IntersectionObserver' in window && revealItems.length) { const revealObserver = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { entry.target.classList.add('is-visible'); revealObserver.unobserve(entry.target); } }); }, { threshold: 0.16 }); revealItems.forEach((item) => revealObserver.observe(item)); } else { revealItems.forEach((item) => item.classList.add('is-visible')); } const filterButtons = document.querySelectorAll('.btn-filter'); const galleryItems = document.querySelectorAll('.gallery-item'); const filterStatus = document.getElementById('filterStatus'); filterButtons.forEach((button) => { button.addEventListener('click', () => { const filter = button.dataset.filter || 'all'; filterButtons.forEach((btn) => btn.classList.remove('active')); button.classList.add('active'); let visibleCount = 0; galleryItems.forEach((item) => { const matches = filter === 'all' || item.dataset.era === filter; item.classList.toggle('is-hidden', !matches); if (matches) visibleCount += 1; }); const statusText = filter === 'all' ? `Showing all ${visibleCount} images.` : `Showing ${visibleCount} ${filter} image${visibleCount === 1 ? '' : 's'}.`; if (filterStatus) filterStatus.textContent = statusText; showToast(statusText); }); }); const galleryModal = document.getElementById('galleryModal'); if (galleryModal) { const modalLabel = document.getElementById('galleryModalLabel'); const modalMeta = document.getElementById('galleryModalMeta'); const modalImage = document.getElementById('galleryModalImage'); const modalCaption = document.getElementById('galleryModalCaption'); galleryModal.addEventListener('show.bs.modal', (event) => { const trigger = event.relatedTarget; if (!trigger) return; const title = trigger.getAttribute('data-title') || 'Gallery image'; const eraLabel = trigger.getAttribute('data-era-label') || 'Archive'; const year = trigger.getAttribute('data-year') || ''; const caption = trigger.getAttribute('data-caption') || ''; const image = trigger.getAttribute('data-image') || ''; const alt = trigger.getAttribute('data-alt') || title; if (modalLabel) modalLabel.textContent = title; if (modalMeta) modalMeta.textContent = `${eraLabel} ยท ${year}`; if (modalCaption) modalCaption.textContent = caption; if (modalImage) { modalImage.src = image; modalImage.alt = alt; } }); } const sections = document.querySelectorAll('main section[id]'); const navLinks = document.querySelectorAll('#mainNav .nav-link'); const setActiveLink = () => { let currentId = ''; sections.forEach((section) => { const top = section.getBoundingClientRect().top; if (top <= 140) currentId = section.id; }); navLinks.forEach((link) => { const href = link.getAttribute('href'); link.classList.toggle('active', href === `#${currentId}`); }); }; setActiveLink(); document.addEventListener('scroll', setActiveLink, { passive: true }); const parallaxItems = document.querySelectorAll('[data-parallax]'); if (parallaxItems.length && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) { const updateParallax = () => { parallaxItems.forEach((item) => { const rect = item.getBoundingClientRect(); const centerOffset = (window.innerHeight * 0.5 - rect.top) / window.innerHeight; const depth = item.dataset.parallax === 'media' ? 16 : 10; const translateY = Math.max(-depth, Math.min(depth, centerOffset * depth)); item.style.transform = `translate3d(0, ${translateY}px, 0)`; }); }; updateParallax(); window.addEventListener('scroll', updateParallax, { passive: true }); window.addEventListener('resize', updateParallax); } });