// Mobile menu functionality document.addEventListener('DOMContentLoaded', function() { const mobileMenuBtn = document.getElementById('mobile-menu-btn'); const mobileMenu = document.getElementById('mobile-menu'); if (mobileMenuBtn && mobileMenu) { mobileMenuBtn.addEventListener('click', function() { mobileMenu.classList.toggle('hidden'); // Change menu icon const icon = mobileMenuBtn.querySelector('[data-feather]'); if (mobileMenu.classList.contains('hidden')) { icon.setAttribute('data-feather', 'menu'); } else { icon.setAttribute('data-feather', 'x'); } feather.replace(); }); } // Smooth scrolling for navigation links const navLinks = document.querySelectorAll('a[href^="#"]'); navLinks.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); const targetId = this.getAttribute('href'); const targetElement = document.querySelector(targetId); if (targetElement) { const offsetTop = targetElement.offsetTop - 80; // Account for fixed navbar window.scrollTo({ top: offsetTop, behavior: 'smooth' }); // Close mobile menu if open if (mobileMenu && !mobileMenu.classList.contains('hidden')) { mobileMenu.classList.add('hidden'); const icon = mobileMenuBtn.querySelector('[data-feather]'); icon.setAttribute('data-feather', 'menu'); feather.replace(); } } }); }); // Navbar background on scroll const navbar = document.querySelector('nav'); window.addEventListener('scroll', function() { if (window.scrollY > 50) { navbar.classList.add('shadow-lg'); } else { navbar.classList.remove('shadow-lg'); } }); // Intersection Observer for fade-in animations const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver(function(entries) { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('animate-fade-in'); } }); }, observerOptions); // Observe sections for animations const sections = document.querySelectorAll('section'); sections.forEach(section => { observer.observe(section); }); // Add loading animation to images const images = document.querySelectorAll('img'); images.forEach(img => { img.addEventListener('load', function() { this.style.opacity = '1'; }); }); // Typing effect for hero text (optional enhancement) function typeWriter(element, text, speed = 100) { let i = 0; element.innerHTML = ''; function type() { if (i < text.length) { text.charAt(i element.innerHTML +=); i++; setTimeout(type, speed); } } type(); } // Contact form handling (if you add a form) const contactForm = document.getElementById('contact-form'); if (contactForm) { contactForm.addEventListener('submit', function(e) { e.preventDefault(); // Get form data const formData = new FormData(this); const data = Object.fromEntries(formData); // Simulate form submission const submitBtn = this.querySelector('button[type="submit"]'); const originalText = submitBtn.textContent; submitBtn.textContent = 'Sending...'; submitBtn.disabled = true; setTimeout(() => { submitBtn.textContent = 'Message Sent!'; setTimeout(() => { submitBtn.textContent = originalText; submitBtn.disabled = false; this.reset(); }, 2000); }, 1000); }); } // Theme toggle functionality (if you want to add dark mode later) function toggleTheme() { document.body.classList.toggle('dark'); localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light'); } // Load saved theme const savedTheme = localStorage.getItem('theme'); if (savedTheme === 'dark') { document.body.classList.add('dark'); } // Add keyboard navigation document.addEventListener('keydown', function(e) { // ESC key closes mobile menu if (e.key === 'Escape' && mobileMenu && !mobileMenu.classList.contains('hidden')) { mobileMenu.classList.add('hidden'); const icon = mobileMenuBtn.querySelector('[data-feather]'); icon.setAttribute('data-feather', 'menu'); feather.replace(); } }); // Add performance optimizations // Lazy load images if ('IntersectionObserver' in window) { const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) = entry.target; { const img img.src = img.dataset.src; img.classList.remove('lazy'); imageObserver.unobserve(img); } }); }); const lazyImages = document.querySelectorAll('img[data-src]'); lazyImages.forEach(img => imageObserver.observe(img)); } // Add error handling for images images.forEach(img => { img.addEventListener('error', function() { this.style.display = 'none'; }); }); // Console message for developers console.log('%c👋 Hi there! Thanks for checking out my portfolio.', 'color: #6366f1; font-size: 16px; font-weight: bold;'); console.log('%cIf you\'re interested in the code, feel free to reach out!', 'color: #4f46e5; font-size: 14px;'); });