Spaces:
Running
Running
| // Smooth scrolling for anchor links | |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { | |
| anchor.addEventListener('click', function (e) { | |
| e.preventDefault(); | |
| document.querySelector(this.getAttribute('href')).scrollIntoView({ | |
| behavior: 'smooth' | |
| }); | |
| }); | |
| }); | |
| // Initialize tooltips for feather icons | |
| document.addEventListener('DOMContentLoaded', () => { | |
| const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); | |
| tooltipTriggerList.map(function (tooltipTriggerEl) { | |
| return new bootstrap.Tooltip(tooltipTriggerEl); | |
| }); | |
| }); | |
| // Mobile menu toggle functionality | |
| function toggleMobileMenu() { | |
| const mobileMenu = document.getElementById('mobile-menu'); | |
| mobileMenu.classList.toggle('hidden'); | |
| mobileMenu.classList.toggle('flex'); | |
| } | |
| // Demo counter animation | |
| function animateCounter(elementId, target, duration = 2000) { | |
| const element = document.getElementById(elementId); | |
| if (!element) return; | |
| const start = 0; | |
| const increment = target / (duration / 16); | |
| let current = start; | |
| const timer = setInterval(() => { | |
| current += increment; | |
| if (current >= target) { | |
| clearInterval(timer); | |
| current = target; | |
| } | |
| element.textContent = Math.floor(current).toLocaleString(); | |
| }, 16); | |
| } | |
| // Initialize counters when they come into view | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| const counterId = entry.target.getAttribute('data-counter-id'); | |
| const target = parseInt(entry.target.getAttribute('data-counter-target')); | |
| animateCounter(counterId, target); | |
| observer.unobserve(entry.target); | |
| } | |
| }); | |
| }, { threshold: 0.5 }); | |
| document.querySelectorAll('[data-counter-id]').forEach(el => { | |
| observer.observe(el); | |
| }); |