// 1. Menu hamburger
menuBtn.addEventListener("click", () => nav.classList.toggle("active"));
// 2. Dark mode toggle + localStorage
darkBtn.addEventListener("click", () => {
document.body.classList.toggle("dark");
localStorage.setItem("theme", document.body.classList.contains("dark") ? "dark" : "light");
});
// 3. Filtre projets
filterBtns.forEach(btn => btn.addEventListener("click", () => {
const cat = btn.dataset.category;
projets.forEach(p => p.style.display = cat === "all" || p.dataset.cat === cat ? "block" : "none");
}));
// 4. Validation formulaire temps réel
email.addEventListener("input", () => { /* validation */ });
// 5. Scroll to top
window.addEventListener("scroll", () => topBtn.style.display = window.scrollY > 300 ? "block" : "none");
Pour animer les sections quand elles deviennent visibles au scroll, sans librairie externe. new IntersectionObserver(callback).observe(element).