
(function() {
'use strict';

if (window._impulseSectionFxLoaded) return;
window._impulseSectionFxLoaded = true;

var sections = [];
var _inputBound = false;
var rafId = null;
var pointerX = 0.5, pointerY = 0.5;
var gyroBaseB = null, gyroBaseG = null;
var gyroGx = 0, gyroGy = 0;
var gyroActive = false;

var _busTargetX = 0, _busTargetY = 0;
var _busCurX = 0, _busCurY = 0;
var _busTickStarted = false;
function _publishTilt(x, y) {
    if (!isFinite(x)) x = 0;
    if (!isFinite(y)) y = 0;
    _busTargetX = x;
    _busTargetY = y;
    if (!_busTickStarted) {
        _busTickStarted = true;
        _busTick();
    }
}
function _busTick() {
    var dx = _busTargetX - _busCurX;
    var dy = _busTargetY - _busCurY;
    _busCurX += dx * 0.035;
    _busCurY += dy * 0.035;
    
    var atTarget = (Math.abs(dx) < 0.0008 && Math.abs(dy) < 0.0008);
    if (atTarget) {
        _busCurX = _busTargetX;
        _busCurY = _busTargetY;
    }
    window._impulseTilt = { x: _busCurX, y: _busCurY };

    

    
    if (atTarget) {
        _busTickStarted = false;
        return;
    }
    requestAnimationFrame(_busTick);
}

function onMouseMove(e) {
    pointerX = e.clientX / (window.innerWidth  || 1);
    pointerY = e.clientY / (window.innerHeight || 1);
    _publishTilt((pointerX - 0.5) * 2, (pointerY - 0.5) * 2);
}

var _gStillCount = 0, _gLastB = null, _gLastG = null;
function onGyro(e) {
    if (e.beta === null && e.gamma === null) return;
    var b = e.beta || 0, g = e.gamma || 0;
    if (gyroBaseB === null) { gyroBaseB = b; gyroBaseG = g; _gLastB = b; _gLastG = g; }
    var frameDB = Math.abs(b - _gLastB);
    var frameDG = Math.abs(g - _gLastG);
    if (frameDB < 0.4 && frameDG < 0.4) {
        _gStillCount++;
        if (_gStillCount > 25) {
            gyroBaseB = b;
            gyroBaseG = g;
        }
    } else {
        _gStillCount = 0;
    }
    _gLastB = b; _gLastG = g;

    gyroBaseB += (b - gyroBaseB) * 0.02;
    gyroBaseG += (g - gyroBaseG) * 0.02;
    gyroGx = Math.max(-1, Math.min(1, (g - gyroBaseG) / 10));
    gyroGy = Math.max(-1, Math.min(1, (b - gyroBaseB) / 10));
    gyroActive = true;
    _publishTilt(gyroGx, gyroGy);
}

function hueToRgbStr(h, s, l) {
    
    h = (((parseFloat(h) || 0) % 360) + 360) % 360 / 360;
    s = s == null ? 0.85 : s;
    l = l == null ? 0.62 : l;
    function hue2rgb(p, q, t) {
        if (t < 0) t += 1;
        if (t > 1) t -= 1;
        if (t < 1/6) return p + (q - p) * 6 * t;
        if (t < 1/2) return q;
        if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
        return p;
    }
    var r, g, b;
    if (s === 0) { r = g = b = l; }
    else {
        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = hue2rgb(p, q, h + 1/3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1/3);
    }
    return Math.round(r * 255) + ',' + Math.round(g * 255) + ',' + Math.round(b * 255);
}

function ensureKeyframes() {
    if (document.getElementById('impulse-fx-keyframes')) return;
    var st = document.createElement('style');
    st.id = 'impulse-fx-keyframes';
    st.textContent =
        '@keyframes impulse-fx-pulse-ring{' +
            '0%{transform:translate(-50%,-50%) scale(0);opacity:0}' +
            '15%{opacity:1}' +
            '100%{transform:translate(-50%,-50%) scale(2.2);opacity:0}' +
        '}' +
        '@keyframes impulse-fx-prism{' +
            '0%{transform:rotate(0deg)}' +
            '100%{transform:rotate(360deg)}' +
        '}' +

        
        
        '@keyframes impulse-fx-aurora-a{' +
            '0%{transform:translate(-12%,0%) rotate(0deg)}' +
            '25%{transform:translate(0%,-12%) rotate(90deg)}' +
            '50%{transform:translate(12%,0%) rotate(180deg)}' +
            '75%{transform:translate(0%,12%) rotate(270deg)}' +
            '100%{transform:translate(-12%,0%) rotate(360deg)}' +
        '}' +
        '@keyframes impulse-fx-aurora-b{' +
            '0%{transform:translate(10%,10%) rotate(0deg)}' +
            '25%{transform:translate(-10%,10%) rotate(-90deg)}' +
            '50%{transform:translate(-10%,-10%) rotate(-180deg)}' +
            '75%{transform:translate(10%,-10%) rotate(-270deg)}' +
            '100%{transform:translate(10%,10%) rotate(-360deg)}' +
        '}' +
        '@keyframes impulse-fx-aurora-c{' +
            '0%{transform:translate(0%,-10%) rotate(180deg)}' +
            '25%{transform:translate(10%,0%) rotate(90deg)}' +
            '50%{transform:translate(0%,10%) rotate(0deg)}' +
            '75%{transform:translate(-10%,0%) rotate(-90deg)}' +
            '100%{transform:translate(0%,-10%) rotate(-180deg)}' +
        '}';
    document.head.appendChild(st);
}

function createShineOverlay(el, ai, z) {
    var sh = document.createElement('div');
    sh.className = 'impulse-fx-shine';
    sh.setAttribute('data-impulse-fx-inject', '1');
    var opacity = (0.08 + 0.7 * ai).toFixed(3);
    sh.style.cssText =
        'position:absolute;inset:0;pointer-events:none;' +
        'background:linear-gradient(105deg,' +
            'transparent 35%,' +
            'rgba(255,255,255,' + opacity + ') 50%,' +
            'transparent 65%);' +
        'mix-blend-mode:overlay;z-index:' + z + ';' +
        'transform:translateX(-130%);will-change:transform';
    var cs = window.getComputedStyle(el);
    if (cs.position === 'static') el.style.position = 'relative';
    el.appendChild(sh);
    return sh;
}

function createRippleFilter(el, ai) {
    var fid = 'impulse-ripple-' + Math.random().toString(36).slice(2, 10);
    var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.setAttribute('data-impulse-fx-inject', '1');
    svg.setAttribute('width', '0');
    svg.setAttribute('height', '0');
    svg.style.cssText = 'position:absolute;width:0;height:0;pointer-events:none;overflow:visible';

    

    var scale = (1 + ai * 26).toFixed(1);
    svg.innerHTML =
        '<filter id="' + fid + '" x="-15%" y="-15%" width="130%" height="130%">' +
          '<feTurbulence type="fractalNoise" baseFrequency="0.012 0.012" numOctaves="2" seed="3" stitchTiles="stitch" result="turb"/>' +
          '<feOffset in="turb" dx="0" dy="0" result="flow">' +
            '<animate attributeName="dx" ' +
              'values="0;28;40;28;0;-28;-40;-28;0" ' +
              'dur="9s" repeatCount="indefinite" calcMode="linear"/>' +
            '<animate attributeName="dy" ' +
              'values="-40;-28;0;28;40;28;0;-28;-40" ' +
              'dur="9s" repeatCount="indefinite" calcMode="linear"/>' +
          '</feOffset>' +
          '<feDisplacementMap in="SourceGraphic" in2="flow" scale="' + scale + '"/>' +
        '</filter>';
    el.parentNode.insertBefore(svg, el);
    el.style.filter = 'url(#' + fid + ')';
    return svg;
}

function createPulseOverlay(el, ai, hue, z) {
    ensureKeyframes();
    var wrap = document.createElement('div');
    wrap.setAttribute('data-impulse-fx-inject', '1');
    wrap.style.cssText =
        'position:absolute;inset:0;pointer-events:none;z-index:' + z + ';overflow:hidden;mix-blend-mode:screen';
    var op  = (0.1 + 0.85 * ai).toFixed(2);
    var rgb = hueToRgbStr(hue);
    var ringCss =
        'position:absolute;top:50%;left:50%;width:45%;aspect-ratio:1;border-radius:50%;' +
        'background:radial-gradient(circle,rgba(' + rgb + ',' + op + ') 0%,rgba(' + rgb + ',0) 65%);' +
        'animation:impulse-fx-pulse-ring 5s linear infinite';
    wrap.innerHTML =
        '<div style="' + ringCss + '"></div>' +
        '<div style="' + ringCss + ';animation-delay:1.65s"></div>' +
        '<div style="' + ringCss + ';animation-delay:3.3s"></div>';
    var cs = window.getComputedStyle(el);
    if (cs.position === 'static') el.style.position = 'relative';
    el.appendChild(wrap);
    return wrap;
}

function createPrismOverlay(el, ai, z) {
    ensureKeyframes();
    
    var wrap = document.createElement('div');
    wrap.setAttribute('data-impulse-fx-inject', '1');
    wrap.style.cssText =
        'position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:' + z + ';mix-blend-mode:color';
    var op = (0.05 + 0.8 * ai).toFixed(2);
    var inner = document.createElement('div');
    inner.style.cssText =
        'position:absolute;inset:-30%;filter:blur(28px);' +
        'background:conic-gradient(from 0deg,' +
            'rgba(255,0,150,' + op + ') 0%,' +
            'rgba(150,0,255,' + op + ') 16%,' +
            'rgba(0,150,255,' + op + ') 33%,' +
            'rgba(0,255,200,' + op + ') 50%,' +
            'rgba(255,220,0,' + op + ') 66%,' +
            'rgba(255,80,0,' + op + ') 83%,' +
            'rgba(255,0,150,' + op + ') 100%);' +
        'animation:impulse-fx-prism 18s linear infinite';
    wrap.appendChild(inner);
    var cs = window.getComputedStyle(el);
    if (cs.position === 'static') el.style.position = 'relative';
    el.appendChild(wrap);
    return wrap;
}

function createAuroraOverlay(el, ai, hue, z) {
    ensureKeyframes();
    var wrap = document.createElement('div');
    wrap.setAttribute('data-impulse-fx-inject', '1');
    wrap.style.cssText =
        'position:absolute;inset:0;pointer-events:none;z-index:' + z + ';overflow:hidden;mix-blend-mode:screen';
    var op = (0.08 + 0.65 * ai).toFixed(2);
    
    var baseHue = parseFloat(hue);
    if (isNaN(baseHue)) baseHue = 200;
    var rgbA = hueToRgbStr(baseHue);
    var rgbB = hueToRgbStr(baseHue + 60);
    var rgbC = hueToRgbStr(baseHue + 180);
    var blobCss =
        'position:absolute;top:-30%;left:-30%;width:160%;height:160%;filter:blur(50px);';
    wrap.innerHTML =
        '<div style="' + blobCss + 'background:radial-gradient(ellipse 55% 40% at 30% 40%,rgba(' + rgbA + ',' + op + ') 0%,rgba(' + rgbA + ',0) 60%);animation:impulse-fx-aurora-a 24s linear infinite"></div>' +
        '<div style="' + blobCss + 'background:radial-gradient(ellipse 50% 55% at 70% 60%,rgba(' + rgbC + ',' + op + ') 0%,rgba(' + rgbC + ',0) 60%);animation:impulse-fx-aurora-b 28s linear infinite"></div>' +
        '<div style="' + blobCss + 'background:radial-gradient(ellipse 65% 40% at 50% 80%,rgba(' + rgbB + ',' + op + ') 0%,rgba(' + rgbB + ',0) 60%);animation:impulse-fx-aurora-c 34s linear infinite"></div>';
    var cs = window.getComputedStyle(el);
    if (cs.position === 'static') el.style.position = 'relative';
    el.appendChild(wrap);
    return wrap;
}

function createSpotlightOverlay(el, ai, hue, z) {
    var wrap = document.createElement('div');
    wrap.setAttribute('data-impulse-fx-inject', '1');
    wrap.className = 'impulse-fx-spotlight';

    var radius = (160 + 260 * ai).toFixed(0);  
    var fade   = (50  + 50  * ai).toFixed(0);  
    var rgb    = hueToRgbStr(hue);
    wrap.dataset.radius = radius;
    wrap.dataset.fade   = fade;
    wrap.dataset.rgb    = rgb;
    wrap.style.cssText =
        'position:absolute;inset:0;pointer-events:none;z-index:' + z + ';mix-blend-mode:screen;' +
        'background:radial-gradient(circle ' + radius + 'px at 50% 50%,' +
        'rgba(' + rgb + ',0.32) 0%,rgba(' + rgb + ',0) ' + fade + '%)';
    var cs = window.getComputedStyle(el);
    if (cs.position === 'static') el.style.position = 'relative';
    el.appendChild(wrap);
    return wrap;
}

function cleanupInjected(el) {
    
    var kids = el.querySelectorAll(':scope > [data-impulse-fx-inject]');
    for (var i = 0; i < kids.length; i++) kids[i].remove();
    
    var sib = el.previousSibling;
    while (sib) {
        var prev = sib.previousSibling;
        if (sib.nodeType === 1 && sib.getAttribute &&
            sib.getAttribute('data-impulse-fx-inject') === '1') {
            sib.remove();
        } else {
            break;
        }
        sib = prev;
    }
    if (el.style.filter) el.style.filter = '';
}

function collect() {
    
    for (var i = 0; i < sections.length; i++) {
        cleanupInjected(sections[i].el);
        sections[i].el.style.transform = '';
    }
    sections = [];

    if (document.querySelector('.impulse-screen-wrapper')) return;

    var nodes = document.querySelectorAll(
        '[data-section-tilt="1"], [data-section-ambient]:not([data-section-ambient=""]):not([data-section-ambient="none"])'
    );
    for (var j = 0; j < nodes.length; j++) {
        var el = nodes[j];
        if (el.closest && el.closest('.impulse-screen-wrapper')) continue;

        var hasTilt = el.getAttribute('data-section-tilt') === '1';
        var amb = el.getAttribute('data-section-ambient') || '';
        if (amb === 'none') amb = '';
        if (!hasTilt && !amb) continue;

        var s = {
            el:    el,
            tilt:  hasTilt,
            tiltI: Math.max(0, Math.min(1, parseFloat(el.getAttribute('data-section-tilt-intensity')    || '50') / 100)),
            amb:   amb,
            ambI:  Math.max(0, Math.min(1, parseFloat(el.getAttribute('data-section-ambient-intensity') || '50') / 100)),
            curX:  0, curY: 0,
            tStart: performance.now() - Math.random() * 2000
        };

        var ambHue = el.getAttribute('data-section-ambient-hue');
        if (ambHue === null) ambHue = 200;

        var ambZ = el.getAttribute('data-section-ambient-over') === '1' ? 50 : 3;
        
        if (amb === 'ripple') {
            s.rippleSvg = createRippleFilter(el, s.ambI);
        } else if (amb === 'prism') {
            createPrismOverlay(el, s.ambI, ambZ);
        }

        sections.push(s);
    }
}

function render() {
    rafId = requestAnimationFrame(render);
    if (!sections.length) return;

    var now = performance.now();

    for (var i = 0; i < sections.length; i++) {
        var s = sections[i];
        var rect = s.el.getBoundingClientRect();
        if (rect.bottom < -100 || rect.top > window.innerHeight + 100) continue;

        var parts = [];
        var t  = (now - s.tStart) / 1000;
        var ai = s.ambI;

        if (s.tilt) {

            

            
            var depthHover = !!s.el.querySelector('[data-depth-intensity]:hover');
            if (!depthHover) {
                var tx, ty;
                if (gyroActive) { tx = gyroGx; ty = gyroGy; }
                else            { tx = (pointerX - 0.5) * 2; ty = (pointerY - 0.5) * 2; }

                
                tx = tx * Math.abs(tx);
                ty = ty * Math.abs(ty);
                
                s.curX += (tx - s.curX) * 0.04;
                s.curY += (ty - s.curY) * 0.04;
            } else {
                
                s.curX += (0 - s.curX) * 0.04;
                s.curY += (0 - s.curY) * 0.04;
            }
            var maxDeg = 3 * s.tiltI;
            parts.push('perspective(1200px)');
            parts.push('rotateX(' + (-s.curY * maxDeg).toFixed(3) + 'deg)');
            parts.push('rotateY(' + (s.curX * maxDeg).toFixed(3) + 'deg)');
        }

        
        
        if (s.amb === 'float') {
            var ty2 = Math.sin(t * 0.5) * 5 * ai;
            var rot = Math.sin(t * 0.6 + 0.7) * 0.4 * ai;
            var sc  = 1 + Math.sin(t * 0.4) * 0.012 * ai;
            parts.push('translateY(' + ty2.toFixed(3) + 'px)');
            parts.push('rotate(' + rot.toFixed(3) + 'deg)');
            parts.push('scale(' + sc.toFixed(5) + ')');
        }

        s.el.style.transform = parts.length ? parts.join(' ') : '';
    }
}

function start() {
    collect();

    

    
    
    if (!_inputBound) {
        _inputBound = true;
        document.addEventListener('mousemove', onMouseMove, { passive: true });
        if (window._impulseGyro && window._impulseGyro.register) {
            window._impulseGyro.register(onGyro);
        } else {
            window.addEventListener('deviceorientation', onGyro);
        }
    }
    if (!sections.length) return;
    render();
}

function init() { setTimeout(start, 400); }

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

window.ImpulseSectionFx = {
    reinit: function() {
        cancelAnimationFrame(rafId);
        start();
    }
};

})();
