
(function () {
    var LAYERS = [
        
        { sel: ':scope > .impulse-icon-wrap, :scope > a > .impulse-icon-wrap', z: 60, travel: 18 },
        { sel: ':scope > .impulse-icon-content > .impulse-icon-title, :scope > a > .impulse-icon-content > .impulse-icon-title, :scope > .impulse-icon-title', z: 30, travel: 10 },
        { sel: ':scope > .impulse-icon-content > .impulse-icon-text, :scope > a > .impulse-icon-content > .impulse-icon-text, :scope > .impulse-icon-text', z: 14, travel: 5 }
    ];


    
    var IS_TOUCH = (function () {
        try {
            return matchMedia('(hover: none)').matches || matchMedia('(pointer: coarse)').matches;
        } catch (e) { return false; }
    })();


    
    
    var gyroX = 0, gyroY = 0;          
    var gyroBiasX = null, gyroBiasY = null;
    var gyroAttached = false;
    var gyroPermRequested = false;
    var GYRO_RANGE_DEG = 22;           

    function screenAngle() {
        try {
            if (screen.orientation && typeof screen.orientation.angle === 'number') return screen.orientation.angle;
        } catch (e) {}
        return window.orientation || 0;
    }

    function attachGyroListener() {
        if (gyroAttached) return;
        gyroAttached = true;
        window.addEventListener('deviceorientation', function (e) {
            if (e.gamma == null || e.beta == null) return;
            var g = e.gamma;     
            var b = e.beta;      

            
            var ang = screenAngle();
            if (ang === 90)        { var tmp = g; g = b;  b = -tmp; }
            else if (ang === -90 || ang === 270) { var tmp2 = g; g = -b; b = tmp2; }
            else if (ang === 180)  { g = -g; b = -b; }

            if (gyroBiasX === null) { gyroBiasX = g; gyroBiasY = b; }
            var dx = (g - gyroBiasX) / GYRO_RANGE_DEG;
            var dy = (b - gyroBiasY) / GYRO_RANGE_DEG;
            gyroX = dx > 1 ? 1 : (dx < -1 ? -1 : dx);
            gyroY = dy > 1 ? 1 : (dy < -1 ? -1 : dy);
        });

        
        window.addEventListener('orientationchange', function () {
            gyroBiasX = null;
            gyroBiasY = null;
        });
    }

    function requestGyroPermission() {
        if (gyroPermRequested) return;
        gyroPermRequested = true;

        
        if (typeof DeviceOrientationEvent !== 'undefined' &&
            typeof DeviceOrientationEvent.requestPermission === 'function') {
            try {
                DeviceOrientationEvent.requestPermission().then(function (state) {
                    if (state === 'granted') attachGyroListener();
                }).catch(function () {  });
            } catch (e) {  }
        } else {
            
            attachGyroListener();
        }
    }

    function setupGyroAfterFirstGesture() {
        if (gyroPermRequested) return;
        
        if (!(typeof DeviceOrientationEvent !== 'undefined' &&
              typeof DeviceOrientationEvent.requestPermission === 'function')) {
            attachGyroListener();
            gyroPermRequested = true;
            return;
        }
        
        var armed = false;
        function arm() {
            if (armed) return;
            armed = true;
            requestGyroPermission();
            document.removeEventListener('touchstart', arm);
            document.removeEventListener('click', arm);
        }
        document.addEventListener('touchstart', arm, { passive: true });
        document.addEventListener('click', arm);
    }

    function normalizeStrokes(scope) {
        scope.querySelectorAll('svg path, svg line, svg circle, svg rect, svg polyline, svg polygon').forEach(function (p) {
            try {
                if (typeof p.getTotalLength !== 'function') return;
                var len = p.getTotalLength();
                if (!(len > 0)) return;
                p.style.setProperty('--sl', len);
                p.style.strokeDasharray = len;
                p.style.strokeDashoffset = '0';
            } catch (e) {}
        });
    }


    

    var mobileCards = [];     
    var mobileTickRunning = false;

    function startMobileTick() {
        if (mobileTickRunning) return;
        mobileTickRunning = true;
        function tick() {
            var anyActive = false;
            for (var i = 0; i < mobileCards.length; i++) {
                var c = mobileCards[i];
                if (!c.active) continue;
                anyActive = true;
                c.curX += (gyroX - c.curX) * 0.14;
                c.curY += (gyroY - c.curY) * 0.14;
                for (var j = 0; j < c.parts.length; j++) {
                    var p = c.parts[j];
                    var tx = c.curX * p.travel;
                    var ty = c.curY * p.travel;
                    p.el.style.transform = 'translate3d(' + tx.toFixed(2) + 'px,' + ty.toFixed(2) + 'px,' + p.z + 'px)';
                }
            }
            if (anyActive) {
                requestAnimationFrame(tick);
            } else {
                mobileTickRunning = false;
            }
        }
        requestAnimationFrame(tick);
    }

    function wire(card) {
        if (card._fcParallax) return;
        card._fcParallax = true;
        normalizeStrokes(card);

        
        var parts = [];
        for (var i = 0; i < LAYERS.length; i++) {
            var node = card.querySelector(LAYERS[i].sel) || card.querySelector(LAYERS[i].sel.split(',')[0].replace(':scope > ', ''));
            if (node) parts.push({ el: node, z: LAYERS[i].z, travel: LAYERS[i].travel });
        }
        if (!parts.length) return;

        if (IS_TOUCH) {
            
            var entry = { el: card, parts: parts, curX: 0, curY: 0, active: false };
            mobileCards.push(entry);

            
            setupGyroAfterFirstGesture();


            var io = ('IntersectionObserver' in window) ? new IntersectionObserver(function (entries) {
                entries.forEach(function (en) {
                    var nowVisible = en.isIntersecting && en.intersectionRatio > 0.05;
                    if (nowVisible && !entry.active) {
                        entry.active = true;

                        parts.forEach(function (p) { p.el.style.transition = 'transform 0.45s cubic-bezier(0.4, 0, 0.2, 1)'; });

                        
                        
                        card.classList.add('impulse-icon-on');
                        startMobileTick();

                        setTimeout(function () {
                            if (entry.active) {
                                parts.forEach(function (p) { p.el.style.transition = 'none'; });
                            }
                        }, 350);
                    } else if (!nowVisible && entry.active) {
                        entry.active = false;
                        card.classList.remove('impulse-icon-on');
                        
                        parts.forEach(function (p) { p.el.style.transition = 'transform 0.45s cubic-bezier(0.4, 0, 0.2, 1)'; });
                        entry.curX = 0; entry.curY = 0;
                        parts.forEach(function (p) { p.el.style.transform = 'translate3d(0,0,0)'; });
                    }
                });
            }, { threshold: [0, 0.05, 0.5] }) : null;
            if (io) io.observe(card);
            else { entry.active = true; startMobileTick(); }
            return;
        }

        
        var hovered = false;
        var targetX = 0, targetY = 0, curX = 0, curY = 0, raf = null;

        function apply() {
            curX += (targetX - curX) * 0.18;
            curY += (targetY - curY) * 0.18;
            parts.forEach(function (p) {
                var tx = curX * p.travel;
                var ty = curY * p.travel;
                var tz = hovered ? p.z : 0;
                p.el.style.transform = 'translate3d(' + tx.toFixed(2) + 'px,' + ty.toFixed(2) + 'px,' + tz + 'px)';
            });
            if (hovered || Math.abs(curX - targetX) > 0.01 || Math.abs(curY - targetY) > 0.01) {
                raf = requestAnimationFrame(apply);
            } else {
                raf = null;
            }
        }

        card.addEventListener('mouseenter', function () {
            hovered = true;
            
            parts.forEach(function (p) { p.el.style.transition = 'none'; });
            if (!raf) raf = requestAnimationFrame(apply);
        });
        card.addEventListener('mousemove', function (e) {
            var r = card.getBoundingClientRect();
            if (!r.width || !r.height) return;
            targetX = ((e.clientX - r.left) / r.width  - 0.5) * 2;
            targetY = ((e.clientY - r.top)  / r.height - 0.5) * 2;
        });
        card.addEventListener('mouseleave', function () {
            hovered = false;
            targetX = 0; targetY = 0;
            
            parts.forEach(function (p) { p.el.style.transition = 'transform 0.45s cubic-bezier(0.4, 0, 0.2, 1)'; });
            if (!raf) raf = requestAnimationFrame(apply);
        });
    }

    function scan(root) {
        (root || document).querySelectorAll('.impulse-icon').forEach(wire);
    }

    function init() {
        scan(document);
        var mo = new MutationObserver(function (list) {
            list.forEach(function (m) {
                m.addedNodes && m.addedNodes.forEach(function (n) {
                    if (n.nodeType !== 1) return;
                    if (n.classList && n.classList.contains('impulse-icon')) wire(n);
                    n.querySelectorAll && n.querySelectorAll('.impulse-icon').forEach(wire);
                });
            });
        });
        mo.observe(document.body, { childList: true, subtree: true });
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

    window.ImpulseFeatureCardParallax = { wire: wire, scan: scan };
})();
