/**
 * Shois Chat Button — Widget Core
 *
 * The main frontend widget. Pure vanilla JS — no React, no jQuery.
 * Target: < 10KB gzipped.
 *
 * @package ShoisChatButton
 */
(function () {
    'use strict';

    var config = window.shcb_config;
    if (!config || config.disabled) {
        return;
    }

    /* ───── SCB Renderer ───────────────────────────────── */

    var SCBRenderer = {

        /**
         * Build the complete widget HTML.
         *
         * @param {Object} cfg The shcb_config object.
         * @return {string} HTML string.
         */
        build: function (cfg) {
            var pos = cfg.position || 'bottom-right';
            var tpl = cfg.template_slug || 'classic-green';
            var agents = cfg.agents || [];
            var platforms = cfg.platforms || [];
            var content = cfg.content || {};
            var badge = cfg.badge || {};

            // Resolve dynamic variables in content fields.
            var vars = cfg.variables || {};
            // Enrich with client-side values for accuracy on cached pages.
            vars.page_title = document.title || vars.page_title || '';
            vars.current_url = window.location.href || vars.current_url || '';

            var rv = window.SCBPlatformLinks ? window.SCBPlatformLinks.resolveVariables : function (s) { return s || ''; };
            content = {
                header_title: rv(content.header_title, vars),
                header_subtitle: rv(content.header_subtitle, vars),
                welcome_message: rv(content.welcome_message, vars),
                offline_message: rv(content.offline_message, vars),
                tooltip_text: rv(content.tooltip_text, vars),
                label_text: rv(content.label_text, vars),
                brand_logo: content.brand_logo || '',
                show_label: content.show_label,
                aria_label: content.aria_label || 'Chat widget',
                trigger_aria: content.trigger_aria || 'Open chat',
                popup_aria: content.popup_aria || 'Chat options',
                next_available: content.next_available || '',
                footer_text: rv(content.footer_text, vars),
            };

            var html = '';

            // Widget root.
            html += '<div id="shcb-widget"';
            html += ' class="shcb-widget shcb-pos-' + this.esc(pos) + ' shcb-template-' + this.esc(tpl) + '"';
            if (content.show_label) {
                html += ' data-show-label="true"';
            }
            html += ' role="complementary"';
            html += ' aria-label="' + this.esc(content.aria_label || 'Chat widget') + '">';

            // Trigger button.
            html += '<button id="shcb-trigger"';
            html += ' class="shcb-trigger-btn"';
            html += ' aria-label="' + this.esc(content.trigger_aria || 'Open chat') + '"';
            html += ' aria-expanded="false"';
            html += ' aria-controls="shcb-popup">';

            html += '<span class="shcb-trigger-icon">' + (cfg.trigger_icon_svg || '') + '</span>';

            if (content.show_label && content.label_text) {
                html += '<span class="shcb-trigger-label">' + this.esc(content.label_text) + '</span>';
            }

            if (badge.enabled) {
                html += '<span class="shcb-badge" aria-label="' + this.esc(badge.value || '1') + '">';
                html += this.esc(badge.value || '1');
                html += '</span>';
            }

            var anims = cfg.animations || {};
            var enablePulse = anims.enable_pulse_ring;
            if (enablePulse === undefined || (enablePulse !== false && enablePulse !== 0 && enablePulse !== '0' && enablePulse !== 'false')) {
                html += '<span class="shcb-pulse-ring" aria-hidden="true"></span>';
            }
            html += '</button>';

            // Popup.
            html += '<div id="shcb-popup"';
            html += ' class="shcb-popup shcb-hidden"';
            html += ' role="dialog"';
            html += ' aria-modal="true"';
            html += ' aria-label="' + this.esc(content.popup_aria || 'Chat options') + '"';
            html += ' aria-hidden="true">';

            // Popup header.
            html += '<div class="shcb-popup-header">';

            if (content.brand_logo) {
                html += '<img class="shcb-brand-logo" src="' + this.esc(content.brand_logo) + '" alt="" loading="lazy">';
            }

            html += '<div class="shcb-header-text">';
            html += '<div class="shcb-header-title">' + this.esc(content.header_title || 'Chat with us! 👋') + '</div>';

            if (content.header_subtitle) {
                html += '<div class="shcb-header-subtitle">' + this.esc(content.header_subtitle) + '</div>';
            }

            html += '</div>'; // .shcb-header-text

            html += '<button class="shcb-close-btn" aria-label="Close chat">';
            html += '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 1l12 12M13 1L1 13"/></svg>';
            html += '</button>';
            html += '</div>'; // .shcb-popup-header

            // Popup body.
            html += '<div class="shcb-popup-body">';

            if (content.welcome_message) {
                html += '<div class="shcb-welcome-message">';
                html += '<p>' + this.esc(content.welcome_message) + '</p>';
                html += '</div>';
            }

            // Quick reply chips.
            if (cfg.chips && cfg.chips.length) {
                html += '<div class="shcb-chips" role="list">';
                for (var c = 0; c < cfg.chips.length; c++) {
                    var chip = cfg.chips[c];
                    html += '<button class="shcb-chip" role="listitem"';
                    html += ' data-message="' + this.esc(chip.message || chip.label) + '">';
                    if (chip.emoji) {
                        html += '<span class="shcb-chip-emoji">' + this.esc(chip.emoji) + '</span> ';
                    }
                    html += this.esc(chip.label);
                    html += '</button>';
                }
                html += '</div>';
            }

            html += '</div>'; // .shcb-popup-body

            // Agents section.
            html += '<div class="shcb-agents">';

            if (agents.length > 0) {
                for (var a = 0; a < agents.length; a++) {
                    var agent = agents[a];
                    if (agent.platforms && agent.platforms.length) {
                        for (var p = 0; p < agent.platforms.length; p++) {
                            if (agent.platforms[p].enabled) {
                                html += this.buildAgentCard(agent, agent.platforms[p], cfg);
                            }
                        }
                    }
                }
            } else if (platforms.length > 0) {
                // No agents — just show platform buttons directly.
                html += '<div class="shcb-platforms-direct">';
                for (var p = 0; p < platforms.length; p++) {
                    html += this.buildPlatformButton(platforms[p], null, cfg);
                }
                html += '</div>';
            }

            html += '</div>'; // .shcb-agents

            // Offline state (hidden by default).
            html += '<div class="shcb-offline-state" hidden>';
            html += '<p class="shcb-offline-message">' + this.esc(content.offline_message || 'We\'re currently offline.') + '</p>';

            if (content.next_available) {
                html += '<p class="shcb-next-available">' + this.esc(content.next_available) + '</p>';
            }

            html += '</div>';

            // Popup footer.
            var footerText = (typeof content.footer_text !== 'undefined' && content.footer_text !== null) ? content.footer_text : 'Powered by Shois Chat Button';
            html += '<div class="shcb-popup-footer">';
            html += '<span class="shcb-powered-by">' + this.esc(footerText) + '</span>';
            html += '</div>';

            html += '</div>'; // .shcb-popup
            html += '</div>'; // .shcb-widget

            return html;
        },

        /**
         * Build an agent card for a specific platform.
         *
         * @param {Object} agent    Agent data.
         * @param {Object} platform Platform data.
         * @param {Object} cfg      Widget config.
         * @return {string} HTML string.
         */
        buildAgentCard: function (agent, platform, cfg) {
            var html = '';
            html += '<div class="shcb-agent-card" data-agent-id="' + this.esc(agent.id) + '"';
            html += ' data-platform-id="' + this.esc(platform.platform_id || '') + '">';

            // Avatar.
            html += '<div class="shcb-agent-avatar-wrap">';
            if (agent.avatar_type === 'initials') {
                html += '<div class="shcb-agent-avatar shcb-avatar-initials"';
                html += ' style="background-color:' + this.esc(agent.avatar_bg_color || '#25D366') + '">';
                html += this.esc(agent.avatar_initials || 'U');
                html += '</div>';
            } else if (agent.avatar_url) {
                html += '<img class="shcb-agent-avatar" src="' + this.esc(agent.avatar_url) + '"';
                html += ' alt="' + this.esc(agent.name) + '" loading="lazy">';
            } else {
                html += '<div class="shcb-agent-avatar shcb-avatar-initials"';
                html += ' style="background-color:' + this.esc(agent.avatar_bg_color || '#25D366') + '">';
                html += this.esc((agent.name || 'U').charAt(0).toUpperCase());
                html += '</div>';
            }
            html += '</div>';

            // Info.
            html += '<div class="shcb-agent-info">';
            html += '<div class="shcb-agent-name">' + this.esc(agent.name) + '</div>';

            if (agent.title) {
                html += '<div class="shcb-agent-title">' + this.esc(agent.title) + '</div>';
            }

            html += '<div class="shcb-agent-status">';
            var statusClass = agent.available ? 'shcb-status-online' : 'shcb-status-offline';
            html += '<span class="shcb-status-dot ' + statusClass + '"></span>';
            html += '<span>' + this.esc(agent.status_message || (agent.available ? 'Online now' : 'Offline')) + '</span>';
            html += '</div>';
            html += '</div>'; // .shcb-agent-info

            // Single platform button for this card.
            if (platform) {
                html += '<div class="shcb-agent-platforms">';
                html += this.buildPlatformButton(platform, agent, cfg);
                html += '</div>';
            }

            html += '</div>'; // .shcb-agent-card
            return html;
        },

        /**
         * Build a platform button link.
         *
         * @param {Object}      plat  Platform contact data.
         * @param {Object|null} agent Agent data (or null).
         * @param {Object}      cfg   Widget config.
         * @return {string} HTML string.
         */
        buildPlatformButton: function (plat, agent, cfg) {
            var platformDef = null;
            var allPlatforms = cfg.platform_defs || {};

            if (allPlatforms[plat.platform_id]) {
                platformDef = allPlatforms[plat.platform_id];
            }

            if (!platformDef) {
                return '';
            }

            var url = window.SCBPlatformLinks
                ? window.SCBPlatformLinks.build(platformDef, plat.value, plat.pre_message || '', cfg.variables || {})
                : '#';

            var label = plat.label || ('Chat on ' + platformDef.name);

            var html = '<a class="shcb-platform-btn shcb-platform-' + this.esc(plat.platform_id) + '"';
            html += ' href="' + this.esc(url) + '"';
            html += ' target="' + (cfg.behavior && cfg.behavior.open_in === 'same' ? '_self' : '_blank') + '"';
            html += ' rel="noopener noreferrer"';
            html += ' aria-label="' + this.esc(label) + '"';
            html += ' data-platform="' + this.esc(plat.platform_id) + '"';
            html += ' data-agent="' + this.esc(agent ? agent.id : '') + '"';
            html += ' style="--shcb-platform-color:' + this.esc(platformDef.color) + '">';
            html += '<span class="shcb-platform-icon">' + (platformDef.icon_svg || '') + '</span>';
            html += '<span class="shcb-platform-name">' + this.esc(platformDef.name) + '</span>';
            html += '</a>';

            return html;
        },

        /**
         * Escape HTML special characters.
         *
         * @param {string} str Input string.
         * @return {string} Escaped string.
         */
        esc: function (str) {
            if (!str) return '';
            var div = document.createElement('div');
            div.textContent = String(str);
            return div.innerHTML;
        },
    };

    /* ───── SCB Widget ─────────────────────────────────── */

    var Widget = {
        isOpen: false,
        el: null,
        trigger: null,
        popup: null,
        tracker: null,

        /**
         * Initialize the widget.
         */
        init: function () {
            if (!this.shouldShow()) {
                return;
            }

            this.render();
            this.bindEvents();

            // Initialize tracker.
            if (window.SCBTracker) {
                this.tracker = new window.SCBTracker(config);
                this.tracker.trackImpression();
            }

            // Handle auto-open.
            this.handleAutoOpen();

            // Handle delay.
            this.handleDelayTimer();

            // Handle scroll trigger.
            this.handleScrollTrigger();

            // Check availability.
            this.checkAvailability();

            // Initialize animations.
            if (window.SCBAnimationEngine && config.animations) {
                this.animEngine = new window.SCBAnimationEngine(config.animations);
                this.animEngine.init();
            }
        },

        /**
         * Whether the widget should be shown.
         *
         * @return {boolean}
         */
        shouldShow: function () {
            var behavior = config.behavior || {};

            // Check if widget was recently closed and "remember closed" is on.
            if (behavior.remember_closed) {
                try {
                    var closedAt = localStorage.getItem('shcb_closed');
                    if (closedAt && (Date.now() - parseInt(closedAt, 10)) < 86400000) {
                        return false;
                    }
                } catch (e) {
                    // localStorage not available.
                }
            }

            return true;
        },

        /**
         * Render the widget HTML into the DOM.
         */
        render: function () {
            var html = SCBRenderer.build(config);
            var container = document.createElement('div');
            container.innerHTML = html;
            document.body.appendChild(container.firstChild);

            this.el = document.getElementById('shcb-widget');
            this.trigger = document.getElementById('shcb-trigger');
            this.popup = document.getElementById('shcb-popup');

            // Handle initial visibility (delay, scroll trigger).
            var behavior = config.behavior || {};
            if (behavior.show_after_delay || behavior.show_after_scroll) {
                this.el.style.opacity = '0';
                this.el.style.pointerEvents = 'none';
            }
        },

        /**
         * Bind all event listeners.
         */
        bindEvents: function () {
            var self = this;

            // Trigger click.
            this.trigger.addEventListener('click', function (e) {
                e.stopPropagation();
                self.toggle();
            });

            // Close button.
            var closeBtn = this.popup.querySelector('.shcb-close-btn');
            if (closeBtn) {
                closeBtn.addEventListener('click', function (e) {
                    e.stopPropagation();
                    self.close();
                });
            }

            // Close on outside click.
            var behavior = config.behavior || {};
            if (behavior.close_on_outside_click !== false) {
                document.addEventListener('click', function (e) {
                    if (self.isOpen && !self.el.contains(e.target) && !self.trigger.contains(e.target)) {
                        self.close();
                    }
                });
            }

            // Escape key.
            document.addEventListener('keydown', function (e) {
                if (e.key === 'Escape' && self.isOpen) {
                    self.close();
                }
            });

            // Platform link clicks.
            var platformBtns = this.popup.querySelectorAll('[data-platform]');
            for (var i = 0; i < platformBtns.length; i++) {
                platformBtns[i].addEventListener('click', function (e) {
                    if (self.tracker) {
                        self.tracker.trackPlatformClick(
                            e.currentTarget.getAttribute('data-platform'),
                            e.currentTarget.getAttribute('data-agent')
                        );
                    }
                });
            }

            // Quick reply chips.
            var chips = this.popup.querySelectorAll('.shcb-chip');
            for (var c = 0; c < chips.length; c++) {
                chips[c].addEventListener('click', function (e) {
                    var msg = e.currentTarget.getAttribute('data-message');
                    self.activatePrimaryPlatform(msg);
                });
            }

            // Delegate agent card clicks for maximum reliability across templates
            if (this.popup) {
                this.popup.addEventListener('click', function (e) {
                    var agentCard = e.target.closest('.shcb-agent-card');
                    if (!agentCard) return;

                    // Do not ripple if they directly clicked the platform link itself
                    if (e.target.closest('.shcb-platform-btn') || e.target.closest('.shcb-chip')) {
                        return;
                    }

                    // ID-based lookup — find the agent and the SPECIFIC platform for this card.
                    var agentId = agentCard.getAttribute('data-agent-id');
                    var clickedPlatformId = agentCard.getAttribute('data-platform-id');
                    var agents = config.agents || [];
                    var agent = agents.find(function (a) { return a.id == agentId; });

                    if (agent) {
                        var platforms = agent.platforms || [];
                        var plat = null;

                        // Find the EXACT platform that matches this card.
                        if (clickedPlatformId) {
                            plat = platforms.find(function (p) {
                                return p.platform_id === clickedPlatformId && p.enabled;
                            });
                        }

                        // Fallback to first enabled platform if no match.
                        if (!plat) {
                            for (var fp = 0; fp < platforms.length; fp++) {
                                if (platforms[fp].enabled) {
                                    plat = platforms[fp];
                                    break;
                                }
                            }
                        }

                        if (plat) {
                            var platformDef = (config.platform_defs || {})[plat.platform_id];

                            if (platformDef && window.SCBPlatformLinks) {
                                var behavior = config.behavior || {};
                                var newTab = behavior.open_in !== 'same';

                                window.SCBPlatformLinks.open(
                                    platformDef,
                                    plat.value,
                                    plat.pre_message || '',
                                    config.variables || {},
                                    newTab
                                );

                                if (self.tracker) {
                                    self.tracker.trackPlatformClick(platformDef.id, agentId);
                                }
                                return;
                            }
                        }
                    }

                    // Fallback to searching for ANY platform button in the card if ID-based lookup fails.
                    var firstBtn = agentCard.querySelector('.shcb-platform-btn');
                    if (firstBtn && window.SCBPlatformLinks) {
                        var platId = firstBtn.getAttribute('data-platform');
                        var btnAgentId = firstBtn.getAttribute('data-agent');
                        var platformDef = (config.platform_defs || {})[platId];

                        // Find platform data in config.
                        var pAgent = agents.find(function(a) { return a.id == (btnAgentId || agentId); });
                        var pData = pAgent ? pAgent.platforms.find(function(p) { return p.platform_id == platId; }) : null;

                        if (pData) {
                            window.SCBPlatformLinks.open(
                                platformDef,
                                pData.value,
                                pData.pre_message || '',
                                config.variables || {},
                                config.behavior.open_in !== 'same'
                            );
                        }
                    }
                });
            }
        },

        /**
         * Toggle popup open/close.
         */
        toggle: function () {
            if (this.isOpen) {
                this.close();
            } else {
                this.open();
            }
        },

        /**
         * Open the popup.
         */
        open: function () {
            if (this.closeListener) {
                this.popup.removeEventListener('transitionend', this.closeListener);
                this.closeListener = null;
            }
            this.isOpen = true;
            this.trigger.setAttribute('aria-expanded', 'true');
            this.popup.classList.remove('shcb-hidden');
            this.popup.removeAttribute('aria-hidden');

            // Animate open.
            var self = this;
            requestAnimationFrame(function () {
                self.popup.classList.add('shcb-popup-visible');
                if (self.animEngine) {
                    self.animEngine.pauseIdle();
                    self.animEngine.animatePlatformIcons(self.popup);
                }
            });

            if (this.tracker) {
                this.tracker.trackButtonClick();
            }

            // Focus management — focus first interactive element in popup.
            var self2 = this;
            setTimeout(function () {
                var first = self2.popup.querySelector('button, a, [tabindex]');
                if (first) {
                    first.focus();
                }
            }, 50);
        },

        /**
         * Close the popup.
         */
        close: function () {
            this.isOpen = false;
            this.trigger.setAttribute('aria-expanded', 'false');
            this.popup.setAttribute('aria-hidden', 'true');
            this.popup.classList.remove('shcb-popup-visible');

            if (this.closeListener) {
                this.popup.removeEventListener('transitionend', this.closeListener);
            }

            var self = this;
            this.closeListener = function (e) {
                if (e && e.target !== self.popup) return;
                self.popup.classList.add('shcb-hidden');
                self.popup.removeEventListener('transitionend', self.closeListener);
                self.closeListener = null;
                if (self.animEngine) {
                    self.animEngine.resumeIdle();
                }
            };
            this.popup.addEventListener('transitionend', this.closeListener);

            // Fallback if transition doesn't fire.
            setTimeout(function () {
                if (!self.popup.classList.contains('shcb-hidden')) {
                    self.popup.classList.add('shcb-hidden');
                }
            }, 400);

            // Return focus.
            this.trigger.focus();

            // Remember closed state.
            var behavior = config.behavior || {};
            if (behavior.remember_closed) {
                try {
                    localStorage.setItem('shcb_closed', Date.now().toString());
                } catch (e) {
                    // Ignore.
                }
            }
        },

        /**
         * Activate the primary platform with a pre-filled message.
         *
         * @param {string} message Pre-filled message from chip click.
         */
        activatePrimaryPlatform: function (message) {
            // Find the first primary platform.
            var agents = config.agents || [];
            var agentPlatform = null;
            var agentData = null;

            for (var a = 0; a < agents.length; a++) {
                var plats = agents[a].platforms || [];
                for (var p = 0; p < plats.length; p++) {
                    if (plats[p].is_primary && plats[p].enabled) {
                        agentPlatform = plats[p];
                        agentData = agents[a];
                        break;
                    }
                }
                if (agentPlatform) break;
            }

            // Fallback to first enabled platform.
            if (!agentPlatform) {
                for (var a2 = 0; a2 < agents.length; a2++) {
                    var plats2 = agents[a2].platforms || [];
                    for (var p2 = 0; p2 < plats2.length; p2++) {
                        if (plats2[p2].enabled) {
                            agentPlatform = plats2[p2];
                            agentData = agents[a2];
                            break;
                        }
                    }
                    if (agentPlatform) break;
                }
            }

            // Also check direct platforms.
            if (!agentPlatform) {
                var directPlats = config.platforms || [];
                for (var d = 0; d < directPlats.length; d++) {
                    if (directPlats[d].enabled) {
                        agentPlatform = directPlats[d];
                        break;
                    }
                }
            }

            if (agentPlatform && window.SCBPlatformLinks) {
                var platformDef = (config.platform_defs || {})[agentPlatform.platform_id];
                if (platformDef) {
                    var behavior = config.behavior || {};
                    var newTab = behavior.open_in !== 'same';
                    window.SCBPlatformLinks.open(
                        platformDef,
                        agentPlatform.value,
                        message || agentPlatform.pre_message || '',
                        config.variables || {},
                        newTab
                    );

                    if (this.tracker) {
                        this.tracker.trackPlatformClick(
                            agentPlatform.platform_id,
                            agentData ? agentData.id : ''
                        );
                    }
                }
            }
        },

        /**
         * Check agent/widget availability based on schedule.
         */
        checkAvailability: function () {
            var schedule = config.schedule;

            if (!schedule || !schedule.enabled) {
                return;
            }

            var available = this.computeAvailability(schedule);

            if (!available) {
                this.el.classList.add('shcb-offline');
                var agentsDiv = this.popup.querySelector('.shcb-agents');
                var offlineDiv = this.popup.querySelector('.shcb-offline-state');

                if (agentsDiv) {
                    agentsDiv.hidden = true;
                }
                if (offlineDiv) {
                    offlineDiv.hidden = false;
                }
            }
        },

        /**
         * Compute availability from schedule data.
         *
         * @param {Object} schedule Schedule object.
         * @return {boolean} Whether currently available.
         */
        computeAvailability: function (schedule) {
            if (!schedule || !schedule.enabled) {
                return true;
            }

            var tz;
            try {
                tz = schedule.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone;
            } catch (e) {
                tz = 'UTC';
            }

            var now;
            try {
                now = new Date(new Date().toLocaleString('en-US', { timeZone: tz }));
            } catch (e) {
                now = new Date();
            }

            var days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
            var day = days[now.getDay()];
            var hours = (schedule.hours || {})[day] || [];

            if (!hours.length) {
                return false;
            }

            var curr = now.getHours() * 60 + now.getMinutes();

            for (var i = 0; i < hours.length; i++) {
                var parts_s = hours[i].start.split(':');
                var parts_e = hours[i].end.split(':');
                var start = parseInt(parts_s[0], 10) * 60 + parseInt(parts_s[1], 10);
                var end = parseInt(parts_e[0], 10) * 60 + parseInt(parts_e[1], 10);

                if (curr >= start && curr < end) {
                    return true;
                }
            }

            return false;
        },

        /**
         * Handle auto-open popup after a delay.
         */
        handleAutoOpen: function () {
            var behavior = config.behavior || {};

            if (!behavior.auto_open) {
                return;
            }

            var delay = (behavior.auto_open_delay || 0) * 1000;
            var self = this;

            setTimeout(function () {
                if (!self.isOpen) {
                    self.open();
                }
            }, delay);
        },

        /**
         * Handle widget visibility delay timer.
         */
        handleDelayTimer: function () {
            var behavior = config.behavior || {};

            if (!behavior.show_after_delay) {
                return;
            }

            var delay = (behavior.delay_seconds || 0) * 1000;
            var self = this;

            setTimeout(function () {
                self.el.style.opacity = '1';
                self.el.style.pointerEvents = 'auto';
            }, delay);
        },

        /**
         * Handle scroll-trigger widget visibility.
         */
        handleScrollTrigger: function () {
            var behavior = config.behavior || {};

            if (!behavior.show_after_scroll) {
                return;
            }

            var threshold = behavior.scroll_percentage || 25;
            var self = this;
            var shown = false;

            var checkScroll = function () {
                if (shown) return;

                var scrolled = (window.scrollY / (document.documentElement.scrollHeight - window.innerHeight)) * 100;

                if (scrolled >= threshold) {
                    self.el.style.opacity = '1';
                    self.el.style.pointerEvents = 'auto';
                    shown = true;
                    window.removeEventListener('scroll', checkScroll);
                }
            };

            window.addEventListener('scroll', checkScroll, { passive: true });
        },
    };

    /* ───── Boot ───────────────────────────────────────── */

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