// Theme toggle with localStorage const themeToggle = document.getElementById('theme-toggle'); const html = document.documentElement; const savedTheme = localStorage.getItem('theme'); function applyTheme(theme) { if (theme === 'light') { html.setAttribute('data-theme', 'light'); themeToggle.textContent = '☀'; themeToggle.setAttribute('aria-label', 'Switch to dark mode'); } else { html.removeAttribute('data-theme'); themeToggle.textContent = '☾'; themeToggle.setAttribute('aria-label', 'Switch to light mode'); } } if (savedTheme) { applyTheme(savedTheme); } themeToggle.addEventListener('click', () => { const current = html.getAttribute('data-theme'); const next = current === 'light' ? 'dark' : 'light'; applyTheme(next); localStorage.setItem('theme', next); }); // Dynamic current year in footer const yearSpan = document.getElementById('current-year'); if (yearSpan) { yearSpan.textContent = new Date().getFullYear(); } // Scroll reveal animation const revealElements = document.querySelectorAll('section'); const revealObserver = new IntersectionObserver((entries) => { entries.forEach((entry, index) => { if (entry.isIntersecting) { setTimeout(() => { entry.target.classList.add('visible'); }, index * 80); revealObserver.unobserve(entry.target); } }); }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' }); revealElements.forEach((el) => { el.classList.add('reveal'); revealObserver.observe(el); }); // Stagger cards inside directory preview const cards = document.querySelectorAll('.card'); const cardObserver = new IntersectionObserver((entries) => { entries.forEach((entry, index) => { if (entry.isIntersecting) { setTimeout(() => { entry.target.classList.add('visible'); }, index * 120); cardObserver.unobserve(entry.target); } }); }, { threshold: 0.2 }); cards.forEach((card) => { card.classList.add('reveal'); cardObserver.observe(card); });