<style>
.rex-lightbox[hidden] { display: none; }
.rex-lightbox { position: fixed; inset: 0; z-index: 999999; display: grid; grid-template-columns: 72px minmax(0,1fr) 72px; grid-template-rows: 64px minmax(0,1fr) 52px; align-items: center; background: #000; color: #fff; }
.rex-lightbox__stage { grid-column: 2; grid-row: 2; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.rex-lightbox__image { display: block; width: auto; height: auto; max-width: 100%; max-height: 100%; object-fit: contain; }
.rex-lightbox__button { appearance: none; border: 0; background: transparent; color: #fff; cursor: pointer; font: 400 40px/1 Arial,sans-serif; min-width: 48px; min-height: 48px; padding: 0; }
.rex-lightbox__button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.rex-lightbox__close { grid-column: 3; grid-row: 1; justify-self: center; font-size: 34px; }
.rex-lightbox__prev { grid-column: 1; grid-row: 2; justify-self: center; }
.rex-lightbox__next { grid-column: 3; grid-row: 2; justify-self: center; }
.rex-lightbox__count { grid-column: 2; grid-row: 3; justify-self: center; align-self: center; font: 400 13px/1.2 Arial,sans-serif; letter-spacing: .04em; }
body.rex-lightbox-open { overflow: hidden; }
@media (max-width: 600px) { .rex-lightbox { grid-template-columns: 48px minmax(0,1fr) 48px; grid-template-rows: 52px minmax(0,1fr) 44px; } .rex-lightbox__button { min-width: 42px; min-height: 42px; font-size: 32px; } .rex-lightbox__close { font-size: 30px; } }
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
var gallery = document.querySelector('.rex-project-gallery');
if (!gallery) return;
var figures = Array.from(gallery.querySelectorAll('figure')).filter(function (figure) { return figure.querySelector('img'); });
if (!figures.length) return;
var items = figures.map(function (figure) {
var img = figure.querySelector('img');
return { src: img.getAttribute('src') || img.currentSrc, alt: img.getAttribute('alt') || '' };
});
var overlay = document.createElement('div');
overlay.className = 'rex-lightbox';
overlay.hidden = true;
overlay.setAttribute('role', 'dialog');
overlay.setAttribute('aria-modal', 'true');
overlay.setAttribute('aria-label', 'Project image slideshow');
overlay.innerHTML = '<button class="rex-lightbox__button rex-lightbox__close" type="button" aria-label="Close slideshow">×</button><button class="rex-lightbox__button rex-lightbox__prev" type="button" aria-label="Previous image">‹</button><div class="rex-lightbox__stage"><img class="rex-lightbox__image" alt=""></div><button class="rex-lightbox__button rex-lightbox__next" type="button" aria-label="Next image">›</button><div class="rex-lightbox__count" aria-live="polite"></div>';
document.body.appendChild(overlay);
var image = overlay.querySelector('.rex-lightbox__image');
var count = overlay.querySelector('.rex-lightbox__count');
var closeButton = overlay.querySelector('.rex-lightbox__close');
var index = 0;
var opener = null;
var touchStart = null;
function show(nextIndex) {
index = (nextIndex + items.length) % items.length;
image.src = items[index].src;
image.alt = items[index].alt;
count.textContent = (index + 1) + ' / ' + items.length;
}
function open(startIndex, trigger) {
opener = trigger || null;
show(startIndex);
overlay.hidden = false;
document.body.classList.add('rex-lightbox-open');
closeButton.focus();
}
function close() {
overlay.hidden = true;
image.removeAttribute('src');
document.body.classList.remove('rex-lightbox-open');
if (opener && opener.focus) opener.focus();
}
gallery.addEventListener('click', function (event) {
var figure = event.target.closest('figure');
if (!figure || !gallery.contains(figure)) return;
event.preventDefault();
event.stopPropagation();
if (event.stopImmediatePropagation) event.stopImmediatePropagation();
open(figures.indexOf(figure), event.target);
}, true);
figures.forEach(function (figure) {
var img = figure.querySelector('img');
img.style.cursor = 'zoom-in';
if (!figure.querySelector('button, a')) {
img.tabIndex = 0;
img.setAttribute('role', 'button');
img.setAttribute('aria-label', 'Open image slideshow');
img.addEventListener('keydown', function (event) { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); open(figures.indexOf(figure), img); } });
}
});
overlay.querySelector('.rex-lightbox__prev').addEventListener('click', function () { show(index - 1); });
overlay.querySelector('.rex-lightbox__next').addEventListener('click', function () { show(index + 1); });
closeButton.addEventListener('click', close);
overlay.addEventListener('click', function (event) { if (event.target === overlay || event.target.classList.contains('rex-lightbox__stage')) close(); });
overlay.addEventListener('touchstart', function (event) { touchStart = event.changedTouches[0].clientX; }, { passive: true });
overlay.addEventListener('touchend', function (event) { if (touchStart === null) return; var dx = event.changedTouches[0].clientX - touchStart; if (Math.abs(dx) > 45) show(index + (dx < 0 ? 1 : -1)); touchStart = null; }, { passive: true });
document.addEventListener('keydown', function (event) {
if (overlay.hidden) return;
if (event.key === 'Escape') close();
else if (event.key === 'ArrowLeft') { event.preventDefault(); show(index - 1); }
else if (event.key === 'ArrowRight') { event.preventDefault(); show(index + 1); }
});
});
</script>