diff --git a/main.js b/main.js
index b825d8b5..6e5aa738 100644
--- a/main.js
+++ b/main.js
@@ -833,6 +833,81 @@ document.addEventListener('DOMContentLoaded', function() {
}
}
+ /**
+ * ===================================================================
+ * REUSABLE LIGHTBOX (for .event-gallery-grid.js-lightbox blocks)
+ * ===================================================================
+ */
+ function setupLightbox() {
+ var grids = document.querySelectorAll('.js-lightbox');
+ if (!grids.length) return;
+
+ var lb = document.createElement('div');
+ lb.className = 'lightbox';
+ lb.setAttribute('role', 'dialog');
+ lb.setAttribute('aria-label', 'Photo viewer');
+ lb.setAttribute('aria-hidden', 'true');
+ lb.innerHTML =
+ '
' +
+ '
' +
+ '
![]()
' +
+ '
' +
+ '
';
+ document.body.appendChild(lb);
+
+ var img = lb.querySelector('.lightbox-img');
+ var cap = lb.querySelector('.lightbox-caption');
+ var group = [];
+ var idx = 0;
+
+ function render() {
+ var it = group[idx];
+ img.setAttribute('src', it.full);
+ img.setAttribute('alt', it.caption || '');
+ cap.textContent = (it.caption || '') + (group.length > 1 ? ' (' + (idx + 1) + '/' + group.length + ')' : '');
+ }
+ function open(grid, start) {
+ group = Array.prototype.map.call(grid.querySelectorAll('.eg-thumb'), function (b) {
+ return { full: b.getAttribute('data-full'), caption: b.getAttribute('data-caption') || '' };
+ });
+ idx = start;
+ render();
+ lb.classList.add('is-open');
+ lb.setAttribute('aria-hidden', 'false');
+ document.documentElement.style.overflow = 'hidden';
+ }
+ function close() {
+ lb.classList.remove('is-open');
+ lb.setAttribute('aria-hidden', 'true');
+ document.documentElement.style.overflow = '';
+ img.setAttribute('src', '');
+ }
+ function step(d) { idx = (idx + d + group.length) % group.length; render(); }
+
+ grids.forEach(function (grid) {
+ grid.querySelectorAll('.eg-thumb').forEach(function (b, i) {
+ b.addEventListener('click', function () { open(grid, i); });
+ });
+ });
+ lb.querySelector('.lightbox-close').addEventListener('click', close);
+ lb.querySelector('.lightbox-prev').addEventListener('click', function () { step(-1); });
+ lb.querySelector('.lightbox-next').addEventListener('click', function () { step(1); });
+ lb.addEventListener('click', function (e) { if (e.target === lb) close(); });
+ document.addEventListener('keydown', function (e) {
+ if (!lb.classList.contains('is-open')) return;
+ if (e.key === 'Escape') close();
+ else if (e.key === 'ArrowLeft') step(-1);
+ else if (e.key === 'ArrowRight') step(1);
+ });
+ // Swipe on touch devices
+ var sx = 0;
+ lb.addEventListener('touchstart', function (e) { sx = e.changedTouches[0].clientX; }, { passive: true });
+ lb.addEventListener('touchend', function (e) {
+ var dx = e.changedTouches[0].clientX - sx;
+ if (Math.abs(dx) > 40) step(dx < 0 ? 1 : -1);
+ }, { passive: true });
+ }
+
/**
* ===================================================================
* HUB USE-CASE CAROUSEL (auto-scrolling)
@@ -863,5 +938,6 @@ document.addEventListener('DOMContentLoaded', function() {
setupLanguageSuggestion();
setupNewsletter();
setupHubCarousel();
+ setupLightbox();
});
\ No newline at end of file