// ============================================
// 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!';
}
});