document.addEventListener('DOMContentLoaded', () => { // --- 1. Navbar Scroll Effect --- const navbar = document.querySelector('.navbar'); window.addEventListener('scroll', () => { if (window.scrollY > 50) { navbar.classList.add('scrolled'); } else { navbar.classList.remove('scrolled'); } }); // --- 2. Powerful Scroll Effects (Reveal Animations) --- const revealElements = document.querySelectorAll('.reveal-up, .reveal-left, .reveal-right, .zoom-in'); const revealOptions = { threshold: 0.15, rootMargin: "0px 0px -50px 0px" }; const revealObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (!entry.isIntersecting) return; entry.target.classList.add('active'); observer.unobserve(entry.target); }); }, revealOptions); revealElements.forEach(el => { revealObserver.observe(el); }); // --- 3. Stagger Delays for Grids (Experience Cards) --- const staggerItems = document.querySelectorAll('.stagger-item'); staggerItems.forEach((item, index) => { item.style.transitionDelay = `${index * 0.15}s`; }); // --- 4. Animated Numbers (Counter Animation) --- const counters = document.querySelectorAll('.counter'); const counterOptions = { threshold: 0.5 }; const counterObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (!entry.isIntersecting) return; const counter = entry.target; counter.innerText = '0'; const target = +counter.getAttribute('data-target'); const duration = 2000; // 2 seconds animation const increment = target / (duration / 16); // 60 FPS const updateCounter = () => { const current = +counter.innerText; if (current < target) { counter.innerText = Math.ceil(current + increment); setTimeout(updateCounter, 16); } else { counter.innerText = target; } }; updateCounter(); observer.unobserve(counter); }); }, counterOptions); counters.forEach(counter => { counterObserver.observe(counter); }); });