// ============================================ // PRELOADER // ============================================ window.addEventListener('load', () => { setTimeout(() => { document.getElementById('preloader').classList.add('hidden'); document.body.style.overflow = 'visible'; }, 2200); }); document.body.style.overflow = 'hidden'; // ============================================ // AOS INIT // ============================================ AOS.init({ duration: 700, once: true, easing: 'ease-out-cubic', offset: 60, }); // ============================================ // STICKY NAVBAR // ============================================ const nav = document.getElementById('mainNav'); window.addEventListener('scroll', () => { nav.classList.toggle('scrolled', window.scrollY > 50); }); // ============================================ // SMOOTH SCROLL FOR NAV LINKS // ============================================ document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { const target = document.querySelector(this.getAttribute('href')); if (target) { e.preventDefault(); const offset = nav.offsetHeight; const top = target.getBoundingClientRect().top + window.scrollY - offset; window.scrollTo({ top, behavior: 'smooth' }); // Close mobile menu if open const bsCollapse = bootstrap.Collapse.getInstance(document.getElementById('navMenu')); if (bsCollapse) bsCollapse.hide(); } }); }); // ============================================ // ANIMATED COUNTERS // ============================================ const counters = document.querySelectorAll('[data-target]'); const counterObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const el = entry.target; const target = parseInt(el.dataset.target); const suffix = el.querySelector('span') ? el.querySelector('span').textContent : ''; const duration = 1800; const step = Math.ceil(target / (duration / 16)); let current = 0; const update = () => { current = Math.min(current + step, target); el.innerHTML = current.toLocaleString() + `${suffix}`; if (current < target) requestAnimationFrame(update); }; update(); counterObserver.unobserve(el); } }); }, { threshold: 0.5 }); counters.forEach(c => counterObserver.observe(c)); // ============================================ // TESTIMONIAL SLIDER // ============================================ (() => { const track = document.getElementById('testiTrack'); const slides = track.children; const totalSlides = slides.length; const dots = document.querySelectorAll('.slider-dot'); let current = 0; const go = (idx) => { current = (idx + totalSlides) % totalSlides; track.style.transform = `translateX(-${current * 100}%)`; dots.forEach((d, i) => d.classList.toggle('active', i === current)); }; document.getElementById('testiPrev').addEventListener('click', () => go(current - 1)); document.getElementById('testiNext').addEventListener('click', () => go(current + 1)); dots.forEach(d => d.addEventListener('click', () => go(parseInt(d.dataset.index)))); // Auto-advance let autoTimer = setInterval(() => go(current + 1), 5000); track.parentElement.addEventListener('mouseenter', () => clearInterval(autoTimer)); track.parentElement.addEventListener('mouseleave', () => { autoTimer = setInterval(() => go(current + 1), 5000); }); // Touch support let startX = 0; track.addEventListener('touchstart', e => { startX = e.touches[0].clientX; }, { passive: true }); track.addEventListener('touchend', e => { const diff = startX - e.changedTouches[0].clientX; if (Math.abs(diff) > 50) go(diff > 0 ? current + 1 : current - 1); }); })(); // ============================================ // SCROLL TO TOP BUTTON // ============================================ const scrollTopBtn = document.getElementById('scrollTop'); window.addEventListener('scroll', () => { scrollTopBtn.classList.toggle('visible', window.scrollY > 400); }); scrollTopBtn.addEventListener('click', () => { window.scrollTo({ top: 0, behavior: 'smooth' }); }); // ============================================ // CONTACT FORM SUBMISSION (demo) // ============================================ document.getElementById('contactForm').addEventListener('submit', function (e) { e.preventDefault(); const name = document.getElementById('name').value.trim(); const email = document.getElementById('email').value.trim(); const message = document.getElementById('message').value.trim(); if (!name || !email || !message) { alert('Please fill in all required fields (Name, Email, Message).'); return; } this.style.display = 'none'; document.getElementById('formSuccess').style.display = 'block'; }); // ============================================ // NEWSLETTER (demo) // ============================================ document.querySelector('.newsletter-btn').addEventListener('click', function () { const input = this.previousElementSibling; if (input.value && input.value.includes('@')) { this.innerHTML = ''; this.style.background = '#22c55e'; input.value = ''; input.placeholder = 'Subscribed!'; } });