// Smooth scroll for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // Contact form handler document.getElementById('contactForm')?.addEventListener('submit', function(e) { e.preventDefault(); // Get form data const formData = new FormData(this); const data = Object.fromEntries(formData); // Show success message showNotification('Message sent successfully! We\'ll get back to you soon.', 'success'); // Reset form this.reset(); }); // Notification system function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `fixed top-4 right-4 z-50 px-6 py-4 rounded-lg shadow-lg transform translate-x-full transition-transform duration-300 ${ type === 'success' ? 'bg-green-500 text-white' : type === 'error' ? 'bg-red-500 text-white' : 'bg-blue-500 text-white' }`; notification.textContent = message; document.body.appendChild(notification); // Animate in setTimeout(() => { notification.style.transform = 'translateX(0)'; }, 100); // Remove after 3 seconds setTimeout(() => { notification.style.transform = 'translateX(100%)'; setTimeout(() => { notification.remove(); }, 300); }, 3000); } // Intersection Observer for scroll animations const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('animate-fade-in'); observer.unobserve(entry.target); } }); }, observerOptions); // Observe all sections document.querySelectorAll('section').forEach(section => { observer.observe(section); }); // Parallax effect for hero section window.addEventListener('scroll', () => { const scrolled = window.pageYOffset; const parallax = document.querySelector('.gradient-animation'); if (parallax) { parallax.style.transform = `translateY(${scrolled * 0.5}px)`; } }); // Mobile menu toggle (if navbar is custom component) document.addEventListener('DOMContentLoaded', () => { // Initialize Feather icons feather.replace(); // Add loading animation document.body.classList.add('loaded'); // Counter animation for stats (if any) animateCounters(); }); // Counter animation function function animateCounters() { const counters = document.querySelectorAll('.counter'); const speed = 200; counters.forEach(counter => { const animate = () => { const value = +counter.getAttribute('data-target'); const data = +counter.innerText; const time = value / speed; if (data < value) { counter.innerText = Math.ceil(data + time); setTimeout(animate, 1); } else { counter.innerText = value; } } animate(); }); } // Dark mode toggle (if implemented) function toggleDarkMode() { document.documentElement.classList.toggle('dark'); localStorage.setItem('darkMode', document.documentElement.classList.contains('dark')); } // Check for saved dark mode preference if (localStorage.getItem('darkMode') === 'true') { document.documentElement.classList.add('dark'); } // Lazy loading for images document.addEventListener('DOMContentLoaded', () => { const lazyImages = document.querySelectorAll('img[data-src]'); const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.classList.remove('lazy'); imageObserver.unobserve(img); } }); }); lazyImages.forEach(img => imageObserver.observe(img)); }); // Typewriter effect for hero title function typeWriter(element, text, speed = 100) { let i = 0; element.textContent = ''; function type() { if (i < text.length) { element.textContent += text.charAt(i); i++; setTimeout(type, speed); } } type(); } // Initialize typewriter effect if needed document.addEventListener('DOMContentLoaded', () => { const heroTitle = document.querySelector('.hero-title'); if (heroTitle) { typeWriter(heroTitle, heroTitle.textContent, 50); } });