    {{-- Alpine plugins (collapse) then Alpine core --}}
    <script defer src="https://unpkg.com/@alpinejs/collapse@3.x.x/dist/cdn.min.js"></script>
    <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
    <script src="https://unpkg.com/aos@2.3.4/dist/aos.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            if (window.AOS) {
                AOS.init({ duration: 700, easing: 'ease-out-cubic', once: true, offset: 60 });
            }

            // Smooth scroll for in-page anchors.
            document.querySelectorAll('a[href^="#"]').forEach(function (a) {
                a.addEventListener('click', function (e) {
                    var id = a.getAttribute('href');
                    if (id.length > 1) {
                        var el = document.querySelector(id);
                        if (el) { e.preventDefault(); el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }
                    }
                });
            });

            // Count-up for numeric stats.
            var stats = document.querySelectorAll('.vs-stat-value[data-count]');
            if (stats.length && 'IntersectionObserver' in window) {
                var io = new IntersectionObserver(function (entries) {
                    entries.forEach(function (en) {
                        if (!en.isIntersecting) return;
                        var el = en.target, raw = el.getAttribute('data-count') || '';
                        var num = parseFloat(raw.replace(/[^0-9.]/g, ''));
                        var suffix = raw.replace(/[0-9.,]/g, '');
                        if (!isNaN(num) && num > 0) {
                            var start = 0, dur = 1400, t0 = performance.now();
                            var step = function (t) {
                                var p = Math.min((t - t0) / dur, 1);
                                var val = Math.floor(p * num);
                                el.textContent = (num % 1 ? (p * num).toFixed(1) : val) + suffix;
                                if (p < 1) requestAnimationFrame(step); else el.textContent = raw;
                            };
                            requestAnimationFrame(step);
                        }
                        io.unobserve(el);
                    });
                }, { threshold: 0.4 });
                stats.forEach(function (s) { io.observe(s); });
            }
        });
    </script>
