import type { Directive } from 'vue'; // Directive `v-reveal` : révèle un bloc quand il entre dans le viewport. // Reprend l'intention du setupReveal() du design (seuil ~92% de la hauteur), // via un IntersectionObserver partagé. Respecte prefers-reduced-motion. let reducedMotion = false; try { reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; } catch { /* matchMedia indisponible */ } let observer: IntersectionObserver | null = null; function getObserver(): IntersectionObserver | null { if (typeof IntersectionObserver === 'undefined') return null; if (!observer) { observer = new IntersectionObserver( (entries) => { for (const entry of entries) { if (entry.isIntersecting) { entry.target.classList.add('is-visible'); observer?.unobserve(entry.target); } } }, // -8% en bas ≈ déclenche quand le haut du bloc franchit ~92% du viewport. { threshold: 0, rootMargin: '0px 0px -8% 0px' }, ); } return observer; } export const reveal: Directive = { mounted(el) { el.classList.add('reveal'); if (reducedMotion) { el.classList.add('is-visible'); return; } const io = getObserver(); if (!io) { // Pas d'IntersectionObserver : on révèle immédiatement (pas de contenu caché). el.classList.add('is-visible'); return; } io.observe(el); }, unmounted(el) { observer?.unobserve(el); }, };