/* ============================================ OneScript — Landing Page JavaScript Scroll animations, FAQ (WCAG), smooth scroll, nav ============================================ */ document.addEventListener('DOMContentLoaded', () => { // ── Header scroll effect ── const header = document.querySelector('.site-header'); if (header) { const onScroll = () => { header.classList.toggle('scrolled', window.scrollY > 50); }; window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); } // ── Mobile navigation toggle (WCAG) ── const mobileToggle = document.querySelector('.mobile-toggle'); const navLinks = document.querySelector('.nav-links'); if (mobileToggle && navLinks) { mobileToggle.addEventListener('click', () => { const isOpen = navLinks.classList.toggle('open'); mobileToggle.classList.toggle('active'); mobileToggle.setAttribute('aria-expanded', isOpen); mobileToggle.setAttribute('aria-label', isOpen ? 'Close navigation menu' : 'Open navigation menu'); document.body.style.overflow = isOpen ? 'hidden' : ''; }); navLinks.querySelectorAll('a').forEach(link => { link.addEventListener('click', () => { mobileToggle.classList.remove('active'); navLinks.classList.remove('open'); mobileToggle.setAttribute('aria-expanded', 'false'); mobileToggle.setAttribute('aria-label', 'Open navigation menu'); document.body.style.overflow = ''; }); }); } // ── Smooth scroll for anchor links ── document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', (e) => { const href = anchor.getAttribute('href'); if (!href || href === '#' || href.length <= 1) return; const target = document.querySelector(href); if (target) { e.preventDefault(); const offset = header ? header.offsetHeight + 20 : 80; const top = target.getBoundingClientRect().top + window.scrollY - offset; window.scrollTo({ top, behavior: 'smooth' }); } }); }); // ── Scroll reveal animations (respects prefers-reduced-motion) ── const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; const revealElements = document.querySelectorAll('.reveal, .rl, .rr'); if (prefersReducedMotion) { revealElements.forEach(el => el.classList.add('revealed')); } else if (revealElements.length > 0) { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('revealed'); observer.unobserve(entry.target); } }); }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' }); revealElements.forEach(el => observer.observe(el)); } // ── FAQ Accordion (WCAG: aria-expanded) ── const faqItems = document.querySelectorAll('.faq-item'); faqItems.forEach(item => { const question = item.querySelector('.faq-q'); if (question) { question.addEventListener('click', () => { const isActive = item.classList.contains('active'); // Close all faqItems.forEach(i => { i.classList.remove('active'); const btn = i.querySelector('.faq-q'); if (btn) btn.setAttribute('aria-expanded', 'false'); }); // Toggle current if (!isActive) { item.classList.add('active'); question.setAttribute('aria-expanded', 'true'); } }); // Keyboard support (Enter / Space already handled by button element) } }); // ── Counter animation ── const counters = document.querySelectorAll('[data-count]'); if (counters.length > 0) { const counterObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const el = entry.target; const target = parseInt(el.getAttribute('data-count')); const suffix = el.getAttribute('data-suffix') || ''; const prefix = el.getAttribute('data-prefix') || ''; const duration = prefersReducedMotion ? 0 : 2000; const start = performance.now(); if (duration === 0) { el.textContent = prefix + target.toLocaleString() + suffix; } else { const animate = (now) => { const progress = Math.min((now - start) / duration, 1); const eased = 1 - Math.pow(1 - progress, 3); const current = Math.floor(eased * target); el.textContent = prefix + current.toLocaleString() + suffix; if (progress < 1) { requestAnimationFrame(animate); } else { el.textContent = prefix + target.toLocaleString() + suffix; } }; requestAnimationFrame(animate); } counterObserver.unobserve(el); } }); }, { threshold: 0.5 }); counters.forEach(el => counterObserver.observe(el)); } // ── Mobile Sticky Bar with Countdown ── const stickyBar = document.getElementById('stickyBar'); const stickyTimer = document.getElementById('stickyTimer'); let stickyBarShown = false; let stickyCountdownInterval = null; if (stickyBar) { const showStickyBar = () => { if (window.scrollY > 600 && !stickyBarShown) { stickyBar.classList.add('visible'); stickyBarShown = true; // Start 15 minute countdown let timeLeft = 900; // 15 minutes in seconds if (stickyTimer) { stickyCountdownInterval = setInterval(() => { timeLeft--; const minutes = Math.floor(timeLeft / 60); const seconds = timeLeft % 60; stickyTimer.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; if (timeLeft <= 0) { clearInterval(stickyCountdownInterval); stickyTimer.textContent = '0:00'; } }, 1000); } } }; window.addEventListener('scroll', showStickyBar, { passive: true }); } // ── Scroll Popup ── const scrollPopup = document.getElementById('scrollPopup'); const popupClose = document.getElementById('popupClose'); const popupOverlay = scrollPopup?.querySelector('.popup-overlay'); let popupShown = false; let scrollTimer = null; let countdownInterval = null; const showPopup = () => { if (!popupShown && scrollPopup) { scrollPopup.classList.add('show'); document.body.style.overflow = 'hidden'; popupShown = true; // Start countdown timer (10 minutes) let timeLeft = 600; // 10 minutes in seconds const timerElement = document.getElementById('popupTimer'); if (timerElement) { countdownInterval = setInterval(() => { timeLeft--; const minutes = Math.floor(timeLeft / 60); const seconds = timeLeft % 60; timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; if (timeLeft <= 0) { clearInterval(countdownInterval); timerElement.textContent = '0:00'; } }, 1000); } } }; const closePopup = () => { if (scrollPopup) { scrollPopup.classList.remove('show'); document.body.style.overflow = ''; if (countdownInterval) { clearInterval(countdownInterval); countdownInterval = null; } } }; // Show popup immediately on page load if (scrollPopup) { // Open popup after 1 second of page load setTimeout(() => { if (!popupShown) { showPopup(); } }, 11000); // Close popup handlers if (popupClose) { popupClose.addEventListener('click', closePopup); } if (popupOverlay) { popupOverlay.addEventListener('click', closePopup); } // Close on escape key document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && scrollPopup.classList.contains('show')) { closePopup(); } }); // Close popup when clicking CTA button const popupCTA = scrollPopup.querySelector('.popup-cta'); if (popupCTA) { popupCTA.addEventListener('click', closePopup); } } });