// Theme Management class ThemeManager { constructor() { this.themeToggle = document.getElementById('theme-toggle'); this.htmlElement = document.documentElement; this.currentTheme = localStorage.getItem('theme') || 'dark'; this.init(); } init() { this.applyTheme(this.currentTheme); this.themeToggle.addEventListener('click', () => this.toggleTheme()); } applyTheme(theme) { if (theme === 'light') { this.htmlElement.classList.remove('dark-mode'); this.htmlElement.classList.add('light-mode'); document.body.classList.add('light-mode'); } else { this.htmlElement.classList.remove('light-mode'); this.htmlElement.classList.add('dark-mode'); document.body.classList.remove('light-mode'); } localStorage.setItem('theme', theme); this.updateIcons(theme); } toggleTheme() { const newTheme = this.currentTheme === 'dark' ? 'light' : 'dark'; this.currentTheme = newTheme; this.applyTheme(newTheme); this.themeToggle.classList.add('animate-pulse-custom'); setTimeout(() => this.themeToggle.classList.remove('animate-pulse-custom'), 500); } updateIcons(theme) { const darkIcon = this.themeToggle.querySelector('.dark-icon'); const lightIcon = this.themeToggle.querySelector('.light-icon'); if (theme === 'light') { darkIcon.classList.remove('hidden'); lightIcon.classList.add('hidden'); } else { darkIcon.classList.add('hidden'); lightIcon.classList.remove('hidden'); } } } // Loading Screen class LoadingManager { constructor() { this.loadingScreen = document.getElementById('loading-screen'); this.init(); } init() { window.addEventListener('load', () => { setTimeout(() => { this.loadingScreen.style.opacity = '0'; setTimeout(() => { this.loadingScreen.style.display = 'none'; }, 500); }, 1000); }); } } // Smooth Scrolling class SmoothScroll { constructor() { this.links = document.querySelectorAll('a[href^="#"]'); this.init(); } init() { this.links.forEach(link => { link.addEventListener('click', (e) => { e.preventDefault(); const targetId = link.getAttribute('href'); const targetSection = document.querySelector(targetId); if (targetSection) { targetSection.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); } } // Intersection Observer for Animations class ScrollAnimations { constructor() { this.sections = document.querySelectorAll('section'); this.init(); } init() { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('section-visible'); entry.target.classList.remove('section-hidden'); } }); }, { threshold: 0.15, rootMargin: '0px 0px -100px 0px' }); this.sections.forEach(section => { section.classList.add('section-hidden'); observer.observe(section); }); } } // Contact Form Handler class ContactForm { constructor() { this.form = document.getElementById('contact-form'); this.init(); } init() { if (this.form) { this.form.addEventListener('submit', (e) => { e.preventDefault(); this.handleSubmit(); }); } } async handleSubmit() { const formData = new FormData(this.form); const data = Object.fromEntries(formData); // Show loading state const submitButton = this.form.querySelector('button[type="submit"]'); const originalText = submitButton.innerHTML; submitButton.innerHTML = ' Sending...'; feather.replace(); try { // Simulate API call await new Promise(resolve => setTimeout(resolve, 2000)); // Show success message this.showSuccess(); this.form.reset(); } catch (error) { console.error('Form submission error:', error); } finally { submitButton.innerHTML = originalText; } } showSuccess() { const successDiv = document.createElement('div'); successDiv.className = 'success-message show'; successDiv.innerHTML = '🎉 Message sent successfully! We\'ll get back to you soon.'; this.form.appendChild(successDiv); setTimeout(() => { successDiv.classList.remove('show'); setTimeout(() => successDiv.remove(), 300); }, 5000); } } // Portfolio Data Loader class PortfolioLoader { constructor() { this.grid = document.getElementById('portfolio-grid'); this.init(); } init() { // Using static.photos for consistent placeholder images const portfolioItems = [ { title: "E-Commerce Revolution", category: "Web Development", image: "http://static.photos/technology/640x360/42", description: "Built a scalable e-commerce platform with 300% conversion increase" }, { title: "Brand Identity Suite", category: "Design", image: "http://static.photos/workspace/640x360/133", description: "Complete brand redesign for a Fortune 500 company" }, { title: "Mobile Banking App", category: "Mobile Development", image: "http://static.photos/abstract/640x360/99", description: "Secure, intuitive banking app with biometric authentication" }, { title: "AI Dashboard", category: "Data Visualization", image: "http://static.photos/industry/640x360/77", description: "Real-time analytics dashboard powered by machine learning" }, { title: "Social Campaign", category: "Marketing", image: "http://static.photos/people/640x360/21", description: "Viral marketing campaign reaching 10M+ impressions" }, { title: "Secure Cloud Migration", category: "Cybersecurity", image: "http://static.photos/network/640x360/55", description: "Zero-downtime migration with enhanced security protocols" } ]; this.renderPortfolio(portfolioItems); } renderPortfolio(items) { items.forEach((item, index) => { const portfolioElement = document.createElement('portfolio-item'); portfolioElement.setAttribute('title', item.title); portfolioElement.setAttribute('category', item.category); portfolioElement.setAttribute('image', item.image); portfolioElement.setAttribute('description', item.description); // Stagger animation setTimeout(() => { this.grid.appendChild(portfolioElement); }, index * 100); }); } } // Testimonials Loader class TestimonialsLoader { constructor() { this.container = document.getElementById('testimonials-slider'); this.currentIndex = 0; this.testimonials = []; this.init(); } async init() { try { // Fetch real testimonials from JSONPlaceholder const response = await fetch('https://jsonplaceholder.typicode.com/comments?_limit=5'); const data = await response.json(); this.testimonials = data.slice(0, 5).map(comment => ({ name: comment.name.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1) ).join(' '), text: comment.body.charAt(0).toUpperCase() + comment.body.slice(1), role: ['CEO', 'Founder', 'CTO', 'Director', 'Product Manager'][Math.floor(Math.random() * 5)], company: ['TechCorp', 'StartupX', 'Digital Dreams', 'FutureLabs', 'Innovate Inc'][Math.floor(Math.random() * 5)] })); this.renderTestimonials(); this.startAutoSlide(); } catch (error) { console.error('Failed to load testimonials:', error); this.renderFallbackTestimonials(); } } renderTestimonials() { const testimonialHTML = this.testimonials.map((t, index) => `
${t.name.split(' ').map(n => n[0]).join('')}

${t.name}

${t.role} at ${t.company}

"${t.text}"
${Array(5).fill().map(() => '').join('')}
`).join(''); this.container.innerHTML = `
${testimonialHTML}
${this.testimonials.map((_, index) => ` `).join('')}
`; this.attachDotListeners(); feather.replace(); } renderFallbackTestimonials() { const fallback = [ { name: "Sarah Johnson", role: "CEO", company: "TechVenture", text: "NeonNexus transformed our digital presence completely. The results exceeded all expectations!" } ]; this.testimonials = fallback; this.renderTestimonials(); } attachDotListeners() { const dots = this.container.querySelectorAll('.testimonial-dot'); dots.forEach(dot => { dot.addEventListener('click', (e) => { this.showTestimonial(parseInt(e.target.dataset.index)); }); }); } showTestimonial(index) { const slides = this.container.querySelectorAll('.testimonial-slide'); const dots = this.container.querySelectorAll('.testimonial-dot'); slides.forEach(slide => slide.classList.remove('active')); dots.forEach(dot => { dot.classList.remove('bg-primary-500'); dot.classList.add('bg-gray-600'); }); slides[index].classList.add('active'); dots[index].classList.remove('bg-gray-600'); dots[index].classList.add('bg-primary-500'); this.currentIndex = index; } startAutoSlide() { setInterval(() => { this.currentIndex = (this.currentIndex + 1) % this.testimonials.length; this.showTestimonial(this.currentIndex); }, 5000); } } // Mobile Menu Handler class MobileMenuHandler { constructor() { this.isOpen = false; this.init(); } init() { // This will be called from the navbar component window.addEventListener('mobile-menu-toggle', (e) => { this.isOpen = e.detail.isOpen; document.body.style.overflow = this.isOpen ? 'hidden' : ''; }); } } // Custom Cursor class CustomCursor { constructor() { this.cursor = document.createElement('div'); this.cursor.className = 'custom-cursor'; this.init(); } init() { document.body.appendChild(this.cursor); document.addEventListener('mousemove', (e) => { this.cursor.style.left = e.clientX + 'px'; this.cursor.style.top = e.clientY + 'px'; }); document.addEventListener('mousedown', () => { this.cursor.style.transform = 'scale(0.8)'; }); document.addEventListener('mouseup', () => { this.cursor.style.transform = 'scale(1)'; }); // Hide on touch devices if ('ontouchstart' in window) { this.cursor.style.display = 'none'; } } } // Initialize everything when DOM is loaded document.addEventListener('DOMContentLoaded', () => { // Core managers new ThemeManager(); new LoadingManager(); new SmoothScroll(); new ScrollAnimations(); new ContactForm(); new MobileMenuHandler(); // Data loaders new PortfolioLoader(); new TestimonialsLoader(); // Optional features new CustomCursor(); // Add some interactive elements initializeInteractiveEffects(); }); function initializeInteractiveEffects() { // Add parallax effect to hero elements window.addEventListener('scroll', () => { const scrolled = window.pageYOffset; const parallaxElements = document.querySelectorAll('.animate-float'); parallaxElements.forEach((element, index) => { const speed = 0.5 + (index * 0.1); element.style.transform = `translateY(${scrolled * speed}px) rotate(${scrolled * 0.05}deg)`; }); }); // Add click ripple effect to buttons document.querySelectorAll('button, .btn-primary').forEach