// Initialize animations and interactions document.addEventListener('DOMContentLoaded', function() { // Animate elements on scroll const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; } }); }, observerOptions); // Observe elements for animation document.querySelectorAll('.animate-on-scroll').forEach(el => { el.style.opacity = '0'; el.style.transform = 'translateY(30px)'; el.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; observer.observe(el); }); // Add animation classes to elements document.querySelectorAll('h1').forEach(el => el.classList.add('animate-fade-in-up')); document.querySelectorAll('h2').forEach(el => el.classList.add('animate-slide-in-left')); document.querySelectorAll('.grid > div').forEach((el, index) => { setTimeout(() => { el.classList.add('animate-fade-in-up'); }, index * 200); }); // Smooth scrolling 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' }); } }); }); // Add hover effects to cards document.querySelectorAll('.hover-lift').forEach(card => { card.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-5px)'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; }); }); // Parallax effect for background sun window.addEventListener('scroll', () => { const scrolled = window.pageYOffset; const sun = document.querySelector('.bg-gradient-to-br'); if (sun) { sun.style.transform = `translateY(${scrolled * 0.5}px)`; } }); // Mobile menu toggle const mobileMenuButton = document.querySelector('[data-feather="menu"]'); const mobileMenu = document.querySelector('.mobile-menu'); if (mobileMenuButton && mobileMenu) { mobileMenuButton.addEventListener('click', () => { mobileMenu.classList.toggle('hidden'); }); } // Form validation for sign-up forms document.querySelectorAll('a[href*="sign-up"]').forEach(link => { link.addEventListener('click', function(e) { // Add any validation logic here console.log('Redirecting to sign up...'); }); }); // Image lazy loading const images = document.querySelectorAll('img[src]'); const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.style.opacity = '1'; observer.unobserve(img); } }); }); images.forEach(img => { img.style.opacity = '0'; img.style.transition = 'opacity 0.3s ease'; imageObserver.observe(img); }); // Add loading state to buttons document.querySelectorAll('a[class*="bg-"]').forEach(button => { button.addEventListener('click', function(e) { const originalText = this.textContent; this.textContent = 'Loading...'; this.style.pointerEvents = 'none'; // Reset after a short delay setTimeout(() => { this.textContent = originalText; this.style.pointerEvents = 'auto'; }, 1000); }); }); // Performance optimization: Debounce scroll events function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } // Apply debounce to scroll handler const debouncedScrollHandler = debounce(() => { const scrolled = window.pageYOffset; const sun = document.querySelector('.bg-gradient-to-br'); if (sun) { sun.style.transform = `translateY(${scrolled * 0.5}px)`; } }, 10); window.addEventListener('scroll', debouncedScrollHandler); console.log('Grok website loaded successfully!'); }); // Utility functions function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `fixed top-4 right-4 p-4 rounded-lg text-white z-50 ${ type === 'success' ? 'bg-green-500' : type === 'error' ? 'bg-red-500' : 'bg-blue-500' }`; notification.textContent = message; document.body.appendChild(notification); setTimeout(() => { notification.remove(); }, 3000); } // Export functions for external use window.GrokUtils = { showNotification };