// --- theme toggle --- const toggle = document.getElementById('theme-toggle'); const root = document.documentElement; const saved = window?.localStorage?.getItem('dark-mode'); const sysDark = window.matchMedia('(prefers-color-scheme: dark)').matches; if (saved === 'true') { root.classList.add('dark'); root.classList.remove('light'); } else if (saved === 'false') { root.classList.add('light'); root.classList.remove('dark'); } else { if (sysDark) { root.classList.add('dark'); root.classList.remove('light'); } else { root.classList.add('light'); root.classList.remove('dark'); } } toggle?.addEventListener('click', () => { const isDark = root.classList.contains('dark'); root.classList.toggle('dark', !isDark); root.classList.toggle('light', isDark); window?.localStorage?.setItem('dark-mode', String(!isDark)); }); const { body } = document; // --- lightbox base --- const lb = document.getElementById('lightbox'); const lbCnt = document.getElementById('lb-content'); const lbCap = document.getElementById('lb-caption'); document.getElementById('lb-close')?.addEventListener('click', () => { lb?.setAttribute('aria-hidden', 'true'); body.classList.remove('lightbox-open'); if (lbCnt) lbCnt.innerHTML = ''; }); // Build picture element for lightbox (name, type only) function createPicture(name, type) { const pic = document.createElement('picture'); const breakpoints = [ { bp: 'desktop', minWidth: 1024 }, { bp: 'tablet', minWidth: 768 }, { bp: 'mobile', minWidth: 0 } ]; for (const { bp, minWidth } of breakpoints) { const src = document.createElement('source'); src.media = `(min-width:${minWidth}px)`; if (type === 'image') { src.srcset = `/assets/media/${bp}/${name}@1x.webp 1x, /assets/media/${bp}/${name}.webp 2x`; } else { src.srcset = `/assets/media/${bp}/${name}_still@1x.webp 1x, /assets/media/${bp}/${name}_still.webp 2x`; } pic.appendChild(src); } const img = document.createElement('img'); img.src = `/assets/media/thumbnail/${name}.webp`; img.alt = ''; pic.appendChild(img); return pic; } function openLightbox(item) { if (!lbCnt || !lbCap || !lb) return; lbCnt.innerHTML = ''; if (item.type === 'video') { const v = document.createElement('video'); v.src = `/assets/media/videos/${item.name}.mp4`; v.controls = true; v.autoplay = true; lbCnt.appendChild(v); } else { lbCnt.appendChild(createPicture(item.name, item.type)); } lbCap.textContent = item.caption; body.classList.add('lightbox-open'); lb.setAttribute('aria-hidden', 'false'); } // --- bind to pre-rendered gallery --- document.querySelectorAll('.gallery-item').forEach((fig) => { const name = fig.getAttribute('data-name'); const type = fig.getAttribute('data-type'); const caption = fig.getAttribute('data-caption'); if (!name || !type || !caption) return; const item = { name, type, caption }; fig.addEventListener('click', () => openLightbox(item)); fig.addEventListener('keydown', (e) => { if (e.key === 'Enter') openLightbox(item); }); }); // --- video toggle --- const videoTgl = document.getElementById('show_video'); videoTgl?.addEventListener('click', () => { const videoFig = document.querySelector('.gallery-item.video'); if (videoFig) { openLightbox({ name: videoFig.getAttribute('data-name'), type: videoFig.getAttribute('data-type'), caption: videoFig.getAttribute('data-caption') }); } });