// ── Pivoine — main.js ───────────────────────────────────────────── // ── HTMX progress bar ───────────────────────────────────────────── (function () { const bar = document.getElementById("progress-bar"); if (!bar) return; document.body.addEventListener("htmx:beforeRequest", () => { bar.style.width = "0"; bar.style.opacity = "1"; requestAnimationFrame(() => { bar.style.width = "55%"; }); }); document.body.addEventListener("htmx:afterSettle", () => { bar.style.width = "100%"; setTimeout(() => { bar.style.opacity = "0"; setTimeout(() => { bar.style.width = "0"; }, 350); }, 150); }); })(); // ── Lazy-load videos (data-src attribute) ───────────────────────── function initLazyVideos(root) { if (!("IntersectionObserver" in window)) return; const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (!entry.isIntersecting) return; const video = entry.target; if (video.dataset.src) { video.src = video.dataset.src; video.load(); } observer.unobserve(video); }); }, { rootMargin: "300px" } ); (root || document).querySelectorAll("video[data-src]").forEach((v) => observer.observe(v)); } initLazyVideos(); // ── After HTMX partial swap ──────────────────────────────────────── document.body.addEventListener("htmx:afterSwap", (e) => { initLazyVideos(e.target); if (window.Alpine) Alpine.initTree(e.target); window.scrollTo({ top: 0, behavior: "instant" }); }); // ── After HTMX history restore (back / forward navigation) ──────── document.body.addEventListener("htmx:historyRestore", () => { // Sync nav active state to the restored URL if (window.Alpine) Alpine.store("nav").path = window.location.pathname; // Complete the progress bar (htmx:afterSettle never fires on history restore) const bar = document.getElementById("progress-bar"); if (bar) { bar.style.width = "100%"; setTimeout(() => { bar.style.opacity = "0"; setTimeout(() => { bar.style.width = "0"; }, 350); }, 150); } const main = document.getElementById("main-content"); if (!main) return; if (window.Alpine) Alpine.initTree(main); // Reload and replay autoplay videos (autoplay attr is ignored on restore) main.querySelectorAll("video[autoplay]").forEach((v) => { v.load(); v.play().catch(() => {}); }); window.scrollTo({ top: 0, behavior: "instant" }); });