(function ($) {
    "use strict";

    // ─────────────────────────────────────────────────────────────────────────
    // HELPER: Pixelated Transition
    // Splits the outgoing element into a CSS grid of pixel-blocks that dissolve.
    // ─────────────────────────────────────────────────────────────────────────
    const buildPixelGrid = (containerEl, count = 20) => {
        let grid = containerEl.querySelector('.sifency-pixel-grid');
        if (grid) grid.remove();

        grid = document.createElement('div');
        grid.className = 'sifency-pixel-grid';
        Object.assign(grid.style, {
            position: 'absolute', top: 0, left: 0,
            width: '100%', height: '100%',
            display: 'grid',
            gridTemplateColumns: `repeat(${count}, 1fr)`,
            gridTemplateRows: `repeat(${count}, 1fr)`,
            zIndex: 20, pointerEvents: 'none',
        });

        for (let i = 0; i < count * count; i++) {
            const cell = document.createElement('div');
            cell.className = 'sifency-pixel-cell';
            Object.assign(cell.style, { width: '100%', height: '100%' });
            grid.appendChild(cell);
        }
        containerEl.appendChild(grid);
        return grid;
    };

    const performPixelTransition = (outEl, inEl, duration, onDone) => {
        const wrapper = outEl.closest('.sifency-parallax-wrapper') || outEl.parentElement;
        const grid = buildPixelGrid(wrapper, 18);
        const cells = Array.from(grid.querySelectorAll('.sifency-pixel-cell'));

        // Paint cells with the outgoing image as background
        const rect = wrapper.getBoundingClientRect();
        cells.forEach(cell => {
            const bg = window.getComputedStyle(outEl).backgroundImage;
            const src = outEl.tagName === 'IMG' ? outEl.src : '';
            Object.assign(cell.style, {
                backgroundColor: '#000',
                backgroundImage: src ? `url(${src})` : bg,
                backgroundSize: `${rect.width}px ${rect.height}px`,
            });
        });

        gsap.set(inEl, { opacity: 0, zIndex: 12 });

        // Randomised stagger dissolve
        const shuffled = [...cells].sort(() => Math.random() - 0.5);

        gsap.to(shuffled, {
            opacity: 0,
            scale: 0,
            duration: duration * 0.6,
            stagger: { each: duration / cells.length, from: 'random' },
            ease: 'power2.in',
            onComplete: () => {
                grid.remove();
                gsap.set(outEl, { opacity: 0 });
                gsap.to(inEl, { opacity: 1, duration: duration * 0.35, ease: 'power1.in',
                    onComplete: onDone });
            },
        });
    };

    // ─────────────────────────────────────────────────────────────────────────
    // HELPER: Shutter Transition
    // Vertical blinds that cover the old image then reveal the new one.
    // ─────────────────────────────────────────────────────────────────────────
    const performShutterTransition = (outEl, inEl, duration, direction, onDone) => {
        const wrapper = outEl.closest('.sifency-parallax-wrapper') || outEl.parentElement;
        const SLATS = 8;
        let shutter = wrapper.querySelector('.sifency-shutter');
        if (shutter) shutter.remove();

        shutter = document.createElement('div');
        shutter.className = 'sifency-shutter';
        Object.assign(shutter.style, {
            position: 'absolute', top: 0, left: 0,
            width: '100%', height: '100%',
            display: 'flex', flexDirection: direction === 'vertical' ? 'column' : 'row',
            zIndex: 25, pointerEvents: 'none', overflow: 'hidden',
        });

        for (let i = 0; i < SLATS; i++) {
            const slat = document.createElement('div');
            Object.assign(slat.style, {
                flex: `0 0 ${100 / SLATS}%`,
                background: '#000',
                transform: direction === 'vertical' ? 'scaleY(0)' : 'scaleX(0)',
                transformOrigin: direction === 'vertical' ? 'top center' : 'left center',
            });
            shutter.appendChild(slat);
        }
        wrapper.appendChild(shutter);

        const slats = Array.from(shutter.children);
        const half = duration / 2;

        // Phase 1: close slats (cover old image)
        gsap.to(slats, {
            [direction === 'vertical' ? 'scaleY' : 'scaleX']: 1,
            duration: half,
            stagger: { each: 0.04, from: 'start' },
            ease: 'power2.in',
            onComplete: () => {
                // Swap images behind the closed slats
                gsap.set(outEl, { opacity: 0 });
                gsap.set(inEl, { opacity: 1, zIndex: 12 });

                // Phase 2: open slats (reveal new image)
                gsap.to(slats, {
                    [direction === 'vertical' ? 'scaleY' : 'scaleX']: 0,
                    transformOrigin: direction === 'vertical' ? 'bottom center' : 'right center',
                    duration: half,
                    stagger: { each: 0.04, from: 'end' },
                    ease: 'power2.out',
                    onComplete: () => {
                        shutter.remove();
                        onDone();
                    },
                });
            },
        });
    };

    // ─────────────────────────────────────────────────────────────────────────
    // HELPER: Disintegration Transition (html2canvas pixel scatter)
    // Requires html2canvas to be enqueued.
    // ─────────────────────────────────────────────────────────────────────────
    const performDisintegrationTransition = (outEl, inEl, duration, onDone) => {
        if (typeof html2canvas === 'undefined') {
            // Graceful fallback to crossfade
            gsap.set(inEl, { opacity: 0, zIndex: 12 });
            gsap.to(outEl, { opacity: 0, duration: duration });
            gsap.to(inEl, { opacity: 1, duration: duration, onComplete: onDone });
            return;
        }

        const wrapper = outEl.closest('.sifency-parallax-wrapper') || outEl.parentElement;
        const COUNT = 60;
        const REPEAT = 3;

        html2canvas(outEl, {
            useCORS: true,
            allowTaint: true,
            backgroundColor: null,
            width: wrapper.offsetWidth,
            height: wrapper.offsetHeight,
        }).then(canvas => {
            const w = canvas.width, h = canvas.height;
            const ctx = canvas.getContext('2d');
            const imageData = ctx.getImageData(0, 0, w, h);
            const dataList = [];

            for (let i = 0; i < COUNT; i++) {
                dataList.push(ctx.createImageData(w, h));
            }
            for (let x = 0; x < w; x++) {
                for (let y = 0; y < h; y++) {
                    for (let l = 0; l < REPEAT; l++) {
                        const idx = (x + y * w) * 4;
                        const di = Math.floor((COUNT * (Math.random() + (2 * x) / w)) / 3);
                        for (let p = 0; p < 4; p++) {
                            dataList[di].data[idx + p] = imageData.data[idx + p];
                        }
                    }
                }
            }

            // Show new image immediately behind the scatter canvases
            gsap.set(inEl, { opacity: 1, zIndex: 11 });
            gsap.set(outEl, { opacity: 0 });

            const particles = [];
            dataList.forEach((data, i) => {
                const c = canvas.cloneNode();
                c.getContext('2d').putImageData(data, 0, 0);
                Object.assign(c.style, {
                    position: 'absolute', top: 0, left: 0,
                    width: '100%', height: '100%',
                    zIndex: 20, pointerEvents: 'none',
                });
                wrapper.appendChild(c);
                particles.push(c);

                const angle = (Math.random() - 0.5) * 2 * Math.PI;
                gsap.to(c, {
                    duration: duration * 0.8,
                    rotate: 30 * (Math.random() - 0.5),
                    x: 50 * Math.sin(angle),
                    y: 50 * Math.cos(angle),
                    opacity: 0,
                    delay: (i / dataList.length) * duration * 0.5,
                    ease: 'power2.in',
                    onComplete: () => {
                        c.remove();
                        if (i === dataList.length - 1) onDone();
                    },
                });
            });

            if (dataList.length === 0) onDone();
        }).catch(() => {
            gsap.set(inEl, { opacity: 1 });
            gsap.set(outEl, { opacity: 0 });
            onDone();
        });
    };

    // ─────────────────────────────────────────────────────────────────────────
    // HELPER: ScrollSmoother Speed Effect (per-element parallax depths)
    // Applied when `smoother_speed` data attribute is set on the container.
    // ─────────────────────────────────────────────────────────────────────────
    const initScrollSmootherEffect = (container, allMedia) => {
        if (typeof ScrollSmoother === 'undefined') return false;

        const speedMin = parseFloat(container.dataset.smootherSpeedMin || 0.55);
        const speedMax = parseFloat(container.dataset.smootherSpeedMax || 0.85);

        // Tag each media element for ScrollSmoother effects
        allMedia.forEach(el => {
            el.setAttribute('data-speed', gsap.utils.random(speedMin, speedMax, 0.05));
        });

        // If a global smoother instance exists, refresh it
        if (window._sifencyScrollSmoother) {
            window._sifencyScrollSmoother.effects(allMedia, {
                speed: () => gsap.utils.random(speedMin, speedMax, 0.05),
            });
        }
        return true;
    };

    // ─────────────────────────────────────────────────────────────────────────
    // SCRUB HELPERS: extend buildScrubReveal with new types
    // ─────────────────────────────────────────────────────────────────────────
    const buildScrubReveal = (timeline, outEl, inEl, type, startTime, duration) => {
        if (type === 'fade' || type === 'crossfade') {
            timeline.fromTo(inEl, { opacity: 0 }, { opacity: 1, ease: "power1.inOut", duration: duration }, startTime);
            if (type === 'crossfade') {
                timeline.fromTo(outEl, { opacity: 1 }, { opacity: 0, ease: "power1.inOut", duration: duration }, startTime);
            }
        } else if (type === 'fade-up') {
            timeline.fromTo(inEl, { opacity: 0, yPercent: 30 }, { opacity: 1, yPercent: 0, ease: "power1.out", duration: duration }, startTime);
        } else if (type === 'clip-vertical') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: "inset(100% 0% 0% 0%)" }, { clipPath: "inset(0% 0% 0% 0%)", ease: "power1.inOut", duration: duration }, startTime);
        } else if (type === 'clip-horizontal') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: "inset(0% 0% 0% 100%)" }, { clipPath: "inset(0% 0% 0% 0%)", ease: "power1.inOut", duration: duration }, startTime);
        } else if (type === 'wipe-down') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: "inset(0% 0% 100% 0%)" }, { clipPath: "inset(0% 0% 0% 0%)", ease: "power1.inOut", duration: duration }, startTime);
        } else if (type === 'circle') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: "circle(0% at 50% 50%)" }, { clipPath: "circle(150% at 50% 50%)", ease: "power1.inOut", duration: duration }, startTime);
        } else if (type === 'zoom') {
            timeline.fromTo(inEl, { opacity: 0, scale: 1.25 }, { opacity: 1, scale: 1.0, ease: "power1.out", duration: duration }, startTime);
        } else if (type === 'swipe-left') {
            timeline.fromTo(inEl, { opacity: 1, xPercent: 100 }, { xPercent: 0, ease: "power1.out", duration: duration }, startTime);
        } else if (type === 'swipe-right') {
            timeline.fromTo(inEl, { opacity: 1, xPercent: -100 }, { xPercent: 0, ease: "power1.out", duration: duration }, startTime);
        } else if (type === 'flip') {
            timeline.fromTo(inEl, { opacity: 1, rotationY: 90, transformStyle: "preserve-3d", transformPerspective: 800 }, { rotationY: 0, ease: "power1.out", duration: duration }, startTime);
        } else if (type === 'clip-circle-top') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: 'inset(100% 0% 0% 0% round 100% 100% 0 0)' }, { clipPath: 'inset(0% 0% 0% 0% round 0 0 0 0)', ease: "power1.inOut", duration: duration }, startTime);
        } else if (type === 'clip-circle-bottom') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: 'inset(0% 0% 100% 0% round 0 0 100% 100%)' }, { clipPath: 'inset(0% 0% 0% 0% round 0 0 0 0)', ease: "power1.inOut", duration: duration }, startTime);
        } else if (type === 'curve-wipe-left') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: 'inset(0% 0% 0% 100% round 100% 0 0 100%)' }, { clipPath: 'inset(0% 0% 0% 0% round 0 0 0 0)', ease: "power1.inOut", duration: duration }, startTime);
        } else if (type === 'curve-wipe-right') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: 'inset(0% 100% 0% 0% round 0 100% 100% 0)' }, { clipPath: 'inset(0% 0% 0% 0% round 0 0 0 0)', ease: "power1.inOut", duration: duration }, startTime);
        } else if (type === 'pill-expand') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: 'inset(20% 45% 20% 45% round 999px)' }, { clipPath: 'inset(0% 0% 0% 0% round 0px)', ease: "power2.inOut", duration: duration }, startTime);
        } else if (type === 'diagonal-reveal') {
            timeline.fromTo(inEl, { opacity: 1, clipPath: 'polygon(0 0, 0 0, 0 100%, 0 100%)' }, { clipPath: 'polygon(0 0, 100% 0, 100% 100%, 0 100%)', ease: "power1.inOut", duration: duration }, startTime);
        }
        // ── NEW: Shutter scrub (horizontal blinds via clip stepping)
        else if (type === 'shutter-h' || type === 'shutter-v') {
            // For scrub mode use a clip-based approximation (8 equal bands)
            const isV = type === 'shutter-v';
            const BANDS = 8;
            const size = 100 / BANDS;
            const step = duration / BANDS;
            for (let b = 0; b < BANDS; b++) {
                const pct = b * size;
                const clipIn  = isV
                    ? `inset(${pct}% 0% ${100 - pct - size}% 0%)`
                    : `inset(0% ${pct}% 0% ${100 - pct - size}%)`;
                const clipFull = isV
                    ? `inset(${pct}% 0% 0% 0%)`
                    : `inset(0% 0% 0% ${pct}%)`;
                timeline.to(inEl, { clipPath: clipFull, opacity: 1, ease: 'none', duration: step }, startTime + b * step);
            }
            timeline.fromTo(inEl, { opacity: 0, clipPath: isV ? 'inset(100% 0% 0% 0%)' : 'inset(0% 100% 0% 0%)' }, { opacity: 1, clipPath: 'inset(0% 0% 0% 0%)', ease: 'power1.inOut', duration: duration }, startTime);
        }
        // ── NEW: Pixel scrub (scale + opacity stagger approximated via single tween)
        else if (type === 'pixelate') {
            timeline.fromTo(inEl, { opacity: 0, filter: 'blur(20px) brightness(2)' }, { opacity: 1, filter: 'blur(0px) brightness(1)', ease: 'power2.out', duration: duration }, startTime);
            timeline.fromTo(outEl, { opacity: 1, filter: 'blur(0px)' }, { opacity: 0, filter: 'blur(20px) brightness(0.5)', ease: 'power2.in', duration: duration }, startTime);
        }
        // ── NEW: Disintegration scrub (drift + fade out pieces via filter)
        else if (type === 'disintegrate') {
            timeline.fromTo(outEl, { opacity: 1, x: 0, y: 0, filter: 'blur(0px)' }, { opacity: 0, x: 30, y: -20, filter: 'blur(8px)', ease: 'power2.in', duration: duration }, startTime);
            timeline.fromTo(inEl, { opacity: 0 }, { opacity: 1, ease: 'power1.out', duration: duration * 0.5 }, startTime + duration * 0.5);
        }
    };

    // ─────────────────────────────────────────────────────────────────────────
    // MAIN INIT
    // ─────────────────────────────────────────────────────────────────────────
    const initAdvancedParallax = ($scope) => {
        const container = $scope.find('.sifency-parallax-container')[0];
        if (!container) return;

        // Cleanup
        if (typeof ScrollTrigger !== 'undefined') {
            ScrollTrigger.getAll().forEach(st => {
                if (st.trigger === container || container.contains(st.trigger)) {
                    st.kill();
                }
            });
        }
        if (container._sifencyTimer) {
            clearTimeout(container._sifencyTimer);
            container._sifencyTimer = null;
        }

        const wrapper    = container.querySelector('.sifency-parallax-wrapper');
        const allMedia   = container.querySelectorAll('.sifency-parallax-media');

        const speed           = parseFloat(container.dataset.speed || 20);
        const enableScale     = container.dataset.scale === 'true';
        const enableReveal    = container.dataset.reveal === 'true';
        const revealEffect    = container.dataset.revealEffect || 'clip';
        const revealDuration  = parseFloat(container.dataset.revealDuration || 1.25);
        const enableSmoother  = container.dataset.scrollSmoother === 'true';

        // ── NEW: ScrollSmoother depth effect
        if (enableSmoother) {
            initScrollSmootherEffect(container, Array.from(allMedia));
        }

        // 1. Initial Setup
        gsap.set(allMedia, {
            height: `${100 + (speed * 2)}%`,
            top: `-${speed}%`,
            position: 'absolute',
            left: 0,
            width: '100%',
            objectFit: 'cover',
        });

        // 2. Entrance / Reveal Animation
        if (enableReveal) {
            const revealProps = {
                scrollTrigger: {
                    trigger: container,
                    start: "top 85%",
                    end: "top 30%",
                    scrub: 1.5,
                },
                duration: revealDuration,
                ease: "power2.out",
            };

            if (revealEffect === 'fade') {
                gsap.fromTo(wrapper, { autoAlpha: 0, y: 30 }, { autoAlpha: 1, y: 0, ...revealProps });
            } else if (revealEffect === 'slide-up') {
                gsap.fromTo(wrapper, { y: 40, autoAlpha: 0 }, { y: 0, autoAlpha: 1, ...revealProps });
            } else if (revealEffect === 'slide-left') {
                gsap.fromTo(wrapper, { x: 80, autoAlpha: 0 }, { x: 0, autoAlpha: 1, ...revealProps });
            } else if (revealEffect === 'slide-right') {
                gsap.fromTo(wrapper, { x: -80, autoAlpha: 0 }, { x: 0, autoAlpha: 1, ...revealProps });
            } else if (revealEffect === 'zoom') {
                gsap.fromTo(wrapper, { scale: 1.08, autoAlpha: 0 }, { scale: 1, autoAlpha: 1, ...revealProps });
            } else {
                gsap.fromTo(wrapper,
                    { clipPath: "inset(20% 10% 20% 10% round 20px)" },
                    { clipPath: "inset(0% 0% 0% 0% round 0px)", ...revealProps }
                );
            }
        }

        // 3. Data
        const videosData         = container.dataset.videos;
        const imagesData         = container.dataset.images;
        const transitionType     = container.dataset.transition || 'fade';
        const transitionDuration = parseFloat(container.dataset.transitionDuration || 1);
        const scrubTransition    = container.dataset.scrubTransition === 'yes' ||
                                   container.dataset.scrubTransition === 'true' ||
                                   container.dataset.scrubTransition === '1';

        let videoList = null, imageList = null;
        try {
            videoList = videosData ? JSON.parse(videosData) : null;
            imageList = imagesData ? JSON.parse(imagesData) : null;
        } catch (e) {}

        const mediaList     = videoList || imageList;
        const isVideo       = !!videoList;
        const mediaElements = mediaList && mediaList.length > 1
            ? Array.from(container.querySelectorAll(isVideo ? '.sifency-video-item' : '.sifency-image-item'))
            : [];

        // 4. Parallax Timeline
        let parallaxTimeline;

        if (scrubTransition && mediaElements && mediaElements.length > 1) {
            let activeType = transitionType;
            if (activeType === 'liquid') activeType = 'crossfade';

            const totalDuration = 100;

            parallaxTimeline = gsap.timeline({
                scrollTrigger: {
                    trigger: container,
                    start: "top bottom",
                    end: "bottom top",
                    scrub: true,
                    onUpdate: (self) => {
                        if (isVideo) {
                            const total       = mediaElements.length;
                            const activeIndex = Math.min(total - 1, Math.floor(self.progress * total));
                            mediaElements.forEach((el, idx) => {
                                if (idx === activeIndex) {
                                    if (el.paused) el.play().catch(() => {});
                                } else {
                                    if (!el.paused) el.pause();
                                }
                            });
                        }
                    },
                },
            });

            parallaxTimeline.fromTo(mediaElements,
                { yPercent: -speed },
                { yPercent: speed, ease: "none", duration: totalDuration },
                0
            );

            if (enableScale) {
                parallaxTimeline.fromTo(mediaElements,
                    { scale: 1.15 },
                    { scale: 1, ease: "none", duration: totalDuration },
                    0
                );
            }

            // Scrub transitions
            const segment = totalDuration / mediaElements.length;
            mediaElements.forEach((el, idx) => {
                if (idx > 0) {
                    const start    = (idx - 0.8) * segment;
                    const dur      = 0.8 * segment;
                    gsap.set(el, { zIndex: 10 + idx });
                    buildScrubReveal(parallaxTimeline, mediaElements[idx - 1], el, activeType, start, dur);
                } else {
                    gsap.set(el, { opacity: 1, zIndex: 10 });
                }
            });

        } else {
            // Standard single-media parallax
            parallaxTimeline = gsap.timeline({
                scrollTrigger: {
                    trigger: container,
                    start: "top bottom",
                    end: "bottom top",
                    scrub: true,
                },
            });

            parallaxTimeline.fromTo(allMedia,
                { yPercent: -speed },
                { yPercent: speed, ease: "none" },
                0
            );

            if (enableScale) {
                parallaxTimeline.fromTo(allMedia,
                    { scale: 1.15 },
                    { scale: 1, ease: "none" },
                    0
                );
            }
        }

        // 5. Autoplay Sequence (non-scrub mode)
        if (!scrubTransition && mediaList && mediaList.length > 1) {
            try {
                const liquidContainer = container.querySelector('.sifency-fx-container');
                let currentIdx    = 0;
                let liquidInstance = null;

                // Liquid (WebGL) init
                if (transitionType === 'liquid' && !isVideo && liquidContainer && typeof hoverEffect !== 'undefined') {
                    const ratio = (liquidContainer.offsetHeight / liquidContainer.offsetWidth) || 1.0;
                    liquidInstance = new hoverEffect({
                        parent: liquidContainer,
                        intensity: parseFloat(container.dataset.intensity || 0.2),
                        image1: mediaList[0].url,
                        image2: mediaList[1].url,
                        displacementImage: container.dataset.disp,
                        imagesRatio: ratio,
                        speedIn: transitionDuration,
                        speedOut: transitionDuration,
                        hover: false,
                    });
                    allMedia.forEach(el => {
                        if (el !== liquidContainer) gsap.set(el, { opacity: 0, visibility: 'hidden' });
                    });
                    gsap.set(liquidContainer, { opacity: 1, visibility: 'visible', zIndex: 10, overflow: 'hidden' });
                    const canvas = liquidContainer.querySelector('canvas');
                    if (canvas) {
                        gsap.set(canvas, { width: '100%', height: '100%', position: 'absolute', top: 0, left: 0, objectFit: 'cover' });
                    }
                }

                // ── performTransition now dispatches new types too
                const performTransition = (outEl, inEl, type, dur, onDone) => {

                    // Liquid
                    if (type === 'liquid' && liquidInstance) {
                        liquidInstance.next();
                        setTimeout(() => {
                            const nextIdx     = (currentIdx + 1) % mediaList.length;
                            const nextNextIdx = (currentIdx + 2) % mediaList.length;
                            const loader = new THREE.TextureLoader();
                            liquidInstance.material.uniforms.texture1.value = loader.load(mediaList[nextIdx].url);
                            liquidInstance.material.uniforms.texture2.value = loader.load(mediaList[nextNextIdx].url);
                            liquidInstance.material.uniforms.dispFactor.value = 0;
                            onDone();
                        }, dur * 1000);
                        return;
                    }

                    // ── NEW: Pixelated
                    if (type === 'pixelate') {
                        performPixelTransition(outEl, inEl, dur, onDone);
                        return;
                    }

                    // ── NEW: Disintegration
                    if (type === 'disintegrate') {
                        performDisintegrationTransition(outEl, inEl, dur, onDone);
                        return;
                    }

                    // ── NEW: Shutter Vertical
                    if (type === 'shutter-v') {
                        performShutterTransition(outEl, inEl, dur, 'vertical', onDone);
                        return;
                    }

                    // ── NEW: Shutter Horizontal
                    if (type === 'shutter-h') {
                        performShutterTransition(outEl, inEl, dur, 'horizontal', onDone);
                        return;
                    }

                    // All existing transitions
                    const tl = gsap.timeline({
                        onComplete: () => {
                            gsap.set(outEl, { opacity: 0 });
                            if (isVideo) outEl.pause();
                            onDone();
                        },
                    });

                    gsap.set(inEl,  { opacity: 0, zIndex: 12, clipPath: "none", xPercent: 0, yPercent: 0, scale: 1, rotationY: 0 });
                    gsap.set(outEl, { zIndex: 11 });

                    if (type === 'fade' || type === 'crossfade') {
                        gsap.set(inEl, { opacity: 0, zIndex: 12 });
                        if (type === 'crossfade') tl.to(outEl, { opacity: 0, duration: dur, ease: "power2.inOut" }, 0);
                        tl.to(inEl, { opacity: 1, duration: dur, ease: "power2.inOut" }, 0);
                    } else if (type === 'fade-up') {
                        gsap.set(inEl, { opacity: 0, yPercent: 30 });
                        tl.to(inEl, { opacity: 1, yPercent: 0, duration: dur, ease: "power2.out" });
                    } else if (type === 'clip-vertical') {
                        gsap.set(inEl, { opacity: 1, clipPath: "inset(100% 0% 0% 0%)" });
                        tl.to(inEl, { clipPath: "inset(0% 0% 0% 0%)", duration: dur, ease: "expo.inOut" });
                    } else if (type === 'clip-horizontal') {
                        gsap.set(inEl, { opacity: 1, clipPath: "inset(0% 0% 0% 100%)" });
                        tl.to(inEl, { clipPath: "inset(0% 0% 0% 0%)", duration: dur, ease: "expo.inOut" });
                    } else if (type === 'wipe-down') {
                        gsap.set(inEl, { opacity: 1, clipPath: "inset(0% 0% 100% 0%)" });
                        tl.to(inEl, { clipPath: "inset(0% 0% 0% 0%)", duration: dur, ease: "expo.inOut" });
                    } else if (type === 'circle') {
                        gsap.set(inEl, { opacity: 1, clipPath: "circle(0% at 50% 50%)" });
                        tl.to(inEl, { clipPath: "circle(100% at 50% 50%)", duration: dur, ease: "expo.inOut" });
                    } else if (type === 'zoom') {
                        gsap.set(inEl, { opacity: 1, scale: 1.25 });
                        tl.fromTo(inEl, { scale: 1.25, opacity: 0 }, { scale: 1, opacity: 1, duration: dur, ease: "power2.out" });
                    } else if (type === 'swipe-left') {
                        gsap.set(inEl, { opacity: 1, xPercent: 100 });
                        tl.to(inEl, { xPercent: 0, duration: dur, ease: "power2.out" });
                    } else if (type === 'swipe-right') {
                        gsap.set(inEl, { opacity: 1, xPercent: -100 });
                        tl.to(inEl, { xPercent: 0, duration: dur, ease: "power2.out" });
                    } else if (type === 'flip') {
                        gsap.set(inEl, { opacity: 1, rotationY: 90, transformStyle: "preserve-3d", transformPerspective: 800 });
                        tl.to(inEl, { rotationY: 0, duration: dur, ease: "back.out(1.4)" });
                    } else if (type === 'clip-circle-top') {
                        gsap.set(inEl, { opacity: 1, clipPath: 'inset(100% 0% 0% 0% round 100% 100% 0 0)' });
                        tl.to(inEl, { clipPath: 'inset(0% 0% 0% 0% round 0 0 0 0)', duration: dur, ease: "power2.inOut" });
                    } else if (type === 'clip-circle-bottom') {
                        gsap.set(inEl, { opacity: 1, clipPath: 'inset(0% 0% 100% 0% round 0 0 100% 100%)' });
                        tl.to(inEl, { clipPath: 'inset(0% 0% 0% 0% round 0 0 0 0)', duration: dur, ease: "power2.inOut" });
                    } else if (type === 'curve-wipe-left') {
                        gsap.set(inEl, { opacity: 1, clipPath: 'inset(0% 0% 0% 100% round 100% 0 0 100%)' });
                        tl.to(inEl, { clipPath: 'inset(0% 0% 0% 0% round 0 0 0 0)', duration: dur, ease: "power2.inOut" });
                    } else if (type === 'curve-wipe-right') {
                        gsap.set(inEl, { opacity: 1, clipPath: 'inset(0% 100% 0% 0% round 0 100% 100% 0)' });
                        tl.to(inEl, { clipPath: 'inset(0% 0% 0% 0% round 0 0 0 0)', duration: dur, ease: "power2.inOut" });
                    } else if (type === 'pill-expand') {
                        gsap.set(inEl, { opacity: 1, clipPath: 'inset(20% 45% 20% 45% round 999px)' });
                        tl.to(inEl, { clipPath: 'inset(0% 0% 0% 0% round 0px)', duration: dur, ease: "power2.inOut" });
                    } else if (type === 'diagonal-reveal') {
                        gsap.set(inEl, { opacity: 1, clipPath: 'polygon(0 0, 0 0, 0 100%, 0 100%)' });
                        tl.to(inEl, { clipPath: 'polygon(0 0, 100% 0, 100% 100%, 0 100%)', duration: dur, ease: "power2.inOut" });
                    }
                };

                const playNext = () => {
                    const prevIdx = currentIdx;
                    currentIdx = (currentIdx + 1) % mediaElements.length;
                    const outEl = mediaElements[prevIdx];
                    const inEl  = mediaElements[currentIdx];

                    if (isVideo) {
                        inEl.play().then(() => {
                            performTransition(outEl, inEl, transitionType, transitionDuration, () => {
                                startSequenceTimer(mediaList[currentIdx].duration);
                            });
                        }).catch(() => {
                            performTransition(outEl, inEl, transitionType, transitionDuration, () => {
                                startSequenceTimer(mediaList[currentIdx].duration);
                            });
                        });
                    } else {
                        if (transitionType === 'liquid') {
                            performTransition(null, null, 'liquid', transitionDuration, () => {
                                startSequenceTimer(mediaList[currentIdx].duration);
                            });
                        } else {
                            performTransition(outEl, inEl, transitionType, transitionDuration, () => {
                                startSequenceTimer(mediaList[currentIdx].duration);
                            });
                        }
                    }
                };

                const startSequenceTimer = (duration) => {
                    if (container._sifencyTimer) clearTimeout(container._sifencyTimer);
                    container._sifencyTimer = setTimeout(playNext, (duration || 3) * 1000);
                };

                mediaElements.forEach((el, index) => {
                    if (index === 0) {
                        gsap.set(el, { opacity: 1, zIndex: 10 });
                        if (isVideo) el.play().catch(() => {});
                    } else {
                        gsap.set(el, { opacity: 0, zIndex: 9 });
                        if (isVideo) el.pause();
                    }
                });
                startSequenceTimer(mediaList[0].duration);

            } catch (e) {
                console.error("Autoplay Sequence Error:", e);
            }
        }
    };

    $(window).on('elementor/frontend/init', function () {
        elementorFrontend.hooks.addAction(
            'frontend/element_ready/sifency-advanced-parallax.default',
            initAdvancedParallax
        );
    });

})(jQuery);