Spaces:
Running
Running
| // Basic interactivity for portfolio | |
| (function(){ | |
| const html = document.documentElement; | |
| const themeToggle = document.getElementById('themeToggle'); | |
| const navToggle = document.getElementById('navToggle'); | |
| const navLinks = document.getElementById('navLinks'); | |
| const yearEl = document.getElementById('year'); | |
| const printBtn = document.getElementById('printBtn'); | |
| // Initialize year | |
| if(yearEl){ yearEl.textContent = new Date().getFullYear(); } | |
| // Theme persistence | |
| const saved = localStorage.getItem('theme'); | |
| if(saved === 'light') html.classList.add('light'); | |
| function toggleTheme(){ | |
| html.classList.toggle('light'); | |
| localStorage.setItem('theme', html.classList.contains('light') ? 'light' : 'dark'); | |
| themeToggle.textContent = html.classList.contains('light') ? 'π' : 'π'; | |
| } | |
| if(themeToggle){ | |
| themeToggle.addEventListener('click', toggleTheme); | |
| themeToggle.textContent = html.classList.contains('light') ? 'π' : 'π'; | |
| } | |
| // Mobile nav | |
| if(navToggle){ | |
| navToggle.addEventListener('click', ()=>{ | |
| navLinks.classList.toggle('show'); | |
| }); | |
| } | |
| if(navLinks){ | |
| navLinks.querySelectorAll('a').forEach(a=>{ | |
| a.addEventListener('click', ()=> navLinks.classList.remove('show')); | |
| }); | |
| } | |
| // Smooth scroll | |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { | |
| anchor.addEventListener('click', function (e) { | |
| const id = this.getAttribute('href'); | |
| if(id.length > 1){ | |
| e.preventDefault(); | |
| document.querySelector(id)?.scrollIntoView({behavior:'smooth'}); | |
| } | |
| }); | |
| }); | |
| // Print to PDF | |
| if(printBtn){ | |
| printBtn.addEventListener('click', ()=> window.print()); | |
| } | |
| // Fade-in sections on scroll | |
| const sections = document.querySelectorAll('.section'); | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| entry.target.classList.add('visible'); | |
| } | |
| }); | |
| }, { threshold: 0.1 }); | |
| sections.forEach(section => { | |
| observer.observe(section); | |
| }); | |
| })(); |