// Main application script document.addEventListener('DOMContentLoaded', function() { // Initialize Feather Icons feather.replace(); // Smooth scrolling for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const targetId = this.getAttribute('href'); if (targetId === '#') return; const targetElement = document.querySelector(targetId); if (targetElement) { window.scrollTo({ top: targetElement.offsetTop - 100, behavior: 'smooth' }); } }); }); // Add hover effect to service cards const serviceCards = document.querySelectorAll('service-card'); serviceCards.forEach(card => { card.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-8px)'; this.style.transition = 'transform 0.3s ease'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; }); }); // Form submission handling const contactForm = document.querySelector('contact-form'); if (contactForm) { contactForm.addEventListener('submit', function(e) { e.preventDefault(); // Get form data const formData = new FormData(e.target); const data = Object.fromEntries(formData); // Show loading state const submitBtn = e.target.querySelector('button[type="submit"]'); const originalText = submitBtn.innerHTML; submitBtn.innerHTML = ''; submitBtn.disabled = true; // Simulate API call setTimeout(() => { // Reset form e.target.reset(); // Show success message showNotification('Message sent successfully! We\'ll get back to you soon.', 'success'); // Reset button submitBtn.innerHTML = originalText; submitBtn.disabled = false; }, 2000); }); } // Intersection Observer for 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-float'); } }); }, observerOptions); // Observe elements that should animate on scroll const animatedElements = document.querySelectorAll('.service-card, .portfolio-card, .testimonial-card'); animatedElements.forEach(el => { observer.observe(el); }); // Counter animation for stats const statsCounters = document.querySelectorAll('stats-counter'); statsCounters.forEach(counter => { observer.observe(counter); }); // Notification function window.showNotification = function(message, type = 'success') { const notification = document.createElement('div'); notification.className = `fixed top-4 right-4 z-50 px-6 py-4 rounded-lg shadow-lg transform transition-all duration-300 translate-x-full ${type === 'success' ? 'bg-green-500' : 'bg-red-500'} text-white`; notification.textContent = message; document.body.appendChild(notification); // Animate in setTimeout(() => { notification.classList.remove('translate-x-full'); }, 10); // Remove after 5 seconds setTimeout(() => { notification.classList.add('translate-x-full'); setTimeout(() => { notification.remove(); }, 300); }, 5000); }; // Mobile menu toggle const mobileMenuBtn = document.querySelector('[data-mobile-menu-toggle]'); const mobileMenu = document.querySelector('[data-mobile-menu]'); if (mobileMenuBtn && mobileMenu) { mobileMenuBtn.addEventListener('click', () => { mobileMenu.classList.toggle('hidden'); mobileMenu.classList.toggle('flex'); }); } // Dark mode toggle (placeholder for future implementation) const darkModeToggle = document.querySelector('[data-dark-mode-toggle]'); if (darkModeToggle) { darkModeToggle.addEventListener('click', () => { document.documentElement.classList.toggle('dark'); localStorage.setItem('darkMode', document.documentElement.classList.contains('dark')); }); // Check for saved preference if (localStorage.getItem('darkMode') === 'true') { document.documentElement.classList.add('dark'); } } // Lazy loading for images const lazyImages = document.querySelectorAll('img[data-src]'); const imageObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.classList.remove('opacity-0'); imageObserver.unobserve(img); } }); }); lazyImages.forEach(img => { imageObserver.observe(img); img.classList.add('opacity-0', 'transition-opacity', 'duration-500'); }); }); // Utility functions function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } // API integration example async function fetchDesignInspiration() { try { const response = await fetch('https://api.unsplash.com/photos/random?query=web-design&count=3', { headers: { 'Authorization': 'Client-ID YOUR_UNSPLASH_ACCESS_KEY' } }); const data = await response.json(); return data; } catch (error) { console.error('Error fetching design inspiration:', error); return []; } } // Export utility functions window.PixelCraftUtils = { debounce, throttle, showNotification: window.showNotification };