1/** 2 * Minimal scroll-reveal effect. 3 * Sections fade in as they enter the viewport. 4 */ 5 6const observer = new IntersectionObserver( 7 (entries) => { 8 for (const entry of entries) { 9 if (entry.isIntersecting) { 10 entry.target.classList.add("visible"); 11 observer.unobserve(entry.target); 12 } 13 } 14 }, 15 { threshold: 0, rootMargin: "0px 0px -40px 0px" } 16); 17 18function observe() { 19 document.querySelectorAll(".reveal:not(.visible)").forEach((el) => { 20 observer.observe(el); 21 }); 22} 23 24// Mark sections for reveal â only ones that start off-screen 25document.addEventListener("DOMContentLoaded", () => { 26 const selectors = ["#aboutMe > .container", "#contact > .container", "#additionalSections .section > .container"]; 27 for (const sel of selectors) { 28 document.querySelectorAll(sel).forEach((el) => el.classList.add("reveal")); 29 } 30 observe(); 31}); 32 33// Re-observe when additional sections are dynamically added 34const additional = document.getElementById("additionalSections"); 35if (additional) { 36 new MutationObserver(() => { 37 additional.querySelectorAll(".section > .container:not(.reveal)").forEach((el) => el.classList.add("reveal")); 38 observe(); 39 }).observe(additional, { childList: true }); 40}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.