// Year in footer document.getElementById('year').textContent = new Date().getFullYear(); // 3D Tilt Card const tiltCard = document.getElementById('tiltCard'); if (tiltCard) { let isHovering = false; tiltCard.addEventListener('mouseenter', () => { isHovering = true; }); tiltCard.addEventListener('mouseleave', () => { isHovering = false; tiltCard.style.transform = 'perspective(800px) rotateX(0deg) rotateY(0deg)'; }); tiltCard.addEventListener('mousemove', (e) => { if (!isHovering) return; const rect = tiltCard.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const centerX = rect.width / 2; const centerY = rect.height / 2; const rotateX = (y - centerY) / 10; const rotateY = (centerX - x) / 10; tiltCard.style.transform = `perspective(800px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; // Update CSS custom properties for the gradient effect const xPercent = (x / rect.width) * 100; const yPercent = (y / rect.height) * 100; tiltCard.style.setProperty('--mx', `${xPercent}%`); tiltCard.style.setProperty('--my', `${yPercent}%`); }); } // Magnetic Button Effect const magneticButtons = document.querySelectorAll('.magnetic-button'); magneticButtons.forEach(button => { let mousePosition = { x: 0, y: 0 }; let buttonPosition = { x: 0, y: 0 }; button.addEventListener('mousemove', (e) => { const rect = button.getBoundingClientRect(); mousePosition = { x: e.clientX - rect.left, y: e.clientY - rect.top }; // Calculate distance from center const centerX = rect.width / 2; const centerY = rect.height / 2; const deltaX = (mousePosition.x - centerX) * 0.3; const deltaY = (mousePosition.y - centerY) * 0.3; button.style.transform = `translate(${deltaX}px, ${deltaY}px)`; }); button.addEventListener('mouseleave', () => { button.style.transform = 'translate(0px, 0px)'; }); }); // Ripple Effect const rippleButtons = document.querySelectorAll('.ripple-button'); rippleButtons.forEach(button => { button.addEventListener('click', function(e) { // Remove existing ripple const existingRipple = this.querySelector('.ripple'); if (existingRipple) { existingRipple.remove(); } // Create new ripple const ripple = document.createElement('span'); ripple.classList.add('ripple'); this.appendChild(ripple); // Position the ripple const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; ripple.style.setProperty('--x', `${x}px`); ripple.style.setProperty('--y', `${y}px`); // Remove ripple after animation setTimeout(() => { ripple.remove(); }, 800); }); }); // Activity Ring Progress const ringInput = document.getElementById('ringInput'); const ringProgress = document.getElementById('ringProgress'); const ringPercent = document.getElementById('ringPercent'); if (ringInput && ringProgress && ringPercent) { const updateRing = (value) => { const num = Math.max(0, Math.min(100, parseInt(value) || 0)); ringProgress.style.setProperty('--progress', num); ringPercent.textContent = `${num}%`; // Add visual feedback if (num > 0) { ringProgress.style.boxShadow = '0 0 20px rgba(148, 163, 184, 0.3)'; } else { ringProgress.style.boxShadow = 'none'; } }; ringInput.addEventListener('input', (e) => { const value = e.target.value.replace(/[^\d]/g, ''); // Remove non-digits ringInput.value = value; // Update input with cleaned value if (value === '' || /^\d+$/.test(value)) { updateRing(value); } }); // Handle Enter key ringInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { e.preventDefault(); updateRing(ringInput.value); } }); // Initialize ring on load updateRing('0'); } // Ring Reset Button const ringReset = document.getElementById('ringReset'); if (ringReset && ringInput) { ringReset.addEventListener('click', () => { ringInput.value = ''; if (ringProgress) { ringProgress.style.setProperty('--progress', 0); } if (ringPercent) { ringPercent.textContent = '0%'; } ringInput.focus(); }); } // Magnetic Button in Header const magneticBtn = document.getElementById('magneticBtn'); if (magneticBtn) { magneticBtn.addEventListener('click', () => { // Smooth scroll to demo section const demoSection = document.getElementById('demo'); if (demoSection) { demoSection.scrollIntoView({ behavior: 'smooth' }); } }); } // Form Progress and Validation const form = document.getElementById('notifyForm'); const nameInput = document.getElementById('name'); const emailInput = document.getElementById('email'); const messageInput = document.getElementById('message'); const formProgress = document.getElementById('formProgress'); const charCount = document.getElementById('charCount'); if (form && nameInput && emailInput) { const updateFormProgress = () => { let progress = 0; const maxLength = 200; // Name progress (0-33%) if (nameInput.value.trim().length > 0) progress += 33; // Email progress (33-66%) if (emailInput.value.trim().length > 0) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (emailRegex.test(emailInput.value)) { progress += 33; } else { progress += 16; // Partial progress for invalid email } } // Message progress (66-100%) if (messageInput && messageInput.value.trim().length > 0) { const messageProgress = Math.min(34, (messageInput.value.length / maxLength) * 34); progress += messageProgress; } // Update progress bar if (formProgress) { formProgress.style.width = `${Math.round(progress)}%`; formProgress.nextElementSibling.textContent = `${Math.round(progress)}%`; } }; // Character count for message if (messageInput && charCount) { messageInput.addEventListener('input', () => { const length = messageInput.value.length; charCount.textContent = `${length} / 200`; if (length > 200) { messageInput.value = messageInput.value.substring(0, 200); charCount.textContent = `200 / 200`; } }); } // Update progress on input [nameInput, emailInput, messageInput].forEach(input => { if (input) { input.addEventListener('input', updateFormProgress); } }); // Form submission form.addEventListener('submit', (e) => { e.preventDefault(); const name = nameInput.value.trim(); const email = emailInput.value.trim(); const message = messageInput ? messageInput.value.trim() : ''; // Basic validation if (!name) { alert('Please enter your name'); nameInput.focus(); return; } if (!email) { alert('Please enter your email'); emailInput.focus(); return; } const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { alert('Please enter a valid email address'); emailInput.focus(); return; } // Simulate form submission const submitBtn = form.querySelector('button[type="submit"]'); const originalText = submitBtn.textContent; submitBtn.textContent = 'Submitting...'; submitBtn.disabled = true; setTimeout(() => { alert('Thank you! We\'ll keep you updated.'); form.reset(); if (formProgress) { formProgress.style.width = '0%'; formProgress.nextElementSibling.textContent = '0%'; } if (charCount) { charCount.textContent = '0 / 200'; } submitBtn.textContent = originalText; submitBtn.disabled = false; }, 1500); }); } // Initialize progress on page load document.addEventListener('DOMContentLoaded', () => { updateFormProgress(); // 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 some additional interactive touches document.addEventListener('DOMContentLoaded', () => { // Add loading animation to tilt card const tiltCard = document.getElementById('tiltCard'); if (tiltCard) { setTimeout(() => { tiltCard.style.opacity = '1'; tiltCard.style.transform = 'perspective(800px) translateY(0px)'; }, 100); } // Add entrance animation to other elements const animatedElements = document.querySelectorAll('.rounded-2xl'); animatedElements.forEach((el, index) => { el.style.opacity = '0'; el.style.transform = 'translateY(20px)'; el.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; setTimeout(() => { el.style.opacity = '1'; el.style.transform = 'translateY(0px)'; }, 200 + (index * 100)); }); });