// Click-through carousel. Generic: wires every `.carousel` on the page from // the markup emitted by `partials/carousel.html`. No autoplay, no animation, // no per-surface config -- the viewer drives it with prev/next, the dots, or // the arrow keys. Progressive enhancement: until this runs, the first frame is // shown and the controls are inert. (function () { "use strict"; function initCarousel(root) { var frames = Array.prototype.slice.call( root.querySelectorAll(".carousel-frame") ); if (frames.length < 2) return; // nothing to navigate var dots = Array.prototype.slice.call( root.querySelectorAll("[data-carousel-dot]") ); var index = frames.findIndex(function (f) { return f.classList.contains("is-active"); }); if (index < 0) index = 0; function show(next) { index = (next + frames.length) % frames.length; // wrap both ends frames.forEach(function (f, i) { var active = i === index; f.classList.toggle("is-active", active); if (active) { f.removeAttribute("aria-hidden"); } else { f.setAttribute("aria-hidden", "true"); } }); dots.forEach(function (d, i) { var active = i === index; d.classList.toggle("is-active", active); d.setAttribute("aria-selected", active ? "true" : "false"); }); } var prev = root.querySelector("[data-carousel-prev]"); var next = root.querySelector("[data-carousel-next]"); if (prev) prev.addEventListener("click", function () { show(index - 1); }); if (next) next.addEventListener("click", function () { show(index + 1); }); dots.forEach(function (d) { d.addEventListener("click", function () { show(parseInt(d.getAttribute("data-carousel-dot"), 10) || 0); }); }); root.addEventListener("keydown", function (e) { if (e.key === "ArrowLeft") { show(index - 1); e.preventDefault(); } else if (e.key === "ArrowRight") { show(index + 1); e.preventDefault(); } }); root.setAttribute("data-ready", ""); // CSS hook: controls become live } function initAll() { document.querySelectorAll(".carousel").forEach(initCarousel); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", initAll); } else { initAll(); } })();