HEX
Server: nginx/1.18.0
System: Linux vcwordpress 5.15.0-174-generic #184-Ubuntu SMP Fri Mar 13 18:41:50 UTC 2026 x86_64
User: root (0)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/viitorx.stgviitor.com/wp-content/themes/viitorx/js/offerings-animate.js
/**
 * Offerings page — GSAP scroll-driven animations.
 * Replaces the flat CSS section-reveal for offering/visual/contact sections.
 * Runs after front-page-animations.js (GSAP + Lenis bridge already initialised).
 *
 * Pattern: gsap.set() initial states on load → ScrollTrigger.create({ onEnter })
 * → gsap.to() inside onEnter. No lenis.resize() during scroll, no extra
 * ScrollTrigger.refresh() — front-page-animations.js handles both.
 */
(function () {
    'use strict';

    if (!document.body.classList.contains('offerings-page')) return;
    if (typeof gsap === 'undefined' || typeof ScrollTrigger === 'undefined') return;
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;

    gsap.registerPlugin(ScrollTrigger);

    /* ── HELPERS ──────────────────────────────────────────────── */

    /** Collect all matrix slot elements sorted in reading order (row → column). */
    function getMatrixCellsOrdered(matrix) {
        if (!matrix) return [];
        var cells = [];

        matrix.querySelectorAll('[class*="offering-matrix__slot--"]').forEach(function (el) {
            var cls = el.className;
            var row = 0, col = 0;
            var hMatch = cls.match(/slot--head-c(\d)/);
            var rMatch = cls.match(/slot--r(\d+)-c(\d)/);
            if (hMatch)       { row = 0; col = parseInt(hMatch[1], 10); }
            else if (rMatch)  { row = parseInt(rMatch[1], 10); col = parseInt(rMatch[2], 10); }
            cells.push({ el: el, row: row, col: col });
        });

        cells.sort(function (a, b) { return a.row !== b.row ? a.row - b.row : a.col - b.col; });
        return cells.map(function (c) { return c.el; });
    }

    /* ── OFFERING CONTENT SECTIONS ─────────────────────────────── */
    document.querySelectorAll('.offering[data-section-reveal]').forEach(function (section) {
        var headerEls = gsap.utils.toArray(section.querySelectorAll('.offering__header > *'));
        var allCells  = getMatrixCellsOrdered(section.querySelector('.offering-matrix'));

        /* Set invisible initial states synchronously so elements never flash. */
        if (headerEls.length) gsap.set(headerEls, { opacity: 0, y: 44 });
        if (allCells.length)  gsap.set(allCells,  { opacity: 0, y: 16 });

        ScrollTrigger.create({
            trigger: section,
            start: 'top 82%',
            once: true,
            onEnter: function () {
                var tl = gsap.timeline();
                var cellOffset = headerEls.length ? 0.28 : 0;

                if (headerEls.length) {
                    tl.to(headerEls, {
                        opacity: 1,
                        y: 0,
                        duration: 0.92,
                        stagger: 0.13,
                        ease: 'power3.out',
                    }, 0);
                }

                /* Single unified wave: all cells in reading order (row → col). */
                if (allCells.length) {
                    tl.to(allCells, {
                        opacity: 1,
                        y: 0,
                        duration: 0.62,
                        stagger: 0.038,
                        ease: 'power3.out',
                    }, cellOffset);
                }
            },
        });
    });

    /* ── FULL-WIDTH VISUAL IMAGES ───────────────────────────────── */
    document.querySelectorAll('.visual[data-section-reveal]').forEach(function (section) {
        var img = section.querySelector('.visual__img');
        if (!img) return;

        gsap.set(img, { opacity: 0, scale: 1.045 });

        ScrollTrigger.create({
            trigger: section,
            start: 'top 88%',
            once: true,
            onEnter: function () {
                gsap.to(img, {
                    opacity: 1,
                    scale: 1,
                    duration: 1.4,
                    ease: 'power2.out',
                });
            },
        });
    });

    /* ── CONTACT SECTION: left slides from left, right from right ─ */
    var contactSection = document.querySelector('.contact[data-section-reveal]');
    if (contactSection) {
        var leftItems  = gsap.utils.toArray(contactSection.querySelectorAll('.contact__left > *'));
        var rightItems = gsap.utils.toArray(contactSection.querySelectorAll('.contact__right > *'));

        if (leftItems.length)  gsap.set(leftItems,  { opacity: 0, x: -44 });
        if (rightItems.length) gsap.set(rightItems, { opacity: 0, x:  44 });

        ScrollTrigger.create({
            trigger: contactSection,
            start: 'top 82%',
            once: true,
            onEnter: function () {
                var tl = gsap.timeline();
                if (leftItems.length) {
                    tl.to(leftItems, {
                        opacity: 1,
                        x: 0,
                        duration: 0.9,
                        stagger: 0.11,
                        ease: 'power3.out',
                    }, 0);
                }
                if (rightItems.length) {
                    tl.to(rightItems, {
                        opacity: 1,
                        x: 0,
                        duration: 0.9,
                        stagger: 0.11,
                        ease: 'power3.out',
                    }, 0.2);
                }
            },
        });
    }

})();