Hide Web Elements Pro

A complete page control tool with a floating dock to hide, edit, reveal, extract media, skip timers, freeze navigation, manage cookies, remove overlays, and save persistent rules locally.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         Hide Web Elements Pro
// @version      16.7
// @changelog    16.7: Precision fixes for Auto Time Skipper, Anti-Paywall/Anti-AdBlock,
// @changelog    Auto-Close Modals & Overlays, and Auto-Close Logins so they stop
// @changelog    targeting unrelated elements (see comments near AUTO_SKIP_HINTS,
// @changelog    skip30Seconds, isPlausibleOverlayCandidate, and the login-modal check).
// @description  A complete page control tool with a floating dock to hide, edit, reveal, extract media, skip timers, freeze navigation, manage cookies, remove overlays, and save persistent rules locally.
// @author       KTZ
// @match        *://*/*
// @icon         https://cdn.corenexis.com/f/v9leABxGUbJ.png
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addValueChangeListener
// @grant        GM_xmlhttpRequest
// @grant        GM_download
// @grant        unsafeWindow
// @connect      *
// @run-at       document-start
// @license      MIT
// @namespace    https://greasyfork.org/users/1620673
// ==/UserScript==

(function() {
    'use strict';

    // ---------- Safe Storage ----------
    const gv = (key, def) => {
        try {
            if (typeof GM_getValue !== 'undefined') return GM_getValue(key, def);
            const item = localStorage.getItem(key);
            return item !== null ? JSON.parse(item) : def;
        } catch {
            return def;
        }
    };

    let isSyncingStorage = false;
    const sv = (key, val) => {
        try {
            if (typeof GM_setValue !== 'undefined') {
                GM_setValue(key, val);
            } else {
                localStorage.setItem(key, JSON.stringify(val));
            }
        } catch {}

        if (!isSyncingStorage) {
            isSyncingStorage = true;
            try {
                if (typeof syncCache === 'function') syncCache();
                if (typeof requestUpdateStyles === 'function') requestUpdateStyles();
                if (isTop && typeof broadcastState === 'function') broadcastState();
            } finally {
                isSyncingStorage = false;
            }
        }
    };

    const doc = document, win = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    const UI_HOST_ID = 'hider-ui-root', STEPPER_BAR_ID = 'hider-stepper-bar';

    let isTop = false;
    try { isTop = (window.self === window.top); } catch { isTop = false; }

    let shadowRoot = null;
    const shadowBy = id => shadowRoot ? shadowRoot.getElementById(id) : null;

    // ---------- Persistent Settings ----------
    let initialMem = gv('hider_freeze_memory', null) || (gv('hider_autono_global', false) ? 'block_all' : 'ask');
    const CACHE = {
        blockedDomainsList: [], blockedDomainsSet: new Set(),
        allowedDomainsList: [], allowedDomainsSet: new Set(),
        customRules: [], isFrozen: gv('hider_freeze_global', false),
        freezeMemory: initialMem, logs: null,
        autoTimeSkipper: gv('hider_auto_time_skipper', false),
        autoScroll: gv('hider_auto_scroll', true),
        enableContextMenu: gv('hider_enable_contextmenu', true),
        autoRemoveBlur: gv('hider_auto_remove_blur', false),
        universalProtect: true,
        antiPaywallLevel: gv('hider_anti_paywall_level', gv('hider_anti_paywall', false) ? 'normal' : 'off'),
        autoCloseModals: gv('hider_auto_close_modals', false),
        cookieConsentMode: gv('hider_cookie_consent_mode', 'ask'),
        autoCloseLogins: gv('hider_auto_close_logins', false),
        filterLists: gv('hider_filter_lists', []),
        editRules: gv('hider_edit_rules_v1', [])
    };

    // ---------- Dock Button Visibility ----------
    const DOCK_BUTTONS = [
        { id: 'btn-select', icon: '🎯', label: 'Hide', desc: 'Select page elements to hide' },
        { id: 'btn-edit', icon: '✏️', label: 'Edit', desc: 'Select page elements to rewrite or replace' },
        { id: 'btn-scope', icon: '🌐', label: 'Scope', desc: 'Cycle site / page / global scope' },
        { id: 'btn-reveal-quick', icon: '👁️', label: 'Reveal', desc: 'Restore hidden/blurred content' },
        { id: 'btn-links', icon: '🔗', label: 'Links', desc: 'Open link & media lab' },
        { id: 'btn-skip-30', icon: '⏩', label: '+30s', desc: 'Advance detected media timers' },
        { id: 'btn-freeze', icon: '❄️', label: 'Freeze', desc: 'Control navigation prompts' }
    ];

    function getHiddenDockButtons() {
        return gv('hider_hidden_dock_buttons', []);
    }
    function setHiddenDockButtons(arr) {
        sv('hider_hidden_dock_buttons', arr);
    }
    function applyDockButtonVisibility() {
        if (!shadowRoot) return;
        const hidden = new Set(getHiddenDockButtons());
        DOCK_BUTTONS.forEach(btn => {
            const el = shadowRoot.getElementById(btn.id);
            if (el) {
                el.style.setProperty('display', hidden.has(btn.id) ? 'none' : 'flex', 'important');
            }
        });
        const menuBtn = shadowRoot.getElementById('btn-manage');
        if (menuBtn) menuBtn.style.setProperty('display', 'flex', 'important');
    }
    function renderDockButtonOptions() {
        if (!shadowRoot) return;
        const container = shadowRoot.getElementById('dock-buttons-list');
        const countEl = shadowRoot.getElementById('dock-visible-count');
        if (!container) return;

        const hidden = new Set(getHiddenDockButtons());
        container.innerHTML = '';
        container.style.cssText = 'display:grid!important;grid-template-columns:repeat(auto-fit,minmax(145px,1fr))!important;gap:6px!important;';

        DOCK_BUTTONS.forEach(btn => {
            const visible = !hidden.has(btn.id);
            const card = document.createElement('button');
            card.type = 'button';
            card.dataset.btnId = btn.id;
            card.setAttribute('aria-pressed', String(visible));
            card.title = btn.desc;
            card.style.cssText = `
                display:flex!important;align-items:center!important;gap:8px!important;
                min-height:44px!important;padding:7px 8px!important;border-radius:12px!important;
                cursor:pointer!important;text-align:left!important;color:#dbeafe!important;
                background:${visible ? 'linear-gradient(145deg,rgba(56,189,248,.12),rgba(255,255,255,.025))' : 'rgba(255,255,255,.018)'}!important;
                border:1px solid ${visible ? 'rgba(56,189,248,.22)' : 'rgba(148,163,184,.08)'}!important;
                box-shadow:${visible ? '0 8px 18px rgba(0,0,0,.12), inset 0 1px 0 rgba(255,255,255,.05)' : 'none'}!important;
                transition:transform .16s ease,background .16s ease,border-color .16s ease,box-shadow .16s ease,opacity .16s ease!important;
                opacity:${visible ? '1' : '.62'}!important;
            `;

            const icon = document.createElement('span');
            icon.textContent = btn.icon;
            icon.style.cssText = 'width:28px;height:28px;display:grid;place-items:center;border-radius:9px;background:rgba(255,255,255,.05);font-size:15px;flex:0 0 28px;';
            card.appendChild(icon);

            const copy = document.createElement('span');
            copy.style.cssText = 'display:flex;flex-direction:column;gap:2px;min-width:0;flex:1;';
            const title = document.createElement('span');
            title.textContent = btn.label;
            title.style.cssText = 'font-size:9px;font-weight:900;letter-spacing:.2px;color:#e2e8f0;';
            const sub = document.createElement('span');
            sub.textContent = visible ? 'VISIBLE' : 'HIDDEN';
            sub.style.cssText = `font-size:7px;letter-spacing:.7px;font-weight:900;color:${visible ? '#6ee7b7' : '#94a3b8'};`;
            copy.append(title, sub);
            card.appendChild(copy);

            card.addEventListener('mouseenter', () => {
                card.style.transform = 'translateY(-1px)';
                card.style.borderColor = visible ? 'rgba(125,211,252,.34)' : 'rgba(148,163,184,.15)';
            });
            card.addEventListener('mouseleave', () => {
                card.style.transform = '';
                card.style.borderColor = visible ? 'rgba(56,189,248,.22)' : 'rgba(148,163,184,.08)';
            });

            card.addEventListener('click', e => {
                e.stopPropagation();
                const nextHidden = new Set(getHiddenDockButtons());
                if (nextHidden.has(btn.id)) nextHidden.delete(btn.id);
                else nextHidden.add(btn.id);
                setHiddenDockButtons(Array.from(nextHidden));
                applyDockButtonVisibility();
                renderDockButtonOptions();
            });
            container.appendChild(card);
        });

        const visibleCount = DOCK_BUTTONS.length - hidden.size;
        if (countEl) countEl.textContent = `${visibleCount}/${DOCK_BUTTONS.length} visible`;
    }

    function setDockButtonsVisible(mode = 'all') {
        const next = mode === 'none' ? DOCK_BUTTONS.map(btn => btn.id) : [];
        setHiddenDockButtons(next);
        applyDockButtonVisibility();
        renderDockButtonOptions();
        showToast(mode === 'all' ? '✅ All dock controls visible' : '🙈 Optional dock controls hidden');
    }

    // ---------- Core Variables ----------
    let isSelecting = false, isFrozen = CACHE.isFrozen, currentScope = 'site', previewElement = null;
    let stepperStack = [], userApprovedNavigation = false, cachedCssString = null, lastUrl = location.href;
    let stepperPos = { x: null, y: null }, isDraggingStepper = false, isDraggingDock = false, logSaveTimer = null;
    let collapseTimer = null, editingRuleId = null, scrollAnimationFrame = null, styleUpdateRAF = null;
    let linkPanelEl = null;
    let linkDisplayMode = 'text';
    let isProtected = false;
    let featuresEnabled = true;
    let CURRENT_DOMAIN = '', CURRENT_URL = '';
    let previewOutsideListener = null;
    let lastHiddenSelector = null;
    let globalScopeTemp = false;
    let selectionMode = 'hide';
    let pendingEditMedia = null;
    let editInputDraft = '';
    let editOriginalValue = '';
    let editOriginalKind = 'text';
    let editOriginalCaptured = false;
    let editCommitPermanent = true;
    let editEditingActive = false;
    let editSessionSavedRule = null;
    let editSessionPreviousRule = null;
    let editSessionPreviousScope = null;
    let editSessionSourceRule = null;
    let editOriginalHTML = '';
    let editOriginalTextNodePath = null;
    let editOriginalMediaAttrs = null;
    let editOriginalTextPaths = [];
    let editOriginalStyleAttr = '';
    let editOriginalContentEditable = null;
    let editOriginalSpellcheck = null;
    let editTypographySnapshot = null;
    let editMenuSession = null;

    // === SMART IMPROVEMENT: Cache for rule signature ===
    let lastRuleSignature = '';
    let activeHiddenSelector = '';    // Combined selector for the proxy

    // ---------- Smart Time Skipper State ----------
    let autoSkipInterval = null;
    let autoSkipObserver = null;
    let autoSkipEmptyCount = 0;
    let autoSkipCandidates = new Set();
    let autoSkipMedia = new Set();
    const AUTO_SKIP_INTERVAL_MS = 700;
    const AUTO_SKIP_MAX_EMPTY = 18;
    // NOTE: every alternative below requires an explicit ad/commercial term.
    // A bare "skip" (no ad/video/advert/commercial qualifier) must NEVER match on
    // its own here -- that previously matched unrelated buttons like "Skip Intro",
    // "Skip to content", "Skip tutorial", causing the smart skipper to click them
    // and to misclassify ordinary <video>/<audio> elements as ad players.
    const AUTO_SKIP_HINTS = /(?:skip\s*(?:this\s*)?(?:ad|advert(?:isement)?s?|video\s*ad|commercial)\b|dismiss\s*(?:this\s*)?ad\b|close\s*(?:this\s*)?ad\b|continue\s*(?:without|after)\s*(?:the\s*)?(?:ad|advert(?:isement)?s?)|ad\s*(?:remaining|in\s*\d)|(?:this\s*)?ad\s*(?:will\s*end|ends)\s*in|commercial\s*break|\badvertisement\b)/i;
    const TIMER_HINTS = /(?:timer|countdown|remaining|wait|seconds?|mins?|minutes?)/i;

    // ---------- Cleanup ----------
    const timers = {
        scrollInterval: null,
        scrollLockDebounce: null,
        blurInterval: null,
        protectionPoller: null,
        logSaveTimer: null,
        collapseTimer: null,
        paywallObserverTimer: null,
        paywallRescanTimer: null,
        modalObserverTimer: null,
        cookieObserverTimer: null,
        overlayScanTimer: null,
        protectionDebounceTimer: null,
        aboutLiveTimer: null,
    };
    const observers = {
        protectionObserver: null,
        scrollLockObserver: null,
        blurObserver: null,
        urlChangeObserver: null,
        paywallObserver: null,
        modalObserver: null,
        cookieObserver: null,
        adSkipObserver: null,
        headMutationObserver: null,
        editObserver: null
    };
    const styleElements = {
        scrollStyleEl: null,
        contextMenuStyleEl: null,
        blurGlobalStyle: null
    };

    function dispose() {
        Object.keys(timers).forEach(key => {
            if (timers[key]) {
                clearInterval(timers[key]);
                clearTimeout(timers[key]);
                timers[key] = null;
            }
        });
        Object.keys(observers).forEach(key => {
            if (observers[key]) {
                observers[key].disconnect();
                observers[key] = null;
            }
        });
        if (timers.overlayScanTimer) { clearInterval(timers.overlayScanTimer); timers.overlayScanTimer = null; }

        Object.values(styleElements).forEach(el => {
            if (el && el.parentNode) el.remove();
        });
        const host = doc.getElementById(UI_HOST_ID);
        if (host) host.remove();
        const stepper = shadowBy(STEPPER_BAR_ID);
        if (stepper) stepper.remove();
        if (linkPanelEl && linkPanelEl.parentNode) linkPanelEl.remove();
        const prompt = shadowBy('hider-freeze-prompt');
        if (prompt) prompt.remove();
        const toast = doc.getElementById('hider-toast');
        if (toast) toast.remove();
        const dyn = doc.getElementById('hider-dynamic-styles');
        if (dyn) dyn.remove();
        stopAutoSkipMonitoring();
        editMediaUrlCache.forEach(u => { try { URL.revokeObjectURL(u); } catch {} });
        editMediaUrlCache.clear();
    }

    window.addEventListener('beforeunload', dispose);

    // ---------- Context Menu Override ----------
    // Restoring right-click means winning the race against the page's own
    // "return false" / preventDefault() blockers. Those are almost always attached
    // via document.oncontextmenu, an element's oncontextmenu attribute, or a plain
    // addEventListener on document/body -- all of which run in the bubble phase (or
    // target phase) *after* a capturing-phase listener higher up the tree. The old
    // handler only ever acted on clicks inside our own UI and silently did nothing
    // for the rest of the page, which is exactly where the feature is needed, so
    // right-click on the actual page content was never actually restored.
    // Listening on `window` (rather than `document`) in the capture phase puts us
    // ahead of every capturing/bubbling listener a page could register, and
    // stopImmediatePropagation() there prevents the event from ever reaching the
    // page's handlers -- so the browser's native context menu shows normally.
    const contextMenuHandler = function(e) {
        if (!CACHE.enableContextMenu || isFeatureBlacklisted() || !featuresEnabled) return;
        const path = e.composedPath ? e.composedPath() : [];
        // Never interfere with right-clicks on our own floating UI.
        if (path.some(el => el?.id === UI_HOST_ID || (el?.closest && el.closest('#' + UI_HOST_ID)))) {
            return;
        }
        e.stopImmediatePropagation();
    };
    window.addEventListener('contextmenu', contextMenuHandler, true);

    // ---------- Freeze Mode ----------
    const FREEZE_LABELS = {
        'ask': '❓ Ask Every Time', 'block_all': '⛔ Auto-Block All Navigations',
        'allow_same': '🔗 Allow Same Domain Only', 'allow_all': '🟢 Allow All Navigations'
    };
    const FREEZE_HINTS = {
        'ask': 'You\u2019ll get an Allow/Deny prompt every time this page tries to navigate away while Freeze is on.',
        'block_all': 'Every navigation attempt is silently blocked while Freeze is on \u2014 you won\u2019t be asked.',
        'allow_same': 'Links and redirects to the same domain go through normally; leaving the domain is blocked while Freeze is on.',
        'allow_all': 'Freeze has no effect on navigation \u2014 everything is allowed through.'
    };

    // Keeps the Freeze tab's status card (dot / title / sub-copy / toggle
    // label) in sync with `isFrozen`. Safe to call any time — no-ops if the
    // panel hasn't been built yet or the Freeze tab markup isn't present.
    function updateFreezeStatusCard() {
        if (!shadowRoot) return;
        const dot = shadowBy('freeze-status-dot'), title = shadowBy('freeze-status-title'),
              sub = shadowBy('freeze-status-sub'), toggleBtn = shadowBy('freeze-toggle-btn');
        if (!dot || !title || !toggleBtn) return;
        dot.classList.toggle('is-on', isFrozen);
        title.textContent = isFrozen ? 'Freeze ON' : 'Freeze OFF';
        if (sub) sub.textContent = isFrozen
            ? (FREEZE_HINTS[CACHE.freezeMemory] || FREEZE_HINTS['ask'])
            : 'Navigation on this page isn\u2019t being intercepted.';
        toggleBtn.textContent = isFrozen ? 'Turn OFF' : 'Turn ON';
        toggleBtn.classList.toggle('btn-blue', !isFrozen);
        toggleBtn.classList.toggle('btn-red', isFrozen);
    }

    const resolveUrl = u => {
        if (!u || typeof u !== 'string') return '';
        const trimmed = u.trim();
        if (trimmed === '*') return '*';
        if (!/^[a-zA-Z][a-zA-Z0-9+-.]*:\/\//.test(trimmed)) {
            if (trimmed.startsWith('//')) return 'http:' + trimmed;
            if (!trimmed.startsWith('/') && !trimmed.startsWith('./') && !trimmed.startsWith('../')) {
                return 'http://' + trimmed;
            }
        }
        try { return new URL(trimmed, win.location.href).href; } catch { return trimmed; }
    };

    const cleanUrl = () => CURRENT_URL || (CURRENT_URL = location.origin + location.pathname);
    const cleanDomain = url => {
        try {
            if (!url) return '';
            if (url === '*') return '*';
            const abs = resolveUrl(url);
            return new URL(abs).hostname.replace(/^www\./, '').toLowerCase();
        } catch {
            return String(url).trim().toLowerCase();
        }
    };

    const updateCurrentLocCache = () => {
        CURRENT_URL = location.origin + location.pathname;
        CURRENT_DOMAIN = cleanDomain(location.href);
        updateProtectionFlag();
        applyAllSettings();
    };

    function getParentDomain(url) {
        if (!url) return '';
        try {
            const host = cleanDomain(url);
            if (!host || host === '*') return host;
            const parts = host.split('.');
            if (parts.length <= 2) return host;
            const multiPartTlds = ['co.uk', 'com.au', 'org.uk', 'gov.uk', 'co.jp', 'com.br', 'co.id', 'or.id', 'ac.uk', 'net.au', 'com.tw', 'co.nz', 'com.sg', 'com.mx', 'co.kr', 'com.tr'];
            const lastTwo = parts.slice(-2).join('.');
            return (multiPartTlds.includes(lastTwo) && parts.length > 2) ? parts.slice(-3).join('.') : lastTwo;
        } catch {
            return cleanDomain(url) || '';
        }
    }

    const FEATURE_BLACKLIST = [];
    const MEDIA_SENSITIVE_DOMAINS = ['facebook.com', 'fb.com', 'instagram.com'];
    let blacklistToastShown = false;

    function isFeatureBlacklisted() {
        if (!CURRENT_DOMAIN || !FEATURE_BLACKLIST.length) return false;
        return FEATURE_BLACKLIST.some(domain =>
            CURRENT_DOMAIN === domain || CURRENT_DOMAIN.endsWith('.' + domain)
        );
    }

    // Some social platforms wrap real media in highly dynamic UI containers.
    // Keep destructive overlay/auto-close/pause helpers away from those media surfaces.
    function isMediaSensitiveDomain() {
        if (!CURRENT_DOMAIN) return false;
        return MEDIA_SENSITIVE_DOMAINS.some(domain =>
            CURRENT_DOMAIN === domain || CURRENT_DOMAIN.endsWith('.' + domain)
        );
    }

    // ============ REVEAL & UNBLOCK ENGINE ============
    function isProtectedPage() {
        try {
            if (win.__cf_chl_opt || win.__cfRLUnblockHandlers || win._cf) return true;
            if (win.turnstile) {
                if (doc.querySelector('.cf-turnstile, #turnstile-wrapper, .turnstile-container, #cf-challenge')) return true;
            }
            const challengeSelectors = [
                '#challenge-running', '#cf-please-wait', '.cf-browser-verification',
                '#cf-content', '#cf-stage', '#cf-challenge', '.cf-challenge',
                '#cf-error-details', '#cf-waiting', '.cf-please-wait',
                '#cf-content-wrapper', '#challenge-form', '.challenge-form', '#cf-intercept'
            ];
            for (const sel of challengeSelectors) {
                if (doc.querySelector(sel)) return true;
            }
            if (doc.querySelector('.ray-id, [data-ray-id], [data-cf-ray]')) return true;
            const title = doc.title || '';
            if (title.includes('Just a moment...') || title.includes('Attention Required!') ||
                title.includes('Security Check') || title.includes('Verify you are human') ||
                title.includes('Checking your browser')) {
                return true;
            }
            const forms = doc.querySelectorAll('form[action*="__cf_chl"], form[action*="cf-challenge"]');
            if (forms.length > 0) return true;
            const scripts = doc.querySelectorAll('script[src*="challenges.cloudflare.com"], script[src*="/cdn-cgi/challenge-platform/"]');
            if (scripts.length > 0) return true;
            if (doc.querySelector('meta[name="cf-options"]')) return true;
        } catch (e) { /* ignore */ }
        return false;
    }

    function updateProtectionFlag() {
        const was = isProtected;
        isProtected = isProtectedPage();
        featuresEnabled = isProtected ? !CACHE.universalProtect : true;
        if (was !== isProtected) requestUpdateStyles();
    }

    function setupProtectionObserver() {
        if (observers.protectionObserver) return;
        let pending = false;
        const schedule = () => {
            if (pending) return;
            pending = true;
            clearTimeout(timers.protectionDebounceTimer);
            timers.protectionDebounceTimer = setTimeout(() => {
                pending = false;
                timers.protectionDebounceTimer = null;
                updateProtectionFlag();
            }, 250);
        };
        observers.protectionObserver = new MutationObserver(mutations => {
            // Challenge pages are normally discovered through added nodes/title changes.
            // Do not watch every attribute change: React sites mutate thousands of attrs.
            for (const m of mutations) {
                if (m.type === 'childList' && m.addedNodes?.length) { schedule(); return; }
            }
        });
        try {
            observers.protectionObserver.observe(doc.documentElement, { childList: true, subtree: true });
        } catch {}

        // One delayed check catches document-start challenges without creating a permanent poller.
        setTimeout(updateProtectionFlag, 600);
    }

    // ---------- Scroll Defeater ----------
    // Do NOT rewrite html/body position/overflow globally. That breaks site menus,
    // search drawers, nested scrollers and pages that intentionally lock the body
    // while keeping an inner container scrollable.
    function forceEnableScroll() {
        if (!CACHE.autoScroll) return;
        if (isFeatureBlacklisted() || !featuresEnabled) return;

        const html = doc.documentElement, body = doc.body;
        if (!html && !body) return;

        // Only remove an actual document-level scroll lock when there is strong
        // evidence that a blocking overlay is active. Never force position/static.
        try {
            const roots = [html, body].filter(Boolean);
            for (const root of roots) {
                const style = win.getComputedStyle(root);
                if (style.overflow === 'hidden' || style.overflowY === 'hidden') {
                    root.style.setProperty('overflow-y', 'auto', 'important');
                }
                if (style.overflowX === 'hidden') {
                    // Keep horizontal overflow behavior unchanged unless both axes
                    // were explicitly locked.
                    if (style.overflow === 'hidden') {
                        root.style.setProperty('overflow-x', 'auto', 'important');
                    }
                }
            }
        } catch {}
    }

    function checkAndAutoUnblockScroll() {
        if (!CACHE.autoScroll || isFeatureBlacklisted() || !featuresEnabled) {
            stopScrollDefeater();
            return;
        }

        const html = doc.documentElement, body = doc.body;
        if (!html || !body) return;

        try {
            // Do not treat fixed/absolute positioning by itself as a scroll lock.
            // It is commonly used by drawers, search boxes, sticky headers, etc.
            const hStyle = win.getComputedStyle(html);
            const bStyle = win.getComputedStyle(body);
            const locked =
                hStyle.overflow === 'hidden' || hStyle.overflowY === 'hidden' ||
                bStyle.overflow === 'hidden' || bStyle.overflowY === 'hidden';

            if (locked && hasBlockingOverlayInDocument()) {
                forceEnableScroll();
            }
        } catch {}
    }

    function startScrollDefeater() {
        if (isFeatureBlacklisted() || !featuresEnabled) {
            stopScrollDefeater();
            return;
        }

        if (timers.scrollInterval) clearInterval(timers.scrollInterval);
        if (observers.scrollLockObserver) { observers.scrollLockObserver.disconnect(); observers.scrollLockObserver = null; }

        if (CACHE.autoScroll) {
            // Polling fallback, kept intentionally infrequent.
            timers.scrollInterval = setInterval(checkAndAutoUnblockScroll, 2500);

            // Instant reaction: a lot of scroll locks are applied and then
            // re-applied (e.g. a script re-asserts overflow:hidden every time a
            // timer fires) faster than a 2.5s poll can catch, so the page wins the
            // race and appears "stuck" between checks. Watching style/class
            // attribute changes on <html>/<body> reacts within one animation frame
            // instead of waiting for the next poll tick.
            const debouncedCheck = () => {
                clearTimeout(timers.scrollLockDebounce);
                timers.scrollLockDebounce = setTimeout(checkAndAutoUnblockScroll, 50);
            };
            observers.scrollLockObserver = new MutationObserver(debouncedCheck);
            try {
                const html = doc.documentElement, body = doc.body;
                const opts = { attributes: true, attributeFilter: ['style', 'class'] };
                if (html) observers.scrollLockObserver.observe(html, opts);
                if (body) observers.scrollLockObserver.observe(body, opts);
            } catch {}
        }
    }

    function stopScrollDefeater() {
        if (timers.scrollInterval) {
            clearInterval(timers.scrollInterval);
            timers.scrollInterval = null;
        }
        if (timers.scrollLockDebounce) {
            clearTimeout(timers.scrollLockDebounce);
            timers.scrollLockDebounce = null;
        }
        if (observers.scrollLockObserver) {
            observers.scrollLockObserver.disconnect();
            observers.scrollLockObserver = null;
        }
    }

    // ---------- Context Menu Styles ----------
    function updateContextMenuStyles() {
        if (isFeatureBlacklisted() || !featuresEnabled) {
            if (styleElements.contextMenuStyleEl) {
                styleElements.contextMenuStyleEl.remove();
                styleElements.contextMenuStyleEl = null;
            }
            return;
        }
        if (!CACHE.enableContextMenu) {
            if (styleElements.contextMenuStyleEl) {
                styleElements.contextMenuStyleEl.remove();
                styleElements.contextMenuStyleEl = null;
            }
            return;
        }
        if (!styleElements.contextMenuStyleEl) {
            styleElements.contextMenuStyleEl = doc.createElement('style');
            styleElements.contextMenuStyleEl.id = 'hider-contextmenu-style';
            (doc.head || doc.documentElement)?.appendChild(styleElements.contextMenuStyleEl);
        }
        styleElements.contextMenuStyleEl.textContent = `
            * {
                -webkit-touch-callout: default !important;
                -webkit-user-select: text !important;
                user-select: text !important;
            }
        `;
    }

    // ---------- Blur Removal ----------
    function unblurSingleElement(el) {
        if (!el || el.nodeType !== Node.ELEMENT_NODE) return;
        if (el.id === UI_HOST_ID || el.closest?.('#' + UI_HOST_ID)) return;
        try {
            const style = win.getComputedStyle(el);
            if (style.filter?.includes('blur')) el.style.setProperty('filter', 'none', 'important');
            if (style.backdropFilter?.includes('blur')) {
                el.style.setProperty('backdrop-filter', 'none', 'important');
                el.style.setProperty('-webkit-backdrop-filter', 'none', 'important');
            }
        } catch {}
    }

    function removeBlurFromElements(roots = [doc]) {
        if (!CACHE.autoRemoveBlur || isFeatureBlacklisted() || !featuresEnabled || isMediaSensitiveDomain()) {
            stopBlurRemoval();
            return;
        }
        const selectors = [
            '[style*="blur"]', '[style*="backdrop-filter"]',
            '[class*="blur" i]', '[data-blur]', '[data-backdrop]'
        ].join(',');
        for (const root of roots) {
            if (!root) continue;
            // querySelectorAll only ever matches descendants, never the root itself.
            // A mutation target (attribute change) or a freshly inserted node is very
            // often the blurred element itself, so it must be checked directly too --
            // otherwise a blur applied straight to that node was silently missed.
            if (root.nodeType === Node.ELEMENT_NODE) unblurSingleElement(root);
            if (!root.querySelectorAll) continue;
            let nodes = [];
            try { nodes = root.querySelectorAll(selectors); } catch { continue; }
            for (const el of nodes) unblurSingleElement(el);
        }
    }

    function scheduleBlurRemoval() {
        if (isFeatureBlacklisted() || !featuresEnabled || isMediaSensitiveDomain()) {
            stopBlurRemoval();
            return;
        }
        if (styleElements.blurGlobalStyle) {
            styleElements.blurGlobalStyle.remove();
            styleElements.blurGlobalStyle = null;
        }
        if (CACHE.autoRemoveBlur) {
            removeBlurFromElements();
            if (!observers.blurObserver) {
                observers.blurObserver = new MutationObserver(mutations => {
                    if (!CACHE.autoRemoveBlur) return;
                    const roots = [];
                    for (const m of mutations) {
                        if (m.type === 'childList') {
                            for (const n of m.addedNodes || []) {
                                if (n.nodeType === Node.ELEMENT_NODE) roots.push(n);
                            }
                        } else if (m.type === 'attributes' && m.target?.nodeType === Node.ELEMENT_NODE) {
                            // Many paywalls/overlays blur existing content by toggling a
                            // class or inline style on an element that's already on the
                            // page, rather than inserting new nodes. Without watching
                            // attribute changes, that re-blur was never detected.
                            roots.push(m.target);
                        }
                    }
                    if (roots.length) removeBlurFromElements(roots);
                });
                try {
                    observers.blurObserver.observe(doc.documentElement, {
                        childList: true, subtree: true,
                        attributes: true, attributeFilter: ['style', 'class']
                    });
                } catch {}
            }
        } else {
            stopBlurRemoval();
        }
    }

    function stopBlurRemoval() {
        if (timers.blurInterval) { clearInterval(timers.blurInterval); timers.blurInterval = null; }
        if (observers.blurObserver) { observers.blurObserver.disconnect(); observers.blurObserver = null; }
        if (styleElements.blurGlobalStyle) { styleElements.blurGlobalStyle.remove(); styleElements.blurGlobalStyle = null; }
    }

    // ---------- SAFE HELPER: Check if element is main content ----------
    function isMainContentElement(el) {
        if (!el) return false;
        if (el === doc.documentElement || el === doc.body) return true;
        if (el.id === UI_HOST_ID || el.closest && el.closest('#' + UI_HOST_ID)) return true;
        const text = el.textContent || '';
        if (text.length > 500) {
            const style = win.getComputedStyle(el);
            if (style.position === 'fixed' || style.position === 'absolute') {
                const z = parseInt(style.zIndex, 10);
                if (z > 1000) return false;
            }
            return true;
        }
        if (el.matches && el.matches('article, main, section, div[role="main"]')) {
            if (text.length > 100) return true;
        }
        return false;
    }

    // ================================================================
    //  NEW HELPER: Detect side panels (smart)
    // ================================================================
    function isSidePanel(el) {
        if (!el || el === doc.documentElement || el === doc.body) return false;
        if (el.closest && el.closest('#' + UI_HOST_ID)) return false;

        const rect = el.getBoundingClientRect();
        const vw = win.innerWidth, vh = win.innerHeight;
        const widthRatio = rect.width / vw;
        const heightRatio = rect.height / vh;
        const isLeft = rect.left < 10;
        const isRight = (vw - rect.right) < 10;

        // 1. Position & size
        if ((isLeft || isRight) && widthRatio < 0.4 && heightRatio > 0.3) return true;

        // 2. Class/id/role keywords
        const classId = (el.className + ' ' + el.id).toLowerCase();
        const role = el.getAttribute('role') || '';
        const combined = classId + ' ' + role;
        const sideKeywords = ['sidebar', 'drawer', 'menu', 'navigation', 'nav', 'sidepanel', 'offcanvas', 'slide', 'panel', 'sidenav'];
        if (sideKeywords.some(kw => combined.includes(kw))) return true;

        // 3. ARIA roles that are typical for menus/navigation
        const menuRoles = ['navigation', 'menu', 'menubar', 'listbox', 'tree', 'tablist'];
        if (menuRoles.includes(role)) return true;

        // 4. Many links and not full‑screen → likely a menu
        const links = el.querySelectorAll('a');
        if (links.length > 5 && widthRatio < 0.5 && heightRatio < 0.9) return true;

        // 5. Contains a search input or hamburger‑like button
        const hasSearch = el.querySelector('input[type="search"], input[placeholder*="search"], .search-input');
        if (hasSearch && widthRatio < 0.5) return true;

        // 6. Check for transform/transition that suggests sliding panel
        const style = win.getComputedStyle(el);
        if (style.transform && style.transform !== 'none' && (style.transform.includes('translateX') || style.transform.includes('translateY'))) {
            return true;
        }

        return false;
    }

    // ================================================================
    //  COMPOSED-TREE / OVERLAY HELPERS
    // ================================================================
    function forEachOpenShadowRoot(callback) {
        const seen = new Set();
        const visit = root => {
            if (!root || seen.has(root)) return;
            seen.add(root);
            callback(root);

            const hosts = root.querySelectorAll ? root.querySelectorAll('*') : [];
            for (const host of hosts) {
                if (host && host.shadowRoot) visit(host.shadowRoot);
            }
        };
        visit(doc);
    }

    function getOverlayRoots() {
        const roots = [];
        forEachOpenShadowRoot(root => roots.push(root));
        return roots;
    }

    function isVisibleElement(el, rootWin = win) {
        if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
        try {
            const s = rootWin.getComputedStyle(el);
            if (s.display === 'none' || s.visibility === 'hidden' || parseFloat(s.opacity) < 0.01) return false;
            const r = el.getBoundingClientRect();
            return r.width > 1 && r.height > 1;
        } catch {
            return false;
        }
    }

    function getElementMeta(el) {
        const cls = typeof el.className === 'string' ? el.className : (el.getAttribute('class') || '');
        return (
            `${el.id || ''} ${cls} ${el.getAttribute('role') || ''} ` +
            `${el.getAttribute('aria-label') || ''} ${el.getAttribute('data-testid') || ''}`
        ).toLowerCase();
    }

    const ESSENTIAL_UI_TERMS = [
        'search', 'sidebar', 'side-bar', 'drawer', 'navigation', 'navbar', 'nav-menu',
        'menu', 'offcanvas', 'dropdown', 'autocomplete', 'suggestion', 'command-palette',
        'settings', 'filter', 'sort', 'toolbar', 'dialog', 'tooltip', 'popover',
        'datepicker', 'calendar', 'select', 'combobox', 'listbox', 'accessibility',
        'player', 'video', 'audio', 'volume', 'caption', 'share', 'login', 'signin',
        'sign-in', 'register', 'account', 'profile'
    ];

    const BLOCKING_UI_TERMS = [
        'paywall', 'subscription', 'premium', 'subscribe', 'adblock', 'ad-block',
        'anti-adblock', 'anti adblock', 'disable ad blocker', 'disable adblock',
        'whitelist', 'detected ad blocker', 'detect adblock', 'please disable',
        'content is locked', 'article is locked', 'members only', 'members-only'
    ];

    function isLikelyEssentialUI(el) {
        if (!el || el === doc.documentElement || el === doc.body) return true;
        if (el.id === UI_HOST_ID || el.closest?.('#' + UI_HOST_ID)) return true;

        const meta = getElementMeta(el);
        if (ESSENTIAL_UI_TERMS.some(term => meta.includes(term))) return true;

        const role = (el.getAttribute('role') || '').toLowerCase();
        if (['navigation', 'menu', 'menubar', 'listbox', 'tree', 'tablist', 'combobox'].includes(role)) return true;

        try {
            const r = el.getBoundingClientRect();
            const vw = win.innerWidth || 1;
            const vh = win.innerHeight || 1;
            const wr = r.width / vw;
            const hr = r.height / vh;

            // Narrow edge panels/drawers are almost always intentional UI.
            const nearLeft = r.left <= 12;
            const nearRight = (vw - r.right) <= 12;
            if ((nearLeft || nearRight) && wr <= 0.48 && hr >= 0.18) return true;

            // Anything containing an active form control is generally user-facing UI.
            if (el.querySelector?.(
                'input, textarea, select, button, [role="button"], [contenteditable="true"]'
            )) {
                // Do not exempt obvious blocking notices.
                const text = (el.textContent || '').toLowerCase();
                if (!BLOCKING_UI_TERMS.some(term => text.includes(term))) return true;
            }
        } catch {}

        return false;
    }

    function getOverlayScore(el) {
        if (!isVisibleElement(el)) return -Infinity;
        if (isLikelyEssentialUI(el)) return -Infinity;

        const style = win.getComputedStyle(el);
        if (style.position !== 'fixed' && style.position !== 'absolute' && style.position !== 'sticky') {
            return -Infinity;
        }

        const r = el.getBoundingClientRect();
        const vw = Math.max(1, win.innerWidth);
        const vh = Math.max(1, win.innerHeight);
        const coverage = (Math.max(0, r.width) * Math.max(0, r.height)) / (vw * vh);

        let score = 0;
        const meta = getElementMeta(el);
        const text = (el.textContent || '').trim().toLowerCase().slice(0, 8000);

        if (style.position === 'fixed' || style.position === 'absolute') score += 1;
        if (coverage >= 0.35) score += 2;
        if (coverage >= 0.60) score += 2;
        if (r.left <= 5 && r.top <= 5) score += 1;
        if (r.width >= vw * 0.90 && r.height >= vh * 0.85) score += 2;

        const z = parseInt(style.zIndex, 10);
        if (Number.isFinite(z)) {
            if (z >= 100) score += 1;
            if (z >= 1000) score += 1;
        }

        if (style.backdropFilter?.includes('blur')) score += 2;
        if (style.pointerEvents !== 'none') score += 1;

        const blockingTermHits = BLOCKING_UI_TERMS.reduce((n, term) => n + (meta.includes(term) || text.includes(term) ? 1 : 0), 0);
        if (blockingTermHits >= 1) score += 4;
        if (blockingTermHits >= 2) score += 2;

        const closeButton = el.querySelector?.(
            '[aria-label*="close" i], [data-testid*="close" i], .close, .dismiss, button'
        );
        if (closeButton) score += 1;

        return score;
    }

    function isBlockingOverlayElement(el, threshold = 6) {
        const score = getOverlayScore(el);
        return Number.isFinite(score) && score >= threshold;
    }

    // ---------- Anti-Paywall / Anti-Adblock strength levels ----------
    // Lower threshold = more borderline overlays get caught (more aggressive,
    // slightly higher false-positive risk). Extreme also re-scans periodically.
    const PAYWALL_LEVEL_CONFIG = {
        weak:    { threshold: 9, forceScroll: false, rescanMs: 0 },
        normal:  { threshold: 6, forceScroll: true,  rescanMs: 0 },
        extreme: { threshold: 4, forceScroll: true,  rescanMs: 3000 }
    };
    const PAYWALL_LEVEL_LABELS = Object.freeze({
        off: 'Off',
        weak: 'Weak',
        normal: 'Normal',
        extreme: 'Extreme'
    });
    const PAYWALL_LEVEL_HINTS = Object.freeze({
        off: 'Disabled. Overlay cleanup does not run.',
        weak: 'High-confidence blocking overlays only; no forced scroll unlock.',
        normal: 'Balanced detection with scroll recovery for confirmed blockers.',
        extreme: 'More aggressive detection plus a periodic re-scan for reinserting blockers.'
    });
    // Returns null for 'off' (or any unrecognized value) so callers can bail out cleanly.
    function getPaywallLevelConfig() {
        return PAYWALL_LEVEL_CONFIG[CACHE.antiPaywallLevel] || null;
    }

    // "gate" and "wall" are broad substrings that also collide with unrelated
    // words: "navigate", "aggregate", "delegate", "negate", "gateway" all
    // contain "gate"; "firewall", "wallet", "waterfall", "sidewall" all contain
    // "wall". A word-boundary check keeps intentional hyphen/underscore-separated
    // names like "pay-gate" or "content-wall" while rejecting those fused false
    // positives. Other terms below (modal/popup/overlay/paywall/adblock/
    // subscribe/premium) have low real-world collision risk and stay as plain
    // substring checks.
    const NARROW_CANDIDATE_RE = /\b(?:gate|wall)\b/i;
    const SAFE_SUBSTRING_RE = /modal|popup|overlay|paywall|adblock|subscribe|premium/i;
    function isPlausibleOverlayCandidate(el) {
        if (!el) return false;
        const role = (el.getAttribute?.('role') || '').toLowerCase();
        if (role === 'dialog' || role === 'alertdialog') return true;
        const cls = typeof el.className === 'string' ? el.className : (el.getAttribute?.('class') || '');
        const id = el.id || '';
        if (SAFE_SUBSTRING_RE.test(cls) || SAFE_SUBSTRING_RE.test(id)) return true;
        return NARROW_CANDIDATE_RE.test(cls) || NARROW_CANDIDATE_RE.test(id);
    }

    function getOverlayCandidates(root) {
        if (!root?.querySelectorAll) return [];
        const selectors = [
            '[role="dialog"]', '[role="alertdialog"]',
            '[class*="modal" i]', '[id*="modal" i]',
            '[class*="popup" i]', '[id*="popup" i]',
            '[class*="overlay" i]', '[id*="overlay" i]',
            '[class*="paywall" i]', '[id*="paywall" i]',
            '[class*="adblock" i]', '[id*="adblock" i]',
            '[class*="subscribe" i]', '[id*="subscribe" i]',
            '[class*="premium" i]', '[id*="premium" i]',
            '[class*="gate" i]', '[id*="gate" i]',
            '[class*="wall" i]', '[id*="wall" i]'
        ];
        try {
            return Array.from(root.querySelectorAll(selectors.join(',')))
                .filter(isPlausibleOverlayCandidate)
                .slice(0, 80);
        }
        catch { return []; }
    }

    function hasBlockingOverlayInDocument() {
        for (const root of getOverlayRoots()) {
            for (const el of getOverlayCandidates(root)) {
                if (isBlockingOverlayElement(el)) return true;
            }
        }
        return false;
    }

    function hideOverlayElement(el, reason, forceScroll = true) {
        if (!el || isLikelyEssentialUI(el)) return false;
        try {
            el.setAttribute('data-hider-overlay-removed', reason || 'overlay');
            el.style.setProperty('display', 'none', 'important');
            el.style.setProperty('visibility', 'hidden', 'important');
            el.style.setProperty('pointer-events', 'none', 'important');

            // Remove only body-level scroll lock that belongs to the now-hidden
            // blocking overlay. Do not touch fixed/absolute positioning. Skipped
            // at the "weak" strength level, which only removes the overlay itself.
            if (forceScroll) forceEnableScroll();
            return true;
        } catch {
            return false;
        }
    }

    // ================================================================
    //  CLIENT-SIDE BLOCKING OVERLAY CLEANUP
    // ================================================================
    function setupPaywallBypass() {
        if (observers.paywallObserver) { observers.paywallObserver.disconnect(); observers.paywallObserver = null; }
        if (timers.paywallObserverTimer) { clearInterval(timers.paywallObserverTimer); timers.paywallObserverTimer = null; }
        if (timers.paywallRescanTimer) { clearInterval(timers.paywallRescanTimer); timers.paywallRescanTimer = null; }

        const cfg = getPaywallLevelConfig();
        if (!cfg || !featuresEnabled || isFeatureBlacklisted() || isMediaSensitiveDomain()) return;

        const { threshold, forceScroll } = cfg;

        const inspectNode = node => {
            if (!node || node.nodeType !== Node.ELEMENT_NODE) return;
            const candidates = [node];
            try {
                const found = node.querySelectorAll?.('[role="dialog"], [role="alertdialog"], [class*="modal" i], [class*="overlay" i], [class*="paywall" i], [class*="adblock" i], [class*="subscribe" i], [class*="premium" i], [class*="gate" i], [class*="wall" i]') || [];
                for (const el of found) if (isPlausibleOverlayCandidate(el)) candidates.push(el);
            } catch {}
            for (const el of candidates.slice(0, 100)) {
                if (!isVisibleElement(el)) continue;
                if (isBlockingOverlayElement(el, threshold)) hideOverlayElement(el, 'blocking-overlay', forceScroll);
            }
        };
        const process = mutations => {
            if (isMediaSensitiveDomain()) return;
            for (const m of mutations) for (const n of m.addedNodes || []) inspectNode(n);
        };
        observers.paywallObserver = new MutationObserver(process);
        try { observers.paywallObserver.observe(doc.documentElement, { childList: true, subtree: true }); } catch {}

        const scanOnce = () => {
            if (isMediaSensitiveDomain()) return;
            for (const root of getOverlayRoots()) {
                for (const el of getOverlayCandidates(root)) {
                    if (isVisibleElement(el) && isBlockingOverlayElement(el, threshold)) hideOverlayElement(el, 'blocking-overlay', forceScroll);
                }
            }
        };
        // Single startup pass only over semantic overlay selectors.
        scanOnce();
        // "extreme" also re-scans periodically to catch overlays that reinsert
        // themselves after being removed (common anti-adblock retry loops).
        if (cfg.rescanMs) timers.paywallRescanTimer = setInterval(scanOnce, cfg.rescanMs);
    }

    function getAgeText(el) {
        if (!el) return '';
        const attrs = [
            el.getAttribute?.('aria-label'), el.getAttribute?.('title'), el.getAttribute?.('placeholder'),
            el.getAttribute?.('name'), el.getAttribute?.('id'),
            typeof el.className === 'string' ? el.className : '',
            el.getAttribute?.('data-testid'), el.getAttribute?.('data-test'), el.getAttribute?.('autocomplete')
        ];
        return `${el.textContent || ''} ${attrs.filter(Boolean).join(' ')}`.toLowerCase().replace(/\s+/g, ' ').trim();
    }
    // ================================================================
    //  AUTO-CLOSE MODALS & OVERLAYS ENGINE
    // ================================================================
    function setupModalAutoClose() {
        if (observers.modalObserver) { observers.modalObserver.disconnect(); observers.modalObserver = null; }
        if (timers.modalObserverTimer) { clearTimeout(timers.modalObserverTimer); timers.modalObserverTimer = null; }
        if (timers.overlayScanTimer) { clearInterval(timers.overlayScanTimer); timers.overlayScanTimer = null; }
        if ((!CACHE.autoCloseModals) || !featuresEnabled || isFeatureBlacklisted() || isMediaSensitiveDomain()) return;

        const closeKeywords = /(close|dismiss|cancel|got it|no thanks)/i;
        const findCloseButton = modal => Array.from(modal.querySelectorAll?.('button, a[role="button"], input[type="button"], input[type="submit"], [aria-label*="close" i], [data-testid*="close" i], .close, .dismiss') || []).find(btn => closeKeywords.test(getAgeText(btn)));
        const processModal = modal => {
            if (!modal || modal.id === UI_HOST_ID || modal.closest?.('#' + UI_HOST_ID)) return;
            if (!isVisibleElement(modal)) return;
            if (!CACHE.autoCloseModals || isLikelyEssentialUI(modal)) return;

            const text = (modal.textContent || '').toLowerCase().slice(0, 5000);
            const meta = getElementMeta(modal);
            const blocking = BLOCKING_UI_TERMS.some(term => text.includes(term) || meta.includes(term));
            const hasForm = !!modal.querySelector?.('input, textarea, select, button, [contenteditable="true"]');
            if (hasForm && !blocking && !CACHE.autoCloseLogins) return;
            if (isBlockingOverlayElement(modal)) {
                const btn = findCloseButton(modal);
                if (btn) { try { btn.click(); return; } catch {} }
                hideOverlayElement(modal, 'modal-overlay');
            } else if (CACHE.autoCloseLogins) {
                // Scope the login check to the modal's own identifying attributes
                // (class/id/role/aria-label/testid) or, failing that, a real form
                // control plus a login-ish leading snippet -- not an arbitrary
                // match anywhere inside up to 5000 characters of unrelated text.
                const loginSignal = /(login|sign[\s-]*in|signin|register)/i;
                const heading = text.slice(0, 200);
                if (loginSignal.test(meta) || (hasForm && loginSignal.test(heading))) {
                    const btn = findCloseButton(modal);
                    if (btn) { try { btn.click(); } catch {} }
                }
            }
        };

        const inspectNode = node => {
            if (!node || node.nodeType !== Node.ELEMENT_NODE) return;
            if (CACHE.autoCloseModals) {
                try {
                    for (const el of node.querySelectorAll?.('[role="dialog"], [role="alertdialog"], [class*="modal" i], [class*="popup" i], [class*="overlay" i], [class*="gate" i], [class*="paywall" i], [class*="adblock" i]') || []) {
                        if (isPlausibleOverlayCandidate(el)) processModal(el);
                    }
                } catch {}
            }
        };

        observers.modalObserver = new MutationObserver(mutations => {
            for (const m of mutations) {
                if (m.type !== 'childList') continue;
                for (const n of m.addedNodes || []) inspectNode(n);
            }
        });
        try { observers.modalObserver.observe(doc.documentElement, { childList: true, subtree: true }); } catch {}
        inspectNode(doc.body || doc.documentElement);
    }

    // ---------- Cookie Consent ----------
    function setupCookieConsent() {
        if (observers.cookieObserver) {
            observers.cookieObserver.disconnect();
            observers.cookieObserver = null;
        }
        if (CACHE.cookieConsentMode === 'ask' || !featuresEnabled || isFeatureBlacklisted()) return;

        const cookieSelectors = [
            '#cookie-consent', '#cookie-banner', '.cookie-consent', '.cookie-banner',
            '[class*="cookie"]', '[id*="cookie"]', '[aria-label*="cookie"]'
        ];
        const acceptKeywords = ['accept', 'agree', 'allow', 'yes', 'ok', 'got it'];
        const rejectKeywords = ['reject', 'decline', 'no', 'deny'];

        function handleCookieBanner() {
            const banners = doc.querySelectorAll(cookieSelectors.join(','));
            for (const banner of banners) {
                if (banner === doc.body || banner === doc.documentElement) continue;
                if (banner.closest && banner.closest('#' + UI_HOST_ID)) continue;
                const style = win.getComputedStyle(banner);
                if (style.display === 'none' || style.visibility === 'hidden') continue;
                if (isMainContentElement(banner)) continue;

                const buttons = banner.querySelectorAll('button, a[role="button"], input[type="button"]');
                const mode = CACHE.cookieConsentMode;
                let targetTexts = mode === 'accept' ? acceptKeywords : rejectKeywords;
                for (const btn of buttons) {
                    const text = btn.textContent.trim().toLowerCase();
                    if (targetTexts.some(kw => text.includes(kw))) {
                        try { btn.click(); } catch {}
                        return;
                    }
                }
                const closeBtn = banner.querySelector('[aria-label*="close"], [aria-label*="Close"], .close, .dismiss');
                if (closeBtn) {
                    try { closeBtn.click(); } catch {}
                }
            }
        }

        observers.cookieObserver = new MutationObserver(() => {
            handleCookieBanner();
        });
        observers.cookieObserver.observe(doc.documentElement, { childList: true, subtree: true });

        setTimeout(handleCookieBanner, 500);
        setTimeout(handleCookieBanner, 2000);
    }

    // ---------- Apply all settings ----------
    function applyAllSettings() {
        if (isFeatureBlacklisted() && !blacklistToastShown) {
            showToast('⚠️ Some Reveal features disabled on this domain');
            blacklistToastShown = true;
        }

        if (CACHE.autoScroll) startScrollDefeater();
        else stopScrollDefeater();

        updateContextMenuStyles();

        if (CACHE.autoRemoveBlur) scheduleBlurRemoval();
        else stopBlurRemoval();

        updateProtectionFlag();

        setupPaywallBypass();
        setupModalAutoClose();
        setupCookieConsent();

        if (CACHE.autoTimeSkipper && featuresEnabled && !isMediaSensitiveDomain()) {
            startAutoSkipMonitoring();
        } else {
            stopAutoSkipMonitoring();
        }
    }

    // ---------- Sync Cache ----------
    function syncCache() {
        CACHE.blockedDomainsList = gv('hider_blocked_domains', []);
        CACHE.blockedDomainsSet = new Set(CACHE.blockedDomainsList.map(cleanDomain).filter(Boolean));
        CACHE.allowedDomainsList = gv('hider_allowed_domains', []);
        CACHE.allowedDomainsSet = new Set(CACHE.allowedDomainsList.map(cleanDomain).filter(Boolean));
        CACHE.customRules = gv('hider_custom_rules_v4', []);
        CACHE.isFrozen = gv('hider_freeze_global', false);
        isFrozen = CACHE.isFrozen;
        CACHE.freezeMemory = gv('hider_freeze_memory', CACHE.freezeMemory);
        CACHE.autoTimeSkipper = gv('hider_auto_time_skipper', false);
        CACHE.autoScroll = gv('hider_auto_scroll', true);
        CACHE.enableContextMenu = gv('hider_enable_contextmenu', true);
        CACHE.autoRemoveBlur = gv('hider_auto_remove_blur', false);
        CACHE.universalProtect = true;
        const storedPaywallLevel = gv('hider_anti_paywall_level', CACHE.antiPaywallLevel || 'off');
        CACHE.antiPaywallLevel = PAYWALL_LEVEL_CONFIG[storedPaywallLevel] ? storedPaywallLevel : 'off';
        CACHE.autoCloseModals = gv('hider_auto_close_modals', false);
        CACHE.cookieConsentMode = gv('hider_cookie_consent_mode', 'ask');
        CACHE.autoCloseLogins = gv('hider_auto_close_logins', false);
        CACHE.filterLists = gv('hider_filter_lists', []);
        CACHE.editRules = gv('hider_edit_rules_v1', []);
        if (gv('hider_last_log_clear_day', '') !== new Date().toDateString()) {
            CACHE.logs = []; sv('hider_global_logs', []); sv('hider_last_log_clear_day', new Date().toDateString());
        }
        applyAllSettings();
    }
    syncCache();

    function disableFreezeMode() {
        isFrozen = false; CACHE.isFrozen = false;
        sv('hider_freeze_global', false);
        shadowBy('btn-freeze')?.classList.remove('is-frozen');
        updateFreezeStatusCard();
        broadcastState();
    }

    // ---------- Stealth Engine (SMART: no class, just proxy) ----------
    // Every native function this script patches is registered here so that
    // Function.prototype.toString still reports "[native code]" for it. Many
    // anti-adblock / anti-tamper probes call fn.toString() on a suspected
    // override before trusting its return value, so a patched function that
    // leaks its real JS source is trivially detectable — this closes that gap
    // for every stealth patch below in one place instead of re-implementing
    // the trick per patch.
    const nativeLookingRegistry = new WeakMap();
    function markNative(fn, name) {
        try { nativeLookingRegistry.set(fn, `function ${name}() { [native code] }`); } catch {}
        return fn;
    }
    try {
        const origFnToString = Function.prototype.toString;
        const patchedFnToString = new Proxy(origFnToString, {
            apply(target, thisArg, args) {
                if (thisArg && nativeLookingRegistry.has(thisArg)) return nativeLookingRegistry.get(thisArg);
                return Reflect.apply(target, thisArg, args);
            }
        });
        markNative(patchedFnToString, 'toString');
        Object.defineProperty(Function.prototype, 'toString', { value: patchedFnToString, writable: true, configurable: true, enumerable: false });
    } catch {}

    // Patches a prototype accessor (offsetWidth, clientHeight, etc.) so that
    // reading it on an element matched by the active hide-selector returns a
    // plausible on-page value instead of the real (zeroed-out) one. Elements
    // that are not currently hidden by this script always fall through to the
    // real, unmodified getter.
    function patchHiddenLayoutGetter(proto, prop, spoofValue) {
        try {
            const desc = Object.getOwnPropertyDescriptor(proto, prop);
            if (!desc || typeof desc.get !== 'function') return;
            const origGetter = desc.get;
            const spoofedGetter = function() {
                try {
                    if (activeHiddenSelector && this instanceof Element && this.matches && this.matches(activeHiddenSelector)) {
                        return typeof spoofValue === 'function' ? spoofValue(this) : spoofValue;
                    }
                } catch {}
                return origGetter.call(this);
            };
            markNative(spoofedGetter, prop);
            Object.defineProperty(proto, prop, { ...desc, get: spoofedGetter });
        } catch {}
    }

    const styleProxyCache = new WeakMap();
    try {
        const origGetComputedStyle = win.getComputedStyle;
        const patchedGetComputedStyle = function(el, pseudo) {
            const style = origGetComputedStyle.apply(this, arguments);
            if (el && el instanceof Element && el.matches && activeHiddenSelector && el.matches(activeHiddenSelector)) {
                let cachedProxy = styleProxyCache.get(style);
                if (!cachedProxy) {
                    cachedProxy = new Proxy(style, {
                        get(target, prop) {
                            switch(prop) {
                                case 'display': return 'block';
                                case 'visibility': return 'visible';
                                case 'opacity': return '1';
                                case 'pointerEvents': return 'auto';
                                default: {
                                    // Some CSSStyleDeclaration getters/methods enforce an internal
                                    // "must be called on a real instance" identity check and throw
                                    // (e.g. "Illegal invocation") when reached through a Proxy. Guard
                                    // every default-path read so one hostile property never crashes
                                    // the whole stealth layer.
                                    let val;
                                    try { val = target[prop]; } catch { return undefined; }
                                    return typeof val === 'function' ? val.bind(target) : val;
                                }
                            }
                        }
                    });
                    styleProxyCache.set(style, cachedProxy);
                }
                return cachedProxy;
            }
            return style;
        };
        markNative(patchedGetComputedStyle, 'getComputedStyle');
        win.getComputedStyle = patchedGetComputedStyle;
    } catch {}

    // Layout-metric probes: the CSS this script applies to hidden elements
    // (width:0, height:0, visibility:hidden, moved off-screen) is exactly what
    // simple anti-adblock/paywall "is the bait element really showing?" checks
    // look for. Spoof the handful of properties those checks actually read.
    try {
        patchHiddenLayoutGetter(HTMLElement.prototype, 'offsetWidth', 96);
        patchHiddenLayoutGetter(HTMLElement.prototype, 'offsetHeight', 40);
        patchHiddenLayoutGetter(Element.prototype, 'clientWidth', 96);
        patchHiddenLayoutGetter(Element.prototype, 'clientHeight', 40);
        patchHiddenLayoutGetter(Element.prototype, 'scrollWidth', 96);
        patchHiddenLayoutGetter(Element.prototype, 'scrollHeight', 40);
    } catch {}

    try {
        const origGetBoundingClientRect = Element.prototype.getBoundingClientRect;
        const makeSpoofRect = () => {
            try {
                if (typeof DOMRect === 'function') return new DOMRect(8, 8, 100, 40);
            } catch {}
            return { x: 8, y: 8, top: 8, left: 8, right: 108, bottom: 48, width: 100, height: 40, toJSON(){ return this; } };
        };
        const patchedGetBoundingClientRect = function() {
            try {
                if (activeHiddenSelector && this instanceof Element && this.matches && this.matches(activeHiddenSelector)) {
                    return makeSpoofRect();
                }
            } catch {}
            return origGetBoundingClientRect.apply(this, arguments);
        };
        markNative(patchedGetBoundingClientRect, 'getBoundingClientRect');
        Element.prototype.getBoundingClientRect = patchedGetBoundingClientRect;
    } catch {}

    try {
        if (typeof Element.prototype.checkVisibility === 'function') {
            const origCheckVisibility = Element.prototype.checkVisibility;
            const patchedCheckVisibility = function() {
                try {
                    if (activeHiddenSelector && this instanceof Element && this.matches && this.matches(activeHiddenSelector)) return true;
                } catch {}
                return origCheckVisibility.apply(this, arguments);
            };
            markNative(patchedCheckVisibility, 'checkVisibility');
            Element.prototype.checkVisibility = patchedCheckVisibility;
        }
    } catch {}

    const isSameDomain = u => cleanDomain(u) && cleanDomain(u) === CURRENT_DOMAIN;

    const isDomainBlocked = u => {
        if (!u || !CACHE.blockedDomainsSet.size) return false;
        const d = cleanDomain(u), lower = String(u).toLowerCase();
        return d && (CACHE.blockedDomainsSet.has(d) || [...CACHE.blockedDomainsSet].some(b => b !== '*' && (d.endsWith('.' + b) || lower.includes(b))));
    };

    const isDomainAllowed = u => {
        if (!u || !CACHE.allowedDomainsSet.size) return false;
        const d = cleanDomain(u), lower = String(u).toLowerCase();
        return d && (CACHE.allowedDomainsSet.has('*') || CACHE.allowedDomainsSet.has(d) || [...CACHE.allowedDomainsSet].some(a => a !== '*' && (d.endsWith('.' + a) || lower.includes(a))));
    };

    // ---------- WILDCARD CONVERSION ----------
    function getBaseName(name) {
        let base = name.replace(/[-_][0-9a-fA-F]+$/, '');
        base = base.replace(/[0-9]+$/, '');
        base = base.replace(/[-_]+$/, '');
        return base || name;
    }

    function convertToWildcardSelector(sel) {
        if (!sel || typeof sel !== 'string') return '';
        return sel.replace(/(?<![#.])(#|\.)([a-zA-Z0-9_-]+)/g, (match, p, name) => {
            if (name.startsWith('hider-')) return match;
            const base = getBaseName(name);
            if (!base) return match;
            return p === '#' ? `[id*="${base}"]` : `[class*="${base}"]`;
        });
    }

    function logBlockedAttempt(url, triggerType) {
        if (!CACHE.logs) CACHE.logs = gv('hider_global_logs', []);
        CACHE.logs.unshift({ url: url || 'about:blank', time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' }), type: triggerType || 'Popup' });
        if (CACHE.logs.length > 50) CACHE.logs.pop();
        if (!timers.logSaveTimer) timers.logSaveTimer = setTimeout(() => { timers.logSaveTimer = null; sv('hider_global_logs', CACHE.logs); }, 1000);
    }

    // ---------- Freeze FX ----------
    function triggerFreezeFx() {
        const fx = doc.createElement('div');
        fx.className = 'hider-freeze-snow-overlay';
        const frag = doc.createDocumentFragment();
        const flakeChars = ['❄', '❅', '❆', '✨', '⚡'];
        for (let i = 0; i < 22; i++) {
            const flake = doc.createElement('div');
            flake.className = 'hider-snow-flake';
            flake.textContent = flakeChars[Math.floor(Math.random() * flakeChars.length)];
            flake.style.cssText = `left:${Math.random() * 98}vw; top:${Math.random() * 60}vh; animation-delay:${Math.random() * 0.35}s; font-size:${14 + Math.random() * 18}px;`;
            frag.appendChild(flake);
        }
        fx.appendChild(frag);
        (doc.body || doc.documentElement)?.appendChild(fx);
        setTimeout(() => fx.remove(), 1450);
    }

    function forceExposeAndPlayVideos() {
        // Never forcibly rewrite social-media players. Their React/media pipeline
        // may legitimately replace the <video> element while a post is playing.
        if (isMediaSensitiveDomain()) return;
        doc.querySelectorAll('video').forEach(v => {
            ['display', 'visibility', 'opacity', 'pointer-events'].forEach(p => v.style.setProperty(p, p === 'display' ? 'block' : p === 'pointer-events' ? 'auto' : '1', 'important'));
            try { v.play()?.catch?.(() => {}); } catch {}
        });
    }

    function triggerVideoResumeChain() {
        if (isMediaSensitiveDomain()) return;
        forceExposeAndPlayVideos();
        [150, 400, 800].forEach(t => setTimeout(forceExposeAndPlayVideos, t));
        broadcastToFrames(window, { type: 'HIDER_RESUME_VIDEOS' });
    }

    function simulateAdWindowSuccess() {
        try {
            win.dispatchEvent(new Event('blur')); doc.dispatchEvent(new Event('visibilitychange'));
            win.onblur?.();
            setTimeout(() => { win.dispatchEvent(new Event('focus')); win.onfocus?.(); }, 60);
            triggerVideoResumeChain();
        } catch {}
    }

    function createDummyWindow() {
        const dummy = {
            closed: false, focus(){}, blur(){}, close(){ this.closed = true; }, postMessage(){},
            location: { href: 'about:blank', replace(u){ if(isDomainBlocked(u)) logBlockedAttempt(u, 'Blocked Dummy Replace'); }, assign(u){ if(isDomainBlocked(u)) logBlockedAttempt(u, 'Blocked Dummy Assign'); } },
            document: { write(){}, close(){}, body:{} }, opener: win
        };
        return new Proxy(dummy, {
            get: (t, p) => p in t ? t[p] : () => {},
            set: (t, p, v) => { if (p === 'location' && isDomainBlocked(v)) logBlockedAttempt(v, 'Blocked Dummy Location Set'); else t[p] = v; return true; }
        });
    }

    function handleFreezeNavigation(url, triggerType, onConfirm, onDeny) {
        if (isDomainBlocked(url)) {
            logBlockedAttempt(url, triggerType + ' (Auto-Block Domain)');
            onDeny?.(); simulateAdWindowSuccess(); return;
        }
        if (isDomainAllowed(url)) {
            userApprovedNavigation = true; onConfirm?.();
            setTimeout(() => userApprovedNavigation = false, 300); return;
        }
        const mem = CACHE.freezeMemory || 'ask';
        if (mem === 'allow_all') {
            disableFreezeMode(); userApprovedNavigation = true; onConfirm?.();
            setTimeout(() => userApprovedNavigation = false, 300); return;
        }
        if (mem === 'block_all') {
            logBlockedAttempt(url, triggerType + ' (Auto-Block)');
            onDeny?.(); simulateAdWindowSuccess(); return;
        }
        if (mem === 'allow_same' && isSameDomain(url)) {
            const domain = getParentDomain(url) || cleanDomain(url);
            if (domain) executeAddAllowedDomain(domain);
            userApprovedNavigation = true; onConfirm?.();
            setTimeout(() => userApprovedNavigation = false, 300); return;
        }
        showFreezePrompt(url, triggerType, onConfirm, onDeny);
    }

    // ---------- Interceptors ----------
    let interceptorsInstalled = false;

    function installInterceptors() {
        if (interceptorsInstalled) return;
        interceptorsInstalled = true;

        try {
            const lp = win.Location ? win.Location.prototype : Object.getPrototypeOf(win.location);
            if (lp) {
                const origA = lp.assign, origR = lp.replace, hrefDesc = Object.getOwnPropertyDescriptor(lp, 'href');

                const checkAndInterceptNav = (u, origFn, contextThis, triggerName) => {
                    if (!featuresEnabled) {
                        return origFn.call(contextThis, u);
                    }
                    if (isDomainBlocked(u)) {
                        logBlockedAttempt(u, `Blocked ${triggerName}`);
                        showToast(`⛔ Blocked ${triggerName}`); simulateAdWindowSuccess(); return;
                    }
                    if (isFrozen && !userApprovedNavigation) {
                        if (isDomainAllowed(u)) {
                            userApprovedNavigation = true; const res = origFn.call(contextThis, u);
                            setTimeout(() => userApprovedNavigation = false, 300); return res;
                        }
                        handleFreezeNavigation(u, triggerName, () => {
                            userApprovedNavigation = true; origFn.call(contextThis, u);
                            setTimeout(() => userApprovedNavigation = false, 300);
                        }, simulateAdWindowSuccess);
                        return;
                    }
                    return origFn.call(contextThis, u);
                };

                if (origA) { lp.assign = function(u) { return checkAndInterceptNav(u, origA, this, 'Redirect (assign)'); }; markNative(lp.assign, 'assign'); }
                if (origR) { lp.replace = function(u) { return checkAndInterceptNav(u, origR, this, 'Redirect (replace)'); }; markNative(lp.replace, 'replace'); }
                if (hrefDesc?.set) {
                    try {
                        const hrefSetter = function(u) { checkAndInterceptNav(u, hrefDesc.set, this, 'Redirect (href)'); };
                        const hrefGetter = function() { return hrefDesc.get.call(this); };
                        markNative(hrefSetter, 'set href'); markNative(hrefGetter, 'get href');
                        Object.defineProperty(lp, 'href', { set: hrefSetter, get: hrefGetter });
                    } catch {}
                }
            }

            const origClick = HTMLAnchorElement.prototype.click;
            const patchedAnchorClick = function() {
                if (!featuresEnabled) return origClick.apply(this, arguments);
                if (isDomainBlocked(this.href)) { logBlockedAttempt(this.href, 'Blocked Click'); showToast('⛔ Blocked link click'); simulateAdWindowSuccess(); return; }
                if (isFrozen && !userApprovedNavigation) {
                    if (isDomainAllowed(this.href)) {
                        userApprovedNavigation = true; const res = origClick.apply(this, arguments);
                        setTimeout(() => userApprovedNavigation = false, 300); return res;
                    }
                    handleFreezeNavigation(this.href, 'Anchor Click', () => {
                        userApprovedNavigation = true; origClick.apply(this, arguments);
                        setTimeout(() => userApprovedNavigation = false, 300);
                    }, simulateAdWindowSuccess);
                    return;
                }
                return origClick.apply(this, arguments);
            };
            markNative(patchedAnchorClick, 'click');
            HTMLAnchorElement.prototype.click = patchedAnchorClick;

            const origOpen = win.open;
            const patchedOpen = function(url, target, features) {
                if (!featuresEnabled) return origOpen.apply(win, arguments);
                if (isDomainBlocked(url)) { logBlockedAttempt(url || 'about:blank', 'Blocked Popup'); simulateAdWindowSuccess(); showToast('⛔ Blocked Popup'); return createDummyWindow(); }
                if (!url || url === 'about:blank') {
                    const realWin = origOpen.apply(win, arguments);
                    return realWin ? new Proxy(realWin, {
                        get: (t, p) => p === 'location' ? new Proxy(t.location, { set: (l, lp, lv) => (lp==='href'||lp==='assign') && isDomainBlocked(lv) ? (logBlockedAttempt(lv, 'Blocked Popup Nav'), showToast('⛔ Blocked popup nav'), t.close(), true) : (l[lp]=lv, true) }) : (typeof t[p]==='function'?t[p].bind(t):t[p]),
                        set: (t, p, v) => p === 'location' && isDomainBlocked(v) ? (logBlockedAttempt(v, 'Blocked Popup Location'), showToast('⛔ Blocked popup nav'), t.close(), true) : (t[p]=v, true)
                    }) : createDummyWindow();
                }
                if (isFrozen && !userApprovedNavigation) {
                    if (isDomainAllowed(url)) {
                        userApprovedNavigation = true; const res = origOpen.apply(win, arguments);
                        setTimeout(() => userApprovedNavigation = false, 300); return res;
                    }
                    handleFreezeNavigation(url, 'win.open()', () => {
                        userApprovedNavigation = true; origOpen.call(win, url, target, features);
                        setTimeout(() => userApprovedNavigation = false, 300);
                    }, () => {});
                    return createDummyWindow();
                }
                return origOpen.apply(win, arguments);
            };
            markNative(patchedOpen, 'open');
            win.open = patchedOpen;
        } catch {}
    }

    // ---------- Broadcast / Sync ----------
    function broadcastToFrames(w, msg) { try { for (let i = 0; i < w.frames.length; i++) { w.frames[i].postMessage(msg, '*'); broadcastToFrames(w.frames[i], msg); } } catch {} }
    function broadcastState() { if (isTop) broadcastToFrames(window, { type: 'HIDER_SYNC_STATE', isSelecting, selectionMode, currentScope, isFrozen }); }

    window.addEventListener('message', e => {
        if (!e.data) return;
        if (e.data.type === 'HIDER_REQUEST_STATE' && isTop) broadcastState();
        if (e.data.type === 'HIDER_SYNC_STATE') {
            ({ isSelecting, selectionMode, currentScope, isFrozen } = e.data);
            selectionMode = selectionMode === 'edit' ? 'edit' : 'hide';
            CACHE.isFrozen = isFrozen;
            syncCache(); requestUpdateStyles();
            shadowBy('btn-select')?.classList.toggle('active', isSelecting && selectionMode === 'hide');
            shadowBy('btn-edit')?.classList.toggle('active', isSelecting && selectionMode === 'edit');
            shadowBy('btn-scope')?.classList.toggle('active', currentScope === 'link');
            shadowBy('btn-scope')?.classList.toggle('scope-global', currentScope === 'global');
            shadowBy('btn-freeze')?.classList.toggle('is-frozen', isFrozen);
            if (!isSelecting) clearSelectionState();
            applyDockButtonVisibility();
        }
        if (e.data.type === 'HIDER_RESUME_VIDEOS') triggerVideoResumeChain();
        if (e.data.type === 'HIDER_SKIP_30') skip30Seconds();
    });

    window.addEventListener('storage', e => {
        if (e.key && e.key.startsWith('hider_')) {
            syncCache(); requestUpdateStyles();
            if (isTop) broadcastState();
            applyDockButtonVisibility();
        }
    });

    if (typeof GM_addValueChangeListener !== 'undefined') {
        ['hider_freeze_global', 'hider_freeze_memory', 'hider_blocked_domains', 'hider_allowed_domains', 'hider_custom_rules_v4', 'hider_auto_time_skipper',
         'hider_auto_scroll', 'hider_enable_contextmenu', 'hider_auto_remove_blur', 'hider_hidden_dock_buttons',
         'hider_anti_paywall_level', 'hider_auto_close_modals', 'hider_cookie_consent_mode', 'hider_auto_close_logins', 'hider_filter_lists'
        ].forEach(key => {
            try { GM_addValueChangeListener(key, () => { syncCache(); requestUpdateStyles(); if (isTop) broadcastState(); applyDockButtonVisibility(); }); } catch {}
        });
    }

    if (!isTop) try { window.top.postMessage({ type: 'HIDER_REQUEST_STATE' }, '*'); } catch {}

    // ---------- Style Update (SMART: signature-based) ----------
    function getRuleSignature() {
        const host = location.hostname;
        const siteRules = gv('hider_site_' + host, []);
        const linkRules = gv('hider_link_' + cleanUrl(), []);
        const customActiveRules = (CACHE.customRules || [])
            .filter(r => {
                if (!r?.selector || r.enabled === false) return false;
                const t = cleanDomain(r.target);
                return t === '*' || t === host || (t && host.endsWith('.' + t));
            })
            .map(r => r.selector);
        const combined = [...new Set([...siteRules, ...linkRules, ...customActiveRules])].filter(Boolean);
        return combined.sort().join('|');
    }

    function requestUpdateStyles(force = false) {
        if (styleUpdateRAF) {
            cancelAnimationFrame(styleUpdateRAF);
            styleUpdateRAF = null;
        }
        styleUpdateRAF = requestAnimationFrame(() => {
            styleUpdateRAF = null;
            updateStyles(force);
        });
    }

    function updateStyles(force = false) {
        const currentSignature = getRuleSignature();
        if (!force && lastRuleSignature === currentSignature) {
            if (CACHE.autoScroll && featuresEnabled) checkAndAutoUnblockScroll();
            return;
        }

        let el = doc.getElementById('hider-dynamic-styles');
        if (!el) {
            el = doc.createElement('style');
            el.id = 'hider-dynamic-styles';
            (doc.head || doc.documentElement)?.appendChild(el);
        }

        const host = location.hostname;
        const siteRules = gv('hider_site_' + host, []);
        const linkRules = gv('hider_link_' + cleanUrl(), []);

        const customActiveRules = (CACHE.customRules || [])
            .filter(r => {
                if (!r?.selector || r.enabled === false) return false;
                const t = cleanDomain(r.target);
                return t === '*' || t === host || (t && host.endsWith('.' + t));
            })
            .map(r => r.selector);

        const combined = [...new Set([...siteRules, ...linkRules, ...customActiveRules])].filter(Boolean);
        const safeCombined = combined.filter(sel => !sel.match(/^document$/i));
        activeHiddenSelector = safeCombined.join(',');

        const hideCss = (featuresEnabled && safeCombined.length)
            ? `${activeHiddenSelector}{opacity:0!important;pointer-events:none!important;position:absolute!important;top:-99999px!important;left:-99999px!important;width:0!important;height:0!important;max-width:0!important;max-height:0!important;overflow:hidden!important;visibility:hidden!important;clip:rect(0,0,0,0)!important}`
            : '';

        const baseAnimationCss = `
        .hider-preview-highlight { outline: none !important; border: 2px solid #38bdf8 !important; background: rgba(56, 189, 248, 0.15) !important; box-shadow: 0 0 24px rgba(56, 189, 248, 0.6), inset 0 0 12px rgba(56, 189, 248, 0.3) !important; transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1) !important; position: relative !important; z-index: 2147483640 !important; cursor: crosshair !important; border-radius: 6px !important; }
        .hider-freeze-snow-overlay { position: fixed !important; top: 0 !important; left: 0 !important; width: 100vw !important; height: 100vh !important; pointer-events: none !important; z-index: 2147483647 !important; overflow: hidden !important; background: radial-gradient(circle at center, rgba(56, 189, 248, 0.18) 0%, transparent 70%) !important; animation: hiderSnowOverlayFade 1.4s cubic-bezier(0.16, 1, 0.3, 1) forwards !important; }
        @keyframes hiderSnowOverlayFade { 0% { opacity: 0; backdrop-filter: blur(0px); } 30% { opacity: 1; backdrop-filter: blur(3px); } 80% { opacity: 1; backdrop-filter: blur(3px); } 100% { opacity: 0; backdrop-filter: blur(0px); } }
        .hider-snow-flake { position: absolute !important; color: #e0f2fe !important; user-select: none !important; pointer-events: none !important; opacity: 0.95 !important; animation: hiderSnowFall 1.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards !important; filter: drop-shadow(0 0 8px rgba(56, 189, 248, 0.9)) !important; }
        @keyframes hiderSnowFall { 0% { transform: translateY(-25px) scale(0.5) rotate(0deg); opacity: 0; } 20% { opacity: 1; } 100% { transform: translateY(140px) scale(1.15) rotate(180deg); opacity: 0; } }`;

        const css = baseAnimationCss + '\n' + hideCss;

        if (cachedCssString !== css) {
            el.textContent = css;
            cachedCssString = css;
        }

        lastRuleSignature = currentSignature;
        if (CACHE.autoScroll && featuresEnabled) checkAndAutoUnblockScroll();
    }
    updateStyles(true);

    // === MOBILE-FRIENDLY PERSISTENCE: Reapply on visibility/focus ===
    function reapplyHiddenStyles() {
        requestUpdateStyles(true);
    }

    document.addEventListener('visibilitychange', () => {
        if (document.visibilityState === 'visible') {
            reapplyHiddenStyles();
        }
    });

    window.addEventListener('focus', reapplyHiddenStyles, { passive: true });

    if (doc.head) {
        observers.headMutationObserver = new MutationObserver((mutations) => {
            for (const mutation of mutations) {
                for (const node of mutation.removedNodes) {
                    if (node.id === 'hider-dynamic-styles') {
                        requestUpdateStyles(true);
                        return;
                    }
                }
            }
        });
        observers.headMutationObserver.observe(doc.head, { childList: true });
    }

    // ============ EDIT ENGINE 17.4 ============
    const EDIT_SITE_PREFIX='hider_edit_site_';
    const EDIT_LINK_PREFIX='hider_edit_link_';
    const EDIT_DB_NAME='hider-edit-media-v1';
    const EDIT_DB_STORE='media';
    const editMediaUrlCache=new Map();
    const getEditStorageKey=(scope=currentScope)=>scope==='global'?'hider_edit_rules_v1':scope==='site'?EDIT_SITE_PREFIX+location.hostname:EDIT_LINK_PREFIX+cleanUrl();
    const readEditRules=(scope=currentScope)=>{const x=gv(getEditStorageKey(scope),[]);return Array.isArray(x)?x:[];};
    const writeEditRules=(scope,rules)=>sv(getEditStorageKey(scope),Array.isArray(rules)?rules:[]);
    function getAllEditRulesForCurrentPage(){const host=location.hostname;return [...readEditRules('global'),...readEditRules('site'),...readEditRules('link')].filter(r=>r&&r.selector);}
    function isEditableMediaElement(el){return !!el&&el.nodeType===1&&['img','video','audio','source','iframe','embed','object'].includes(el.tagName.toLowerCase());}
    function getEditKind(el){if(!el||el.nodeType!==1)return'text';const t=el.tagName.toLowerCase();if(isEditableMediaElement(el))return'media';if(['input','textarea','select'].includes(t))return'value';if(el.isContentEditable||el.getAttribute('contenteditable')==='true')return'text';const role=(el.getAttribute('role')||'').toLowerCase();return ['textbox','spinbutton','combobox'].includes(role)?'value':'text';}
    function getEditCurrentValue(el,kind=getEditKind(el)){if(!el)return'';if(kind==='media')return el.currentSrc||el.src||el.getAttribute('src')||el.getAttribute('data-src')||'';if(kind==='value'&&'value'in el)return String(el.value??'');return String(el.textContent??'');}
    function getTextNodePath(root,target){if(!root||!target)return null;const path=[];let n=target;while(n&&n!==root){const parent=n.parentNode;if(!parent)return null;path.unshift(Array.prototype.indexOf.call(parent.childNodes,n));n=parent;}return n===root?path:null;}
    function resolveTextNodePath(root,path){if(!root||!Array.isArray(path))return null;let n=root;for(const i of path){if(!n?.childNodes?.[i])return null;n=n.childNodes[i];}return n?.nodeType===3?n:null;}
    function findPrimaryTextNode(root){if(!root)return null;const walker=doc.createTreeWalker(root,NodeFilter.SHOW_TEXT,{acceptNode:n=>String(n.nodeValue||'').trim()?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT});return walker.nextNode();}
    function getEditableTextNodes(root){const out=[];if(!root)return out;const walker=doc.createTreeWalker(root,NodeFilter.SHOW_TEXT,{acceptNode:n=>String(n.nodeValue||'').trim()?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT});let n;while((n=walker.nextNode()))out.push(n);return out;}
    function captureEditTypography(el){
        if(!el||el.nodeType!==1)return null;
        try{
            const cs=win.getComputedStyle(el);
            const props=['font-family','font-size','font-weight','font-style','font-stretch','font-variant','font-kerning','font-feature-settings','font-variation-settings','line-height','letter-spacing','word-spacing','text-transform','text-decoration-line','text-decoration-style','text-decoration-thickness','text-underline-offset','color','white-space','text-rendering','vertical-align','direction','unicode-bidi','font-synthesis','font-optical-sizing'];
            const out={}; for(const p of props){const v=cs.getPropertyValue(p);if(v)out[p]=v;} return out;
        }catch{return null;}
    }
    function applyEditTypography(el,typography){
        if(!el||!typography)return false;
        try{for(const [prop,val] of Object.entries(typography)){if(typeof val==='string'&&val)el.style.setProperty(prop,val,'');}return true;}catch{return false;}
    }
    function buildTypographyAwarePreview(targetEl, textValue, typography, patches){
        const wrap=doc.createElement('div');
        wrap.style.cssText='min-height:42px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;';
        if(!targetEl){wrap.textContent=String(textValue??'Preview');if(typography)applyEditTypography(wrap,typography);return wrap;}
        try{
            const clone=targetEl.cloneNode(true); clone.removeAttribute('contenteditable'); if(clone.id)clone.removeAttribute('id');
            const props=['font-family','font-size','font-weight','font-style','font-stretch','font-variant','font-kerning','font-feature-settings','font-variation-settings','line-height','letter-spacing','word-spacing','text-transform','text-decoration-line','text-decoration-style','text-decoration-thickness','text-underline-offset','color','white-space','text-rendering','vertical-align','direction','unicode-bidi','font-synthesis','font-optical-sizing'];
            const srcWalker=doc.createTreeWalker(targetEl,NodeFilter.SHOW_TEXT), dstWalker=doc.createTreeWalker(clone,NodeFilter.SHOW_TEXT);
            const srcNodes=[],dstNodes=[];let a,b;while((a=srcWalker.nextNode()))srcNodes.push(a);while((b=dstWalker.nextNode()))dstNodes.push(b);
            const applyPair=(src,dst)=>{if(src?.parentElement&&dst?.parentElement){const cs=win.getComputedStyle(src.parentElement);for(const prop of props){const v=cs.getPropertyValue(prop);if(v)dst.parentElement.style.setProperty(prop,v,'');}}};
            for(let i=0;i<Math.min(srcNodes.length,dstNodes.length);i++)applyPair(srcNodes[i],dstNodes[i]);
            if(Array.isArray(patches)){for(const patch of patches){let n=Number.isInteger(patch.index)?dstNodes[patch.index]:null;if(!n&&Array.isArray(patch.path)){n=clone;for(const idx of patch.path){n=n?.childNodes?.[idx];}}if(n?.nodeType===3)n.nodeValue=String(patch.value??'');}}
            if(typeof textValue==='string'&&dstNodes[0])dstNodes[0].nodeValue=String(textValue);
            wrap.appendChild(clone); return wrap;
        }catch{wrap.textContent=String(textValue??'Preview');if(typography)applyEditTypography(wrap,typography);return wrap;}
    }

    function captureEditOriginalState(el){
        if(!el)return;
        editOriginalStyleAttr=el.getAttribute('style')||'';
        editOriginalContentEditable=el.getAttribute('contenteditable');
        editOriginalSpellcheck=el.getAttribute('spellcheck');
    }
    function restoreEditOriginalState(el){
        if(!el)return;
        try{if(editOriginalStyleAttr)el.setAttribute('style',editOriginalStyleAttr);else el.removeAttribute('style');}catch{}
        try{if(editOriginalContentEditable===null)el.removeAttribute('contenteditable');else el.setAttribute('contenteditable',editOriginalContentEditable);}catch{}
        try{if(editOriginalSpellcheck===null)el.removeAttribute('spellcheck');else el.setAttribute('spellcheck',editOriginalSpellcheck);}catch{}
    }

    function diffAffixLengths(oldStr,newStr){const oldLen=oldStr.length,newLen=newStr.length;const maxPrefix=Math.min(oldLen,newLen);let prefix=0;while(prefix<maxPrefix&&oldStr.charCodeAt(prefix)===newStr.charCodeAt(prefix))prefix++;const maxSuffix=Math.min(oldLen,newLen)-prefix;let suffix=0;while(suffix<maxSuffix&&oldStr.charCodeAt(oldLen-1-suffix)===newStr.charCodeAt(newLen-1-suffix))suffix++;return{prefix,suffix};}
    // Rebuilds `el`'s content from the pristine pre-edit markup, redistributing
    // only the changed slice of text back into the ORIGINAL run(s) it belongs to.
    // This guarantees every other run keeps its exact original styling (font
    // size, color, superscript, etc.) instead of trusting whatever structure
    // the browser's native contenteditable left behind after typing across
    // differently-styled runs (which can merge/duplicate/lose formatting).
    function reconcileMultiRunText(el,originalHTML,originalFlatText,newFlatText){
        if(!el)return newFlatText;
        try{
            if(originalFlatText===newFlatText)return newFlatText;
            const holder=doc.createElement('div');
            holder.innerHTML=originalHTML;
            const runs=getEditableTextNodes(holder);
            if(runs.length<=1){
                el.innerHTML=originalHTML;
                const node=getEditableTextNodes(el)[0];
                if(node)node.nodeValue=newFlatText; else el.textContent=newFlatText;
                return newFlatText;
            }
            const{prefix,suffix}=diffAffixLengths(originalFlatText,newFlatText);
            const changeStart=prefix, changeEnd=Math.max(prefix,originalFlatText.length-suffix);
            const newMiddle=newFlatText.slice(prefix,newFlatText.length-suffix);
            let cursor=0;
            const runInfo=runs.map(n=>{const text=String(n.nodeValue||'');const start=cursor,end=cursor+text.length;cursor=end;return{node:n,text,start,end};});
            let touched=runInfo.filter(r=>r.end>changeStart&&r.start<changeEnd);
            if(!touched.length){
                touched=[runInfo.find(r=>r.start>=changeStart)||runInfo[runInfo.length-1]];
            }
            touched.forEach((r,i)=>{
                const localStart=Math.max(0,Math.min(r.text.length,changeStart-r.start));
                const localEnd=Math.max(localStart,Math.min(r.text.length,changeEnd-r.start));
                r.node.nodeValue=i===0?(r.text.slice(0,localStart)+newMiddle+r.text.slice(localEnd)):(r.text.slice(0,localStart)+r.text.slice(localEnd));
            });
            el.innerHTML=holder.innerHTML;
            return newFlatText;
        }catch{ try{el.textContent=newFlatText;}catch{}; return newFlatText; }
    }
    function captureTextPatches(el){if(!el)return[];const originalPaths=Array.isArray(editOriginalTextPaths)?editOriginalTextPaths:[];const currentNodes=getEditableTextNodes(el);const patches=[];if(originalPaths.length){originalPaths.forEach((path,index)=>{const n=resolveTextNodePath(el,path)||currentNodes[index];if(n)patches.push({index,path:Array.isArray(path)?path:null,value:String(n.nodeValue||'')});});}else{currentNodes.forEach((n,index)=>{patches.push({index,path:getTextNodePath(el,n),value:String(n.nodeValue||'')});});}return patches;}
    function applyTextPatches(el,patches){if(!el||!Array.isArray(patches))return false;const nodes=getEditableTextNodes(el);let applied=0;for(const patch of patches){let n=Number.isInteger(patch.index)?nodes[patch.index]:null;if(!n&&Array.isArray(patch.path))n=resolveTextNodePath(el,patch.path);if(n){n.nodeValue=String(patch.value??'');applied++;}}return applied>0||patches.length===0;}
    function replacePreservingTextMarkup(el,value){const v=String(value??'');let node=editOriginalTextNodePath?resolveTextNodePath(el,editOriginalTextNodePath):null;if(!node)node=findPrimaryTextNode(el);if(node){node.nodeValue=v;return true;}el.textContent=v;return true;}
    function setEditValue(el,value,kind=getEditKind(el)){if(!el||el.nodeType!==1)return false;try{const v=String(value??''),t=el.tagName.toLowerCase();if(kind==='media'){if(t==='object')el.setAttribute('data',v);else {el.setAttribute('src',v);if(t==='img'||t==='source'){el.removeAttribute('srcset');el.removeAttribute('sizes');}const parent=el.parentElement;if(t==='source'&&parent&&(parent.tagName.toLowerCase()==='video'||parent.tagName.toLowerCase()==='audio')){try{parent.load();}catch{}}}if(t==='video'||t==='audio'){try{el.load();}catch{}}return true;}if(kind==='value'&&'value'in el){let setter=null;try{setter=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(el),'value')?.set;}catch{};if(setter)setter.call(el,v);else el.value=v;try{el.dispatchEvent(new Event('input',{bubbles:true}));el.dispatchEvent(new Event('change',{bubbles:true}));}catch{};return true;}return replacePreservingTextMarkup(el,v);}catch{return false;}}
    async function openEditDB(){return new Promise((resolve,reject)=>{if(!('indexedDB'in win))return resolve(null);const req=win.indexedDB.open(EDIT_DB_NAME,1);req.onupgradeneeded=()=>{try{req.result.createObjectStore(EDIT_DB_STORE);}catch{}};req.onsuccess=()=>resolve(req.result);req.onerror=()=>reject(req.error);});}
    async function putEditMedia(id,blob){try{const db=await openEditDB();if(!db)return false;await new Promise((res,rej)=>{const tx=db.transaction(EDIT_DB_STORE,'readwrite');tx.objectStore(EDIT_DB_STORE).put(blob,id);tx.oncomplete=res;tx.onerror=()=>rej(tx.error);});return true;}catch{return false;}}
    async function getEditMedia(id){try{const db=await openEditDB();if(!db)return null;return await new Promise((res,rej)=>{const tx=db.transaction(EDIT_DB_STORE,'readonly');const q=tx.objectStore(EDIT_DB_STORE).get(id);q.onsuccess=()=>res(q.result||null);q.onerror=()=>rej(q.error);});}catch{return null;}}
    async function deleteEditMedia(id){const u=editMediaUrlCache.get(id);if(u){try{URL.revokeObjectURL(u)}catch{};editMediaUrlCache.delete(id);}try{const db=await openEditDB();if(!db)return;await new Promise(res=>{const tx=db.transaction(EDIT_DB_STORE,'readwrite');tx.objectStore(EDIT_DB_STORE).delete(id);tx.oncomplete=res;tx.onerror=res;});}catch{}}
    function applyEditRuleToElement(el,rule){
        try{
            if(editEditingActive&&el===previewElement)return false;
            if(!el.matches(rule.selector))return false;
            // A saved Edit represents one specific element. For legacy selectors
            // that accidentally match multiple nodes, only the first DOM match is
            // eligible; newly saved rules use unique nth-of-type selectors.
            const all=doc.querySelectorAll(rule.selector);
            if(all.length>1 && all[0]!==el)return false;
        }catch{return false;}
        if(rule.kind==='media'&&rule.mediaRef){
            if(editMediaUrlCache.has(rule.mediaRef)){setEditValue(el,editMediaUrlCache.get(rule.mediaRef),'media');}
            else{getEditMedia(rule.mediaRef).then(b=>{if(!b)return;try{const u=URL.createObjectURL(b);editMediaUrlCache.set(rule.mediaRef,u);setEditValue(el,u,'media');}catch{}});}
            return true;
        }
        if((rule.kind||'text')==='text'&&Array.isArray(rule.textPatches)){try{if(applyTextPatches(el,rule.textPatches))return true;}catch{}}
        if((rule.kind||'text')==='text'&&typeof rule.html==='string'&&rule.html){try{el.innerHTML=rule.html;return true;}catch{}}
        return setEditValue(el,rule.value||'',rule.kind||getEditKind(el));
    }
    function applyEditRulesToNode(node){if(!node||node.nodeType!==1)return;const rules=getAllEditRulesForCurrentPage();if(!rules.length)return;const els=[node];try{for(const c of node.querySelectorAll('*')){els.push(c);if(els.length>=500)break;}}catch{};for(const el of els){for(let i=rules.length-1;i>=0;i--)if(applyEditRuleToElement(el,rules[i]))break;}}
    function applyAllEditRules(){const rules=getAllEditRulesForCurrentPage();if(!rules.length)return;try{let n=0;for(const el of doc.querySelectorAll('*')){for(let i=rules.length-1;i>=0;i--)if(applyEditRuleToElement(el,rules[i]))break;if(++n>=2500)break;}}catch{}}
    function setupEditObserver(){if(observers.editObserver){observers.editObserver.disconnect();observers.editObserver=null;}if(!getAllEditRulesForCurrentPage().length)return;observers.editObserver=new MutationObserver(ms=>{for(const m of ms)for(const n of m.addedNodes||[])if(n.nodeType===1)applyEditRulesToNode(n);});try{observers.editObserver.observe(doc.documentElement,{childList:true,subtree:true});}catch{};applyAllEditRules();}
    function enterEditMode(){
        if(isSelecting&&selectionMode==='edit'){exitEditMode(true);return;}
        // Hide and Edit are mutually exclusive modes.
        if(isSelecting) {
            clearSelectionState();
            isSelecting=false;
        }
        selectionMode='edit';
        isSelecting=true;
        editOriginalCaptured=false;
        editOriginalValue='';
        editInputDraft='';
        editCommitPermanent=true;
        editEditingActive=false;
        editSessionSavedRule=null;
        editSessionPreviousRule=null;
        editSessionPreviousScope=null;
        editSessionSourceRule=null;
        editOriginalHTML='';
        editOriginalTextNodePath=null;
        editOriginalStyleAttr=''; editOriginalContentEditable=null; editOriginalSpellcheck=null; editTypographySnapshot=null; editMenuSession=null;
        editOriginalMediaAttrs=null;
        editOriginalTextPaths=[];
        pendingEditMedia=null;
        shadowBy('btn-select')?.classList.remove('active');
        shadowBy('btn-edit')?.classList.add('active');
        shadowBy('btn-select')?.setAttribute('aria-pressed','false');
        shadowBy('btn-edit')?.setAttribute('aria-pressed','true');
        const p=shadowBy('hider-panel');
        if(p?.classList.contains('is-visible')){p.classList.remove('is-visible');setTimeout(()=>{if(!p.classList.contains('is-visible'))p.style.display='none';},250);}
        shadowBy('btn-manage')?.classList.remove('active');
        showToast('✏️ Edit mode ON – tap an element to select');
        broadcastState();
    }
    function captureEditSessionSnapshot(el){
        if(!el)return;
        // Capture the state exactly when the user presses Edit. This snapshot is
        // temporary for the current edit session and is never written to storage.
        editOriginalKind=getEditKind(el);
        editOriginalValue=getEditCurrentValue(el,editOriginalKind);
        captureEditOriginalState(el);
        editTypographySnapshot=captureEditTypography(el);
        editOriginalHTML=editOriginalKind==='text'?el.innerHTML:'';
        const textNodes=getEditableTextNodes(el);
        editOriginalTextPaths=textNodes.map(n=>getTextNodePath(el,n)).filter(Array.isArray);
        const tn=textNodes[0]||null;
        editOriginalTextNodePath=getTextNodePath(el,tn);
        if(editOriginalKind==='media'){
            editOriginalMediaAttrs={};
            for(const a of ['src','srcset','sizes','data','poster']){
                if(el.hasAttribute?.(a))editOriginalMediaAttrs[a]=el.getAttribute(a);
            }
        } else {
            editOriginalMediaAttrs=null;
        }
        editOriginalCaptured=true;
    }

    function beginDirectEdit(){
        if(!previewElement)return;
        // Always refresh the temporary snapshot here. Selection-time capture can
        // become stale if the page or an existing edit rule changes the element
        // before the user actually starts editing.
        captureEditSessionSnapshot(previewElement);
        editEditingActive=true;
        applyEditTypography(previewElement,editTypographySnapshot);
        const kind=editOriginalKind;
        try{
            if(kind==='text'){
                previewElement.contentEditable='true';
                previewElement.spellcheck=false;
                previewElement.focus();
                const r=doc.createRange(); r.selectNodeContents(previewElement); r.collapse(false);
                const sel=win.getSelection(); sel?.removeAllRanges(); sel?.addRange(r);
                showToast('✏️ Edit directly on the page');
            } else if(kind==='value') {
                previewElement.focus?.();
                if(typeof previewElement.select==='function')previewElement.select();
                showToast('✏️ Edit the value directly on the page');
            } else {
                showToast('🎞️ Choose a file or URL to replace this media');
            }
        }catch{showToast('⚠️ This element cannot be edited directly');}
        renderEditControls();
    }
    async function commitEdit(permanent=editCommitPermanent){
        const el=previewElement;if(!el)return;
        const selector=getExactSelector(el),kind=getEditKind(el);let value='';let mediaRef=null;
        if(kind==='media'){
            value=String(shadowBy('hider-edit-media-url')?.value||'').trim();
            if(pendingEditMedia?.blob&&permanent){const id='editmedia_'+Date.now()+'_'+Math.random().toString(36).slice(2,7);if(await putEditMedia(id,pendingEditMedia.blob))mediaRef=id;}
            if(!value&&!mediaRef&&pendingEditMedia?.objectUrl)value=pendingEditMedia.objectUrl;
            if(!value&&!mediaRef)return showToast('⚠️ Choose a file or enter a media URL');
            if(!permanent&&pendingEditMedia?.blob&&pendingEditMedia.objectUrl){
                try{const keepUrl=pendingEditMedia.objectUrl;const node=el;
                    const release=()=>{try{URL.revokeObjectURL(keepUrl)}catch{}};
                    if(node.tagName.toLowerCase()==='img') node.addEventListener('load',release,{once:true});
                    else if(node.tagName.toLowerCase()==='video'||node.tagName.toLowerCase()==='audio') node.addEventListener('loadeddata',release,{once:true});
                    setTimeout(release,60000);
                    pendingEditMedia.keepObjectUrl=true;
                }catch{}
            }
        } else if(kind==='value') value=String('value'in el?el.value:'');
        else { value=String(el.textContent??''); }
        if(mediaRef){const blob=await getEditMedia(mediaRef);if(!blob)return showToast('❌ Stored media could not be loaded');try{if(!setEditValue(el,URL.createObjectURL(blob),'media'))return showToast('❌ Unable to replace this media');}catch{return showToast('❌ Unable to replace this media');}}
        else if(kind==='text'){
            // The element was already edited live via contenteditable, and it may
            // contain multiple styled text runs (e.g. a superscript price, mixed
            // font sizes). Reconcile against the pristine pre-edit markup so only
            // the actually-changed text moves, and every run keeps its own
            // original font/styling instead of being flattened into one node.
            try{value=reconcileMultiRunText(el,editOriginalHTML,editOriginalValue,value);}catch{if(!setEditValue(el,value,kind))return showToast('❌ Unable to edit this element');}
        }
        else if(!setEditValue(el,value,kind))return showToast('❌ Unable to edit this element');
        if(permanent){
            const rule={id:'edit_'+Date.now()+'_'+Math.random().toString(36).slice(2,7),selector,kind,value:mediaRef?'':value,html:'',textPatches:kind==='text'?captureTextPatches(el):null,textNodePath:kind==='text'?(editOriginalTextNodePath||getTextNodePath(el,findPrimaryTextNode(el))):null,typography:editTypographySnapshot||captureEditTypography(el),mediaRef,target:currentScope==='global'?'*':currentScope==='site'?location.hostname:cleanUrl(),scope:currentScope,updatedAt:Date.now()};
            const rules=readEditRules(currentScope),i=rules.findIndex(r=>r.selector===selector);
            if(editSessionSavedRule===null){
                editSessionPreviousRule=i>=0?{...rules[i]}:null;
                editSessionPreviousScope=currentScope;
            }
            if(i>=0)rules[i]=rule;else rules.push(rule);
            writeEditRules(currentScope,rules);
            editSessionSavedRule={...rule};
            setupEditObserver();showToast('✏️ Permanent edit saved');
        }else showToast('✏️ Edited one time');
        exitEditMode(false);
    }
    async function savePermanentMediaEdit(){
        const el=previewElement;
        if(!el||getEditKind(el)!=='media')return false;
        const selector=getExactSelector(el);
        if(!selector)return false;
        const scope=currentScope;
        const url=String(shadowBy('hider-edit-media-url')?.value||'').trim();
        let mediaRef='';
        let value=url;
        if(pendingEditMedia?.blob){
            const id='editmedia_'+Date.now()+'_'+Math.random().toString(36).slice(2,7);
            if(!await putEditMedia(id,pendingEditMedia.blob))return false;
            mediaRef=id;
            value='';
        }
        if(!value&&!mediaRef)return false;
        const rules=readEditRules(scope);
        const index=rules.findIndex(r=>r&&r.selector===selector);
        if(editSessionSavedRule===null){
            editSessionPreviousRule=index>=0?{...rules[index]}:null;
            editSessionPreviousScope=scope;
        }
        const rule={id:'edit_'+Date.now()+'_'+Math.random().toString(36).slice(2,7),selector,kind:'media',value,mediaRef,target:scope==='global'?'*':scope==='site'?location.hostname:cleanUrl(),scope,updatedAt:Date.now(),typography:editTypographySnapshot||captureEditTypography(el)};
        const oldSessionMediaRef=editSessionSavedRule?.mediaRef||'';
        if(index>=0)rules[index]=rule;else rules.push(rule);
        writeEditRules(scope,rules);
        editSessionSavedRule={...rule};
        if(oldSessionMediaRef&&oldSessionMediaRef!==mediaRef)await deleteEditMedia(oldSessionMediaRef);
        setupEditObserver();
        return true;
    }

    async function rollbackEditSessionRule(){
        if(!editSessionSavedRule||!editSessionPreviousScope)return;
        const rules=readEditRules(editSessionPreviousScope);
        const index=rules.findIndex(r=>r&&r.id===editSessionSavedRule.id);
        if(index<0)return;
        if(editSessionPreviousRule)rules[index]=editSessionPreviousRule;
        else rules.splice(index,1);
        writeEditRules(editSessionPreviousScope,rules);
        if(editSessionSavedRule.mediaRef&&!editSessionPreviousRule?.mediaRef)await deleteEditMedia(editSessionSavedRule.mediaRef);
    }

    async function exitEditMode(restore=false){
        const sessionEl=previewElement;
        if(restore&&sessionEl&&editOriginalCaptured){
            // Cancel is a true transaction rollback: restore the exact DOM/style
            // snapshot captured when Edit was pressed before closing the editor.
            restoreOriginalEditContent(sessionEl);
            restoreEditOriginalState(sessionEl);
        }
        if(restore)await rollbackEditSessionRule();
        if(previewElement&&editEditingActive&&editOriginalKind==='text'&&previewElement.isContentEditable){try{previewElement.contentEditable='false';}catch{}}
        const pendingUrl=pendingEditMedia?.objectUrl;
        if(pendingUrl&&!pendingEditMedia?.keepObjectUrl){try{URL.revokeObjectURL(pendingUrl)}catch{}}
        pendingEditMedia=null;
        editEditingActive=false;
        isSelecting=false;
        selectionMode='edit';
        shadowBy('btn-select')?.classList.remove('active');
        shadowBy('btn-edit')?.classList.remove('active');
        shadowBy('btn-select')?.setAttribute('aria-pressed','false');
        shadowBy('btn-edit')?.setAttribute('aria-pressed','false');
        clearSelectionState();
        editOriginalCaptured=false; editOriginalValue=''; editInputDraft=''; editOriginalStyleAttr=''; editOriginalContentEditable=null; editOriginalSpellcheck=null; editTypographySnapshot=null;
        editSessionSavedRule=null; editSessionPreviousRule=null; editSessionPreviousScope=null; editSessionSourceRule=null; editOriginalHTML=''; editOriginalTextNodePath=null; editOriginalMediaAttrs=null; editOriginalTextPaths=[];
        broadcastState();
    }

    function restoreOriginalEditContent(el){if(!el)return false;try{if(editOriginalKind==='text'&&editOriginalHTML!==''){el.innerHTML=editOriginalHTML;return true;}if(editOriginalKind==='media'&&editOriginalMediaAttrs){for(const a of ['src','srcset','sizes','data','poster']){if(Object.prototype.hasOwnProperty.call(editOriginalMediaAttrs,a)){const v=editOriginalMediaAttrs[a];if(v==null)el.removeAttribute(a);else el.setAttribute(a,v);}else if(a==='src'||a==='data'||a==='poster'){el.removeAttribute(a);}}if(['video','audio'].includes(el.tagName.toLowerCase()))try{el.load();}catch{}return true;}return setEditValue(el,editOriginalValue,editOriginalKind);}catch{return false;}}
    function openSavedEditRule(rule,scope){
        if(!rule?.selector)return false;
        let el=null;
        try{el=doc.querySelector(rule.selector);}catch{}
        if(!el){showToast('⚠️ Saved edit target is not on this page');return false;}
        if(isSelecting)clearSelectionState();
        selectionMode='edit';isSelecting=true;previewElement=el;el.classList.add('hider-preview-highlight');
        currentScope=scope;editCommitPermanent=true;editEditingActive=false;pendingEditMedia=null;
        editSessionSavedRule={...rule};editSessionPreviousRule={...rule};editSessionPreviousScope=scope;editSessionSourceRule={...rule};
        editOriginalKind=rule.kind||getEditKind(el);editOriginalValue=getEditCurrentValue(el,editOriginalKind);captureEditOriginalState(el);editTypographySnapshot=rule.typography||captureEditTypography(el);editOriginalHTML=editOriginalKind==='text'?el.innerHTML:'';applyEditTypography(el,editTypographySnapshot);
        const textNodes=getEditableTextNodes(el);editOriginalTextPaths=Array.isArray(rule.textPatches)?rule.textPatches.map(x=>x.path).filter(Array.isArray):textNodes.map(n=>getTextNodePath(el,n)).filter(Array.isArray);const tn=textNodes[0]||null;editOriginalTextNodePath=Array.isArray(rule.textNodePath)?rule.textNodePath:getTextNodePath(el,tn);if(editOriginalKind==='media'){editOriginalMediaAttrs={};for(const a of ['src','srcset','sizes','data','poster']){if(el.hasAttribute?.(a))editOriginalMediaAttrs[a]=el.getAttribute(a);}}editOriginalCaptured=true;
        renderTouchStepperUI();
        showToast('✏️ Editing saved rule');
        return true;
    }

    function renderEditControls(){
        const st=shadowBy(STEPPER_BAR_ID);
        if(!st||!previewElement||selectionMode!=='edit')return false;
        const old=st.querySelector('#hider-edit-controls'); old?.remove();
        const kind=getEditKind(previewElement);

        const box=doc.createElement('div');
        box.id='hider-edit-controls';
        box.className='hider-edit-editor';

        const head=doc.createElement('div');
        head.className='hider-edit-editor-head';
        const title=doc.createElement('div');
        title.className='hider-edit-editor-title';
        title.textContent=kind==='media'?'MEDIA REPLACER':kind==='value'?'FIELD EDITOR':'TEXT EDITOR';
        const sub=doc.createElement('div');
        sub.className='hider-edit-editor-sub';
        sub.textContent=kind==='media'?'Choose a file or provide a media URL.':kind==='value'?'Edit the field value directly on the page.':'Edit the selected text directly on the page. Site styling stays untouched.';
        head.append(title,sub);
        box.appendChild(head);

        if(kind==='media'){
            const sourceRow=doc.createElement('div');
            sourceRow.className='hider-edit-source-row';
            const file=doc.createElement('input');
            file.type='file'; file.accept='image/*,video/*,audio/*'; file.style.display='none';
            const choose=doc.createElement('button');
            choose.type='button'; choose.className='hider-edit-source-btn'; choose.textContent='📁 Choose File';
            choose.setAttribute('aria-label','Choose media file');
            choose.onclick=e=>{e.stopPropagation();file.click();};
            const urlBtn=doc.createElement('button');
            urlBtn.type='button'; urlBtn.className='hider-edit-source-btn'; urlBtn.textContent='🔗 URL';
            urlBtn.setAttribute('aria-expanded','false');
            const url=doc.createElement('input');
            url.id='hider-edit-media-url'; url.type='url'; url.placeholder='Paste media URL…';
            url.className='hider-edit-url';
            url.hidden=true;
            urlBtn.onclick=e=>{
                e.stopPropagation();
                const open=!!url.hidden;
                url.hidden=!open;
                urlBtn.setAttribute('aria-expanded',String(open));
                if(open){url.focus();}
            };
            url.oninput=()=>{
                if(!url.value.trim())return;
                pendingEditMedia=null;
                try{setEditValue(previewElement,url.value.trim(),'media');}catch{}
            };
            url.onkeydown=e=>{if(e.key==='Escape'){e.preventDefault();url.hidden=true;urlBtn.setAttribute('aria-expanded','false');} if(e.key==='Enter'){e.preventDefault();e.stopPropagation();}};

            file.onchange=()=>{
                const f=file.files?.[0]; if(!f)return;
                const oldUrl=pendingEditMedia?.objectUrl;
                if(oldUrl)try{URL.revokeObjectURL(oldUrl)}catch{}
                const u=URL.createObjectURL(f);
                pendingEditMedia={blob:f,objectUrl:u};
                url.value=''; url.hidden=true; urlBtn.setAttribute('aria-expanded','false');
                try{setEditValue(previewElement,u,'media');showToast('🎞️ File selected — press ✅ to save');}
                catch{showToast('⚠️ Unable to preview this file');}
            };
            sourceRow.append(choose,urlBtn,file);
            box.appendChild(sourceRow);
            box.appendChild(url);
        }else{
            const edit=doc.createElement('button');
            edit.type='button'; edit.className='hider-edit-main-btn';
            edit.textContent=editEditingActive?'✏️ Editing…':'✏️ Edit';
            edit.setAttribute('aria-label','Edit selected element directly on page');
            edit.onclick=e=>{
                e.stopPropagation();
                if(!editEditingActive)beginDirectEdit();
            };
            box.appendChild(edit);
        }

        const modeRow=doc.createElement('div');
        modeRow.className='hider-edit-mode-row';
        const modeLabel=doc.createElement('span');
        modeLabel.className='hider-edit-mode-label';
        modeLabel.textContent='SAVE MODE';
        const mode=doc.createElement('button');
        mode.type='button'; mode.className='hider-edit-mode';
        const syncMode=()=>{
            mode.textContent=editCommitPermanent?'Permanent':'One Time';
            mode.classList.toggle('is-permanent',editCommitPermanent);
            mode.classList.toggle('is-onetime',!editCommitPermanent);
            mode.setAttribute('aria-pressed',String(editCommitPermanent));
        };
        mode.title='Switch between Permanent and One Time';
        mode.onclick=e=>{e.stopPropagation();editCommitPermanent=!editCommitPermanent;syncMode();};
        syncMode();
        modeRow.append(modeLabel,mode);
        box.appendChild(modeRow);

        const actionRow=doc.createElement('div');
        actionRow.className='hider-edit-actions';
        const save=doc.createElement('button');
        save.type='button'; save.className='hider-edit-icon-btn hider-edit-save'; save.textContent='✅';
        save.title=editCommitPermanent?'Save Permanent Edit':'Save One Time Edit';
        save.setAttribute('aria-label','Save edit');
        save.onclick=async e=>{
            e.stopPropagation();
            await commitEdit(editCommitPermanent);
        };
        const cancel=doc.createElement('button');
        cancel.type='button'; cancel.className='hider-edit-icon-btn hider-edit-cancel'; cancel.textContent='❌';
        cancel.title='Cancel and restore original';
        cancel.setAttribute('aria-label','Cancel edit');
        cancel.onclick=async e=>{e.stopPropagation();await exitEditMode(true);};
        actionRow.append(save,cancel);
        box.appendChild(actionRow);
        st.appendChild(box);
        return true;
    }

    // Apply saved edits after the Edit engine declarations are initialized.
    setupEditObserver();

    // ---------- Selector Helpers ----------
    function safeCSSEscape(str) { return (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') ? CSS.escape(str) : str.replace(/([!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~])/g, '\\$1'); }

    function getExactSelector(el) {
        if (!el || el.nodeType !== 1) return '';
        const clean = s => safeCSSEscape(String(s || ''));
        const parts = [];
        let curr = el;
        while (curr && curr.nodeType === 1 && curr.tagName.toLowerCase() !== 'html') {
            const tag = curr.tagName.toLowerCase();
            if (tag === 'body') { parts.unshift('body'); break; }

            // IDs are only used when unique on the current document.
            if (curr.id && !curr.id.startsWith('hider-') && !/^\d+$/.test(curr.id) && curr.id.length < 80) {
                const idSel = `#${clean(curr.id)}`;
                try { if (doc.querySelectorAll(idSel).length === 1) { parts.unshift(idSel); break; } } catch {}
            }

            // Always include structural position. Classes alone are not an exact
            // selector because many sites reuse the same class on sibling cards.
            let index = 1;
            let sib = curr.previousElementSibling;
            while (sib) { if (sib.tagName === curr.tagName) index++; sib = sib.previousElementSibling; }
            parts.unshift(`${tag}:nth-of-type(${index})`);
            curr = curr.parentElement;
        }
        const selector = parts.join(' > ');
        if (!selector) return '';
        try {
            const matches = doc.querySelectorAll(selector);
            if (matches.length === 1) return selector;
        } catch {}

        // Final fallback: refine the last component with all same-tag position
        // information until it resolves to the selected element only.
        try {
            let node = el;
            const fallback = [];
            while (node && node.nodeType === 1 && node !== doc.documentElement) {
                let idx = 1, n = node.previousElementSibling;
                while (n) { if (n.tagName === node.tagName) idx++; n = n.previousElementSibling; }
                fallback.unshift(`${node.tagName.toLowerCase()}:nth-of-type(${idx})`);
                node = node.parentElement;
            }
            const fb = fallback.join(' > ');
            if (doc.querySelectorAll(fb).length === 1) return fb;
        } catch {}
        return selector;
    }

    // ---------- Drag Listeners ----------
    function attachDragListeners(barEl, handleEl) {
        if (!handleEl) return;
        let startX, startY, initialX, initialY;

        const onMove = e => {
            if (!isDraggingStepper) return;
            if (e.cancelable) e.preventDefault();
            const p = e.touches ? e.touches[0] : e, maxX = win.innerWidth - barEl.offsetWidth, maxY = win.innerHeight - barEl.offsetHeight;
            stepperPos = { x: Math.max(0, Math.min(maxX, initialX + (p.clientX - startX))), y: Math.max(0, Math.min(maxY, initialY + (p.clientY - startY))) };
            barEl.style.setProperty('left', `${stepperPos.x}px`, 'important'); barEl.style.setProperty('top', `${stepperPos.y}px`, 'important');
            barEl.style.setProperty('right', 'auto', 'important'); barEl.style.setProperty('bottom', 'auto', 'important'); barEl.style.setProperty('transform', 'none', 'important');
        };

        const onEnd = () => {
            if (isDraggingStepper) { isDraggingStepper = false; }
            win.removeEventListener('mousemove', onMove); win.removeEventListener('mouseup', onEnd);
            win.removeEventListener('touchmove', onMove); win.removeEventListener('touchend', onEnd); win.removeEventListener('touchcancel', onEnd);
        };

        const onStart = e => {
            if (e.target.tagName === 'BUTTON') return;
            if (e.cancelable) e.preventDefault();
            isDraggingStepper = true;
            const p = e.touches ? e.touches[0] : e, r = barEl.getBoundingClientRect();
            startX = p.clientX; startY = p.clientY; initialX = r.left; initialY = r.top;
            barEl.style.setProperty('right', 'auto', 'important');
            barEl.style.setProperty('bottom', 'auto', 'important');
            barEl.style.setProperty('transform', 'none', 'important');
            barEl.style.setProperty('margin', '0', 'important');
            barEl.style.setProperty('left', `${initialX}px`, 'important');
            barEl.style.setProperty('top', `${initialY}px`, 'important');
            win.addEventListener('mousemove', onMove, { passive: false }); win.addEventListener('mouseup', onEnd);
            win.addEventListener('touchmove', onMove, { passive: false }); win.addEventListener('touchend', onEnd); win.addEventListener('touchcancel', onEnd);
        };
        handleEl.addEventListener('mousedown', onStart, { passive: false });
        handleEl.addEventListener('touchstart', onStart, { passive: false });
    }

    function clearSelectionState() {
        previewElement?.classList.remove('hider-preview-highlight'); previewElement = null; stepperStack = [];
        const stepper = shadowBy(STEPPER_BAR_ID);
        if (stepper) {
            stepper.remove();
        }
        globalScopeTemp = false;
    }

    function turnOffHideMode() {
        if (isSelecting) {
            if(selectionMode==='edit') {
                exitEditMode(true);
                showToast('✏️ Edit selection cancelled');
                return;
            }
            isSelecting = false;
            shadowBy('btn-select')?.classList.remove('active');
            shadowBy('btn-edit')?.classList.remove('active');
            selectionMode='hide';
            clearSelectionState(); broadcastState();
            showToast('🎯 Selection mode OFF');
        }
        globalScopeTemp = false;
    }

    function closeAllMenus(e, force = false) {
        if (!shadowRoot) return false;
        if (!force) {
            if (isSelecting || isDraggingDock || isDraggingStepper) return false;
            const active = shadowRoot.activeElement || doc.activeElement;
            if (active && (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA')) return false;
            const path = e?.composedPath?.() || [];
            if (path.length > 0 && path.some(el => el.id === UI_HOST_ID || el.id === STEPPER_BAR_ID)) return false;
            if (shadowBy('hider-panel')?.querySelector('.is-editing')) return false;
        }

        const panel = shadowBy('hider-panel'), menu = shadowBy('hider-dock-menu'), mainBtn = shadowBy('btn-toggle-dock'), dockEl = shadowBy('hider-main-dock');
        let closed = false;
        shadowRoot.querySelectorAll('.h-custom-select').forEach(c => c.classList.remove('is-open'));

        if (linkPanelEl && linkPanelEl.classList.contains('is-visible')) {
            linkPanelEl.classList.remove('is-visible');
            setTimeout(() => linkPanelEl.style.display = 'none', 300);
            closed = true;
        }

        if (panel && panel.classList.contains('is-visible')) {
            panel.classList.remove('is-visible');
            setTimeout(()=> { if(!panel.classList.contains('is-visible')) panel.style.display='none'; }, 300);
            shadowBy('btn-manage')?.classList.remove('active');
            closed = true;
        }
        if (menu && menu.classList.contains('is-open')) {
            menu.classList.remove('is-open'); mainBtn?.classList.remove('expanded'); dockEl?.classList.remove('expanded'); dockEl?.classList.add('manual-hidden');
            if (timers.collapseTimer) clearTimeout(timers.collapseTimer);
            timers.collapseTimer = setTimeout(() => { dockEl?.classList.add('is-collapsed'); timers.collapseTimer = null; }, 1000);
            closed = true;
        }
        return closed;
    }

    // ---------- Edit Control Panel Reliability ----------
    function ensureEditControlPanel() {
        if (!isSelecting || selectionMode !== 'edit' || !previewElement || !shadowRoot) return false;
        try {
            let stepper = shadowBy(STEPPER_BAR_ID);
            // Create the stepper only if it is missing. Never recurse through
            // renderTouchStepperUI() when that renderer is already in the Edit path.
            if (!stepper) {
                renderTouchStepperUI();
                stepper = shadowBy(STEPPER_BAR_ID);
            }
            if (!stepper) return false;
            stepper.hidden = false;
            stepper.style.setProperty('display','flex','important');
            stepper.style.setProperty('visibility','visible','important');
            stepper.style.setProperty('opacity','1','important');
            stepper.style.setProperty('pointer-events','auto','important');
            stepper.style.setProperty('z-index','2147483646','important');
            renderEditControls();
            return !!shadowBy('hider-edit-controls');
        } catch (err) {
            try { console.debug('[Hide Web Elements Pro] Edit panel render failed', err); } catch {}
            return false;
        }
    }

    // ---------- Stepper UI ----------
    function renderTouchStepperUI() {
        if (!shadowRoot) return;
        let stepper = shadowBy(STEPPER_BAR_ID);
        if (!previewElement) { stepper?.remove(); return; }
        if (selectionMode === 'edit' && !editOriginalCaptured) { captureEditSessionSnapshot(previewElement); }
        if (!stepper) {
            stepper = doc.createElement('div'); stepper.id = STEPPER_BAR_ID;
            shadowRoot.appendChild(stepper);
        }

        stepper.className = 'h-glass h-stepper-pill';
        if (stepperPos.x !== null && stepperPos.y !== null) {
            stepper.style.setProperty('left', `${stepperPos.x}px`, 'important');
            stepper.style.setProperty('top', `${stepperPos.y}px`, 'important');
            stepper.style.setProperty('bottom', 'auto', 'important');
            stepper.style.setProperty('right', 'auto', 'important');
            stepper.style.setProperty('transform', 'none', 'important');
            stepper.style.setProperty('margin', '0', 'important');
        } else {
            stepper.style.setProperty('left', '50%', 'important');
            stepper.style.setProperty('top', 'auto', 'important');
            stepper.style.setProperty('bottom', '24px', 'important');
            stepper.style.setProperty('right', 'auto', 'important');
            stepper.style.setProperty('transform', 'translateX(-50%)', 'important');
            stepper.style.setProperty('margin', '0', 'important');
        }

        let stepperExtrasHtml = '';
        if (selectionMode !== 'edit') {
            const tag = previewElement.tagName.toLowerCase(), c = typeof previewElement.className === 'string' ? previewElement.className.trim().split(/\s+/)[0] : '';
            const classStr = c && !c.startsWith('hider-') ? `.${c}` : '', idStr = previewElement.id && !previewElement.id.startsWith('hider-') ? `#${previewElement.id}` : '';
            const fullText = `${tag}${idStr}${classStr}`;
            const isLongText = fullText.length > 14;
            stepperExtrasHtml = `
                <div class="h-stepper-row">
                    <button id="hider-step-up" class="h-btn-icon" title="Select Parent Element">▲</button>
                    <button id="hider-step-down" class="h-btn-icon" title="Select Child Element">▼</button>
                </div>
                <div class="h-tag-badge-box" title="${fullText}">
                    <span class="h-tag-badge-text ${isLongText ? 'is-animating' : ''}">${fullText}</span>
                </div>
            `;
        }

        stepper.innerHTML = `
            <div id="hider-drag-handle" class="h-drag-dots" title="Drag Selector Bar">⠿</div>
            ${stepperExtrasHtml}
            <div class="h-stepper-row" style="display:flex;flex-direction:column;gap:4px;width:100%;">
                ${selectionMode==='edit' ? '' : '<button id="hider-step-confirm" class="h-btn-pill btn-blue" style="width:100%;">🙈 Hide</button><button id="hider-step-undo" class="h-btn-pill btn-gray" style="width:100%;">↩️ Undo</button><button id="hider-step-cancel" class="h-btn-pill btn-red" style="width:100%;">✖ Cancel</button>'}
            </div>
        `;

        attachDragListeners(stepper, stepper.querySelector('#hider-drag-handle'));

        if (selectionMode !== 'edit') {
            stepper.querySelector('#hider-step-up').onclick = e => {
                e.stopPropagation(); const p = previewElement.parentElement;
                if (p && p !== doc.body && p !== doc.documentElement && p.id !== UI_HOST_ID) {
                    previewElement.classList.remove('hider-preview-highlight'); stepperStack.push(previewElement);
                    previewElement = p; previewElement.classList.add('hider-preview-highlight'); renderTouchStepperUI();
                } else showToast('⛰️ Top parent reached');
            };
            stepper.querySelector('#hider-step-down').onclick = e => {
                e.stopPropagation();
                if (stepperStack.length || previewElement.firstElementChild) {
                    previewElement.classList.remove('hider-preview-highlight');
                    previewElement = stepperStack.length ? stepperStack.pop() : previewElement.firstElementChild;
                    previewElement.classList.add('hider-preview-highlight'); renderTouchStepperUI();
                }
            };
        }

        if(selectionMode==='edit') {
            stepper.querySelector('#hider-step-confirm')?.remove();
            stepper.querySelector('#hider-step-undo')?.remove();
            stepper.querySelector('#hider-step-cancel')?.remove();
            // Render the editor directly after the stepper DOM is built. A single
            // RAF retry only runs when the editor did not materialize.
            renderEditControls();
            if (!shadowBy('hider-edit-controls') && typeof win.requestAnimationFrame === 'function') {
                win.requestAnimationFrame(() => {
                    if (isSelecting && selectionMode === 'edit' && previewElement) ensureEditControlPanel();
                });
            }
        } else {
            stepper.querySelector('#hider-step-confirm').onclick = e => { e.stopPropagation(); confirmHideSelectedElement(); };
            stepper.querySelector('#hider-step-undo').onclick = e => { e.stopPropagation(); undoLastHide(); };
            stepper.querySelector('#hider-step-cancel').onclick = e => { e.stopPropagation(); clearSelectionState(); showToast('❌ Selection cancelled'); };
        }
    }

    function confirmHideSelectedElement() {
        if (!previewElement) return;
        const el = previewElement;
        el.classList.remove('hider-preview-highlight');
        const sel = getExactSelector(el);
        if (sel) {
            if (/^(html|body)$/i.test(sel)) {
                if (!confirm('⚠️ Warning: You are about to hide the entire page (html/body). Are you sure?')) {
                    clearSelectionState();
                    showToast('❌ Cancelled hiding entire page');
                    return;
                }
            }
            lastHiddenSelector = sel;
            if (currentScope === 'global') {
                const rule = { id: 'rule_' + Date.now(), selector: sel, target: '*' };
                CACHE.customRules.push(rule);
                sv('hider_custom_rules_v4', CACHE.customRules);
                showToast('🌐 Global hide rule added!');
            } else if (currentScope === 'site') {
                const key = 'hider_site_' + location.hostname;
                const s = gv(key, []); if (!s.includes(sel)) { s.push(sel); sv(key, s); }
                showToast('🌐 Site-wide hide rule added!');
            } else { // link
                const key = 'hider_link_' + cleanUrl();
                const s = gv(key, []); if (!s.includes(sel)) { s.push(sel); sv(key, s); }
                showToast('📄 Page-only hide rule added!');
            }
        }
        requestUpdateStyles(); clearSelectionState();
    }

    // ---------- Undo Last Hide ----------
    function undoLastHide() {
        if (!lastHiddenSelector) {
            showToast('⚠️ No hidden element to undo');
            return;
        }
        let found = false;
        for (let i = 0; i < CACHE.customRules.length; i++) {
            if (CACHE.customRules[i].selector === lastHiddenSelector) {
                CACHE.customRules.splice(i, 1);
                sv('hider_custom_rules_v4', CACHE.customRules);
                found = true;
                break;
            }
        }
        if (!found) {
            const key = 'hider_site_' + location.hostname;
            let rules = gv(key, []);
            let idx = rules.indexOf(lastHiddenSelector);
            if (idx !== -1) {
                rules.splice(idx, 1);
                sv(key, rules);
                found = true;
            } else {
                const linkKey = 'hider_link_' + cleanUrl();
                rules = gv(linkKey, []);
                idx = rules.indexOf(lastHiddenSelector);
                if (idx !== -1) {
                    rules.splice(idx, 1);
                    sv(linkKey, rules);
                    found = true;
                }
            }
        }
        if (found) {
            requestUpdateStyles();
            showToast('↩️ Undone last hide');
            lastHiddenSelector = null;
        } else {
            showToast('⚠️ Selector not found in rules');
        }
    }

    // ---------- Toast ----------
    function showToast(msg) {
        let targetRoot = shadowRoot;
        if (!targetRoot) targetRoot = doc.body;
        if (!targetRoot) return;

        const existing = targetRoot.querySelector('#hider-toast');
        if (existing) existing.remove();

        const toast = doc.createElement('div');
        toast.id = 'hider-toast';
        toast.className = 'h-glass h-toast';
        toast.textContent = msg;

        Object.assign(toast.style, {
            position: 'fixed',
            bottom: '70px',
            left: '50%',
            transform: 'translateX(-50%) translateY(16px)',
            opacity: '0',
            padding: '6px 16px',
            fontSize: '11px',
            fontWeight: '700',
            zIndex: '2147483647',
            pointerEvents: 'none',
            transition: 'all .3s ease',
            textAlign: 'center',
            borderRadius: '20px',
            border: '1px solid rgba(56,189,248,.5)',
            color: '#e0f2fe',
            background: 'rgba(13,18,30,0.95)',
            backdropFilter: 'blur(12px)',
            WebkitBackdropFilter: 'blur(12px)',
            boxShadow: '0 12px 30px rgba(0,0,0,0.6)',
            fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, sans-serif',
            lineHeight: '1.3',
            maxWidth: '90vw',
            whiteSpace: 'nowrap'
        });

        targetRoot.appendChild(toast);
        requestAnimationFrame(() => {
            toast.style.opacity = '1';
            toast.style.transform = 'translateX(-50%) translateY(0)';
        });

        setTimeout(() => {
            toast.style.opacity = '0';
            toast.style.transform = 'translateX(-50%) translateY(12px)';
            setTimeout(() => {
                if (toast.parentNode) toast.remove();
            }, 400);
        }, 2500);
    }

    // ---------- Clipboard ----------
    function copyToClipboard(text) {
        if (!text) return;
        if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(text).then(() => {
                showToast('📋 Copied!');
            }).catch(() => {
                fallbackCopy(text);
            });
        } else {
            fallbackCopy(text);
        }
    }

    function fallbackCopy(text) {
        const textarea = document.createElement('textarea');
        textarea.value = text;
        textarea.style.position = 'fixed';
        textarea.style.opacity = '0';
        textarea.style.left = '-9999px';
        textarea.style.top = '-9999px';
        textarea.style.width = '1px';
        textarea.style.height = '1px';
        document.body.appendChild(textarea);
        textarea.select();
        try {
            document.execCommand('copy');
            showToast('📋 Copied!');
        } catch (err) {
            showToast('❌ Copy failed');
        }
        document.body.removeChild(textarea);
    }

    // ---------- Custom Option Selector ----------
    function setupCustomDropdown(container, initialValue, onChangeCallback, labelMap = null) {
        if (!container) return;
        const trigger = container.querySelector('.h-custom-trigger');
        const textSpan = container.querySelector('.h-custom-value-text');
        const options = Array.from(container.querySelectorAll('.h-custom-opt'));
        if (!trigger || !textSpan || !options.length) return;

        const labels = labelMap || FREEZE_LABELS;
        let currentVal = initialValue ?? options[0]?.getAttribute('data-val') ?? 'ask';

        const applyValue = (value, fire = false) => {
            const selected = options.find(opt => opt.getAttribute('data-val') === value) || options[0];
            if (!selected) return;
            currentVal = selected.getAttribute('data-val') || value;
            textSpan.textContent = labels[currentVal] || selected.textContent.trim();
            options.forEach(opt => {
                const isSelected = opt === selected;
                opt.classList.toggle('is-selected', isSelected);
                opt.setAttribute('aria-selected', String(isSelected));
            });
            trigger.setAttribute('aria-expanded', String(container.classList.contains('is-open')));
            trigger.dataset.value = currentVal;
            if (fire) onChangeCallback?.(currentVal);
        };

        options.forEach((opt, index) => {
            opt.setAttribute('role', 'option');
            opt.tabIndex = -1;
            const selectOption = e => {
                e.stopPropagation();
                e.preventDefault?.();
                applyValue(opt.getAttribute('data-val'), true);
                container.classList.remove('is-open');
                trigger.setAttribute('aria-expanded', 'false');
                trigger.focus?.({preventScroll:true});
            };
            opt.onclick = selectOption;
            opt.onkeydown = e => {
                if (e.key === 'Enter' || e.key === ' ') {
                    selectOption(e);
                    return;
                }
                if (e.key === 'Escape') {
                    container.classList.remove('is-open');
                    trigger.setAttribute('aria-expanded', 'false');
                    trigger.focus?.({preventScroll:true});
                    e.preventDefault();
                    return;
                }
                if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
                    const delta = e.key === 'ArrowUp' ? -1 : 1;
                    options[(index + delta + options.length) % options.length]?.focus?.({preventScroll:true});
                    e.preventDefault();
                }
            };
        });

        trigger.type = 'button';
        trigger.setAttribute('role', 'combobox');
        trigger.setAttribute('aria-haspopup', 'listbox');
        trigger.setAttribute('aria-expanded', 'false');
        trigger.tabIndex = 0;

        trigger.onclick = e => {
            e.stopPropagation();
            const isOpen = container.classList.contains('is-open');
            shadowRoot?.querySelectorAll('.h-custom-select').forEach(c => {
                c.classList.remove('is-open');
                c.querySelector('.h-custom-trigger')?.setAttribute('aria-expanded', 'false');
            });
            if (!isOpen) {
                container.classList.add('is-open');
                trigger.setAttribute('aria-expanded', 'true');
                options.find(o => o.getAttribute('data-val') === currentVal)?.focus?.({preventScroll:true});
            }
        };
        trigger.onkeydown = e => {
            if (e.key === 'Escape') {
                container.classList.remove('is-open');
                trigger.setAttribute('aria-expanded', 'false');
                e.preventDefault();
                return;
            }
            if (['Enter',' ','ArrowDown','ArrowUp'].includes(e.key)) {
                e.preventDefault();
                if (!container.classList.contains('is-open')) trigger.click();
                else {
                    const selectedIndex = Math.max(0, options.findIndex(o => o.getAttribute('data-val') === currentVal));
                    const delta = e.key === 'ArrowUp' ? -1 : 1;
                    options[Math.max(0, Math.min(options.length - 1, selectedIndex + delta))]?.focus?.({preventScroll:true});
                }
            }
        };

        applyValue(currentVal, false);
    }

    // ---------- Domain Management ----------
    function executeAddBlockDomain(parentDomain, triggerType, onDeny, promptEl) {
        if (parentDomain && !CACHE.blockedDomainsSet.has(parentDomain)) {
            CACHE.blockedDomainsList.push(parentDomain); CACHE.blockedDomainsSet.add(parentDomain);
            sv('hider_blocked_domains', CACHE.blockedDomainsList);
        }
        logBlockedAttempt(parentDomain, triggerType + ' (User Domain Block)'); promptEl?.remove();
        showToast(`🚫 Blocked ${parentDomain}! Managed in Control Panel.`); onDeny?.(); simulateAdWindowSuccess();
    }

    function executeAddAllowedDomain(parentDomain) {
        if (parentDomain && !CACHE.allowedDomainsSet.has(parentDomain)) {
            CACHE.allowedDomainsList.push(parentDomain); CACHE.allowedDomainsSet.add(parentDomain);
            sv('hider_allowed_domains', CACHE.allowedDomainsList);
            if (shadowBy('hider-panel')?.classList.contains('is-visible')) renderList();
        }
    }

    function showFreezePrompt(url, triggerType, onConfirm, onDeny) {
        if (!shadowRoot) return;
        shadowBy('hider-freeze-prompt')?.remove();
        const promptEl = Object.assign(doc.createElement('div'), { id: 'hider-freeze-prompt', className: 'h-glass h-prompt' });
        const displayUrl = url ? (url.length > 38 ? url.substring(0, 35) + '...' : url) : 'another page';
        const parentDomain = getParentDomain(url) || 'unknown domain';

        promptEl.innerHTML = `
            <div style="font-weight:800;color:#38bdf8;font-size:11px!important;text-transform:uppercase!important;letter-spacing:0.5px">❄️ Navigation Intercepted</div>
            <div style="font-size:11px!important;color:#f8fafc!important;font-weight:600">Proceed to page?</div>
            <div class="h-url-box">${displayUrl}</div>
            <div class="h-custom-select" id="hider-modal-custom-dropdown">
                <div class="h-custom-trigger"><span class="h-custom-value-text">${FREEZE_LABELS[CACHE.freezeMemory] || FREEZE_LABELS['ask']}</span><span class="h-custom-arrow">▼</span></div>
                <div class="h-custom-options"><div class="h-custom-opt" data-val="ask">❓ Ask Every Time</div><div class="h-custom-opt" data-val="block_all">⛔ Auto-Block All Navigations</div><div class="h-custom-opt" data-val="allow_same">🔗 Allow Same Domain Only</div><div class="h-custom-opt" data-val="allow_all">🟢 Allow All Navigations</div></div>
            </div>
            <div style="display:flex;gap:6px;width:100%;margin-top:4px"><button id="hider-freeze-yes" class="h-btn-pill btn-green" style="flex:1">Allow Once</button><button id="hider-freeze-no" class="h-btn-pill btn-red" style="flex:1">Deny</button></div>
            <button id="hider-freeze-allow-btn" class="h-btn-pill" style="width:100%;margin-top:4px;background:rgba(16,185,129,0.15)!important;border:1px solid rgba(16,185,129,0.4)!important;color:#34d399!important;">🟢 Always Allow (${parentDomain})</button>
            <button id="hider-freeze-block-btn" class="h-btn-pill" style="width:100%;margin-top:4px;background:rgba(239,68,68,0.15)!important;border:1px solid rgba(239,68,68,0.4)!important;color:#fca5a5!important;">🚫 Always Block (${parentDomain})</button>
        `;

        shadowRoot.appendChild(promptEl); let selectedMem = CACHE.freezeMemory || 'ask';
        setupCustomDropdown(promptEl.querySelector('#hider-modal-custom-dropdown'), selectedMem, v => { selectedMem = v; });

        setTimeout(() => { promptEl.style.opacity = '1'; promptEl.style.transform = 'translateX(-50%) translateY(0)'; }, 10);

        const saveMem = () => { if (selectedMem !== CACHE.freezeMemory) { CACHE.freezeMemory = selectedMem; sv('hider_freeze_memory', selectedMem); } };

        promptEl.querySelector('#hider-freeze-yes').onclick = () => {
            saveMem(); if (selectedMem === 'allow_all') disableFreezeMode(); else if (selectedMem === 'allow_same' && parentDomain !== 'unknown domain') executeAddAllowedDomain(parentDomain);
            promptEl.remove(); onConfirm?.();
        };
        promptEl.querySelector('#hider-freeze-no').onclick = () => {
            saveMem(); if (selectedMem === 'allow_all') disableFreezeMode();
            logBlockedAttempt(url, triggerType + ' (User)'); promptEl.remove(); onDeny?.(); simulateAdWindowSuccess();
        };
        promptEl.querySelector('#hider-freeze-allow-btn').onclick = () => {
            saveMem(); if (parentDomain !== 'unknown domain') executeAddAllowedDomain(parentDomain);
            if (selectedMem === 'allow_all') disableFreezeMode();
            promptEl.remove(); showToast(`🟢 Allowed ${parentDomain}!`); onConfirm?.();
        };
        promptEl.querySelector('#hider-freeze-block-btn').onclick = () => {
            saveMem(); const skipConfirm = gv('hider_skip_block_confirm', false);
            if (skipConfirm) { executeAddBlockDomain(parentDomain, triggerType, onDeny, promptEl); return; }

            promptEl.innerHTML = `
                <div style="font-weight:800;color:#ef4444;font-size:11px!important;text-transform:uppercase!important;">🚫 Confirm Domain Block</div>
                <div style="font-size:11px!important;color:#f8fafc!important;text-align:center;margin:2px 0">Block all future requests to:<br><strong style="color:#38bdf8;font-size:12px!important">${parentDomain}</strong>?</div>
                <label style="font-size:10px!important;color:#cbd5e1!important;display:flex;align-items:center;gap:4px;cursor:pointer;margin:4px 0;user-select:none"><input type="checkbox" id="hider-dont-ask-block" style="cursor:pointer;accent-color:#38bdf8;width:12px!important;height:12px!important"> Don't ask confirmation again</label>
                <div style="display:flex;gap:6px;width:100%;margin-top:4px"><button id="hider-confirm-block-yes" class="h-btn-pill btn-red" style="flex:1">Yes, Block</button><button id="hider-confirm-block-no" class="h-btn-pill" style="flex:1;background:rgba(255,255,255,0.1)!important;color:#f1f5f9!important;border:1px solid rgba(255,255,255,0.15)!important;">Cancel</button></div>
            `;
            promptEl.querySelector('#hider-confirm-block-yes').onclick = () => {
                if (promptEl.querySelector('#hider-dont-ask-block')?.checked) sv('hider_skip_block_confirm', true);
                executeAddBlockDomain(parentDomain, triggerType, onDeny, promptEl);
            };
            promptEl.querySelector('#hider-confirm-block-no').onclick = () => { showFreezePrompt(url, triggerType, onConfirm, onDeny); };
        };
    }

    // ---------- Enhanced Reveal ----------
    function revealHiddenElements() {
        if (!doc.body) return;

        const targets = new Set();

        const inlineHidden = doc.querySelectorAll([
            '[style*="display:none"]',
            '[style*="display: none"]',
            '[style*="visibility:hidden"]',
            '[style*="visibility: hidden"]',
            '[style*="opacity:0"]',
            '[style*="opacity: 0"]',
            '[style*="filter:blur"]',
            '[style*="filter: blur"]',
            '[style*="backdrop-filter:blur"]',
            '[style*="backdrop-filter: blur"]'
        ].join(','));
        inlineHidden.forEach(el => targets.add(el));

        const overlaySelector = [
            'div[style*="position:fixed"]',
            'div[style*="position: fixed"]',
            'div[style*="position:absolute"]',
            'div[style*="position: absolute"]',
            'div[style*="z-index: 999"]',
            'div[style*="z-index:999"]',
            'div[style*="z-index: 9999"]',
            'div[style*="z-index:9999"]',
            'div[style*="z-index: 99999"]',
            'div[style*="z-index:99999"]'
        ].join(',');
        const overlayCandidates = doc.querySelectorAll(overlaySelector);
        overlayCandidates.forEach(el => {
            const rect = el.getBoundingClientRect();
            if (rect.width < 100 || rect.height < 100) return;
            if (el.innerText.length > 200) return;
            if (el.querySelector('article, main, p, h1, h2, h3, h4, h5, h6')) return;
            targets.add(el);
        });

        doc.querySelectorAll([
            '.modal', '.overlay', '.popup', '.lightbox', '.blocker',
            '.paywall', '.gate', '.wall', '.restricted', '.locked',
            '[data-overlay]', '[data-modal]', '[data-popup]', '[data-paywall]'
        ].join(',')).forEach(el => targets.add(el));

        if (!isMediaSensitiveDomain()) {
            doc.querySelectorAll('[style*="display:none"], [style*="display: none"], [style*="visibility:hidden"], [style*="visibility: hidden"], [style*="opacity:0"], [style*="opacity: 0"], [style*="filter:blur"], [style*="filter: blur"], [style*="backdrop-filter:blur"], [style*="backdrop-filter: blur"]').forEach(el => targets.add(el));
        }

        let count = 0;
        let blurCount = 0, hiddenCount = 0, overlayCount = 0;

        const processBatch = (arr, start) => {
            const end = Math.min(start + 50, arr.length);
            for (let i = start; i < end; i++) {
                const el = arr[i];
                const style = win.getComputedStyle(el);
                let changed = false;

                if (style.filter && style.filter.includes('blur')) {
                    el.style.setProperty('filter', 'none', 'important');
                    el.style.setProperty('backdrop-filter', 'none', 'important');
                    el.style.setProperty('-webkit-backdrop-filter', 'none', 'important');
                    blurCount++;
                    changed = true;
                }

                if (style.display === 'none') {
                    el.style.setProperty('display', 'block', 'important');
                    hiddenCount++;
                    changed = true;
                }
                if (style.visibility === 'hidden') {
                    el.style.setProperty('visibility', 'visible', 'important');
                    hiddenCount++;
                    changed = true;
                }
                if (style.opacity === '0') {
                    el.style.setProperty('opacity', '1', 'important');
                    hiddenCount++;
                    changed = true;
                }

                if (style.pointerEvents === 'none') {
                    el.style.setProperty('pointer-events', 'auto', 'important');
                }
                if (style.userSelect === 'none') {
                    el.style.setProperty('user-select', 'text', 'important');
                    el.style.setProperty('-webkit-user-select', 'text', 'important');
                }

                if (style.position === 'fixed' || style.position === 'absolute') {
                    const z = parseInt(style.zIndex, 10);
                    if (z > 900) {
                        el.style.setProperty('position', 'static', 'important');
                        el.style.setProperty('z-index', 'auto', 'important');
                        overlayCount++;
                        changed = true;
                    }
                }

                if (changed) count++;
            }

            if (end < arr.length) {
                requestAnimationFrame(() => processBatch(arr, end));
            } else {
                const parts = [];
                if (hiddenCount) parts.push(`${hiddenCount} hidden`);
                if (blurCount) parts.push(`${blurCount} blurred`);
                if (overlayCount) parts.push(`${overlayCount} overlays`);
                const summary = parts.length ? `👁️ Revealed: ${parts.join(', ')}` : '👁️ No hidden/blurred elements found.';
                showToast(summary);
                if (CACHE.autoScroll && featuresEnabled) forceEnableScroll();
            }
        };

        const targetArray = Array.from(targets);
        if (targetArray.length === 0) {
            showToast('👁️ No hidden/blurred elements found.');
            return;
        }
        requestAnimationFrame(() => processBatch(targetArray, 0));
    }

    // ---------- Time Skipper (Manual 30s) ----------
    function skip30Seconds() {
        let mediaCount = 0;
        doc.querySelectorAll('video, audio').forEach(el => {
            try {
                if (!isNaN(el.duration) && isFinite(el.duration)) {
                    el.currentTime = Math.min(el.duration, el.currentTime + 30);
                } else {
                    el.currentTime += 30;
                }
                mediaCount++;
            } catch {}
        });

        // Only elements explicitly labeled as a timer/countdown are eligible --
        // never scan the whole page. A page-wide scan for "any element whose
        // text is a short number" previously zeroed out unrelated 1-2 digit
        // badges (unread counts, ratings, quantities, prices) anywhere on the
        // page, since e.g. a plain "5" or "42" satisfied that old pattern.
        let timerCount = 0;
        const timerElements = isMediaSensitiveDomain() ? [] : doc.querySelectorAll(
            '[class*="timer" i], [class*="countdown" i], [id*="timer" i], [id*="countdown" i], ' +
            '[data-timer], [data-countdown], [aria-label*="countdown" i], [aria-label*="timer" i]'
        );
        timerElements.forEach(el => {
            if (!timerLooksActionable(el)) return;
            const raw = el.textContent.trim();
            const m = raw.match(/^(?:(\d{1,2}):(\d{2})|(\d{1,3})\s*(?:s|sec|secs|seconds?)|(\d{1,3})\s*(?:m|min|mins|minutes?))$/i);
            const seconds = m ? (m[1] != null ? Number(m[1]) * 60 + Number(m[2]) : m[3] != null ? Number(m[3]) : Number(m[4]) * 60) : Infinity;
            if (seconds > 30) return; // manual +30s should not fast-forward long countdowns to zero
            el.textContent = '0';
            el.dispatchEvent(new Event('input', { bubbles: true }));
            timerCount++;
        });

        // Only click buttons with explicit ad-skip wording, or buttons that sit
        // inside a confirmed blocking overlay -- not any button anywhere on the
        // page whose label merely contains "close" or "dismiss" (that previously
        // risked closing unrelated dialogs/menus the user did not want touched).
        let clickCount = 0;
        const skipBtns = doc.querySelectorAll('button, a[role="button"], [role="button"]');
        skipBtns.forEach(btn => {
            const text = getAgeText(btn);
            if (!text) return;
            const inOverlay = !!btn.closest?.('[role="dialog"], [role="alertdialog"]') && isBlockingOverlayElement(btn.closest('[role="dialog"], [role="alertdialog"]'));
            if (!AUTO_SKIP_HINTS.test(text) && !inOverlay) return;
            const rect = btn.getBoundingClientRect();
            if (rect.width > 0 && rect.height > 0) {
                try { btn.click(); clickCount++; } catch {}
            }
        });

        broadcastToFrames(window, { type: 'HIDER_SKIP_30' });

        const msgParts = [];
        if (mediaCount) msgParts.push(`${mediaCount} media`);
        if (timerCount) msgParts.push(`${timerCount} timers`);
        if (clickCount) msgParts.push(`${clickCount} buttons`);
        const summary = msgParts.length ? `⏩ Skipped: ${msgParts.join(', ')}` : '⏩ Skipped +30s';
        showToast(summary);
    }

    // ================================================================
    //  SMART AUTO TIME SKIPPER + VIDEO AD SKIPPER
    // ================================================================
    function isInsideMedia(el) {
        let node = el;
        while (node && node !== doc) {
            if (node.tagName === 'VIDEO' || node.tagName === 'AUDIO') return true;
            node = node.parentElement;
        }
        return false;
    }

    function timerLooksActionable(el) {
        if (!el || el.nodeType !== Node.ELEMENT_NODE || isInsideMedia(el)) return false;
        const text = (el.textContent || '').trim();
        if (!text || text.length > 40) return false;
        const meta = getAgeText(el);
        if (!TIMER_HINTS.test(meta)) return false;
        return /^(?:\d{1,2}:\d{2}|\d{1,3}\s*(?:s|sec|secs|seconds?|m|min|mins|minutes?))$/i.test(text);
    }

    function registerTimeSkipNode(node) {
        if (!node || node.nodeType !== Node.ELEMENT_NODE) return;
        if (timerLooksActionable(node)) autoSkipCandidates.add(node);
        try {
            for (const el of node.querySelectorAll?.('[class*="timer" i], [class*="countdown" i], [id*="timer" i], [id*="countdown" i], [data-timer], [data-countdown], [aria-label*="countdown" i], [aria-label*="timer" i]') || []) {
                if (timerLooksActionable(el)) autoSkipCandidates.add(el);
            }
            for (const media of node.querySelectorAll?.('video, audio') || []) attachSmartMedia(media);
            if (node.matches?.('video, audio')) attachSmartMedia(node);
            for (const el of node.querySelectorAll?.('button, [role="button"], a[role="button"]') || []) {
                const text = getAgeText(el);
                if (AUTO_SKIP_HINTS.test(text)) autoSkipCandidates.add(el);
            }
        } catch {}
    }

    function isAdLikeMedia(media) {
        const meta = getAgeText(media) + ' ' + getAgeText(media.parentElement);
        return AUTO_SKIP_HINTS.test(meta) || /(?:ad-player|ad-container|video-ad|preroll|midroll|postroll|commercial)/i.test(meta);
    }

    function attachSmartMedia(media) {
        if (!media || autoSkipMedia.has(media)) return;
        autoSkipMedia.add(media);
        const onTime = () => {
            if (!CACHE.autoTimeSkipper || !featuresEnabled || isMediaSensitiveDomain()) return;
            if (!isAdLikeMedia(media) || !Number.isFinite(media.duration) || media.duration <= 0) return;
            const remain = media.duration - media.currentTime;
            if (remain <= 1.2) return;
            if (remain <= 5 || media.currentTime < 0.5) {
                try { media.currentTime = Math.max(0, media.duration - 0.05); } catch {}
            }
        };
        media.addEventListener('timeupdate', onTime, { passive: true });
        media.addEventListener('loadedmetadata', onTime, { passive: true });
        media.addEventListener('durationchange', onTime, { passive: true });
    }

    function processSmartSkipCandidates() {
        let found = false;
        for (const el of [...autoSkipCandidates]) {
            if (!el?.isConnected) { autoSkipCandidates.delete(el); continue; }
            if (el.matches?.('button, [role="button"], a[role="button"]')) {
                const text = getAgeText(el);
                if (AUTO_SKIP_HINTS.test(text)) {
                    const r = el.getBoundingClientRect();
                    if (r.width > 0 && r.height > 0) {
                        try { el.click(); found = true; } catch {}
                    }
                }
            } else if (timerLooksActionable(el)) {
                const raw = (el.textContent || '').trim();
                const m = raw.match(/^(?:(\d{1,2}):(\d{2})|(\d{1,3})\s*(?:s|sec|secs|seconds?)|(\d{1,3})\s*(?:m|min|mins|minutes?))$/i);
                const seconds = m ? (m[1] != null ? Number(m[1]) * 60 + Number(m[2]) : m[3] != null ? Number(m[3]) : Number(m[4]) * 60) : Infinity;
                const nearbyButton = el.closest?.('button, [role="button"], a[role="button"]') || el.parentElement?.querySelector?.('button, [role="button"], a[role="button"]');
                if (nearbyButton && AUTO_SKIP_HINTS.test(getAgeText(nearbyButton))) {
                    try { nearbyButton.click(); found = true; } catch {}
                } else if (seconds <= 1) {
                    try { el.textContent = '0'; el.dispatchEvent(new Event('input', {bubbles:true, composed:true})); found = true; } catch {}
                }
            } else {
                autoSkipCandidates.delete(el);
            }
        }
        for (const media of [...autoSkipMedia]) {
            if (!media?.isConnected) autoSkipMedia.delete(media);
        }
        return found;
    }

    function startAutoSkipMonitoring() {
        stopAutoSkipMonitoring();
        if (!CACHE.autoTimeSkipper || !featuresEnabled || isMediaSensitiveDomain()) return;
        autoSkipCandidates = new Set();
        autoSkipMedia = new Set();
        registerTimeSkipNode(doc.body || doc.documentElement);
        for (const media of doc.querySelectorAll?.('video, audio') || []) attachSmartMedia(media);
        autoSkipObserver = new MutationObserver(mutations => {
            for (const m of mutations) {
                if (m.type !== 'childList') continue;
                for (const n of m.addedNodes || []) registerTimeSkipNode(n);
            }
        });
        try { autoSkipObserver.observe(doc.documentElement, {childList:true, subtree:true}); } catch {}
        autoSkipInterval = setInterval(() => {
            if (!CACHE.autoTimeSkipper || !featuresEnabled || isMediaSensitiveDomain()) return;
            const found = processSmartSkipCandidates();
            autoSkipEmptyCount = found ? 0 : autoSkipEmptyCount + 1;
            if (autoSkipEmptyCount >= AUTO_SKIP_MAX_EMPTY && autoSkipCandidates.size === 0) {
                autoSkipEmptyCount = 0;
                // Keep observer-driven monitoring alive without scanning the DOM.
            }
        }, AUTO_SKIP_INTERVAL_MS);
    }

    function stopAutoSkipMonitoring() {
        if (autoSkipInterval) { clearInterval(autoSkipInterval); autoSkipInterval = null; }
        if (autoSkipObserver) { autoSkipObserver.disconnect(); autoSkipObserver = null; }
        autoSkipCandidates.clear();
        autoSkipMedia.clear();
        autoSkipEmptyCount = 0;
        if (observers.adSkipObserver) { observers.adSkipObserver.disconnect(); observers.adSkipObserver = null; }
    }

    // ========== AGGRESSIVE PAUSE ==========
    function pauseAllVideos() {
        // Opening the script's media lab must not pause or reset Facebook/Instagram playback.
        if (isMediaSensitiveDomain()) return;
        function pauseMedia(el) {
            try {
                if (el.tagName === 'VIDEO' || el.tagName === 'AUDIO') {
                    el.pause();
                    el.currentTime = 0;
                    el.loop = false;
                }
            } catch(e) {}
        }

        function traverse(node) {
            if (!node) return;
            if (node.nodeType === Node.ELEMENT_NODE) {
                pauseMedia(node);
                if (node.shadowRoot) {
                    traverse(node.shadowRoot);
                }
                if (node.tagName === 'IFRAME' || node.tagName === 'FRAME') {
                    try {
                        if (node.contentDocument) {
                            traverse(node.contentDocument);
                        }
                    } catch(e) {}
                }
                if (node.childNodes) {
                    node.childNodes.forEach(child => traverse(child));
                }
            } else if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.DOCUMENT_NODE) {
                if (node.childNodes) {
                    node.childNodes.forEach(child => traverse(child));
                }
            }
        }

        traverse(document);
        document.querySelectorAll('video, audio').forEach(pauseMedia);
    }

    // ========== LINK EXTRACTOR ==========
    function isDirectMedia(url) {
        if (!url) return false;
        const lower = String(url).toLowerCase();
        if (lower.startsWith('blob:') || lower.startsWith('data:image/')) return true;
        const mediaExts = [
            '.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp', '.ico', '.tiff', '.tif', '.avif', '.heic', '.heif',
            '.mp4', '.webm', '.ogg', '.ogv', '.mov', '.avi', '.mkv', '.ts', '.m4v', '.wmv', '.flv', '.m3u8',
            '.mp3', '.wav', '.flac', '.m4a', '.aac', '.wma'
        ];
        try {
            const u = new URL(url, location.href);
            const pathAndQuery = (u.pathname + u.search).toLowerCase();
            return mediaExts.some(ext => pathAndQuery.includes(ext));
        } catch {
            return mediaExts.some(ext => lower.includes(ext));
        }
    }

    function getMediaType(url) {
        if (!url) return null;
        const lower = String(url).toLowerCase();
        if (lower.startsWith('data:image/')) return 'image';
        try {
            const u = new URL(url, location.href);
            const target = (u.pathname + u.search).toLowerCase();
            const imgExts = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp', '.ico', '.tiff', '.tif', '.avif', '.heic', '.heif'];
            if (imgExts.some(ext => target.includes(ext))) return 'image';
            const vidExts = ['.mp4', '.webm', '.ogg', '.ogv', '.mov', '.avi', '.mkv', '.ts', '.m4v', '.wmv', '.flv', '.m3u8'];
            if (vidExts.some(ext => target.includes(ext))) return 'video';
            const audExts = ['.mp3', '.wav', '.flac', '.m4a', '.aac', '.ogg', '.wma'];
            if (audExts.some(ext => target.includes(ext))) return 'audio';
        } catch {}
        // A blob URL has no extension. Callers that know the element type
        // provide the correct media subtype explicitly.
        return lower.startsWith('blob:') ? null : null;
    }

    function isMediaUrl(url) {
        return getMediaType(url) !== null;
    }

    function getAllLinks() {
        const linkMap = new Map();

        function addLink(url, text, type = 'link', forcedMediaType = null) {
            if (!url) return;
            try {
                const abs = new URL(url, location.href).href;
                if (abs.startsWith('javascript:') || abs.startsWith('mailto:') || abs.startsWith('tel:') || abs === '#') return;
                let finalType = type;
                const mediaType = forcedMediaType || getMediaType(abs);
                if (mediaType) finalType = 'media';
                if (!linkMap.has(abs)) {
                    linkMap.set(abs, { url: abs, text: text || abs, type: finalType, mediaSubtype: mediaType });
                } else {
                    const existing = linkMap.get(abs);
                    if (finalType === 'media' && existing.type === 'link') {
                        existing.type = 'media';
                        existing.mediaSubtype = mediaType;
                    } else if (finalType === 'media' && !existing.mediaSubtype && mediaType) {
                        existing.mediaSubtype = mediaType;
                    }
                    if (text && text !== abs && (existing.text === existing.url || !existing.text)) {
                        existing.text = text;
                    }
                }
            } catch (e) { /* ignore */ }
        }

        function traverse(node) {
            if (!node) return;
            if (node.nodeType === Node.ELEMENT_NODE) {
                const el = node;

                if (el.tagName === 'VIDEO' || el.tagName === 'AUDIO') {
                    const src = el.getAttribute('src') || el.currentSrc;
                    const elementMediaType = el.tagName === 'VIDEO' ? 'video' : 'audio';
                    if (src) {
                        const text = el.getAttribute('title') || el.getAttribute('aria-label') || el.getAttribute('alt') || el.textContent.trim() || src;
                        addLink(src, text, 'media', elementMediaType);
                    }
                    el.querySelectorAll('source').forEach(source => {
                        const s = source.getAttribute('src') || source.getAttribute('srcset');
                        if (s) {
                            const label = source.getAttribute('label') || source.getAttribute('title') || s;
                            addLink(s, label, 'media', elementMediaType);
                        }
                    });
                    const poster = el.getAttribute('poster');
                    if (poster) {
                        addLink(poster, 'Poster image', 'media', 'image');
                    }
                }

                if (el.tagName === 'IMG') {
                    const src = el.getAttribute('src') || el.currentSrc;
                    if (src) {
                        const text = el.alt || el.title || el.getAttribute('aria-label') || src;
                        addLink(src, text, 'media', 'image');
                    }
                    const srcset = el.getAttribute('srcset');
                    if (srcset) {
                        const urls = srcset.split(',').map(s => s.trim().split(/\s+/)[0]).filter(Boolean);
                        urls.forEach(u => {
                            if (u) addLink(u, el.alt || el.title || u, 'media');
                        });
                    }
                    const lazyAttrs = ['data-src', 'data-original', 'data-lazy-src', 'data-srcset'];
                    lazyAttrs.forEach(attr => {
                        const val = el.getAttribute(attr);
                        if (val) {
                            if (attr === 'data-srcset') {
                                const urls = val.split(',').map(s => s.trim().split(/\s+/)[0]).filter(Boolean);
                                urls.forEach(u => addLink(u, el.alt || el.title || u, 'media'));
                            } else {
                                addLink(val, el.alt || el.title || val, 'media');
                            }
                        }
                    });
                }

                if (el.tagName === 'SOURCE' && el.closest('picture')) {
                    const s = el.getAttribute('src');
                    if (s) {
                        const label = el.getAttribute('label') || el.getAttribute('title') || s;
                        addLink(s, label, 'media', 'image');
                    }
                    const srcset = el.getAttribute('srcset');
                    if (srcset) {
                        const urls = srcset.split(',').map(s => s.trim().split(/\s+/)[0]).filter(Boolean);
                        urls.forEach(u => addLink(u, el.getAttribute('label') || u, 'media'));
                    }
                }

                const dataAttrs = ['src', 'url', 'link', 'video-src', 'audio-src', 'media-url', 'file', 'image', 'img', 'photo'];
                for (const attr of dataAttrs) {
                    const val = el.getAttribute('data-' + attr);
                    if (val && isMediaUrl(val)) {
                        const text = el.textContent.trim() || el.title || el.getAttribute('aria-label') || val;
                        addLink(val, text, 'media');
                    }
                }

                if (el.matches('a[href], area[href]')) {
                    const href = el.getAttribute('href');
                    if (href && isMediaUrl(href)) {
                        const text = el.textContent.trim() || el.title || el.getAttribute('aria-label') || href;
                        addLink(href, text, 'media');
                    } else if (href) {
                        const text = el.textContent.trim() || el.title || el.getAttribute('aria-label') || href;
                        addLink(href, text, 'link');
                    }
                }

                const onclick = el.getAttribute('onclick');
                if (onclick) {
                    const matches = onclick.match(/(?:location\.href|window\.open)\s*\(\s*['"]([^'"]+)['"]/gi);
                    if (matches) {
                        matches.forEach(m => {
                            const urlMatch = m.match(/['"]([^'"]+)['"]/);
                            if (urlMatch) {
                                const url = urlMatch[1];
                                if (isMediaUrl(url)) {
                                    const text = el.textContent.trim() || el.title || el.getAttribute('aria-label') || url;
                                    addLink(url, text, 'media');
                                }
                            }
                        });
                    }
                }

                if (el.matches('form[action]')) {
                    const action = el.getAttribute('action');
                    if (action && isMediaUrl(action)) {
                        const text = el.getAttribute('name') || el.id || 'Form action';
                        addLink(action, text, 'media');
                    }
                }

                if (el.tagName === 'IFRAME') {
                    const iframeSrc = el.getAttribute('src');
                    if (iframeSrc) {
                        const text = el.getAttribute('title') || el.getAttribute('aria-label') || 'iframe';
                        addLink(iframeSrc, text, 'link');
                    }
                }

                if (el.shadowRoot) {
                    traverseShadow(el.shadowRoot);
                }
            }

            if (node.childNodes) {
                for (const child of node.childNodes) {
                    traverse(child);
                }
            }
        }

        function traverseShadow(root) {
            if (root.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
                for (const child of root.children) {
                    traverse(child);
                }
            }
        }

        traverse(document);
        return Array.from(linkMap.values());
    }

    // ---------- Preview Modal ----------
    function closePreviewModal(modalEl) {
        const modal = modalEl || shadowBy('hider-link-preview-modal');
        if (modal && modal.parentNode) {
            modal.remove();
        }
        if (previewOutsideListener) {
            document.removeEventListener('click', previewOutsideListener);
            previewOutsideListener = null;
        }
    }

    function showLinkPreview(url) {
        const existing = shadowBy('hider-link-preview-modal');
        if (existing) {
            closePreviewModal(existing);
        }

        const mediaType = getMediaType(url);
        const isDirect = isDirectMedia(url);

        const modal = doc.createElement('div');
        modal.id = 'hider-link-preview-modal';
        modal.className = 'h-glass';
        modal.style.cssText = `
            position: fixed !important;
            top: 50% !important;
            left: 50% !important;
            transform: translate(-50%, -50%) !important;
            z-index: 2147483647 !important;
            padding: 16px !important;
            border-radius: 16px !important;
            background: rgba(13, 18, 30, 0.96) !important;
            backdrop-filter: blur(16px) !important;
            border: 1px solid rgba(255,255,255,0.15) !important;
            box-shadow: 0 24px 48px rgba(0,0,0,0.8) !important;
            min-width: 280px !important;
            max-width: 90vw !important;
            max-height: 90vh !important;
            pointer-events: auto !important;
            display: flex !important;
            flex-direction: column !important;
            gap: 10px !important;
            color: #f8fafc !important;
            overflow-y: auto !important;
        `;

        let typeIcon = '🔗';
        if (mediaType === 'image') typeIcon = '🖼️';
        else if (mediaType === 'video') typeIcon = '🎬';
        else if (mediaType === 'audio') typeIcon = '🔊';

        const title = doc.createElement('div');
        title.style.cssText = 'font-weight:800; font-size:12px; color:#38bdf8; text-transform:uppercase; letter-spacing:0.5px;';
        title.textContent = `${typeIcon} ${mediaType ? mediaType.toUpperCase() : 'Link'} Preview`;
        modal.appendChild(title);

        if (mediaType) {
            const mediaWrapper = doc.createElement('div');
            mediaWrapper.style.cssText = `
                display:flex; justify-content:center; align-items:center;
                background: rgba(0,0,0,0.4); border-radius:8px; padding:4px;
                min-height: 80px; max-height: 55vh; overflow:hidden;
            `;

            if (mediaType === 'image') {
                const img = doc.createElement('img');
                img.src = url;
                img.style.cssText = 'max-width:100%; max-height:55vh; object-fit:contain; border-radius:4px;';
                img.onerror = () => {
                    img.alt = '❌ Failed to load image';
                    img.style.cssText += 'height:60px; width:auto;';
                };
                mediaWrapper.appendChild(img);
            } else if (mediaType === 'video') {
                if (isDirect) {
                    const video = doc.createElement('video');
                    video.src = url;
                    video.controls = true;
                    video.preload = 'metadata';
                    video.style.cssText = 'max-width:100%; max-height:55vh; border-radius:4px; background:#000;';
                    video.onerror = () => {
                        video.innerHTML = '<div style="padding:20px;color:#f87171;font-size:12px;">❌ Failed to load video</div>';
                    };
                    mediaWrapper.appendChild(video);
                } else {
                    mediaWrapper.textContent = '🎬 Video – click "Open" to watch in new tab.';
                    mediaWrapper.style.cssText += 'padding:20px;color:#94a3b8;font-size:12px;';
                }
            } else if (mediaType === 'audio') {
                const audio = doc.createElement('audio');
                audio.src = url;
                audio.controls = true;
                audio.preload = 'metadata';
                audio.style.cssText = 'width:100%;';
                audio.onerror = () => {
                    audio.innerHTML = '<div style="padding:20px;color:#f87171;font-size:12px;">❌ Failed to load audio</div>';
                };
                mediaWrapper.appendChild(audio);
            } else {
                mediaWrapper.textContent = 'Media preview not available';
                mediaWrapper.style.cssText += 'padding:20px;color:#94a3b8;font-size:12px;';
            }
            modal.appendChild(mediaWrapper);
        } else {
            const linkPreview = doc.createElement('div');
            linkPreview.textContent = '🔗 Link Preview';
            linkPreview.style.cssText = 'font-size:12px;color:#94a3b8;padding:10px;';
            modal.appendChild(linkPreview);
        }

        const urlDisplay = doc.createElement('div');
        urlDisplay.style.cssText = 'font-size:10px; word-break:break-all; background:rgba(0,0,0,0.3); padding:6px 8px; border-radius:6px; border:1px solid rgba(255,255,255,0.1); font-family:monospace; max-height:80px; overflow-y:auto;';
        urlDisplay.textContent = url;
        modal.appendChild(urlDisplay);

        const btnGroup = doc.createElement('div');
        btnGroup.style.cssText = 'display:flex; gap:6px; justify-content:flex-end; flex-wrap:wrap;';

        const copyBtn = doc.createElement('button');
        copyBtn.className = 'hider-btn-small btn-blue';
        copyBtn.textContent = '📋 Copy';
        copyBtn.onclick = () => {
            copyToClipboard(url);
            showToast('📋 URL copied!');
        };
        btnGroup.appendChild(copyBtn);

        if (isDirect && (mediaType === 'image' || mediaType === 'video' || mediaType === 'audio')) {
            const downloadBtn = doc.createElement('button');
            downloadBtn.className = 'hider-btn-small btn-green';
            downloadBtn.textContent = '⬇️ Download';
            downloadBtn.onclick = function(e) {
                e.stopPropagation();
                let filename = url.split('/').pop().split(/[?#]/)[0] || 'media_file';
                if (!filename.includes('.')) {
                    if (mediaType === 'image') filename += '.jpg';
                    else if (mediaType === 'video') filename += '.mp4';
                    else if (mediaType === 'audio') filename += '.mp3';
                    else filename += '.bin';
                }
                try {
                    GM_download({
                        url: url,
                        name: filename,
                        onerror: function(err) {
                            console.error('GM_download failed, trying fetch fallback', err);
                            fetch(url).then(res => {
                                if (!res.ok) throw new Error('Network error');
                                return res.blob();
                            }).then(blob => {
                                const a = document.createElement('a');
                                const objectUrl = URL.createObjectURL(blob);
                                a.href = objectUrl;
                                a.download = filename;
                                document.body.appendChild(a);
                                a.click();
                                document.body.removeChild(a);
                                URL.revokeObjectURL(objectUrl);
                                showToast('⬇️ Downloaded using fallback');
                            }).catch(() => {
                                showToast('❌ Download failed – opening in new tab');
                                window.open(url, '_blank');
                            });
                        }
                    });
                    showToast(`⬇️ Downloading: ${filename}`);
                } catch (err) {
                    console.error('GM_download error:', err);
                    showToast('❌ Download error – opening in new tab');
                    window.open(url, '_blank');
                }
            };
            btnGroup.appendChild(downloadBtn);
        }

        const openBtn = doc.createElement('button');
        openBtn.className = 'hider-btn-small btn-purple';
        openBtn.textContent = '↗ Open';
        openBtn.onclick = () => {
            win.open(url, '_blank');
        };
        btnGroup.appendChild(openBtn);

        const closeBtn = doc.createElement('button');
        closeBtn.className = 'hider-btn-small btn-gray';
        closeBtn.textContent = '✖ Close';
        closeBtn.onclick = () => closePreviewModal(modal);
        btnGroup.appendChild(closeBtn);

        modal.appendChild(btnGroup);
        shadowRoot.appendChild(modal);

        const closeModalHandler = (e) => {
            if (!modal.parentNode) {
                document.removeEventListener('click', closeModalHandler);
                return;
            }
            const path = e.composedPath ? e.composedPath() : [];
            if (path.some(el => el === modal || (el && el.contains && el.contains(modal)))) {
                return;
            }
            if (path.some(el => el.id === UI_HOST_ID || el.id === STEPPER_BAR_ID)) {
                return;
            }
            closePreviewModal(modal);
        };
        if (previewOutsideListener) {
            document.removeEventListener('click', previewOutsideListener);
        }
        previewOutsideListener = closeModalHandler;
        setTimeout(() => {
            document.addEventListener('click', previewOutsideListener);
        }, 10);
    }

    // ----- Grid item for Media Mode -----
    function buildGridItem(link) {
        const div = doc.createElement('div');
        div.className = 'hider-grid-item';
        div.style.cssText = `
            position: relative;
            background: rgba(255,255,255,0.04);
            border-radius: 8px;
            overflow: hidden;
            aspect-ratio: 1 / 1;
            cursor: pointer;
            border: 1px solid rgba(255,255,255,0.08);
            transition: transform 0.2s ease, box-shadow 0.2s ease;
        `;
        div.onmouseover = () => { div.style.transform = 'scale(1.03)'; div.style.boxShadow = '0 4px 12px rgba(0,0,0,0.6)'; };
        div.onmouseout = () => { div.style.transform = 'scale(1)'; div.style.boxShadow = 'none'; };

        const mediaType = link.mediaSubtype || getMediaType(link.url);
        const isDirect = isDirectMedia(link.url);
        let icon = '📎';
        if (mediaType === 'image') icon = '🖼️';
        else if (mediaType === 'video') icon = '🎬';
        else if (mediaType === 'audio') icon = '🔊';

        let thumbnail = '';
        if (mediaType === 'image') {
            thumbnail = `<img src="${link.url}" style="width:100%;height:100%;object-fit:cover;" onerror="this.style.display='none';">`;
        } else if (mediaType === 'video' && isDirect) {
            thumbnail = `<video src="${link.url}" muted preload="metadata" style="width:100%;height:100%;object-fit:cover;" onerror="this.style.display='none';"></video>`;
        } else {
            thumbnail = `<div style="display:flex;align-items:center;justify-content:center;width:100%;height:100%;font-size:48px;color:#94a3b8;background:rgba(0,0,0,0.3);">${icon}</div>`;
        }

        div.innerHTML = thumbnail;

        const overlay = doc.createElement('div');
        overlay.style.cssText = `
            position: absolute;
            bottom: 4px;
            left: 4px;
            background: rgba(0,0,0,0.7);
            padding: 2px 6px;
            border-radius: 4px;
            font-size: 8px;
            color: #e0f2fe;
            backdrop-filter: blur(4px);
            pointer-events: none;
            font-weight: 600;
            letter-spacing: 0.3px;
            text-transform: uppercase;
        `;
        overlay.textContent = mediaType || 'media';
        div.appendChild(overlay);

        if (isDirect && (mediaType === 'image' || mediaType === 'video' || mediaType === 'audio')) {
            const downloadBtn = doc.createElement('button');
            downloadBtn.className = 'hider-btn-small';
            downloadBtn.textContent = '⬇️';
            downloadBtn.title = 'Download this media';
            downloadBtn.style.cssText = `
                position: absolute;
                bottom: 4px;
                right: 4px;
                background: rgba(0,0,0,0.7) !important;
                backdrop-filter: blur(4px);
                border: none;
                border-radius: 4px;
                color: #fff;
                padding: 2px 6px;
                font-size: 10px;
                cursor: pointer;
                z-index: 2;
                pointer-events: auto;
                transition: background 0.2s;
            `;
            downloadBtn.onmouseover = () => { downloadBtn.style.background = 'rgba(56,189,248,0.8) !important'; };
            downloadBtn.onmouseout = () => { downloadBtn.style.background = 'rgba(0,0,0,0.7) !important'; };

            downloadBtn.addEventListener('click', function(e) {
                e.stopPropagation();
                const url = link.url;
                if (!url) {
                    showToast('❌ No media URL');
                    return;
                }
                let filename = url.split('/').pop().split(/[?#]/)[0] || 'media_file';
                if (!filename.includes('.')) {
                    if (mediaType === 'image') filename += '.jpg';
                    else if (mediaType === 'video') filename += '.mp4';
                    else if (mediaType === 'audio') filename += '.mp3';
                    else filename += '.bin';
                }
                try {
                    GM_download({
                        url: url,
                        name: filename,
                        onerror: function(err) {
                            console.error('GM_download failed, trying fetch fallback', err);
                            fetch(url).then(res => {
                                if (!res.ok) throw new Error('Network error');
                                return res.blob();
                            }).then(blob => {
                                const a = document.createElement('a');
                                const objectUrl = URL.createObjectURL(blob);
                                a.href = objectUrl;
                                a.download = filename;
                                document.body.appendChild(a);
                                a.click();
                                document.body.removeChild(a);
                                URL.revokeObjectURL(objectUrl);
                                showToast('⬇️ Downloaded using fallback');
                            }).catch(() => {
                                showToast('❌ Download failed – opening in new tab');
                                window.open(url, '_blank');
                            });
                        }
                    });
                    showToast(`⬇️ Downloading: ${filename}`);
                } catch (err) {
                    console.error('GM_download error:', err);
                    showToast('❌ Download error – opening in new tab');
                    window.open(url, '_blank');
                }
            });

            div.appendChild(downloadBtn);
        }

        div.addEventListener('click', (e) => {
            if (e.target.closest('button')) return;
            showLinkPreview(link.url);
        });

        return div;
    }

    // ----- List item for normal mode -----
    function buildListItem(link, filterText, hideInternal, mediaOnly) {
        const currentHost = location.hostname;
        if (hideInternal) {
            try {
                const urlObj = new URL(link.url);
                if (urlObj.hostname === currentHost) return null;
            } catch { /* ignore */ }
        }
        if (mediaOnly && link.type !== 'media') return null;

        if (filterText) {
            const lower = filterText.toLowerCase();
            if (!link.text.toLowerCase().includes(lower) && !link.url.toLowerCase().includes(lower)) {
                return null;
            }
        }

        const div = doc.createElement('div');
        div.className = 'list-item';
        div.style.cssText = 'display:flex; justify-content:space-between; align-items:center; gap:4px;';

        let icon = '🔗';
        if (link.type === 'media') {
            const subtype = link.mediaSubtype || getMediaType(link.url);
            if (subtype === 'image') icon = '🖼️';
            else if (subtype === 'video') icon = '🎬';
            else if (subtype === 'audio') icon = '🔊';
            else icon = '🎬';
        }

        let displayText = link.text;
        if (link.type === 'media') {
            displayText = icon + ' ' + displayText;
        }
        if (linkDisplayMode === 'url') {
            displayText = link.url + (link.type === 'media' ? ' ' + icon : '');
        }

        const textSpan = doc.createElement('span');
        textSpan.className = 'rule-text';
        textSpan.textContent = displayText;
        textSpan.title = link.url;
        textSpan.style.cssText = 'flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;';

        const btnGroup = doc.createElement('div');
        btnGroup.style.cssText = 'display:flex; gap:2px; flex-shrink:0;';

        const previewBtn = doc.createElement('button');
        previewBtn.className = 'hider-btn-small btn-purple';
        previewBtn.textContent = '🔍';
        previewBtn.title = 'Preview full link (media preview if applicable)';
        previewBtn.onclick = (e) => {
            e.stopPropagation();
            showLinkPreview(link.url);
        };
        btnGroup.appendChild(previewBtn);

        const copyBtn = doc.createElement('button');
        copyBtn.className = 'hider-btn-small btn-blue';
        copyBtn.textContent = '📋';
        copyBtn.title = 'Copy URL';
        copyBtn.onclick = (e) => {
            e.stopPropagation();
            copyToClipboard(link.url);
            showToast('📋 Copied!');
        };
        btnGroup.appendChild(copyBtn);

        const openBtn = doc.createElement('button');
        openBtn.className = 'hider-btn-small btn-green';
        openBtn.textContent = '↗';
        openBtn.title = 'Open in new tab';
        openBtn.onclick = (e) => {
            e.stopPropagation();
            win.open(link.url, '_blank');
        };
        btnGroup.appendChild(openBtn);

        div.appendChild(textSpan);
        div.appendChild(btnGroup);
        return div;
    }

    function populateLinkList() {
        const listContainer = shadowBy('hider-link-list');
        if (!listContainer) return;
        const searchInput = shadowBy('hider-link-search');
        const hideInternalCheck = shadowBy('hider-link-hide-internal');
        const mediaModeCheck = shadowBy('hider-link-media-mode');
        const filterText = searchInput ? searchInput.value.toLowerCase() : '';
        const hideInternal = hideInternalCheck ? hideInternalCheck.checked : false;
        const mediaMode = mediaModeCheck ? mediaModeCheck.checked : false;

        const links = getAllLinks();
        const title = shadowBy('link-panel-title');
        if (title) title.textContent = `🔗 Extracted Links (${links.length})`;

        listContainer.innerHTML = '';
        let displayed = 0;
        const frag = doc.createDocumentFragment();

        if (mediaMode) {
            const grid = doc.createElement('div');
            grid.style.cssText = 'display:grid;grid-template-columns:repeat(3,1fr);gap:6px;';
            links.forEach(link => {
                if (link.type !== 'media') return;
                if (filterText) {
                    const lower = filterText;
                    if (!link.text.toLowerCase().includes(lower) && !link.url.toLowerCase().includes(lower)) return;
                }
                if (hideInternal) {
                    try {
                        const urlObj = new URL(link.url);
                        if (urlObj.hostname === location.hostname) return;
                    } catch {}
                }
                const item = buildGridItem(link);
                grid.appendChild(item);
                displayed++;
            });
            if (displayed === 0) {
                const empty = doc.createElement('div');
                empty.style.cssText = 'font-size:9px!important;color:#94a3b8!important;padding:8px!important;text-align:center!important;border:1px dashed rgba(255,255,255,0.12)!important;border-radius:6px!important;grid-column:1/4;';
                empty.textContent = 'No media items.';
                grid.appendChild(empty);
            }
            frag.appendChild(grid);
        } else {
            links.forEach(link => {
                const item = buildListItem(link, filterText, hideInternal, false);
                if (item) {
                    frag.appendChild(item);
                    displayed++;
                }
            });
            if (displayed === 0) {
                const empty = doc.createElement('div');
                empty.style.cssText = 'font-size:9px!important;color:#94a3b8!important;padding:8px!important;text-align:center!important;border:1px dashed rgba(255,255,255,0.12)!important;border-radius:6px!important;';
                empty.textContent = 'No matching links.';
                frag.appendChild(empty);
            }
        }

        listContainer.appendChild(frag);
        if (title) title.textContent = `🔗 Extracted Links (${displayed} shown)`;
    }

    // --- Link panel with Refresh button ---
    function createLinkPanel() {
        if (linkPanelEl) return linkPanelEl;

        const panel = doc.createElement('div');
        panel.id = 'hider-link-panel';
        panel.className = 'h-glass';
        panel.style.cssText = `
            position: fixed !important;
            right: 14px !important;
            top: 55px !important;
            z-index: 2147483645 !important;
            width: min(310px, 90vw) !important;
            max-height: min(580px, 82vh) !important;
            border-radius: 16px !important;
            padding: 10px !important;
            display: none;
            flex-direction: column !important;
            overflow-y: auto !important;
            overscroll-behavior: contain !important;
            touch-action: pan-y !important;
            pointer-events: auto !important;
            gap: 6px !important;
            opacity: 0;
            transform: scale(0.96) translateY(-8px);
            transition: opacity 0.2s ease, transform 0.2s ease !important;
        `;

        const header = doc.createElement('div');
        header.className = 'panel-header';
        header.style.cssText = 'display:flex; justify-content:space-between; align-items:center;';
        const title = doc.createElement('span');
        title.id = 'link-panel-title';
        title.textContent = '🔗 Extracted Links';
        const headerRight = doc.createElement('div');
        headerRight.style.cssText = 'display:flex; gap:4px;';

        const modeBtn = doc.createElement('button');
        modeBtn.className = 'hider-btn-small btn-gray';
        modeBtn.textContent = '📝';
        modeBtn.title = 'Toggle display: text / URL';
        modeBtn.onclick = (e) => {
            e.stopPropagation();
            linkDisplayMode = linkDisplayMode === 'text' ? 'url' : 'text';
            modeBtn.textContent = linkDisplayMode === 'text' ? '📝' : '🔗';
            populateLinkList();
        };
        headerRight.appendChild(modeBtn);

        const refreshBtn = doc.createElement('button');
        refreshBtn.className = 'hider-btn-small btn-purple';
        refreshBtn.textContent = '🔄';
        refreshBtn.title = 'Refresh links & pause media';
        refreshBtn.onclick = (e) => {
            e.stopPropagation();
            pauseAllVideos();
            populateLinkList();
            showToast('🔄 Links refreshed');
        };
        headerRight.appendChild(refreshBtn);

        const closeBtn = doc.createElement('button');
        closeBtn.className = 'hider-btn-small';
        closeBtn.style.cssText = 'background:rgba(255,255,255,0.12)!important; padding:2px 6px!important;';
        closeBtn.textContent = '✖';
        closeBtn.onclick = () => { toggleLinkPanel(); };
        headerRight.appendChild(closeBtn);

        header.appendChild(title);
        header.appendChild(headerRight);
        panel.appendChild(header);

        const searchWrapper = doc.createElement('div');
        searchWrapper.style.cssText = 'display:flex; gap:4px; align-items:center; margin-bottom:2px; flex-wrap:wrap;';
        const searchInput = doc.createElement('input');
        searchInput.id = 'hider-link-search';
        searchInput.className = 'h-select';
        searchInput.placeholder = '🔍 Filter links...';
        searchInput.style.cssText = 'flex:1; height:26px; font-size:10px; min-width:80px;';
        searchInput.oninput = () => populateLinkList();
        searchWrapper.appendChild(searchInput);

        const hideCheck = doc.createElement('label');
        hideCheck.style.cssText = 'font-size:9px; color:#cbd5e1; display:flex; align-items:center; gap:4px; cursor:pointer; user-select:none; white-space:nowrap;';
        const checkBox = doc.createElement('input');
        checkBox.id = 'hider-link-hide-internal';
        checkBox.type = 'checkbox';
        checkBox.style.cssText = 'accent-color:#38bdf8; width:12px; height:12px; cursor:pointer;';
        checkBox.onchange = () => populateLinkList();
        hideCheck.appendChild(checkBox);
        hideCheck.appendChild(doc.createTextNode('Hide internal'));
        searchWrapper.appendChild(hideCheck);

        const mediaCheck = doc.createElement('label');
        mediaCheck.style.cssText = 'font-size:9px; color:#cbd5e1; display:flex; align-items:center; gap:4px; cursor:pointer; user-select:none; white-space:nowrap;';
        const mediaBox = doc.createElement('input');
        mediaBox.id = 'hider-link-media-mode';
        mediaBox.type = 'checkbox';
        mediaBox.style.cssText = 'accent-color:#f59e0b; width:12px; height:12px; cursor:pointer;';
        mediaBox.onchange = () => populateLinkList();
        mediaCheck.appendChild(mediaBox);
        mediaCheck.appendChild(doc.createTextNode('📺 Media mode'));
        searchWrapper.appendChild(mediaCheck);

        panel.appendChild(searchWrapper);

        const listContainer = doc.createElement('div');
        listContainer.id = 'hider-link-list';
        listContainer.style.cssText = 'display:flex; flex-direction:column; gap:4px; overflow-y:auto; flex:1; overscroll-behavior:contain;';
        panel.appendChild(listContainer);

        shadowRoot.appendChild(panel);
        linkPanelEl = panel;

        return panel;
    }

    function toggleLinkPanel() {
        if (!shadowRoot) return;
        if (!linkPanelEl || !linkPanelEl.parentNode) {
            linkPanelEl = createLinkPanel();
        }

        const isVisible = linkPanelEl.classList.contains('is-visible');
        if (isVisible) {
            linkPanelEl.classList.remove('is-visible');
            setTimeout(() => linkPanelEl.style.display = 'none', 300);
        } else {
            pauseAllVideos();
            populateLinkList();
            linkPanelEl.style.display = 'flex';
            void linkPanelEl.offsetWidth;
            linkPanelEl.classList.add('is-visible');
        }
    }

    // ================================================================
    //  RULE OVERLAY (ADD / EDIT) – ENLARGED HEIGHT, TARGET FIELD
    // ================================================================
    let currentRuleOverlayMode = 'add';
    let currentRuleEditInfo = null;

    function showRuleOverlay(options) {
        const existing = shadowRoot?.getElementById('hider-rule-overlay');
        if (existing) existing.remove();

        const mode = options.mode || 'add';
        const initialSelector = options.selector || '';
        const initialScope = options.scope || 'global';
        const initialTarget = options.target || '';

        currentRuleOverlayMode = mode;
        currentRuleEditInfo = options.editInfo || null;

        const overlay = doc.createElement('div');
        overlay.id = 'hider-rule-overlay';
        overlay.className = 'h-glass';
        overlay.style.cssText = `
            position: fixed !important;
            top: 50% !important;
            left: 50% !important;
            transform: translate(-50%, -50%) !important;
            z-index: 2147483647 !important;
            padding: 22px !important;
            border-radius: 16px !important;
            min-width: 360px !important;
            max-width: 92vw !important;
            width: 420px !important;
            min-height: 280px !important;
            display: flex !important;
            flex-direction: column !important;
            gap: 14px !important;
            pointer-events: auto !important;
            background: rgba(13,18,30,0.96) !important;
            backdrop-filter: blur(16px) !important;
            border: 1px solid rgba(255,255,255,0.15) !important;
            box-shadow: 0 24px 48px rgba(0,0,0,0.8) !important;
        `;

        const title = doc.createElement('div');
        title.style.cssText = 'font-weight:800;font-size:14px;color:#38bdf8;margin-bottom:4px;';
        title.textContent = mode === 'add' ? '➕ Add Rule' : '✏️ Edit Rule';
        overlay.appendChild(title);

        const scopeContainer = doc.createElement('div');
        scopeContainer.className = 'h-custom-select';
        scopeContainer.id = 'rule-scope-select';
        scopeContainer.innerHTML = `
            <div class="h-custom-trigger"><span class="h-custom-value-text">Global</span><span class="h-custom-arrow">▼</span></div>
            <div class="h-custom-options">
                <div class="h-custom-opt" data-val="global">🌍 Global</div>
                <div class="h-custom-opt" data-val="site">🌐 Site‑Wide</div>
                <div class="h-custom-opt" data-val="link">📄 Page‑Only</div>
            </div>
        `;
        overlay.appendChild(scopeContainer);

        const targetContainer = doc.createElement('div');
        targetContainer.id = 'rule-target-container';
        targetContainer.style.cssText = 'display:none; flex-direction:column; gap:4px;';
        const targetLabel = doc.createElement('div');
        targetLabel.style.cssText = 'font-size:10px;color:#94a3b8;font-weight:600;text-transform:uppercase;letter-spacing:0.3px;';
        targetLabel.textContent = '🎯 Target (domain or URL)';
        targetContainer.appendChild(targetLabel);
        const targetInput = doc.createElement('input');
        targetInput.id = 'rule-target-input';
        targetInput.className = 'h-select';
        targetInput.placeholder = 'example.com or /path';
        targetInput.value = initialTarget || '';
        targetInput.style.cssText = 'width:100%;height:34px;font-size:11px;padding:4px 10px;';
        targetContainer.appendChild(targetInput);
        overlay.appendChild(targetContainer);

        const input = doc.createElement('input');
        input.id = 'rule-selector-input';
        input.className = 'h-select';
        input.placeholder = 'CSS Selector (e.g. .ad, #banner)';
        input.value = initialSelector;
        input.style.cssText = 'width:100%;height:34px;font-size:11px;padding:4px 10px;';
        overlay.appendChild(input);

        const btnGroup = doc.createElement('div');
        btnGroup.style.cssText = 'display:flex;gap:8px;justify-content:flex-end;margin-top:6px;';
        const saveBtn = doc.createElement('button');
        saveBtn.className = 'hider-btn-small btn-green';
        saveBtn.textContent = '💾 Save';
        saveBtn.style.cssText = 'height:32px;padding:0 16px;font-size:11px;';
        const cancelBtn = doc.createElement('button');
        cancelBtn.className = 'hider-btn-small btn-gray';
        cancelBtn.textContent = '✖ Cancel';
        cancelBtn.style.cssText = 'height:32px;padding:0 16px;font-size:11px;';
        btnGroup.appendChild(saveBtn);
        btnGroup.appendChild(cancelBtn);
        overlay.appendChild(btnGroup);

        shadowRoot.appendChild(overlay);

        let selectedScope = initialScope;
        const trigger = scopeContainer.querySelector('.h-custom-trigger');
        const valueSpan = trigger.querySelector('.h-custom-value-text');
        const optionsList = scopeContainer.querySelectorAll('.h-custom-opt');
        const updateScopeLabel = (val) => {
            const labels = { global: '🌍 Global', site: '🌐 Site‑Wide', link: '📄 Page‑Only' };
            valueSpan.textContent = labels[val] || 'Global';
            optionsList.forEach(opt => opt.classList.toggle('is-selected', opt.dataset.val === val));
            selectedScope = val;
            if (val === 'global') {
                targetContainer.style.display = 'none';
            } else {
                targetContainer.style.display = 'flex';
                if (!targetInput.value) {
                    if (val === 'site') targetInput.value = location.hostname;
                    else if (val === 'link') targetInput.value = cleanUrl();
                }
            }
        };
        optionsList.forEach(opt => {
            opt.addEventListener('click', (e) => {
                e.stopPropagation();
                updateScopeLabel(opt.dataset.val);
                scopeContainer.classList.remove('is-open');
            });
        });
        trigger.addEventListener('click', (e) => {
            e.stopPropagation();
            const isOpen = scopeContainer.classList.contains('is-open');
            shadowRoot.querySelectorAll('.h-custom-select').forEach(c => c.classList.remove('is-open'));
            if (!isOpen) scopeContainer.classList.add('is-open');
        });
        document.addEventListener('click', function closeDropdown(e) {
            if (scopeContainer && !scopeContainer.contains(e.target)) {
                scopeContainer.classList.remove('is-open');
                document.removeEventListener('click', closeDropdown);
            }
        });

        updateScopeLabel(initialScope);

        const saveRule = () => {
            const selector = input.value.trim();
            if (!selector) {
                showToast('⚠️ Please enter a CSS selector');
                return;
            }
            try {
                doc.querySelectorAll(selector);
            } catch (err) {
                showToast('⚠️ That isn\u2019t a valid CSS selector \u2014 check the syntax');
                return;
            }

            let newScope = selectedScope;
            let targetValue = targetInput.value.trim();

            if (newScope === 'global') {
                targetValue = '*';
            } else {
                if (!targetValue) {
                    showToast(`⚠️ Please enter a target ${newScope === 'site' ? 'domain' : 'URL'}`);
                    return;
                }
                if (newScope === 'site') {
                    targetValue = cleanDomain(targetValue);
                    if (!targetValue) {
                        showToast('⚠️ Invalid domain');
                        return;
                    }
                } else if (newScope === 'link') {
                    try {
                        const abs = resolveUrl(targetValue);
                        if (!abs) throw new Error();
                        targetValue = abs;
                    } catch {
                        showToast('⚠️ Invalid URL');
                        return;
                    }
                }
            }

            if (newScope === 'global') {
                const editingId = (mode === 'edit' && currentRuleEditInfo?.listType === 'custom') ? currentRuleEditInfo.id : null;
                const isDuplicate = CACHE.customRules.some(r => r.selector === selector && r.id !== editingId);
                if (isDuplicate) {
                    showToast('⚠️ A global rule for this selector already exists');
                    return;
                }
            }

            if (mode === 'edit' && currentRuleEditInfo) {
                const info = currentRuleEditInfo;
                if (info.listType === 'custom') {
                    CACHE.customRules = CACHE.customRules.filter(r => r.id !== info.id);
                    sv('hider_custom_rules_v4', CACHE.customRules);
                } else if (info.listType === 'site') {
                    const key = 'hider_site_' + location.hostname;
                    let rules = gv(key, []);
                    if (info.index >= 0 && info.index < rules.length) {
                        rules.splice(info.index, 1);
                        sv(key, rules);
                    }
                } else if (info.listType === 'link') {
                    const key = 'hider_link_' + cleanUrl();
                    let rules = gv(key, []);
                    if (info.index >= 0 && info.index < rules.length) {
                        rules.splice(info.index, 1);
                        sv(key, rules);
                    }
                }
            }

            if (newScope === 'global') {
                const newRule = { id: 'rule_' + Date.now() + '_' + Math.random().toString(36).substr(2,4), selector: selector, target: '*' };
                CACHE.customRules.push(newRule);
                sv('hider_custom_rules_v4', CACHE.customRules);
                showToast(`🌍 Added global rule: ${selector}`);
            } else if (newScope === 'site') {
                const key = 'hider_site_' + targetValue;
                let rules = gv(key, []);
                if (!rules.includes(selector)) {
                    rules.push(selector);
                    sv(key, rules);
                    showToast(`🌐 Added site-wide rule for ${targetValue}: ${selector}`);
                } else {
                    showToast('⚠️ Rule already exists for this site');
                }
            } else if (newScope === 'link') {
                const key = 'hider_link_' + targetValue;
                let rules = gv(key, []);
                if (!rules.includes(selector)) {
                    rules.push(selector);
                    sv(key, rules);
                    showToast(`📄 Added page-only rule for ${targetValue}: ${selector}`);
                } else {
                    showToast('⚠️ Rule already exists for this page');
                }
            }

            overlay.remove();
            requestUpdateStyles();
            renderList();
            currentRuleEditInfo = null;
        };

        const cancel = () => {
            overlay.remove();
            currentRuleEditInfo = null;
        };

        saveBtn.addEventListener('click', saveRule);
        cancelBtn.addEventListener('click', cancel);
    }

    // ---------- UI Creation ----------
    function createShadowUI() {
        if (!isTop) return;
        const parentEl = doc.documentElement || doc.body;
        if (!parentEl) return;

        let hostEl = doc.getElementById(UI_HOST_ID);
        if (!hostEl) {
            hostEl = doc.createElement('div'); hostEl.id = UI_HOST_ID;
            hostEl.style.cssText = 'position:fixed!important;top:0!important;left:0!important;width:0!important;height:0!important;z-index:2147483647!important;pointer-events:none!important;display:block!important;visibility:visible!important;opacity:1!important;overflow:visible!important;';
            parentEl.appendChild(hostEl);
        }

        shadowRoot = hostEl.shadowRoot || hostEl.attachShadow({ mode: 'open' });
        const style = doc.createElement('style');

        style.textContent = `
        * { box-sizing: border-box !important; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, sans-serif !important; line-height: 1.3 !important; }

        .h-glass {
            background: rgba(13, 18, 30, 0.92) !important;
            backdrop-filter: blur(12px) !important;
            -webkit-backdrop-filter: blur(12px) !important;
            border: 1px solid rgba(255, 255, 255, 0.12) !important;
            color: #f8fafc !important;
            border-radius: 14px !important;
            box-shadow: 0 12px 30px rgba(0, 0, 0, 0.6) !important;
        }

        ::-webkit-scrollbar { width: 4px !important; height: 4px !important; }
        ::-webkit-scrollbar-track { background: transparent !important; }
        ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2) !important; border-radius: 8px !important; }

        #hider-panel {
            position: fixed !important;
            right: 14px !important;
            top: 55px !important;
            z-index: 2147483645 !important;
            width: min(480px, 92vw) !important;
            max-height: min(700px, 85vh) !important;
            border-radius: 16px !important;
            padding: 0 !important;
            display: none;
            flex-direction: column !important;
            overflow: hidden !important;
            pointer-events: auto !important;
            opacity: 0;
            transform: scale(0.96) translateY(-8px);
            transition: opacity 0.2s ease, transform 0.2s ease !important;
        }
        #hider-panel.is-visible {
            opacity: 1 !important;
            transform: scale(1) translateY(0) !important;
            display: flex !important;
        }

        #hider-link-panel.is-visible {
            opacity: 1 !important;
            transform: scale(1) translateY(0) !important;
            display: flex !important;
        }

        .panel-header {
            padding: 8px 12px;
            border-bottom: 1px solid rgba(255,255,255,0.08);
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-shrink: 0;
        }
        .panel-header .title {
            font-weight: 800;
            font-size: 12px;
            color: #f8fafc;
        }
        .panel-header .close-btn {
            background: rgba(255,255,255,0.08);
            border: none;
            border-radius: 6px;
            color: #cbd5e1;
            padding: 2px 8px;
            cursor: pointer;
            font-size: 11px;
        }
        .panel-header .close-btn:hover { background: rgba(255,255,255,0.16); }

        .panel-body {
            display: flex;
            flex: 1;
            overflow: hidden;
        }

        .panel-sidebar {
            flex: 0 0 110px;
            background: rgba(0,0,0,0.2);
            padding: 6px 4px;
            overflow-y: auto;
            border-right: 1px solid rgba(255,255,255,0.06);
        }

        .panel-sidebar .tab-btn {
            display: block;
            width: 100%;
            text-align: left;
            background: transparent;
            border: none;
            border-radius: 6px;
            padding: 5px 8px;
            color: #94a3b8;
            font-size: 10px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.15s ease;
            margin-bottom: 2px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .panel-sidebar .tab-btn:hover {
            background: rgba(255,255,255,0.08);
            color: #e2e8f0;
        }
        .panel-sidebar .tab-btn.active {
            background: rgba(56,189,248,0.15);
            color: #38bdf8;
            border-left: 2px solid #38bdf8;
        }

        .panel-content {
            flex: 1;
            padding: 8px 10px;
            overflow-y: auto;
            display: flex;
            flex-direction: column;
            gap: 6px;
        }

        .panel-content .tab-content {
            display: none;
            flex-direction: column;
            gap: 6px;
        }
        .panel-content .tab-content.active {
            display: flex;
        }

        .h-dock {
            position: fixed !important; right: 10px !important; top: 35%; z-index: 2147483643 !important;
            display: flex !important; flex-direction: column !important; align-items: center !important; gap: 5px !important;
            padding: 5px !important; pointer-events: auto !important; transition: transform 0.3s ease, opacity 0.3s ease !important;
            user-select: none !important; border-radius: 20px !important;
        }
        .h-dock.is-collapsed { transform: translateX(65%) !important; opacity: 0.5 !important; }
        .h-dock.manual-hidden { transform: translateX(65%) !important; opacity: 0.5 !important; }
        .h-dock.is-collapsed:not(.manual-hidden):hover, .h-dock.expanded { transform: translateX(0) !important; opacity: 1 !important; }

        .h-dock-main {
            width: 34px !important; height: 34px !important; font-size: 16px !important;
            background: linear-gradient(135deg, rgba(56, 189, 248, 0.3), rgba(37, 99, 235, 0.4)) !important;
            border: 1px solid rgba(56, 189, 248, 0.4) !important; cursor: grab !important; border-radius: 50% !important;
            flex-shrink: 0 !important; min-height: 34px !important; min-width: 34px !important; display: flex !important; align-items: center !important; justify-content: center !important;
        }
        .h-dock-main.expanded {
            background: linear-gradient(135deg, #0ea5e9, #2563eb) !important; color: #fff !important;
            box-shadow: 0 0 12px rgba(14, 165, 233, 0.5) !important; border-color: transparent !important;
        }

        .h-dock-menu { display: flex; flex-direction: column !important; gap: 5px !important; overflow: hidden !important; max-height: 0; opacity: 0; transition: max-height 0.3s ease, opacity 0.2s ease !important; }
        .h-dock-menu.is-open { max-height: 450px; opacity: 1; }

        .h-dock-btn {
            width: 32px !important; height: 32px !important; border-radius: 10px !important;
            border: 1px solid rgba(255, 255, 255, 0.1) !important; background: rgba(255, 255, 255, 0.06) !important;
            color: #cbd5e1 !important; font-size: 11px !important; font-weight: 700 !important; display: flex !important;
            flex-direction: column !important; align-items: center !important; justify-content: center !important;
            cursor: pointer !important; transition: all 0.2s ease !important; margin: 0 !important; padding: 0 !important;
            flex-shrink: 0 !important; min-height: 32px !important; min-width: 32px !important;
        }
        .h-dock-btn:hover { background: rgba(255, 255, 255, 0.18) !important; color: #fff !important; transform: scale(1.05) !important; }
        .h-dock-btn.active { background: linear-gradient(135deg, #0ea5e9, #2563eb) !important; color: #fff !important; border-color: transparent !important; }
        .h-dock-btn.scope-link { background: linear-gradient(135deg, #10b981, #059669) !important; color: #fff !important; border-color: transparent !important; }
        .h-dock-btn.scope-global { background: linear-gradient(135deg, #a855f7, #7e22ce) !important; color: #fff !important; border-color: transparent !important; }
        .h-dock-btn.is-frozen { background: linear-gradient(135deg, #8b5cf6, #6d28d9) !important; color: #fff !important; border-color: transparent !important; }
        .h-dock-btn span { font-size: 7px !important; font-weight: 800 !important; margin-top: 1px !important; letter-spacing: 0.3px !important; text-transform: uppercase !important; }

        .btn-blue { background: linear-gradient(135deg, #0ea5e9, #0284c7) !important; color: #fff !important; border: 1px solid rgba(255,255,255,0.2) !important; }
        .btn-green { background: linear-gradient(135deg, #10b981, #059669) !important; color: #fff !important; border: 1px solid rgba(255,255,255,0.2) !important; }
        .btn-red { background: linear-gradient(135deg, #f43f5e, #e11d48) !important; color: #fff !important; border: 1px solid rgba(255,255,255,0.2) !important; }
        .btn-purple { background: linear-gradient(135deg, #a855f7, #7e22ce) !important; color: #fff !important; border: 1px solid rgba(255,255,255,0.2) !important; }
        .btn-gray { background: linear-gradient(135deg, #475569, #334155) !important; color: #fff !important; border: 1px solid rgba(255,255,255,0.15) !important; }

        .h-stepper-pill {
            position: fixed !important; bottom: 20px !important; left: 50% !important; transform: translateX(-50%) !important;
            z-index: 2147483644 !important; padding: 6px 8px !important; display: flex !important; flex-direction: column !important;
            align-items: center !important; gap: 4px !important; pointer-events: auto !important; width: 130px !important;
            user-select: none !important; border-radius: 12px !important;
        }
        .h-stepper-row { display: flex !important; gap: 4px !important; width: 100% !important; justify-content: center !important; }
        .h-stepper-row .h-btn-icon { flex: 1 !important; }
        .h-drag-dots { cursor: grab !important; color: #64748b !important; font-size: 11px !important; width: 100% !important; text-align: center !important; line-height: 1 !important; letter-spacing: 2px !important; }
        .h-btn-icon { width: 100% !important; height: 22px !important; border-radius: 6px !important; border: 1px solid rgba(255,255,255,.12) !important; background: rgba(255,255,255,.08) !important; color: #f1f5f9 !important; font-size: 9px !important; font-weight: 700 !important; cursor: pointer !important; display: flex !important; align-items: center !important; justify-content: center !important; }
        .h-btn-icon:hover { background: rgba(255,255,255,.2) !important; }

        .h-tag-badge-box { width: 100% !important; height: 22px !important; overflow: hidden !important; position: relative !important; background: rgba(0, 0, 0, 0.5) !important; border: 1px solid rgba(56, 189, 248, 0.3) !important; border-radius: 6px !important; display: flex !important; align-items: center !important; flex-shrink: 0 !important; }
        .h-tag-badge-text { color: #38bdf8 !important; font-size: 9px !important; font-family: monospace !important; font-weight: 700 !important; display: block !important; width: 100% !important; text-align: center !important; overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important; line-height: 22px !important; }
        .h-tag-badge-text.is-animating { position: absolute !important; left: 0 !important; width: auto !important; padding-left: 100% !important; text-align: left !important; animation: hiderMarqueeR2L 8s linear infinite !important; }
        @keyframes hiderMarqueeR2L { 0% { transform: translate3d(0,0,0); } 100% { transform: translate3d(-100%,0,0); } }

        .h-btn-pill { height: 22px !important; min-height: 22px !important; width: 100% !important; padding: 0 6px !important; border-radius: 6px !important; font-size: 9px !important; font-weight: 800 !important; border: none !important; cursor: pointer !important; display: flex !important; align-items: center !important; justify-content: center !important; }
        .h-btn-pill:hover { filter: brightness(1.15) !important; }

        .h-toast { /* overridden by inline styles */ }
        .h-prompt { position: fixed !important; top: 25px !important; left: 50% !important; transform: translateX(-50%) translateY(-15px) !important; opacity: 0; padding: 12px 14px !important; z-index: 2147483646 !important; display: flex !important; flex-direction: column !important; align-items: center !important; gap: 6px !important; pointer-events: auto !important; width: min(290px, 88vw) !important; max-height: 85vh !important; transition: all 0.3s ease !important; }
        .h-url-box { font-size: 10px !important; color: #94a3b8 !important; word-break: break-all !important; max-height: 32px !important; overflow: hidden !important; background: rgba(0,0,0,.4) !important; padding: 4px 8px !important; border-radius: 6px !important; width: 100% !important; border: 1px solid rgba(255,255,255,.1) !important; font-family: monospace !important; }
        .h-select { width: 100% !important; background: rgba(255,255,255,.06) !important; border: 1px solid rgba(255,255,255,.14) !important; border-radius: 6px !important; color: #fff !important; padding: 4px 8px !important; font-size: 10px !important; outline: 0 !important; height: 28px !important; }

        .h-custom-select { position: relative !important; width: 100% !important; user-select: none !important; margin-top: 2px !important; z-index: 10 !important; }
        .h-custom-trigger { background: rgba(30,41,59,.85) !important; border: 1px solid rgba(96,165,250,.4) !important; border-radius: 8px !important; color: #f1f5f9 !important; padding: 6px 10px !important; font-size: 10px !important; font-weight: 700 !important; cursor: pointer !important; display: flex !important; justify-content: space-between !important; align-items: center !important; height: 30px !important; }
        .h-custom-arrow { font-size: 9px !important; color: #38bdf8 !important; transition: transform .2s ease !important; }
        .h-custom-select.is-open .h-custom-arrow { transform: rotate(-180deg) !important; }
        .h-custom-options { display: none; position: relative !important; z-index: 100 !important; flex-direction: column !important; background: rgba(15,23,42,0.98) !important; border: 1px solid rgba(255,255,255,.2) !important; border-radius: 8px !important; max-height: 160px !important; overflow-y: auto !important; margin-top: 4px !important; }
        .h-custom-select.is-open .h-custom-options { display: flex !important; }
        .h-custom-opt { padding: 6px 10px !important; color: #cbd5e1 !important; font-size: 10px !important; cursor: pointer !important; border-bottom: 1px solid rgba(255,255,255,.05) !important; }
        .h-custom-opt:hover, .h-custom-opt.is-selected { background: rgba(56,189,248,.2) !important; color: #38bdf8 !important; font-weight: 700 !important; }

        .panel-header { font-weight: 800 !important; font-size: 11px !important; border-bottom: 1px solid rgba(255,255,255,.12) !important; padding-bottom: 6px !important; display: flex !important; justify-content: space-between !important; align-items: center !important; margin-bottom: 2px !important; color: #f8fafc !important; }
        .list-item { font-size: 10px !important; background: rgba(255,255,255,.04) !important; border: 1px solid rgba(255,255,255,.08) !important; border-radius: 6px !important; padding: 4px 6px !important; display: flex !important; justify-content: space-between !important; align-items: center !important; gap: 6px !important; }
        .list-item span.rule-text { word-break: break-all !important; color: #e2e8f0 !important; font-family: monospace !important; font-size: 9px !important; flex: 1 !important; overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important; }
        .hider-btn-small { cursor: pointer !important; border: none !important; border-radius: 4px !important; padding: 2px 6px !important; color: #fff !important; font-weight: 700 !important; font-size: 9px !important; height: 20px !important; display: flex; align-items: center; justify-content: center; }

        /* ==================== PRO UI 15.0 VISUAL SYSTEM ==================== */
        :host, #hider-ui-root { --hx-bg:#07101d; --hx-panel:rgba(10,18,31,.90); --hx-line:rgba(148,163,184,.12); --hx-cyan:#38bdf8; --hx-blue:#2563eb; --hx-violet:#8b5cf6; --hx-gold:#fbbf24; }
        * { box-sizing:border-box; }
        #hider-panel, #hider-link-panel { backdrop-filter:blur(24px) saturate(145%); -webkit-backdrop-filter:blur(24px) saturate(145%); border:1px solid rgba(125,211,252,.14)!important; box-shadow:0 24px 70px rgba(0,0,0,.48), inset 0 1px 0 rgba(255,255,255,.045); }
        #hider-panel { background:linear-gradient(145deg,rgba(8,15,28,.96),rgba(9,18,34,.88) 55%,rgba(22,15,39,.82))!important; }
        .panel-header { min-height:42px; padding:8px 11px!important; background:linear-gradient(90deg,rgba(56,189,248,.055),transparent 48%,rgba(139,92,246,.045)); }
        .panel-header .title { font-size:12px!important; letter-spacing:.2px; }
        .panel-sidebar { background:linear-gradient(180deg,rgba(255,255,255,.025),rgba(0,0,0,.18))!important; }
        .panel-sidebar .tab-btn { position:relative; transition:background .18s ease,color .18s ease,transform .18s ease!important; }
        .panel-sidebar .tab-btn:hover { transform:translateX(2px); }
        .panel-sidebar .tab-btn.active { box-shadow:inset 0 0 0 1px rgba(56,189,248,.08),0 5px 18px rgba(14,165,233,.08); }
        .panel-content { scroll-behavior:smooth; overscroll-behavior:contain; scrollbar-width:thin; scrollbar-color:rgba(125,211,252,.24) transparent; }
        .panel-content::-webkit-scrollbar { width:6px; } .panel-content::-webkit-scrollbar-thumb { background:rgba(125,211,252,.22); border-radius:20px; }
        .h-dock { filter:drop-shadow(0 14px 30px rgba(0,0,0,.32)); }
        .h-dock-main { transition:transform .22s cubic-bezier(.2,.8,.2,1),box-shadow .22s ease,background .22s ease!important; }
        .h-dock-main:hover { transform:scale(1.06); box-shadow:0 0 22px rgba(56,189,248,.30)!important; }
        .h-dock-menu { gap:6px!important; }
        .h-dock-btn { transform:translateZ(0); transition:transform .16s ease,background .16s ease,border-color .16s ease,box-shadow .16s ease!important; }
        .h-dock-btn:active { transform:scale(.94)!important; }
        .h-dock-btn:hover { box-shadow:0 8px 20px rgba(0,0,0,.24); }
        .hider-btn-small { transition:transform .14s ease,filter .14s ease,box-shadow .14s ease!important; }
        .hider-btn-small:hover { filter:brightness(1.08); box-shadow:0 5px 14px rgba(0,0,0,.22); transform:translateY(-1px); }
        .hider-btn-small:active { transform:translateY(0) scale(.97); }
        .hx-card { position:relative; overflow:hidden; border:1px solid rgba(148,163,184,.10); border-radius:12px; background:linear-gradient(145deg,rgba(255,255,255,.045),rgba(255,255,255,.018)); box-shadow:0 10px 28px rgba(0,0,0,.16); }
        .hx-input { width:100%; background:rgba(2,6,23,.46)!important; border:1px solid rgba(148,163,184,.15)!important; color:#f8fafc!important; border-radius:8px!important; outline:none; transition:border-color .18s ease,box-shadow .18s ease,background .18s ease; }
        .hx-input:focus { border-color:rgba(56,189,248,.52)!important; box-shadow:0 0 0 3px rgba(56,189,248,.09); background:rgba(2,6,23,.66)!important; }
        .hx-cookie-row { transition:background .16s ease,border-color .16s ease,transform .16s ease; }
        .hx-cookie-row:hover { background:rgba(56,189,248,.055)!important; border-color:rgba(56,189,248,.18)!important; transform:translateY(-1px); }
        .hx-cookie-value { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
        .hx-chip { display:inline-flex; align-items:center; gap:4px; padding:3px 7px; border-radius:999px; border:1px solid rgba(148,163,184,.12); background:rgba(255,255,255,.035); color:#94a3b8; font-size:8px; font-weight:800; }
        .hx-empty { border:1px dashed rgba(148,163,184,.16); border-radius:12px; padding:18px 10px; text-align:center; color:#64748b; }
        @media (max-width:600px) { #hider-panel { width:min(94vw,480px)!important; max-height:88vh!important; } .panel-sidebar { flex-basis:92px!important; } .panel-content { padding:8px!important; } }
        /* ==================== PRO UI 15.4 — FUTURE GLASS SYSTEM ==================== */
        :host, #hider-ui-root {
            --hx-bg:#050914;
            --hx-surface:rgba(8,14,25,.78);
            --hx-surface-2:rgba(15,23,42,.52);
            --hx-line:rgba(148,163,184,.14);
            --hx-line-bright:rgba(125,211,252,.30);
            --hx-cyan:#7dd3fc;
            --hx-cyan-strong:#38bdf8;
            --hx-violet:#a78bfa;
            --hx-green:#6ee7b7;
            --hx-red:#fb7185;
            --hx-gold:#fbbf24;
            --hx-text:#e7eef8;
            --hx-muted:#718096;
            --hx-radius:14px;
        }
        * { box-sizing:border-box; }
        button,input,select,textarea { font-family:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif !important; }
        button { -webkit-font-smoothing:antialiased; }

        /* --- Master glass surfaces --- */
        .h-glass, #hider-panel, #hider-link-panel, .h-stepper-pill, .h-prompt {
            background:
                linear-gradient(180deg,rgba(255,255,255,.052),rgba(255,255,255,.018)),
                rgba(5,10,20,.86) !important;
            border:1px solid var(--hx-line) !important;
            box-shadow:
                0 30px 80px rgba(0,0,0,.46),
                0 1px 0 rgba(255,255,255,.045) inset,
                0 0 0 1px rgba(0,0,0,.16) !important;
            backdrop-filter:blur(28px) saturate(125%) !important;
            -webkit-backdrop-filter:blur(28px) saturate(125%) !important;
        }
        .h-glass::before, #hider-panel::before, #hider-link-panel::before {
            content:"" !important;
            position:absolute !important;
            inset:0 !important;
            pointer-events:none !important;
            border-radius:inherit !important;
            background:linear-gradient(115deg,rgba(125,211,252,.055),transparent 25%,transparent 72%,rgba(167,139,250,.035)) !important;
            opacity:1 !important;
        }

        /* --- Header: minimal command console --- */
        .panel-header {
            min-height:50px !important;
            padding:8px 10px !important;
            margin:0 !important;
            border-bottom:1px solid rgba(148,163,184,.10) !important;
            background:rgba(255,255,255,.018) !important;
        }
        .panel-brand { gap:9px !important; }
        .panel-brand-copy { min-width:0 !important; }
        .panel-brand-title { font-size:12px !important; letter-spacing:.1px !important; }
        .panel-brand-sub { color:#718096 !important; font-size:8px !important; letter-spacing:1.15px !important; text-transform:uppercase !important; }
        .panel-status {
            display:inline-flex !important; align-items:center !important; gap:4px !important;
            margin-left:5px !important; padding:2px 5px !important; border-radius:999px !important;
            color:#86efac !important; background:rgba(34,197,94,.055) !important;
            border:1px solid rgba(74,222,128,.16) !important; font-size:6px !important; letter-spacing:1px !important;
        }
        .panel-status::before { content:""; width:4px; height:4px; border-radius:50%; background:#4ade80; box-shadow:0 0 8px rgba(74,222,128,.7); }
        .hx-brand-icon { width:32px !important; height:32px !important; flex:0 0 32px !important; border-radius:9px !important; overflow:hidden !important; opacity:.96 !important; filter:drop-shadow(0 4px 12px rgba(56,189,248,.16)); }
        .hx-brand-icon svg { width:100% !important; height:100% !important; display:block !important; }
        .close-btn { width:27px !important; height:27px !important; border-radius:9px !important; border:1px solid rgba(148,163,184,.12) !important; background:rgba(255,255,255,.035) !important; color:#94a3b8 !important; transition:.18s ease !important; }
        .close-btn:hover { color:#e7eef8 !important; background:rgba(125,211,252,.07) !important; border-color:rgba(125,211,252,.24) !important; transform:none !important; }
        .close-btn:active { transform:scale(.94) !important; }

        /* --- Sidebar / navigation: precision rail --- */
        .panel-sidebar {
            background:rgba(255,255,255,.012) !important;
            border-right:1px solid rgba(148,163,184,.08) !important;
            padding:7px 5px !important;
        }
        .panel-sidebar .tab-btn {
            position:relative !important; min-height:28px !important; padding:6px 8px 6px 10px !important;
            border:1px solid transparent !important; border-radius:9px !important; color:#718096 !important;
            font-size:9px !important; font-weight:700 !important; letter-spacing:.15px !important;
            transition:background .18s ease,border-color .18s ease,color .18s ease,transform .18s ease !important;
        }
        .panel-sidebar .tab-btn::before { content:""; position:absolute; left:4px; top:8px; bottom:8px; width:2px; border-radius:4px; background:transparent; transition:.18s ease; }
        .panel-sidebar .tab-btn:hover { transform:translateX(1px) !important; background:rgba(255,255,255,.035) !important; color:#b9c7d9 !important; }
        .panel-sidebar .tab-btn.active {
            background:linear-gradient(90deg,rgba(56,189,248,.075),rgba(56,189,248,.018)) !important;
            border-color:rgba(56,189,248,.12) !important; color:#cfeeff !important;
            box-shadow:0 6px 20px rgba(0,0,0,.10) !important;
        }
        .panel-sidebar .tab-btn.active::before { background:#38bdf8; box-shadow:0 0 9px rgba(56,189,248,.7); }
        .panel-content { padding:10px 11px !important; gap:8px !important; scrollbar-width:thin !important; scrollbar-color:rgba(125,211,252,.18) transparent !important; }
        .panel-content::-webkit-scrollbar { width:5px; }
        .panel-content::-webkit-scrollbar-thumb { background:rgba(125,211,252,.18); border-radius:99px; }
        .hx-feature-note { margin:-2px 0 1px 26px !important; padding:6px 8px !important; border-left:2px solid rgba(56,189,248,.28) !important; border-radius:7px !important; background:linear-gradient(90deg,rgba(56,189,248,.045),transparent) !important; color:#64748b !important; font-size:8px !important; line-height:1.4 !important; }
        .hx-feature-note b { color:#7dd3fc !important; font-weight:900 !important; letter-spacing:.4px !important; }
        .hx-toggle-row { min-height:32px !important; padding:6px 8px !important; border:1px solid rgba(148,163,184,.07) !important; border-radius:10px !important; background:rgba(255,255,255,.018) !important; transition:background .16s ease,border-color .16s ease,transform .16s ease !important; }
        .hx-toggle-row:hover { background:rgba(125,211,252,.045) !important; border-color:rgba(125,211,252,.12) !important; transform:translateX(1px) !important; }
        .h-dock-btn { position:relative !important; overflow:hidden !important; }
        .h-dock-btn::after { content:"" !important; position:absolute !important; inset:1px !important; border-radius:inherit !important; background:linear-gradient(135deg,rgba(255,255,255,.05),transparent 45%,rgba(56,189,248,.035)) !important; pointer-events:none !important; opacity:.75 !important; }
        .h-dock-btn.active::before,.h-dock-btn.is-frozen::before { content:"" !important; position:absolute !important; top:5px !important; right:5px !important; width:5px !important; height:5px !important; border-radius:50% !important; background:#6ee7b7 !important; box-shadow:0 0 9px rgba(110,231,183,.9) !important; }

        /* --- Every small control becomes the same glass language --- */
        .hider-btn-small, .h-btn-icon, .h-btn-pill, .h-custom-trigger, .h-select {
            border:1px solid rgba(148,163,184,.13) !important;
            background:rgba(255,255,255,.035) !important;
            color:#cbd5e1 !important;
            border-radius:8px !important;
            box-shadow:0 1px 0 rgba(255,255,255,.035) inset !important;
            transition:background .16s ease,border-color .16s ease,color .16s ease,box-shadow .16s ease,transform .12s ease !important;
        }
        .hider-btn-small:hover, .h-btn-icon:hover, .h-btn-pill:hover, .h-custom-trigger:hover {
            background:rgba(125,211,252,.065) !important; border-color:rgba(125,211,252,.22) !important;
            color:#eff8ff !important; filter:none !important; transform:translateY(-1px) !important;
            box-shadow:0 7px 18px rgba(0,0,0,.16),0 0 0 1px rgba(125,211,252,.035) inset !important;
        }
        .hider-btn-small:active, .h-btn-icon:active, .h-btn-pill:active, .h-custom-trigger:active { transform:scale(.965) !important; }
        .btn-blue,.btn-green,.btn-red,.btn-purple,.btn-gray {
            background:rgba(255,255,255,.035) !important; border-color:rgba(148,163,184,.13) !important;
        }
        .btn-blue { color:#7dd3fc !important; }
        .btn-green { color:#6ee7b7 !important; }
        .btn-red { color:#fb7185 !important; }
        .btn-purple { color:#c4b5fd !important; }
        .btn-gray { color:#cbd5e1 !important; }
        .btn-blue:hover { border-color:rgba(56,189,248,.28) !important; background:rgba(56,189,248,.065) !important; }
        .btn-green:hover { border-color:rgba(52,211,153,.25) !important; background:rgba(52,211,153,.055) !important; }
        .btn-red:hover { border-color:rgba(251,113,133,.25) !important; background:rgba(251,113,133,.055) !important; }
        .btn-purple:hover { border-color:rgba(167,139,250,.25) !important; background:rgba(167,139,250,.055) !important; }
        input, textarea, select { outline:none !important; }
        input:focus, textarea:focus, select:focus { border-color:rgba(56,189,248,.34) !important; box-shadow:0 0 0 3px rgba(56,189,248,.055) !important; }

        /* --- Dock: floating glass instrument --- */
        .h-dock {
            padding:4px !important; gap:4px !important; border-radius:15px !important;
            background:rgba(5,10,19,.70) !important; border:1px solid rgba(148,163,184,.12) !important;
            box-shadow:0 18px 50px rgba(0,0,0,.34),inset 0 1px 0 rgba(255,255,255,.045) !important;
            backdrop-filter:blur(22px) saturate(125%) !important; -webkit-backdrop-filter:blur(22px) saturate(125%) !important;
        }
        .h-dock-main {
            width:36px !important; height:36px !important; min-width:36px !important; min-height:36px !important;
            border-radius:11px !important; padding:3px !important; background:rgba(56,189,248,.055) !important;
            border:1px solid rgba(125,211,252,.22) !important; box-shadow:0 0 18px rgba(56,189,248,.07) !important;
        }
        .h-dock-main:hover { transform:none !important; background:rgba(56,189,248,.09) !important; box-shadow:0 0 24px rgba(56,189,248,.16) !important; }
        .h-dock-main.expanded { background:rgba(56,189,248,.10) !important; border-color:rgba(125,211,252,.40) !important; box-shadow:0 0 25px rgba(56,189,248,.18) !important; }
        .h-dock-btn {
            width:34px !important; height:34px !important; min-width:34px !important; min-height:34px !important;
            border-radius:10px !important; background:rgba(255,255,255,.025) !important; border:1px solid rgba(148,163,184,.10) !important;
            color:#aab8ca !important; transition:background .16s ease,border-color .16s ease,color .16s ease,transform .12s ease,box-shadow .16s ease !important;
        }
        .h-dock-btn:hover { transform:none !important; background:rgba(255,255,255,.055) !important; color:#eef8ff !important; border-color:rgba(125,211,252,.18) !important; box-shadow:0 8px 18px rgba(0,0,0,.18) !important; }
        .h-dock-btn:active { transform:scale(.93) !important; }
        .h-dock-btn.active,.h-dock-btn.scope-link,.h-dock-btn.scope-global,.h-dock-btn.is-frozen {
            background:rgba(56,189,248,.08) !important; color:#7dd3fc !important; border-color:rgba(56,189,248,.27) !important;
            box-shadow:0 0 15px rgba(56,189,248,.07) !important;
        }
        .h-dock-btn.scope-link { color:#6ee7b7 !important; border-color:rgba(110,231,183,.24) !important; background:rgba(110,231,183,.055) !important; }
        .h-dock-btn.scope-global,.h-dock-btn.is-frozen { color:#c4b5fd !important; border-color:rgba(167,139,250,.24) !important; background:rgba(167,139,250,.055) !important; }
        .h-dock-btn span { color:inherit !important; opacity:.82 !important; font-size:6.5px !important; letter-spacing:.8px !important; }
        .h-dock-menu { gap:4px !important; }

        /* --- Cards, rows, selectors, cookie workspace --- */
        .list-item,.hx-card,.hx-cookie-row { background:rgba(255,255,255,.025) !important; border:1px solid rgba(148,163,184,.09) !important; border-radius:10px !important; box-shadow:none !important; }
        .list-item:hover,.hx-cookie-row:hover { background:rgba(125,211,252,.035) !important; border-color:rgba(125,211,252,.16) !important; transform:none !important; }
        .h-custom-options { background:rgba(7,12,22,.96) !important; border-color:rgba(148,163,184,.15) !important; box-shadow:0 18px 40px rgba(0,0,0,.36) !important; }
        .h-custom-opt:hover,.h-custom-opt.is-selected { background:rgba(56,189,248,.07) !important; color:#7dd3fc !important; }
        .h-tag-badge-box { background:rgba(255,255,255,.025) !important; border-color:rgba(148,163,184,.10) !important; }
        .h-tag-badge-text { color:#7dd3fc !important; }

        /* --- Stepper / transient controls --- */
        .h-stepper-pill { padding:5px !important; border-radius:12px !important; gap:4px !important; }
        .h-drag-dots { color:#526176 !important; }
        .h-prompt { border-radius:14px !important; }
        .h-url-box { background:rgba(0,0,0,.20) !important; border-color:rgba(148,163,184,.10) !important; }

        /* --- Motion: restrained, not flashy --- */
        @keyframes hxPanelIn { from{opacity:0;transform:translateY(6px) scale(.992)} to{opacity:1;transform:none} }
        @keyframes hxGlow { 0%,100%{box-shadow:0 0 0 rgba(56,189,248,0)} 50%{box-shadow:0 0 20px rgba(56,189,248,.10)} }
        #hider-panel.is-visible { animation:hxPanelIn .22s cubic-bezier(.2,.75,.2,1) both; }
        .h-dock-main.expanded { animation:hxGlow 2.8s ease-in-out infinite; }
        @media (prefers-reduced-motion:reduce) { *,*::before,*::after { animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; scroll-behavior:auto !important; } }
        @media (max-width:600px) {
            #hider-panel { width:min(94vw,480px)!important; max-height:90vh!important; border-radius:16px!important; }
            .panel-sidebar { flex-basis:94px!important; }
            .panel-content { padding:9px!important; }
            .h-dock { right:7px !important; }
        }
        /* ==================== PRO UI 15.4 — SIGNAL / TOGGLE LAYER ==================== */
        /* Clearer ON states + futuristic tactile checks. No feature logic changes. */
        .h-dock-btn {
            color:#c5d1df !important;
            background:rgba(255,255,255,.045) !important;
            border-color:rgba(180,205,225,.15) !important;
            text-shadow:0 1px 8px rgba(0,0,0,.35) !important;
        }
        .h-dock-btn:hover { color:#f4fbff !important; background:rgba(125,211,252,.10) !important; border-color:rgba(125,211,252,.30) !important; }
        .h-dock-btn.active,
        .h-dock-btn.scope-link,
        .h-dock-btn.scope-global,
        .h-dock-btn.is-frozen {
            color:#ecfbff !important;
            background:linear-gradient(145deg,rgba(56,189,248,.22),rgba(56,189,248,.075)) !important;
            border-color:rgba(125,211,252,.48) !important;
            box-shadow:0 0 0 1px rgba(125,211,252,.07) inset,0 0 18px rgba(56,189,248,.18),0 8px 22px rgba(0,0,0,.18) !important;
        }
        .h-dock-btn.scope-link { color:#effff9 !important; background:linear-gradient(145deg,rgba(52,211,153,.20),rgba(52,211,153,.065)) !important; border-color:rgba(110,231,183,.44) !important; box-shadow:0 0 0 1px rgba(110,231,183,.06) inset,0 0 18px rgba(52,211,153,.15),0 8px 22px rgba(0,0,0,.18) !important; }
        .h-dock-btn.scope-global,.h-dock-btn.is-frozen { color:#f5f0ff !important; background:linear-gradient(145deg,rgba(167,139,250,.20),rgba(167,139,250,.065)) !important; border-color:rgba(196,181,253,.44) !important; box-shadow:0 0 0 1px rgba(196,181,253,.06) inset,0 0 18px rgba(167,139,250,.15),0 8px 22px rgba(0,0,0,.18) !important; }
        .h-dock-btn.active::after,
        .h-dock-btn.scope-link::after,
        .h-dock-btn.scope-global::after,
        .h-dock-btn.is-frozen::after {
            content:""; position:absolute; width:4px; height:4px; border-radius:50%; right:5px; top:5px;
            background:#a5f3fc; box-shadow:0 0 8px #67e8f9; pointer-events:none;
        }
        .h-dock-btn.scope-link::after { background:#86efac; box-shadow:0 0 8px #4ade80; }
        .h-dock-btn.scope-global::after,.h-dock-btn.is-frozen::after { background:#ddd6fe; box-shadow:0 0 8px #a78bfa; }

        /* Command menu toggle cards */
        .hx-toggle-row {
            position:relative !important;
            min-height:36px !important;
            padding:7px 9px 7px 8px !important;
            margin:0 !important;
            gap:9px !important;
            border:1px solid rgba(148,163,184,.09) !important;
            border-radius:11px !important;
            background:linear-gradient(135deg,rgba(255,255,255,.035),rgba(255,255,255,.014)) !important;
            transition:background .18s ease,border-color .18s ease,box-shadow .18s ease,transform .15s ease !important;
        }
        .hx-toggle-row:hover { background:rgba(125,211,252,.045) !important; border-color:rgba(125,211,252,.17) !important; transform:translateX(1px) !important; }
        .hx-toggle-row:has(.hx-check:checked) {
            background:linear-gradient(100deg,rgba(56,189,248,.095),rgba(56,189,248,.025)) !important;
            border-color:rgba(56,189,248,.24) !important;
            box-shadow:0 0 0 1px rgba(56,189,248,.025) inset,0 7px 20px rgba(0,0,0,.12) !important;
            color:#e8f8ff !important;
        }
        .hx-toggle-child { margin-left:5px !important; border-left:1px solid rgba(56,189,248,.16) !important; }
        .hx-check {
            appearance:none !important; -webkit-appearance:none !important;
            position:relative !important; flex:0 0 31px !important; width:31px !important; height:18px !important;
            margin:0 !important; border-radius:999px !important; cursor:pointer !important;
            background:rgba(71,85,105,.46) !important; border:1px solid rgba(148,163,184,.23) !important;
            box-shadow:inset 0 2px 4px rgba(0,0,0,.24),0 1px 0 rgba(255,255,255,.035) !important;
            transition:background .18s ease,border-color .18s ease,box-shadow .18s ease !important;
        }
        .hx-check::after {
            content:"" !important; position:absolute !important; top:3px !important; left:3px !important;
            width:10px !important; height:10px !important; border-radius:50% !important;
            background:#aab8c8 !important; box-shadow:0 1px 4px rgba(0,0,0,.35) !important;
            transition:transform .20s cubic-bezier(.16,1,.3,1),background .18s ease,box-shadow .18s ease !important;
        }
        .hx-check:checked {
            background:linear-gradient(90deg,#0284c7,#38bdf8) !important;
            border-color:rgba(125,211,252,.66) !important;
            box-shadow:0 0 14px rgba(56,189,248,.22),inset 0 1px 1px rgba(255,255,255,.22) !important;
        }
        .hx-check:checked::after {
            transform:translateX(13px) !important; background:#f5fdff !important;
            box-shadow:0 0 9px rgba(224,242,254,.9),0 1px 4px rgba(0,0,0,.25) !important;
        }
        #chk-auto-time-skipper:checked,#chk-auto-close-modals:checked,#chk-auto-close-logins:checked {
            background:linear-gradient(90deg,#b45309,#fbbf24) !important; border-color:rgba(251,191,36,.62) !important; box-shadow:0 0 14px rgba(251,191,36,.20),inset 0 1px 1px rgba(255,255,255,.20) !important;
        }
        .hx-toggle-row:has(#chk-auto-time-skipper:checked),.hx-toggle-row:has(#chk-auto-close-modals:checked),.hx-toggle-row:has(#chk-auto-close-logins:checked) { background:linear-gradient(100deg,rgba(245,158,11,.085),rgba(245,158,11,.018)) !important; border-color:rgba(251,191,36,.20) !important; }
        .hx-toggle-row:focus-within { border-color:rgba(125,211,252,.28) !important; box-shadow:0 0 0 3px rgba(56,189,248,.045) !important; }

        /* Make section labels feel like compact instrument readouts. */
        .panel-section-label { display:block !important; font-size:9px !important; font-weight:800 !important; text-transform:uppercase !important; letter-spacing:0.6px !important; color:#94a3b8 !important; margin:8px 0 2px !important; }
        #tab-tools .panel-section-label { color:#718096 !important; letter-spacing:1.1px !important; }
        #tab-tools select { min-height:29px !important; border-radius:9px !important; }
        #dock-buttons-list { padding:4px !important; border:1px solid rgba(148,163,184,.07) !important; border-radius:11px !important; background:rgba(0,0,0,.12) !important; }
        #dock-buttons-list label { min-height:30px !important; border-radius:8px !important; padding:5px 7px !important; background:rgba(255,255,255,.025) !important; border:1px solid rgba(148,163,184,.07) !important; }
        #dock-buttons-list button:hover { transform:translateY(-1px) !important; }
        #dock-buttons-list button:active { transform:translateY(1px) scale(.985) !important; }
        #cookie-new-editor[hidden] { display:none !important; }
        #cookie-new-editor:not([hidden]) { animation:hxPanelIn .2s cubic-bezier(.2,.75,.2,1) both !important; }
        @media (max-width:600px) { .hx-toggle-row { min-height:38px !important; padding:8px !important; } .hx-check { flex-basis:33px !important; width:33px !important; } }

        /* ===== 17.7 ABOUT DASHBOARD ===== */
        .hx-about2{display:flex!important;flex-direction:column!important;gap:10px!important;color:#dbe7f3!important;font-size:9px!important;min-width:0!important}
        .hx-about2-hero{display:grid!important;grid-template-columns:72px minmax(0,1fr)!important;gap:12px!important;align-items:center!important;padding:12px!important;border:1px solid rgba(125,211,252,.15)!important;border-radius:17px!important;background:radial-gradient(circle at 12% 8%,rgba(56,189,248,.13),transparent 30%),radial-gradient(circle at 90% 92%,rgba(167,139,250,.10),transparent 28%),linear-gradient(145deg,rgba(255,255,255,.04),rgba(255,255,255,.012))!important;box-shadow:0 18px 42px rgba(0,0,0,.20),inset 0 1px 0 rgba(255,255,255,.05)!important}
        .hx-about2-icon{width:72px!important;height:72px!important;display:grid!important;place-items:center!important;filter:drop-shadow(0 10px 22px rgba(56,189,248,.15))!important}.hx-about2-icon svg{width:100%!important;height:100%!important;display:block!important}
        .hx-about2-kicker{font-size:7px!important;font-weight:950!important;letter-spacing:1.5px!important;color:#7dd3fc!important}.hx-about2-title{font-size:17px!important;font-weight:950!important;letter-spacing:-.4px!important;color:#f8fafc!important;margin-top:2px!important}.hx-about2-title span{color:#fbbf24!important}.hx-about2-desc{max-width:560px!important;color:#718096!important;font-size:9px!important;line-height:1.5!important;margin-top:6px!important}.hx-about2-meta{display:flex!important;align-items:center!important;gap:6px!important;margin-top:7px!important;color:#718096!important;font-size:8px!important}.hx-about2-live-dot{width:6px!important;height:6px!important;border-radius:50%!important;background:#4ade80!important;box-shadow:0 0 11px rgba(74,222,128,.75)!important;animation:hxLiveDotPulse 1.8s ease-in-out infinite!important}.hx-about2-live-dot.is-idle{background:#64748b!important;box-shadow:0 0 8px rgba(100,116,139,.5)!important;animation:none!important}@keyframes hxLiveDotPulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.72)}}
        .hx-about2-status,.hx-about2-section{padding:10px!important;border:1px solid rgba(148,163,184,.09)!important;border-radius:14px!important;background:linear-gradient(145deg,rgba(255,255,255,.026),rgba(255,255,255,.010))!important}.hx-about2-section-head{display:flex!important;justify-content:space-between!important;align-items:flex-start!important;gap:8px!important;margin-bottom:7px!important}.hx-about2-section-head b{display:block!important;color:#e8f1fa!important;font-size:10px!important;font-weight:950!important}.hx-about2-section-head span{display:block!important;color:#5f7085!important;font-size:7px!important;line-height:1.4!important;margin-top:2px!important}.hx-about2-state-pill{padding:4px 7px!important;border-radius:999px!important;border:1px solid rgba(125,211,252,.12)!important;background:rgba(56,189,248,.05)!important;color:#7dd3fc!important;font-size:7px!important;font-weight:900!important;white-space:nowrap!important}.hx-about2-updated{margin-top:7px!important;text-align:right!important;color:#455166!important;font-size:7px!important;font-weight:700!important;letter-spacing:.2px!important}
        .hx-about2-status-grid{display:grid!important;grid-template-columns:repeat(3,minmax(0,1fr))!important;gap:6px!important}.hx-about2-status-card{min-width:0!important;padding:8px!important;border-radius:11px!important;border:1px solid rgba(148,163,184,.07)!important;background:rgba(255,255,255,.018)!important}.hx-about2-status-top{display:flex!important;align-items:center!important;gap:6px!important}.hx-about2-status-icon{width:22px!important;height:22px!important;display:grid!important;place-items:center!important;border-radius:7px!important;background:rgba(56,189,248,.055)!important;border:1px solid rgba(56,189,248,.08)!important}.hx-about2-status-name{font-size:8px!important;font-weight:900!important;color:#dbe7f3!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.hx-about2-status-value{margin-top:5px!important;font-size:8px!important;font-weight:900!important;color:#64748b!important}.hx-about2-status-value.is-on{color:#6ee7b7!important}.hx-about2-status-value.is-off{color:#64748b!important}.hx-about2-status-value.is-mode{color:#7dd3fc!important}
        .hx-about2-cap-grid{display:grid!important;grid-template-columns:repeat(2,minmax(0,1fr))!important;gap:6px!important}.hx-about2-cap{display:flex!important;gap:8px!important;padding:8px!important;border-radius:10px!important;border:1px solid rgba(148,163,184,.07)!important;background:rgba(255,255,255,.015)!important;min-width:0!important}.hx-about2-cap i{font-style:normal!important;width:25px!important;height:25px!important;display:grid!important;place-items:center!important;border-radius:8px!important;background:rgba(255,255,255,.03)!important;flex:0 0 25px!important}.hx-about2-cap b{display:block!important;color:#dbe7f3!important;font-size:8px!important;font-weight:900!important}.hx-about2-cap span{display:block!important;color:#627286!important;font-size:7px!important;line-height:1.4!important;margin-top:2px!important}
        .hx-about2-levels{display:grid!important;grid-template-columns:repeat(4,minmax(0,1fr))!important;gap:5px!important}.hx-about2-levels>div{padding:7px!important;border-radius:9px!important;background:rgba(255,255,255,.018)!important;border:1px solid rgba(148,163,184,.07)!important}.hx-about2-levels strong{display:block!important;font-size:7px!important;letter-spacing:.8px!important;color:#7dd3fc!important}.hx-about2-levels span{display:block!important;margin-top:2px!important;color:#64748b!important;font-size:7px!important}.hx-about2-foot{display:flex!important;justify-content:center!important;align-items:center!important;gap:5px!important;flex-wrap:wrap!important;color:#506175!important;font-size:7px!important;padding:2px 6px 4px!important}
        @media(max-width:560px){.hx-about2-hero{grid-template-columns:58px minmax(0,1fr)!important;padding:10px!important;gap:9px!important}.hx-about2-icon{width:58px!important;height:58px!important}.hx-about2-title{font-size:14px!important}.hx-about2-status-grid{grid-template-columns:repeat(2,minmax(0,1fr))!important}.hx-about2-cap-grid{grid-template-columns:1fr!important}.hx-about2-levels{grid-template-columns:repeat(2,minmax(0,1fr))!important}}

        /* ===== 15.8 UNIFIED OPTION / ABOUT UI ===== */
        .hx-setting-block {
            display:flex !important; flex-direction:column !important; gap:5px !important;
            padding:8px !important; border:1px solid rgba(148,163,184,.08) !important;
            border-radius:11px !important; background:rgba(255,255,255,.018) !important;
        }
        .hx-setting-label {
            display:flex !important; align-items:center !important; justify-content:space-between !important;
            gap:8px !important; color:#cbd5e1 !important; font-size:9px !important; font-weight:800 !important;
        }
        .hx-setting-value {
            color:#7dd3fc !important; font-size:8px !important; font-weight:900 !important;
            text-transform:uppercase !important; letter-spacing:.65px !important;
        }
        .hx-setting-select { margin-top:0 !important; }
        .hx-setting-select .h-custom-trigger {
            min-height:34px !important; height:34px !important; border-radius:10px !important;
            padding:7px 10px !important; font-size:9px !important;
            background:linear-gradient(135deg,rgba(255,255,255,.045),rgba(255,255,255,.018)) !important;
        }
        .hx-setting-select .h-custom-options {
            position:absolute !important; left:0 !important; right:0 !important; top:calc(100% + 5px) !important;
            margin:0 !important; max-height:190px !important; border-radius:11px !important;
            overflow:auto !important; box-shadow:0 18px 45px rgba(0,0,0,.44),0 0 0 1px rgba(125,211,252,.05) !important;
        }
        .hx-setting-select .h-custom-opt {
            min-height:34px !important; display:flex !important; align-items:center !important;
            padding:8px 10px !important; border-bottom:1px solid rgba(255,255,255,.045) !important;
            font-size:9px !important;
        }
        .hx-setting-select .h-custom-opt:last-child { border-bottom:0 !important; }
        .hx-setting-select .h-custom-opt.is-selected { box-shadow:inset 2px 0 0 #38bdf8 !important; }
        .hx-about {
            display:flex !important; flex-direction:column !important; gap:10px !important;
            color:#cbd5e1 !important; font-size:9px !important;
        }
        .hx-about-hero {
            display:flex !important; gap:12px !important; align-items:center !important; padding:12px !important;
            border-radius:15px !important; border:1px solid rgba(125,211,252,.15) !important;
            background:
                radial-gradient(circle at 15% 15%,rgba(56,189,248,.13),transparent 32%),
                radial-gradient(circle at 90% 85%,rgba(167,139,250,.10),transparent 30%),
                linear-gradient(145deg,rgba(255,255,255,.035),rgba(255,255,255,.012)) !important;
            box-shadow:0 14px 38px rgba(0,0,0,.18),inset 0 1px 0 rgba(255,255,255,.04) !important;
        }
        .hx-about-icon {
            position:relative !important; width:58px !important; height:58px !important; flex:0 0 58px !important;
            border-radius:16px !important; overflow:hidden !important;
            background:radial-gradient(circle at 35% 30%,rgba(125,211,252,.25),transparent 38%),linear-gradient(145deg,#0c1728,#101b31) !important;
            border:1px solid rgba(125,211,252,.22) !important; box-shadow:0 0 28px rgba(56,189,248,.12) !important;
        }
        .hx-about-orbit { position:absolute; inset:10px; border:1px dashed rgba(125,211,252,.38); border-radius:50%; }
        .hx-about-eye {
            position:absolute; left:13px; right:13px; top:21px; height:17px; border:3px solid #7dd3fc;
            border-radius:50% 50% 50% 50% / 62% 62% 38% 38%; transform:rotate(-8deg);
            box-shadow:0 0 12px rgba(56,189,248,.32);
        }
        .hx-about-eye::after { content:""; position:absolute; width:7px; height:7px; left:50%; top:50%; transform:translate(-50%,-50%); border-radius:50%; background:#e0f2fe; box-shadow:0 0 8px rgba(125,211,252,.7); }
        .hx-about-slash { position:absolute; width:58px; height:4px; left:1px; top:27px; transform:rotate(-43deg); background:#f8fafc; box-shadow:0 0 12px rgba(125,211,252,.35); border-radius:999px; }
        .hx-about-kicker { color:#7dd3fc !important; font-size:7px !important; font-weight:900 !important; letter-spacing:1.35px !important; }
        .hx-about-title { color:#f8fafc !important; font-size:16px !important; font-weight:950 !important; margin-top:2px !important; letter-spacing:-.25px !important; }
        .hx-about-summary { color:#7b8ba1 !important; font-size:9px !important; line-height:1.5 !important; margin-top:7px !important; }
        .hx-about-grid { display:grid !important; grid-template-columns:repeat(2,minmax(0,1fr)) !important; gap:7px !important; }
        .hx-info-card {
            display:flex !important; gap:8px !important; align-items:flex-start !important; min-width:0 !important;
            padding:9px !important; border:1px solid rgba(148,163,184,.08) !important; border-radius:11px !important;
            background:linear-gradient(145deg,rgba(255,255,255,.03),rgba(255,255,255,.012)) !important;
        }
        .hx-info-icon {
            width:27px !important; height:27px !important; flex:0 0 27px !important; display:grid !important; place-items:center !important;
            border-radius:8px !important; background:rgba(125,211,252,.06) !important; border:1px solid rgba(125,211,252,.10) !important;
        }
        .hx-info-card b { display:block !important; color:#e2e8f0 !important; font-size:9px !important; }
        .hx-info-card span { display:block !important; color:#64748b !important; margin-top:2px !important; line-height:1.4 !important; }
        .hx-about-section { padding:9px !important; border:1px solid rgba(148,163,184,.08) !important; border-radius:11px !important; background:rgba(255,255,255,.016) !important; }
        .hx-about-section-title { color:#94a3b8 !important; text-transform:uppercase !important; letter-spacing:1px !important; font-size:8px !important; font-weight:900 !important; margin-bottom:6px !important; }
        .hx-level-grid { display:grid !important; grid-template-columns:repeat(4,minmax(0,1fr)) !important; gap:5px !important; }
        .hx-level-grid > div { min-width:0 !important; padding:7px !important; border-radius:9px !important; background:rgba(255,255,255,.022) !important; border:1px solid rgba(148,163,184,.07) !important; }
        .hx-level-grid b { display:block !important; color:#7dd3fc !important; font-size:7px !important; letter-spacing:.7px !important; }
        .hx-level-grid span { display:block !important; color:#64748b !important; font-size:7px !important; line-height:1.35 !important; margin-top:2px !important; }
        .hx-chip-row { display:flex !important; flex-wrap:wrap !important; gap:5px !important; }
        .hx-about-note { display:grid !important; grid-template-columns:auto 1fr !important; gap:5px 8px !important; padding:9px !important; border-left:2px solid rgba(56,189,248,.24) !important; border-radius:8px !important; background:linear-gradient(90deg,rgba(56,189,248,.04),transparent) !important; color:#64748b !important; }
        .hx-about-note b { color:#94a3b8 !important; font-size:8px !important; }
        .hx-about-footer { text-align:center !important; color:#4f6075 !important; font-size:8px !important; padding:2px 8px 4px !important; }
        @media (max-width:560px) {
            .hx-about-grid { grid-template-columns:1fr !important; }
            .hx-level-grid { grid-template-columns:repeat(2,minmax(0,1fr)) !important; }
            .hx-about-hero { align-items:flex-start !important; }
            .hx-about-title { font-size:14px !important; }
        }

        `;
        const container = doc.createElement('div');
        container.innerHTML = `
        <div class="h-glass h-dock is-collapsed manual-hidden" id="hider-main-dock">
            <button class="h-dock-btn h-dock-main" id="btn-toggle-dock" title="Toggle Control Dock">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="100%" height="100%" style="display:block;">
                    <defs>
                        <radialGradient id="bgGradient" cx="50%" cy="50%" r="50%">
                            <stop offset="0%" stop-color="#1e293b" />
                            <stop offset="60%" stop-color="#0d121e" />
                            <stop offset="100%" stop-color="#050816" />
                        </radialGradient>
                        <linearGradient id="neonCyan" x1="0%" y1="0%" x2="100%" y2="100%">
                            <stop offset="0%" stop-color="#7dd3fc" />
                            <stop offset="50%" stop-color="#38bdf8" />
                            <stop offset="100%" stop-color="#0284c7" />
                        </linearGradient>
                        <linearGradient id="proGradient" x1="0%" y1="0%" x2="100%" y2="100%">
                            <stop offset="0%" stop-color="#fbbf24" />
                            <stop offset="100%" stop-color="#f59e0b" />
                        </linearGradient>
                        <linearGradient id="glassBorder" x1="0%" y1="0%" x2="100%" y2="100%">
                            <stop offset="0%" stop-color="#38bdf8" stop-opacity="0.9"/>
                            <stop offset="50%" stop-color="#1e293b" stop-opacity="0.3"/>
                            <stop offset="100%" stop-color="#38bdf8" stop-opacity="0.7"/>
                        </linearGradient>
                        <filter id="neonGlow" x="-20%" y="-20%" width="140%" height="140%">
                            <feGaussianBlur stdDeviation="8" result="blur" />
                            <feMerge>
                                <feMergeNode in="blur" />
                                <feMergeNode in="SourceGraphic" />
                            </feMerge>
                        </filter>
                        <filter id="proGlow" x="-20%" y="-20%" width="140%" height="140%">
                            <feGaussianBlur stdDeviation="4" result="blur" />
                            <feMerge>
                                <feMergeNode in="blur" />
                                <feMergeNode in="SourceGraphic" />
                            </feMerge>
                        </filter>
                    </defs>
                    <circle cx="256" cy="256" r="230" fill="url(#bgGradient)" stroke="url(#glassBorder)" stroke-width="6" filter="url(#neonGlow)"/>
                    <g stroke="#38bdf8" stroke-opacity="0.12" stroke-width="2">
                        <line x1="126" y1="180" x2="386" y2="180"/>
                        <line x1="126" y1="256" x2="386" y2="256"/>
                        <line x1="126" y1="332" x2="386" y2="332"/>
                        <line x1="180" y1="126" x2="180" y2="386"/>
                        <line x1="256" y1="126" x2="256" y2="386"/>
                        <line x1="332" y1="126" x2="332" y2="386"/>
                    </g>
                    <circle cx="256" cy="256" r="145" fill="none" stroke="#38bdf8" stroke-width="2.5" stroke-dasharray="8 8" opacity="0.45" />
                    <g filter="url(#neonGlow)">
                        <path d="M 136 256 C 180 176, 332 176, 376 256 C 332 336, 180 336, 136 256 Z"
                              fill="none" stroke="url(#neonCyan)" stroke-width="12" stroke-linejoin="round" stroke-linecap="round"/>
                        <circle cx="256" cy="256" r="46" fill="#0d121e" stroke="url(#neonCyan)" stroke-width="8"/>
                        <circle cx="256" cy="256" r="18" fill="#e0f2fe"/>
                        <line x1="150" y1="362" x2="362" y2="150" stroke="#f8fafc" stroke-width="12" stroke-linecap="round"/>
                        <line x1="150" y1="362" x2="362" y2="150" stroke="#38bdf8" stroke-width="6" stroke-linecap="round"/>
                    </g>
                    <g stroke="#e0f2fe" stroke-width="2.5" opacity="0.8">
                        <path d="M 360 130 L 360 154 M 348 142 L 372 142 M 351 133 L 369 151 M 351 151 L 369 133" />
                    </g>
                    <g transform="translate(85, 335)" filter="url(#proGlow)">
                        <rect x="0" y="0" width="112" height="50" rx="14" fill="#0d121e" stroke="url(#proGradient)" stroke-width="3.5"/>
                        <text x="56" y="34" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="25" fill="url(#proGradient)" text-anchor="middle" letter-spacing="3.5">PRO</text>
                    </g>
                </svg>
            </button>
            <div class="h-dock-menu" id="hider-dock-menu">
                <button class="h-dock-btn" id="btn-select" title="Target Element to Hide">🎯<span>Hide</span></button>
                <button class="h-dock-btn" id="btn-edit" title="Target Element to Edit">✏️<span>Edit</span></button>
                <button class="h-dock-btn" id="btn-scope" title="Toggle Scope (Site/Link/Global)">🌐<span>SITE</span></button>
                <button class="h-dock-btn" id="btn-reveal-quick" title="Reveal hidden/blurred elements">👁️<span>Reveal</span></button>
                <button class="h-dock-btn" id="btn-links" title="Extract all links from the page">🔗<span>Links</span></button>
                <button class="h-dock-btn" id="btn-skip-30" title="Skip 30 seconds forward">⏩<span>+30s</span></button>
                <button class="h-dock-btn ${isFrozen?'is-frozen':''}" id="btn-freeze" title="Toggle Navigation Freeze">❄️<span>Freeze</span></button>
                <button class="h-dock-btn" id="btn-manage" title="Open Control Panel">⚙️<span>Control</span></button>
            </div>
        </div>

        <div id="hider-panel" class="h-glass">
            <div class="panel-header">
                <div class="panel-brand">
                    <div class="panel-brand-mark hx-brand-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="100%" height="100%">
  <defs>
    <radialGradient id="aboutBgGradient" cx="50%" cy="50%" r="50%"><stop offset="0%" stop-color="#1e293b"/><stop offset="60%" stop-color="#0d121e"/><stop offset="100%" stop-color="#050816"/></radialGradient>
    <linearGradient id="aboutNeonCyan" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#7dd3fc"/><stop offset="50%" stop-color="#38bdf8"/><stop offset="100%" stop-color="#0284c7"/></linearGradient>
    <linearGradient id="aboutProGradient" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#fbbf24"/><stop offset="100%" stop-color="#f59e0b"/></linearGradient>
    <linearGradient id="aboutGlassBorder" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#38bdf8" stop-opacity="0.9"/><stop offset="50%" stop-color="#1e293b" stop-opacity="0.3"/><stop offset="100%" stop-color="#38bdf8" stop-opacity="0.7"/></linearGradient>
    <filter id="aboutNeonGlow" x="-20%" y="-20%" width="140%" height="140%"><feGaussianBlur stdDeviation="8" result="blur"/><feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
    <filter id="aboutProGlow" x="-20%" y="-20%" width="140%" height="140%"><feGaussianBlur stdDeviation="4" result="blur"/><feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
  </defs>
  <circle cx="256" cy="256" r="230" fill="url(#aboutBgGradient)" stroke="url(#aboutGlassBorder)" stroke-width="6" filter="url(#aboutNeonGlow)"/>
  <g stroke="#38bdf8" stroke-opacity="0.12" stroke-width="2"><line x1="126" y1="180" x2="386" y2="180"/><line x1="126" y1="256" x2="386" y2="256"/><line x1="126" y1="332" x2="386" y2="332"/><line x1="180" y1="126" x2="180" y2="386"/><line x1="256" y1="126" x2="256" y2="386"/><line x1="332" y1="126" x2="332" y2="386"/></g>
  <circle cx="256" cy="256" r="145" fill="none" stroke="#38bdf8" stroke-width="2.5" stroke-dasharray="8 8" opacity="0.45"/>
  <g filter="url(#aboutNeonGlow)">
    <path d="M 136 256 C 180 176, 332 176, 376 256 C 332 336, 180 336, 136 256 Z" fill="none" stroke="url(#aboutNeonCyan)" stroke-width="12" stroke-linejoin="round" stroke-linecap="round"/>
    <circle cx="256" cy="256" r="46" fill="#0d121e" stroke="url(#aboutNeonCyan)" stroke-width="8"/><circle cx="256" cy="256" r="18" fill="#e0f2fe"/>
    <line x1="150" y1="362" x2="362" y2="150" stroke="#f8fafc" stroke-width="12" stroke-linecap="round"/><line x1="150" y1="362" x2="362" y2="150" stroke="#38bdf8" stroke-width="6" stroke-linecap="round"/>
  </g>
  <g stroke="#e0f2fe" stroke-width="2.5" opacity="0.8"><path d="M 360 130 L 360 154 M 348 142 L 372 142 M 351 133 L 369 151 M 351 151 L 369 133"/></g>
  <g transform="translate(85, 335)" filter="url(#aboutProGlow)"><rect x="0" y="0" width="112" height="50" rx="14" fill="#0d121e" stroke="url(#aboutProGradient)" stroke-width="3.5"/><text x="56" y="34" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="25" fill="url(#aboutProGradient)" text-anchor="middle" letter-spacing="3.5">PRO</text></g>
</svg></div>
                    <div class="panel-brand-copy">
                        <div class="panel-brand-title">Hide Web Elements <span style="color:#fbbf24;">PRO</span><span class="panel-status">ONLINE</span></div>
                        <div class="panel-brand-sub">Web control command center</div>
                    </div>
                </div>
                <button class="close-btn" id="close-p" title="Close control center">✕</button>
            </div>
            <div class="panel-body">
                <div class="panel-sidebar" id="panel-sidebar"></div>
                <div class="panel-content" id="panel-content"></div>
            </div>
        </div>`;


        // ===================== 15.4 FUTURE GLASS SYSTEM =====================
        // Visual-only layer. Existing IDs, event handlers and feature logic remain unchanged.
        style.textContent += `
        :host { color-scheme: dark !important; }
        *, *::before, *::after { -webkit-tap-highlight-color: transparent !important; }

        .h-glass {
            background:
                radial-gradient(circle at 0% 0%, rgba(56,189,248,.12), transparent 32%),
                radial-gradient(circle at 100% 100%, rgba(139,92,246,.11), transparent 34%),
                linear-gradient(145deg, rgba(5,10,20,.96), rgba(11,19,35,.92) 52%, rgba(5,8,18,.97)) !important;
            border: 1px solid rgba(125,211,252,.19) !important;
            box-shadow: 0 28px 80px rgba(0,0,0,.55), 0 0 45px rgba(56,189,248,.055), inset 0 1px 0 rgba(255,255,255,.045) !important;
            isolation: isolate !important;
        }
        .h-glass::before {
            content:"" !important; position:absolute !important; inset:0 !important; pointer-events:none !important; border-radius:inherit !important;
            background:linear-gradient(120deg,rgba(255,255,255,.065),transparent 16%,transparent 75%,rgba(56,189,248,.025)) !important;
            mix-blend-mode:screen !important; opacity:.8 !important;
        }

        /* COMMAND CENTER */
        #hider-panel {
            width:min(680px,95vw) !important;
            max-height:min(820px,91vh) !important;
            border-radius:24px !important;
            transform-origin: top right !important;
            transition:opacity .22s ease, transform .36s cubic-bezier(.16,1,.3,1), filter .22s ease !important;
            overflow:hidden !important;
        }
        #hider-panel.is-visible { animation:hiderCommandIn .38s cubic-bezier(.16,1,.3,1) both !important; }
        @keyframes hiderCommandIn {
            from { opacity:0; transform:translate3d(0,-12px,0) scale(.965); filter:blur(7px); }
            to { opacity:1; transform:translate3d(0,0,0) scale(1); filter:blur(0); }
        }
        #hider-panel::after {
            content:""; position:absolute; top:0; left:-20%; width:40%; height:1px; pointer-events:none; z-index:20;
            background:linear-gradient(90deg,transparent,#38bdf8,#c4b5fd,transparent); box-shadow:0 0 18px rgba(56,189,248,.65);
            animation:hiderSweep 5.8s ease-in-out infinite;
        }
        @keyframes hiderSweep { 0%,70%{transform:translateX(-30%);opacity:0} 76%{opacity:1} 95%,100%{transform:translateX(360%);opacity:0} }

        .panel-header {
            min-height:70px !important; padding:11px 13px !important; position:relative !important; overflow:hidden !important;
            background:
                radial-gradient(circle at 16% 50%,rgba(56,189,248,.14),transparent 22%),
                radial-gradient(circle at 82% 0%,rgba(167,139,250,.09),transparent 28%),
                linear-gradient(90deg,rgba(56,189,248,.06),rgba(255,255,255,.02) 48%,rgba(139,92,246,.06)) !important;
            border-bottom:1px solid rgba(125,211,252,.10) !important;
        }
        .panel-header::before {
            content:""; position:absolute; right:-40px; top:-55px; width:150px; height:150px; border-radius:50%; pointer-events:none;
            background:radial-gradient(circle,rgba(56,189,248,.16),transparent 68%); filter:blur(2px);
        }
        .panel-header::after {
            content:""; position:absolute; left:14px; right:14px; bottom:0; height:1px; pointer-events:none;
            background:linear-gradient(90deg,rgba(56,189,248,.72),rgba(167,139,250,.42),transparent 75%); opacity:.7;
        }
        .panel-brand { display:flex !important; align-items:center !important; gap:10px !important; min-width:0 !important; position:relative !important; z-index:2 !important; }
        .panel-brand-mark {
            width:36px !important; height:36px !important; flex:0 0 36px !important; display:grid !important; place-items:center !important; border-radius:12px !important;
            background:radial-gradient(circle at 30% 22%,rgba(125,211,252,.30),transparent 38%),linear-gradient(145deg,#0ea5e9,#2563eb 55%,#7c3aed) !important;
            border:1px solid rgba(125,211,252,.32) !important; box-shadow:0 0 24px rgba(14,165,233,.25),inset 0 1px 0 rgba(255,255,255,.22) !important;
            animation:hiderBrandGlow 4s ease-in-out infinite !important;
        }
        @keyframes hiderBrandGlow { 0%,100%{box-shadow:0 0 20px rgba(14,165,233,.20),inset 0 1px 0 rgba(255,255,255,.18)} 50%{box-shadow:0 0 34px rgba(56,189,248,.34),inset 0 1px 0 rgba(255,255,255,.25)} }
        .panel-brand-copy { min-width:0 !important; }
        .panel-brand-title { font-size:14px !important; font-weight:950 !important; letter-spacing:.1px !important; }
        .panel-brand-sub { margin-top:3px !important; font-size:8px !important; letter-spacing:1.05px !important; text-transform:uppercase !important; font-weight:850 !important; color:#7dd3fc !important; }
        .panel-status {
            display:inline-flex !important; align-items:center !important; gap:5px !important; margin-left:7px !important; padding:3px 7px !important; border-radius:999px !important;
            font-size:7px !important; letter-spacing:.75px !important; text-transform:uppercase !important; font-weight:900 !important;
            color:#86efac !important; background:rgba(34,197,94,.07) !important; border:1px solid rgba(134,239,172,.15) !important; vertical-align:middle !important;
        }
        .panel-status::before { content:""; width:5px; height:5px; border-radius:50%; background:#4ade80; box-shadow:0 0 10px #4ade80; animation:hiderLivePulse 1.7s ease-in-out infinite; }
        @keyframes hiderLivePulse { 0%,100%{opacity:.5;transform:scale(.9)} 50%{opacity:1;transform:scale(1.12)} }
        .panel-header .close-btn {
            position:relative !important; z-index:3 !important; width:30px !important; height:30px !important; padding:0 !important; border-radius:10px !important;
            background:rgba(255,255,255,.035) !important; border:1px solid rgba(255,255,255,.09) !important; color:#94a3b8 !important;
            transition:transform .22s cubic-bezier(.16,1,.3,1), background .18s ease, border-color .18s ease, color .18s ease !important;
        }
        .panel-header .close-btn:hover { transform:rotate(90deg) scale(1.08) !important; background:rgba(244,63,94,.12) !important; border-color:rgba(244,63,94,.28) !important; color:#fda4af !important; }

        /* TAB RAIL */
        .panel-sidebar {
            flex:0 0 138px !important; padding:11px 8px !important; gap:5px !important;
            background:linear-gradient(180deg,rgba(2,6,23,.80),rgba(15,23,42,.46)) !important;
            border-right:1px solid rgba(125,211,252,.085) !important;
        }
        .panel-sidebar .tab-btn {
            position:relative !important; margin:0 !important; padding:10px 10px 10px 14px !important; border-radius:12px !important;
            color:#718096 !important; font-size:9px !important; font-weight:850 !important; letter-spacing:.15px !important;
            transition:transform .22s cubic-bezier(.16,1,.3,1), background .22s ease, color .22s ease, box-shadow .22s ease !important;
        }
        .panel-sidebar .tab-btn::before { content:""; position:absolute; left:4px; top:50%; width:3px; height:0; transform:translateY(-50%); border-radius:999px; background:#38bdf8; box-shadow:0 0 14px rgba(56,189,248,.9); transition:height .22s ease !important; }
        .panel-sidebar .tab-btn:hover { transform:translateX(3px) !important; background:rgba(255,255,255,.045) !important; color:#e2e8f0 !important; }
        .panel-sidebar .tab-btn.active {
            transform:translateX(4px) !important; color:#e0f2fe !important;
            background:linear-gradient(100deg,rgba(56,189,248,.13),rgba(56,189,248,.035)) !important;
            border:1px solid rgba(56,189,248,.09) !important; box-shadow:inset 0 0 0 1px rgba(255,255,255,.015),0 9px 24px rgba(0,0,0,.16) !important;
        }
        .panel-sidebar .tab-btn.active::before { height:24px !important; }
        .panel-content { padding:12px 14px 16px !important; gap:10px !important; scrollbar-gutter:stable !important; }
        .panel-content .tab-content.active { animation:hiderTabRise .30s cubic-bezier(.16,1,.3,1) both !important; }
        @keyframes hiderTabRise { from{opacity:0;transform:translateY(7px)} to{opacity:1;transform:translateY(0)} }

        /* CARDS / CONTROLS */
        .hider-btn-small, .h-btn-icon, .h-btn-pill, .h-dock-btn, .h-custom-trigger { transition:transform .16s ease, box-shadow .18s ease, filter .18s ease, border-color .18s ease, background .18s ease !important; }
        .hider-btn-small:hover, .h-btn-icon:hover, .h-btn-pill:hover { transform:translateY(-1px) !important; filter:brightness(1.08) saturate(1.08) !important; box-shadow:0 8px 20px rgba(0,0,0,.20) !important; }
        .hider-btn-small:active, .h-btn-icon:active, .h-btn-pill:active, .h-dock-btn:active { transform:translateY(1px) scale(.965) !important; }
        .hider-btn-small { border-radius:9px !important; font-weight:850 !important; box-shadow:inset 0 1px 0 rgba(255,255,255,.12) !important; }
        input[type="text"],input[type="number"],input[type="date"],textarea,select,.h-select,.h-custom-trigger { background:rgba(2,6,23,.42) !important; border:1px solid rgba(148,163,184,.15) !important; box-shadow:inset 0 1px 0 rgba(255,255,255,.035) !important; }
        input[type="text"]:focus,input[type="number"]:focus,input[type="date"]:focus,textarea:focus,select:focus,.h-select:focus,.h-custom-trigger:focus { outline:none !important; border-color:rgba(56,189,248,.55) !important; box-shadow:0 0 0 3px rgba(56,189,248,.07),0 0 22px rgba(56,189,248,.08) !important; }

        /* FLOATING DOCK */
        .h-dock {
            padding:7px !important; gap:7px !important; border-radius:24px !important;
            background:linear-gradient(180deg,rgba(3,9,19,.80),rgba(15,23,42,.68)) !important;
            border:1px solid rgba(125,211,252,.18) !important; backdrop-filter:blur(20px) !important; -webkit-backdrop-filter:blur(20px) !important;
            box-shadow:0 22px 55px rgba(0,0,0,.48),0 0 28px rgba(56,189,248,.075),inset 0 1px 0 rgba(255,255,255,.05) !important;
            transition:transform .42s cubic-bezier(.16,1,.3,1),opacity .28s ease,box-shadow .28s ease !important;
        }
        .h-dock.expanded { box-shadow:0 26px 65px rgba(0,0,0,.54),0 0 40px rgba(56,189,248,.14),inset 0 1px 0 rgba(255,255,255,.07) !important; }
        .h-dock-main {
            width:44px !important; height:44px !important; min-width:44px !important; min-height:44px !important; border-radius:15px !important;
            background:radial-gradient(circle at 31% 24%,rgba(125,211,252,.30),transparent 36%),linear-gradient(145deg,rgba(14,165,233,.78),rgba(37,99,235,.76) 55%,rgba(124,58,237,.76)) !important;
            border:1px solid rgba(125,211,252,.34) !important; box-shadow:0 0 24px rgba(14,165,233,.20),inset 0 1px 0 rgba(255,255,255,.22) !important;
        }
        .h-dock-main:hover { transform:scale(1.07) !important; box-shadow:0 0 36px rgba(56,189,248,.32),inset 0 1px 0 rgba(255,255,255,.24) !important; }
        .h-dock-main.expanded { box-shadow:0 0 42px rgba(56,189,248,.35),0 0 76px rgba(124,58,237,.12) !important; }
        .h-dock-menu { gap:6px !important; padding-top:2px !important; transition:max-height .42s cubic-bezier(.16,1,.3,1),opacity .22s ease !important; }
        .h-dock-btn { width:39px !important; height:39px !important; min-width:39px !important; min-height:39px !important; border-radius:13px !important; background:rgba(255,255,255,.035) !important; border:1px solid rgba(255,255,255,.08) !important; box-shadow:inset 0 1px 0 rgba(255,255,255,.035) !important; }
        .h-dock-btn:hover { background:rgba(255,255,255,.085) !important; color:#fff !important; transform:translateY(-2px) scale(1.045) !important; box-shadow:0 10px 20px rgba(0,0,0,.22),0 0 16px rgba(56,189,248,.08) !important; }
        .h-dock-btn span { font-size:7px !important; letter-spacing:.6px !important; }

        /* COOKIE WORKSPACE */
        #cookie-count { display:inline-flex !important; min-width:20px !important; height:18px !important; align-items:center !important; justify-content:center !important; padding:0 6px !important; border-radius:999px !important; background:rgba(56,189,248,.10) !important; color:#7dd3fc !important; border:1px solid rgba(56,189,248,.14) !important; }
        #cookie-search { width:min(190px,46%) !important; height:30px !important; border-radius:10px !important; }
        #cookie-new-name,#cookie-new-value,#cookie-new-expiry { height:30px !important; border-radius:10px !important; }
        #cookie-list { scrollbar-width:thin !important; }
        #cookie-list > div { transition:transform .18s ease,background .18s ease,border-color .18s ease,box-shadow .18s ease !important; }
        #cookie-list > div:hover { transform:translateX(2px) !important; border-color:rgba(56,189,248,.18) !important; background:linear-gradient(90deg,rgba(56,189,248,.065),rgba(255,255,255,.03)) !important; box-shadow:0 7px 20px rgba(0,0,0,.14) !important; }

        /* RESPONSIVE / REDUCED MOTION */
        @media (max-width:560px) {
            #hider-panel { left:6px !important; right:6px !important; top:44px !important; width:auto !important; max-height:92vh !important; border-radius:21px !important; }
            .panel-sidebar { flex:0 0 100px !important; padding:9px 6px !important; }
            .panel-sidebar .tab-btn { padding:9px 7px 9px 10px !important; font-size:8px !important; }
            .panel-content { padding:10px !important; }
            .panel-header { min-height:60px !important; }
            .panel-brand-title { font-size:12px !important; }
            .panel-brand-sub { font-size:7px !important; }
            .panel-status { display:none !important; }
            .h-dock { right:5px !important; }
            .h-dock-main { width:41px !important; height:41px !important; min-width:41px !important; min-height:41px !important; }
            .h-dock-btn { width:37px !important; height:37px !important; min-width:37px !important; min-height:37px !important; }
        }
        @media (prefers-reduced-motion:reduce) {
            *,*::before,*::after { animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; }
        }
        /* ===== 16.0 EDIT MODE ===== */
        #btn-edit{order:2!important}
        #btn-scope{order:3!important}
        #btn-reveal-quick{order:4!important}
        #btn-links{order:5!important}
        #btn-skip-30{order:6!important}
        #btn-freeze{order:7!important}
        #btn-manage{order:8!important}
        #hider-edit-controls input,#hider-edit-controls textarea{font-family:Inter,ui-sans-serif,system-ui,sans-serif!important}
        /* ===== 16.8 EDITOR PANEL ===== */
        #hider-edit-controls.hider-edit-editor{
            width:100%!important; margin-top:5px!important; padding:8px!important; gap:7px!important;
            border:1px solid rgba(125,211,252,.14)!important; border-radius:13px!important;
            background:linear-gradient(145deg,rgba(56,189,248,.055),rgba(167,139,250,.035) 55%,rgba(255,255,255,.018))!important;
            box-shadow:0 12px 28px rgba(0,0,0,.18),inset 0 1px 0 rgba(255,255,255,.045)!important;
        }
        .hider-edit-editor-head{display:flex!important;flex-direction:column!important;gap:2px!important;padding:1px 2px 3px!important;}
        .hider-edit-editor-title{font-size:8px!important;font-weight:950!important;letter-spacing:1px!important;color:#dff5ff!important;text-transform:uppercase!important;}
        .hider-edit-editor-sub{font-size:7px!important;line-height:1.35!important;color:#718096!important;}
        .hider-edit-source-row{display:grid!important;grid-template-columns:1fr 1fr!important;gap:5px!important;}
        .hider-edit-source-btn,.hider-edit-main-btn,.hider-edit-mode,.hider-edit-icon-btn{
            appearance:none!important;-webkit-appearance:none!important;min-height:31px!important;border-radius:9px!important;
            border:1px solid rgba(148,163,184,.14)!important;background:rgba(255,255,255,.04)!important;color:#cbd5e1!important;
            font:800 8px/1 system-ui,sans-serif!important;cursor:pointer!important;transition:.16s ease!important;
        }
        .hider-edit-source-btn:hover,.hider-edit-main-btn:hover,.hider-edit-mode:hover,.hider-edit-icon-btn:hover{transform:translateY(-1px)!important;border-color:rgba(125,211,252,.28)!important;background:rgba(125,211,252,.08)!important;color:#effaff!important;}
        .hider-edit-main-btn{width:100%!important;border-color:rgba(56,189,248,.24)!important;background:linear-gradient(135deg,rgba(56,189,248,.12),rgba(56,189,248,.035))!important;color:#bfeeff!important;}
        .hider-edit-url{width:100%!important;height:31px!important;padding:6px 8px!important;border-radius:9px!important;background:rgba(2,6,23,.55)!important;border:1px solid rgba(148,163,184,.16)!important;color:#f8fafc!important;font:700 8px/1 system-ui,sans-serif!important;outline:none!important;}
        .hider-edit-url:focus{border-color:rgba(56,189,248,.45)!important;box-shadow:0 0 0 3px rgba(56,189,248,.06)!important;}
        .hider-edit-mode-row{display:flex!important;align-items:center!important;justify-content:space-between!important;gap:7px!important;padding-top:2px!important;}
        .hider-edit-mode-label{font-size:7px!important;font-weight:900!important;letter-spacing:.8px!important;color:#718096!important;}
        .hider-edit-mode{flex:1!important;min-height:29px!important;font-size:8px!important;letter-spacing:.2px!important;}
        .hider-edit-mode.is-permanent{border-color:rgba(56,189,248,.25)!important;color:#7dd3fc!important;background:rgba(56,189,248,.075)!important;}
        .hider-edit-mode.is-onetime{border-color:rgba(110,231,183,.25)!important;color:#6ee7b7!important;background:rgba(110,231,183,.065)!important;}
        .hider-edit-actions{display:grid!important;grid-template-columns:1fr 1fr!important;gap:6px!important;margin-top:1px!important;}
        .hider-edit-icon-btn{height:34px!important;font-size:17px!important;line-height:1!important;background:rgba(255,255,255,.035)!important;}
        .hider-edit-save{border-color:rgba(110,231,183,.20)!important;background:rgba(110,231,183,.055)!important;}
        .hider-edit-cancel{border-color:rgba(251,113,133,.20)!important;background:rgba(251,113,133,.05)!important;}
        .hider-edit-save:hover{border-color:rgba(110,231,183,.38)!important;background:rgba(110,231,183,.10)!important;}
        .hider-edit-cancel:hover{border-color:rgba(251,113,133,.38)!important;background:rgba(251,113,133,.10)!important;}
        .hider-edit-editor{gap:7px!important;padding:9px!important;border:1px solid rgba(125,211,252,.14)!important;border-radius:14px!important;background:linear-gradient(145deg,rgba(8,16,29,.92),rgba(17,25,42,.68))!important;box-shadow:0 16px 38px rgba(0,0,0,.28),inset 0 1px 0 rgba(255,255,255,.045)!important;}
        .hider-edit-editor::before{content:''!important;display:block!important;height:2px!important;border-radius:99px!important;background:linear-gradient(90deg,#38bdf8,#8b5cf6,transparent)!important;opacity:.75!important;}
        .hider-edit-source-btn{min-height:34px!important;font-weight:850!important;}
        .hider-edit-mode-row{padding:6px 8px!important;border-radius:10px!important;background:rgba(255,255,255,.025)!important;border:1px solid rgba(148,163,184,.07)!important;}
        .hider-edit-mode{min-height:31px!important;font-weight:900!important;}
        .hider-edit-actions{gap:7px!important;margin-top:2px!important;}
        .hider-edit-icon-btn{height:38px!important;border-radius:11px!important;font-size:18px!important;font-weight:950!important;}
        .hx-edit-rule-row{align-items:center!important;}
        .hx-edit-rule-value{font-size:8px!important;color:#64748b!important;margin-top:3px!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important;}
        .hx-edit-menu-editor{animation:hxPanelIn .2s cubic-bezier(.2,.75,.2,1) both!important;}
        .hx-edit-live-preview{color:#e7eef8!important;line-height:1.45!important;white-space:pre-wrap!important;}
        .hx-edit-menu-editor .hider-edit-source-btn{min-height:32px!important;}
        .hx-edit-menu-editor .hx-input{font-family:inherit!important;color:#f8fafc!important;background:rgba(2,6,23,.42)!important;border:1px solid rgba(148,163,184,.15)!important;}
        @media(max-width:560px){.hider-edit-icon-btn{height:40px!important}.hider-edit-editor-sub{font-size:6.5px!important}}

        /* ---------- Rules / Edit / Freeze redesign (v16.6) ---------- */
        .hx-menu-v2{display:flex!important;flex-direction:column!important;gap:7px!important;}
        .hx-menu-title{font-size:13px!important;font-weight:900!important;color:#f8fafc!important;}
        .hx-menu-sub{font-size:8px!important;color:#718096!important;margin-top:3px!important;line-height:1.4!important;}
        .hx-scope-legend{display:flex!important;flex-direction:column!important;gap:4px!important;padding:8px 9px!important;}
        .hx-scope-legend-row{display:flex!important;align-items:baseline!important;gap:6px!important;font-size:8px!important;color:#94a3b8!important;line-height:1.4!important;}
        .hx-scope-legend-row b{font-size:9px!important;}
        .hx-badge-dot{display:inline-block!important;width:8px!important;height:8px!important;border-radius:999px!important;flex:0 0 auto!important;box-shadow:0 0 6px currentColor!important;}
        .hx-badge-global{background:#38bdf8!important;color:#38bdf8!important;}
        .hx-badge-site{background:#34d399!important;color:#34d399!important;}
        .hx-badge-page{background:#c4b5fd!important;color:#c4b5fd!important;}
        .hx-section-head-v2{display:flex!important;align-items:center!important;justify-content:space-between!important;gap:6px!important;margin-top:5px!important;padding-top:5px!important;border-top:1px solid rgba(255,255,255,.06)!important;flex-wrap:wrap!important;}
        .hx-section-head-v2:first-of-type{border-top:none!important;margin-top:0!important;padding-top:0!important;}
        .hx-section-head-title{display:flex!important;align-items:center!important;gap:6px!important;font-size:10px!important;font-weight:800!important;color:#e2e8f0!important;text-transform:uppercase!important;letter-spacing:.4px!important;}
        .hx-count-pill{display:inline-flex!important;align-items:center!important;justify-content:center!important;min-width:16px!important;height:15px!important;padding:0 4px!important;border-radius:999px!important;background:rgba(255,255,255,.08)!important;color:#cbd5e1!important;font-size:8px!important;font-weight:900!important;}
        .hx-section-head-actions{display:flex!important;gap:4px!important;flex-wrap:wrap!important;}
        .hx-list{display:flex!important;flex-direction:column!important;gap:3px!important;}
        .hx-status-card{display:flex!important;align-items:center!important;justify-content:space-between!important;gap:8px!important;padding:10px 11px!important;border-radius:13px!important;border:1px solid rgba(148,163,184,.12)!important;background:linear-gradient(145deg,rgba(255,255,255,.05),rgba(255,255,255,.018))!important;}
        .hx-status-card-left{display:flex!important;align-items:center!important;gap:9px!important;min-width:0!important;}
        .hx-status-dot{width:11px!important;height:11px!important;border-radius:999px!important;flex:0 0 auto!important;background:#64748b!important;box-shadow:0 0 0 4px rgba(100,116,139,.15)!important;transition:background .18s ease,box-shadow .18s ease!important;}
        .hx-status-dot.is-on{background:#22d3ee!important;box-shadow:0 0 0 4px rgba(34,211,238,.2),0 0 10px rgba(34,211,238,.7)!important;animation:hxStatusPulse 2s ease-in-out infinite!important;}
        @keyframes hxStatusPulse{0%,100%{opacity:1;}50%{opacity:.55;}}
        .hx-status-card-title{font-size:12px!important;font-weight:900!important;color:#f8fafc!important;}
        .hx-status-card-sub{font-size:8px!important;color:#94a3b8!important;margin-top:2px!important;line-height:1.35!important;max-width:210px!important;}
        .hx-quick-actions{display:grid!important;grid-template-columns:1fr 1fr!important;gap:5px!important;}
        .hx-quick-actions .hider-btn-small{height:28px!important;font-size:9px!important;width:100%!important;}
        `;
        shadowRoot.innerHTML = ''; shadowRoot.appendChild(style); shadowRoot.appendChild(container);
        buildPanelTabs();
        setupShadowUIEvents();
        applyDockButtonVisibility();
        renderDockButtonOptions();

        const panel = shadowRoot.getElementById('hider-panel');
        if (panel) {
            const stopProp = (e) => e.stopPropagation();
            panel.addEventListener('wheel', stopProp, { passive: true, capture: true });
            panel.addEventListener('touchmove', stopProp, { passive: true, capture: true });
            panel.addEventListener('scroll', stopProp, { passive: true, capture: true });
            panel.addEventListener('pointerdown', stopProp, { capture: true });
            panel.addEventListener('mousedown', stopProp, { capture: true });
        }
        const linkPanel = shadowRoot.getElementById('hider-link-panel');
        if (linkPanel) {
            const stopProp = (e) => e.stopPropagation();
            linkPanel.addEventListener('wheel', stopProp, { passive: true, capture: true });
            linkPanel.addEventListener('touchmove', stopProp, { passive: true, capture: true });
            linkPanel.addEventListener('scroll', stopProp, { passive: true, capture: true });
            linkPanel.addEventListener('pointerdown', stopProp, { capture: true });
            linkPanel.addEventListener('mousedown', stopProp, { capture: true });
        }
        const stepper = shadowRoot.getElementById(STEPPER_BAR_ID);
        if (stepper) {
            const stopProp = (e) => e.stopPropagation();
            stepper.addEventListener('wheel', stopProp, { passive: true, capture: true });
            stepper.addEventListener('touchmove', stopProp, { passive: true, capture: true });
            stepper.addEventListener('pointerdown', stopProp, { capture: true });
        }
    }

    // ---------- Build Panel Tabs ----------
    function updateAboutDashboard() {
        const grid = shadowBy('about-status-grid');
        if (!grid) return;
        try {
            const siteRules = gv('hider_site_' + location.hostname, []);
            const pageRules = gv('hider_link_' + cleanUrl(), []);
            const globalRules = Array.isArray(CACHE.customRules) ? CACHE.customRules : [];
            const editCount = (typeof getAllEditRulesForCurrentPage === 'function') ? getAllEditRulesForCurrentPage().length : 0;
            // Checked locally (not the identically-named variable scoped inside
            // setupShadowUIEvents) so this keeps working no matter which tab was
            // opened first.
            const hasCookieStoreApi = typeof win.cookieStore !== 'undefined' && !!win.cookieStore;
            const mediaLabOpen = !!(linkPanelEl && linkPanelEl.classList.contains('is-visible'));
            const items = [
                ['🎯','Hide', (globalRules.length + siteRules.length + pageRules.length) + ' rules', 'muted'],
                ['✏️','Edit', editCount + ' saved', isSelecting && selectionMode==='edit' ? 'mode' : 'muted'],
                ['🚫','Paywall', PAYWALL_LEVEL_LABELS?.[CACHE.antiPaywallLevel] || CACHE.antiPaywallLevel || 'Off', CACHE.antiPaywallLevel !== 'off' ? 'mode' : 'off'],
                ['🪟','Modals', CACHE.autoCloseModals ? 'ON' : 'OFF', CACHE.autoCloseModals ? 'on' : 'off'],
                ['🛡️','Logins', CACHE.autoCloseLogins ? 'ON' : 'OFF', CACHE.autoCloseLogins ? 'on' : 'off'],
                ['🖱️','Right‑Click', CACHE.enableContextMenu ? 'ON' : 'OFF', CACHE.enableContextMenu ? 'on' : 'off'],
                ['↕️','Scroll Lock', CACHE.autoScroll ? 'ON' : 'OFF', CACHE.autoScroll ? 'on' : 'off'],
                ['👁️','Remove Blur', CACHE.autoRemoveBlur ? 'ON' : 'OFF', CACHE.autoRemoveBlur ? 'on' : 'off'],
                ['⏩','Time Skipper', CACHE.autoTimeSkipper ? 'ON' : 'OFF', CACHE.autoTimeSkipper ? 'on' : 'off'],
                ['❄️','Freeze', isFrozen ? (FREEZE_LABELS?.[CACHE.freezeMemory] || 'ON') : 'OFF', isFrozen ? 'mode' : 'off'],
                ['🍪','Cookies', hasCookieStoreApi ? 'API ready' : 'Fallback', 'mode'],
                ['🔗','Media Lab', mediaLabOpen ? 'OPEN' : 'Ready', mediaLabOpen ? 'on' : 'muted']
            ];
            grid.innerHTML='';
            const frag=doc.createDocumentFragment();
            items.forEach(([icon,name,value,state])=>{
                const card=doc.createElement('div'); card.className='hx-about2-status-card';
                const top=doc.createElement('div'); top.className='hx-about2-status-top';
                const ic=doc.createElement('div'); ic.className='hx-about2-status-icon'; ic.textContent=icon;
                const nm=doc.createElement('div'); nm.className='hx-about2-status-name'; nm.textContent=name; top.append(ic,nm);
                const val=doc.createElement('div'); val.className='hx-about2-status-value ' + (state==='on'?'is-on':state==='off'?'is-off':state==='mode'?'is-mode':''); val.textContent=value;
                card.append(top,val); frag.appendChild(card);
            });
            grid.appendChild(frag);
            const active=items.filter(x=>x[3]==='on'||x[3]==='mode').length;
            const summary=shadowBy('about-active-summary'); if(summary) summary.textContent=`${active} / ${items.length} active`;
            const runtime=shadowBy('about-runtime-status'); if(runtime) runtime.textContent=isProtected ? 'Protected page' : 'Running';
            const domain=shadowBy('about-domain-status'); if(domain) domain.textContent=location.hostname || 'Current page';
            const dot=shadowBy('about-live-dot'); if(dot) dot.classList.toggle('is-idle', active===0);
            const updatedAt=shadowBy('about-updated-at'); if(updatedAt) updatedAt.textContent='Updated ' + new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
        } catch (err) {
            try { console.debug('[Hide Web Elements Pro] About dashboard render failed', err); } catch {}
        }
    }

    // ---------- About Tab Live Refresh ----------
    // The dashboard reflects state that can change from outside the About tab
    // (dock toggles, media lab, edit mode, navigation). Rather than relying on
    // every call site to remember to refresh it, poll lightly while the tab is
    // actually visible so "Live status" is genuinely live.
    function setupAboutLiveRefresh() {
        if (timers.aboutLiveTimer) return;
        timers.aboutLiveTimer = setInterval(() => {
            if (!shadowRoot) return;
            const aboutTab = shadowBy('tab-about');
            if (aboutTab && aboutTab.classList.contains('active')) updateAboutDashboard();
        }, 1500);
    }

    function buildPanelTabs() {
        const sidebar = shadowBy('panel-sidebar');
        const content = shadowBy('panel-content');
        if (!sidebar || !content) return;

        const tabs = [
            { id: 'tab-tools', label: '◈ Command', html: `
                <div style="display:flex;flex-direction:column;gap:6px;">
                    <div style="font-size:9px;color:#94a3b8;text-transform:uppercase;letter-spacing:0.5px;font-weight:700;">Basic</div>
                    <label class="hx-toggle-row" style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;">
                        <input class="hx-check" type="checkbox" id="chk-auto-scroll" ${CACHE.autoScroll?'checked':''}> Auto Anti‑Scroll Lock
                    </label>
                    <label class="hx-toggle-row" style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;">
                        <input class="hx-check" type="checkbox" id="chk-enable-contextmenu" ${CACHE.enableContextMenu?'checked':''}> Auto Right‑Click / Long‑Press
                    </label>
                    <label class="hx-toggle-row" style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;">
                        <input class="hx-check" type="checkbox" id="chk-auto-remove-blur" ${CACHE.autoRemoveBlur?'checked':''}> Auto Remove Blur
                    </label>
                    <label class="hx-toggle-row" style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;margin-top:2px;">
                        <input class="hx-check" type="checkbox" id="chk-auto-time-skipper" ${CACHE.autoTimeSkipper?'checked':''}> Auto Time Skipper (Smart)
                    </label>
                    <div class="hx-feature-note"><b>SMART:</b> targets detected countdowns + ad skip controls without scanning the whole page every second.</div>

                    <div style="font-size:9px;color:#94a3b8;text-transform:uppercase;letter-spacing:0.5px;font-weight:700;margin-top:6px;border-top:1px solid rgba(255,255,255,0.06);padding-top:6px;">Overlays & Paywalls</div>
                    <div class="hx-setting-block">
                        <div class="hx-setting-label"><span>🚫 Anti‑Paywall / Anti‑Adblock</span><span class="hx-setting-value" id="anti-paywall-level-value"></span></div>
                        <div class="h-custom-select hx-setting-select" id="anti-paywall-level-select">
                            <button type="button" class="h-custom-trigger">
                                <span class="h-custom-value-text">Off</span><span class="h-custom-arrow">▼</span>
                            </button>
                            <div class="h-custom-options" role="listbox">
                                <div class="h-custom-opt" data-val="off">○ Off</div>
                                <div class="h-custom-opt" data-val="weak">◌ Weak</div>
                                <div class="h-custom-opt" data-val="normal">◉ Normal</div>
                                <div class="h-custom-opt" data-val="extreme">✦ Extreme</div>
                            </div>
                        </div>
                        <div class="hx-feature-note" id="anti-paywall-hint"></div>
                    </div>
                    <label class="hx-toggle-row" style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;">
                        <input class="hx-check" type="checkbox" id="chk-auto-close-modals" ${CACHE.autoCloseModals?'checked':''}> Auto‑Close Modals & Overlays
                    </label>
                    <label class="hx-toggle-row" style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;padding-left:16px;border-left:2px solid rgba(56,189,248,0.3);">
                        <input class="hx-check" type="checkbox" id="chk-auto-close-logins" ${CACHE.autoCloseLogins?'checked':''}> Auto‑Close Logins
                    </label>
                    <div class="hx-setting-block">
                        <div class="hx-setting-label"><span>🍪 Cookie Consent</span><span class="hx-setting-value" id="cookie-consent-mode-value"></span></div>
                        <div class="h-custom-select hx-setting-select" id="cookie-consent-mode-select">
                            <button type="button" class="h-custom-trigger">
                                <span class="h-custom-value-text">Ask</span><span class="h-custom-arrow">▼</span>
                            </button>
                            <div class="h-custom-options" role="listbox">
                                <div class="h-custom-opt" data-val="ask">❔ Ask</div>
                                <div class="h-custom-opt" data-val="accept">✓ Accept</div>
                                <div class="h-custom-opt" data-val="reject">✕ Reject</div>
                            </div>
                        </div>
                    </div>

                    <div style="font-size:9px;color:#94a3b8;text-transform:uppercase;letter-spacing:0.5px;font-weight:700;margin-top:6px;border-top:1px solid rgba(255,255,255,0.06);padding-top:6px;">Dock Buttons</div>
                    <div style="display:flex;align-items:center;justify-content:space-between;gap:6px;margin-bottom:1px;">
                        <span id="dock-visible-count" style="font-size:8px;color:#6ee7b7;font-weight:900;letter-spacing:.5px;">—</span>
                        <div style="display:flex;gap:4px;">
                            <button class="hider-btn-small btn-blue" id="dock-show-all" style="height:24px;padding:0 8px;">Show All</button>
                            <button class="hider-btn-small btn-gray" id="dock-hide-optional" style="height:24px;padding:0 8px;">Hide Optional</button>
                        </div>
                    </div>
                    <div style="font-size:8px;color:#64748b;margin-bottom:4px;">Tap a card to toggle whether that control stays on the floating dock. Control/Menu remains available.</div>
                    <div id="dock-buttons-list" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(145px,1fr));gap:6px;"></div>
                </div>
            ` },
            { id: 'tab-rules', label: '⌁ Rules', html: `
                <div class="hx-menu-v2">
                    <div class="hx-card hx-scope-legend">
                        <div class="hx-scope-legend-row"><span class="hx-badge-dot hx-badge-global"></span><b style="color:#7dd3fc;">Global</b><span>hides on every site you visit</span></div>
                        <div class="hx-scope-legend-row"><span class="hx-badge-dot hx-badge-site"></span><b style="color:#6ee7b7;">Site‑wide</b><span>hides only on this domain</span></div>
                        <div class="hx-scope-legend-row"><span class="hx-badge-dot hx-badge-page"></span><b style="color:#c4b5fd;">Page‑only</b><span>hides only on this exact URL</span></div>
                    </div>
                    <input type="text" id="rules-search" class="h-select" placeholder="🔍 Search all rules by selector\u2026">

                    <div class="hx-section-head-v2">
                        <span class="hx-section-head-title"><span class="hx-badge-dot hx-badge-global"></span>Global<span class="hx-count-pill" id="cnt-custom">0</span></span>
                        <div class="hx-section-head-actions">
                            <button class="hider-btn-small btn-gray" id="pause-all-custom" title="Pause every global rule (keeps them saved)">⏸️ Pause All</button>
                            <button class="hider-btn-small btn-green" id="resume-all-custom" title="Resume every paused global rule">▶️ Resume All</button>
                        </div>
                    </div>
                    <div style="display:flex;gap:4px;">
                        <button class="hider-btn-small btn-blue" id="add-rule-btn" style="height:26px;padding:0 10px;flex:1;">➕ Add Rule</button>
                        <button class="hider-btn-small btn-red" id="clear-custom-rules" style="height:26px;padding:0 8px;">Clear All</button>
                    </div>
                    <div id="list-custom-rules" class="hx-list"></div>

                    <div class="hx-section-head-v2">
                        <span class="hx-section-head-title"><span class="hx-badge-dot hx-badge-site"></span>Site‑Wide<span class="hx-count-pill" id="cnt-site">0</span></span>
                        <button class="hider-btn-small btn-red" id="clear-site-rules">Clear All</button>
                    </div>
                    <div id="list-site" class="hx-list"></div>

                    <div class="hx-section-head-v2">
                        <span class="hx-section-head-title"><span class="hx-badge-dot hx-badge-page"></span>Page‑Only<span class="hx-count-pill" id="cnt-link">0</span></span>
                        <button class="hider-btn-small btn-red" id="clear-page-rules">Clear All</button>
                    </div>
                    <div id="list-link" class="hx-list"></div>
                </div>
            ` },
            { id: 'tab-edit', label: '✎ Edit', html: `
                <div class="hx-menu-v2">
                    <div class="hx-card" style="padding:11px;">
                        <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:8px;">
                            <div>
                                <div class="hx-menu-title">Permanent Element Edits</div>
                                <div class="hx-menu-sub">Rewrite text or values, or replace media, while keeping the site's own styling.</div>
                            </div>
                            <button class="hider-btn-small btn-blue" id="btn-new-edit" style="height:26px;padding:0 9px;white-space:nowrap;flex:0 0 auto;">➕ New Edit</button>
                        </div>
                    </div>
                    <input type="text" id="edit-search" class="h-select" placeholder="🔍 Search saved edits by selector\u2026">

                    <div class="hx-section-head-v2">
                        <span class="hx-section-head-title"><span class="hx-badge-dot hx-badge-global"></span>Global<span class="hx-count-pill" id="cnt-edit-global">0</span></span>
                        <button class="hider-btn-small btn-red" id="clear-edit-global">Clear</button>
                    </div>
                    <div id="list-edit-global" class="hx-list"></div>

                    <div class="hx-section-head-v2">
                        <span class="hx-section-head-title"><span class="hx-badge-dot hx-badge-site"></span>This Site<span class="hx-count-pill" id="cnt-edit-site">0</span></span>
                    </div>
                    <div id="list-edit-site" class="hx-list"></div>

                    <div class="hx-section-head-v2">
                        <span class="hx-section-head-title"><span class="hx-badge-dot hx-badge-page"></span>This Page<span class="hx-count-pill" id="cnt-edit-page">0</span></span>
                    </div>
                    <div id="list-edit-page" class="hx-list"></div>

                    <button class="hider-btn-small btn-red" id="clear-edit-current" style="width:100%;height:27px;margin-top:2px;">🗑️ Clear Site + Page Edits</button>
                </div>
            ` },
            { id: 'tab-freeze', label: '◒ Freeze', html: `
                <div class="hx-menu-v2">
                    <div class="hx-status-card" id="freeze-status-card">
                        <div class="hx-status-card-left">
                            <span class="hx-status-dot" id="freeze-status-dot"></span>
                            <div>
                                <div class="hx-status-card-title" id="freeze-status-title">Freeze OFF</div>
                                <div class="hx-status-card-sub" id="freeze-status-sub">Navigation on this page isn\u2019t being intercepted.</div>
                            </div>
                        </div>
                        <button class="hider-btn-small btn-blue" id="freeze-toggle-btn" style="height:30px;padding:0 14px;white-space:nowrap;flex:0 0 auto;">Turn ON</button>
                    </div>

                    <div style="font-size:9px;color:#94a3b8;text-transform:uppercase;letter-spacing:0.5px;font-weight:700;margin-top:2px;">While Frozen, Navigation Is\u2026</div>
                    <div class="h-custom-select" id="freeze-custom-panel-dropdown">
                        <div class="h-custom-trigger"><span class="h-custom-value-text">${FREEZE_LABELS[CACHE.freezeMemory] || FREEZE_LABELS['ask']}</span><span class="h-custom-arrow">▼</span></div>
                        <div class="h-custom-options">
                            <div class="h-custom-opt" data-val="ask">❓ Ask Every Time</div>
                            <div class="h-custom-opt" data-val="block_all">⛔ Auto‑Block All</div>
                            <div class="h-custom-opt" data-val="allow_same">🔗 Allow Same Domain Only</div>
                            <div class="h-custom-opt" data-val="allow_all">🟢 Allow All</div>
                        </div>
                    </div>
                    <div id="freeze-mode-hint" style="font-size:8px;color:#64748b;line-height:1.45;padding:0 2px;">${FREEZE_HINTS[CACHE.freezeMemory] || FREEZE_HINTS['ask']}</div>

                    <div style="font-size:9px;color:#94a3b8;text-transform:uppercase;letter-spacing:0.5px;font-weight:700;margin-top:4px;">Quick Actions \u2014 Current Site</div>
                    <div class="hx-quick-actions">
                        <button class="hider-btn-small btn-red" id="freeze-quick-block-site" title="Add this site's domain to Blocked Domains">🚫 Block This Site</button>
                        <button class="hider-btn-small btn-green" id="freeze-quick-allow-site" title="Add this site's domain to Allowed Domains">🟢 Allow This Site</button>
                    </div>

                    <button id="btn-reset-block-confirm" class="hider-btn-small" style="background:rgba(255,255,255,0.06);color:#cbd5e1;width:100%;padding:4px;height:auto;font-size:9px;" title="If you previously ticked 'don't ask again' on the block-domain confirmation, this brings it back.">🔄 Reset "Always Block" Confirmation</button>
                    <div class="hx-card" style="padding:7px 9px;margin-top:2px;">
                        <div style="font-size:8px;color:#94a3b8;line-height:1.5;">🚫🟢 These lists are global \u2014 they also control redirects, popups and blocked form submissions on every site, not only Freeze prompts.</div>
                    </div>
                    <input type="text" id="domains-search" class="h-select" placeholder="🔍 Filter domain lists\u2026">
                    <div class="hx-section-head-v2" style="margin-top:6px;">
                        <span class="hx-section-head-title">🚫 Blocked Domains<span class="hx-count-pill" id="cnt-domains">0</span></span>
                    </div>
                    <div style="display:flex;gap:4px;margin-bottom:4px;">
                        <input type="text" id="manual-domain-input" placeholder="Block domain (e.g. bad.com)" class="h-select" style="flex:1;">
                        <button class="hider-btn-small btn-red" id="add-domain-btn" style="height:28px;padding:0 8px;">Block</button>
                    </div>
                    <div id="list-blocked-domains" class="hx-list"></div>
                    <div class="hx-section-head-v2" style="margin-top:8px;">
                        <span class="hx-section-head-title">🟢 Allowed Domains<span class="hx-count-pill" id="cnt-allowed">0</span></span>
                    </div>
                    <div style="display:flex;gap:4px;margin-bottom:4px;">
                        <input type="text" id="manual-allowed-domain-input" placeholder="Allow domain (e.g. trusted.com)" class="h-select" style="flex:1;">
                        <button class="hider-btn-small btn-green" id="add-allowed-domain-btn" style="height:28px;padding:0 8px;">Allow</button>
                    </div>
                    <div id="list-allowed-domains" class="hx-list"></div>
                </div>
            ` },
            { id: 'tab-logs', label: '◌ Logs', html: `
                <div style="display:flex;justify-content:space-between;align-items:center;">
                    <span style="font-size:10px;color:#94a3b8;">Blocked (<span id="cnt-logs">0</span>)</span>
                    <button class="hider-btn-small btn-gray" id="clear-log-btn" style="font-size:8px;padding:1px 5px;height:18px;">Clear</button>
                </div>
                <div id="list-blocked-log" style="display:flex;flex-direction:column;gap:3px;margin-top:4px;"></div>
            ` },
            { id: 'tab-export', label: '⇅ Backup', html: `
                <div style="display:flex;gap:4px;flex-wrap:wrap;align-items:center;margin-bottom:8px;">
                    <button class="hider-btn-small btn-blue" id="btn-export-settings" style="flex:1;min-width:70px;height:26px;">📤 Export All</button>
                    <button class="hider-btn-small btn-green" id="btn-import-settings" style="flex:1;min-width:70px;height:26px;">📥 Import All</button>
                    <input type="file" id="import-file-input" accept=".json" style="display:none;">
                </div>
                <div style="font-size:9px;color:#94a3b8;margin-bottom:8px;">Export/Import all settings (rules, domains, toggles, logs).</div>
            ` },
            { id: 'tab-cookies', label: '◉ Cookies', html: `
                <div style="display:flex;flex-direction:column;gap:8px;">
                    <div class="hx-card" style="padding:12px;background:linear-gradient(145deg,rgba(56,189,248,.075),rgba(8,15,28,.68) 60%,rgba(139,92,246,.055));">
                        <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:8px;">
                            <div>
                                <div style="font-size:14px;font-weight:900;color:#f8fafc;">Cookie Workspace</div>
                                <div style="font-size:9px;color:#64748b;margin-top:2px;">Inspect · edit · create · remove · backup</div>
                            </div>
                            <span class="hx-chip" id="cookie-api-status">Detecting…</span>
                        </div>
                        <div style="display:flex;gap:5px;flex-wrap:wrap;margin-top:8px;">
                            <span class="hx-chip">🌐 <span id="cookie-host-label"></span></span>
                            <span class="hx-chip">🍪 <b id="cookie-count">0</b> visible</span>
                            <span class="hx-chip" id="cookie-http-only-note">HttpOnly: browser-protected</span>
                        </div>
                    </div>
                    <div style="display:flex;gap:5px;align-items:center;">
                        <input class="hx-input" type="search" id="cookie-search" placeholder="Search cookie name or value…" style="height:30px;padding:0 9px;font-size:9px;flex:1;">
                        <button class="hider-btn-small btn-blue" id="cookie-refresh" style="height:30px;min-width:32px;padding:0 9px;">↻</button>
                    </div>
                    <div id="cookie-list" style="display:flex;flex-direction:column;gap:5px;max-height:250px;overflow-y:auto;padding-right:2px;"></div>
                    <div class="hx-card" style="padding:10px;">
                        <div style="display:flex;justify-content:space-between;align-items:center;gap:7px;">
                            <div>
                                <div style="font-size:10px;font-weight:900;color:#e2e8f0;">➕ New Cookie</div>
                                <div style="font-size:8px;color:#64748b;margin-top:2px;">Composer stays closed until you choose Add New.</div>
                            </div>
                            <button class="hider-btn-small btn-green" id="cookie-add-new" aria-expanded="false" style="height:28px;padding:0 11px;">+ Add New</button>
                        </div>

                        <div id="cookie-new-editor" hidden style="margin-top:9px;padding-top:9px;border-top:1px solid rgba(148,163,184,.08);">
                            <div style="display:grid;grid-template-columns:1fr 1.3fr;gap:5px;">
                                <input class="hx-input" id="cookie-new-name" placeholder="Name" style="height:27px;padding:0 7px;font-size:9px;">
                                <input class="hx-input" id="cookie-new-value" placeholder="Value" style="height:27px;padding:0 7px;font-size:9px;">
                                <input class="hx-input" id="cookie-new-path" value="/" placeholder="Path" style="height:27px;padding:0 7px;font-size:9px;">
                                <input class="hx-input" id="cookie-new-expiry" type="datetime-local" style="height:27px;padding:0 7px;font-size:9px;">
                            </div>
                            <div style="display:flex;gap:7px;flex-wrap:wrap;margin-top:7px;align-items:center;">
                                <label style="font-size:8px;color:#94a3b8;display:flex;gap:4px;align-items:center;"><input type="checkbox" id="cookie-new-secure"> Secure</label>
                                <select class="hx-input" id="cookie-new-samesite" style="width:92px;height:25px;padding:0 5px;font-size:8px;"><option value="lax">SameSite=Lax</option><option value="strict">SameSite=Strict</option><option value="none">SameSite=None</option></select>
                                <button class="hider-btn-small btn-green" id="cookie-add" style="height:27px;padding:0 12px;margin-left:auto;">Create</button>
                                <button class="hider-btn-small btn-gray" id="cookie-new-cancel" style="height:27px;padding:0 10px;">Cancel</button>
                            </div>
                        </div>
                    </div>
                    <div style="display:flex;gap:5px;flex-wrap:wrap;">
                        <button class="hider-btn-small btn-red" id="cookie-clear-all" style="height:26px;padding:0 10px;">Delete Visible</button>
                        <button class="hider-btn-small btn-blue" id="cookie-export" style="height:26px;padding:0 10px;">Export</button>
                        <button class="hider-btn-small btn-purple" id="cookie-import" style="height:26px;padding:0 10px;">Import</button>
                        <input type="file" id="cookie-import-file" accept=".json" style="display:none;">
                    </div>
                    <div style="font-size:8px;line-height:1.5;color:#475569;">This manager can only access cookies exposed to page scripts. HttpOnly cookies cannot be read or changed by a userscript. Attribute editing uses the browser Cookie Store API when available and falls back to standard cookie writes.</div>
                </div>
            ` },
            { id: 'tab-about', label: '✦ About', html: `
                <div class="hx-about2">
                    <section class="hx-about2-hero">
                        <div class="hx-about2-icon" aria-hidden="true">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="100%" height="100%">
                              <defs>
                                <radialGradient id="aboutBgGradient" cx="50%" cy="50%" r="50%"><stop offset="0%" stop-color="#1e293b" /><stop offset="60%" stop-color="#0d121e" /><stop offset="100%" stop-color="#050816" /></radialGradient>
                                <linearGradient id="aboutNeonCyan" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#7dd3fc" /><stop offset="50%" stop-color="#38bdf8" /><stop offset="100%" stop-color="#0284c7" /></linearGradient>
                                <linearGradient id="aboutProGradient" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#fbbf24" /><stop offset="100%" stop-color="#f59e0b" /></linearGradient>
                                <linearGradient id="aboutGlassBorder" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#38bdf8" stop-opacity="0.9"/><stop offset="50%" stop-color="#1e293b" stop-opacity="0.3"/><stop offset="100%" stop-color="#38bdf8" stop-opacity="0.7"/></linearGradient>
                                <filter id="aboutNeonGlow" x="-20%" y="-20%" width="140%" height="140%"><feGaussianBlur stdDeviation="8" result="blur"/><feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
                                <filter id="aboutProGlow" x="-20%" y="-20%" width="140%" height="140%"><feGaussianBlur stdDeviation="4" result="blur"/><feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
                              </defs>
                              <circle cx="256" cy="256" r="230" fill="url(#aboutBgGradient)" stroke="url(#aboutGlassBorder)" stroke-width="6" filter="url(#aboutNeonGlow)"/>
                              <g stroke="#38bdf8" stroke-opacity="0.12" stroke-width="2"><line x1="126" y1="180" x2="386" y2="180"/><line x1="126" y1="256" x2="386" y2="256"/><line x1="126" y1="332" x2="386" y2="332"/><line x1="180" y1="126" x2="180" y2="386"/><line x1="256" y1="126" x2="256" y2="386"/><line x1="332" y1="126" x2="332" y2="386"/></g>
                              <circle cx="256" cy="256" r="145" fill="none" stroke="#38bdf8" stroke-width="2.5" stroke-dasharray="8 8" opacity="0.45"/>
                              <g filter="url(#aboutNeonGlow)"><path d="M 136 256 C 180 176, 332 176, 376 256 C 332 336, 180 336, 136 256 Z" fill="none" stroke="url(#aboutNeonCyan)" stroke-width="12" stroke-linejoin="round" stroke-linecap="round"/><circle cx="256" cy="256" r="46" fill="#0d121e" stroke="url(#aboutNeonCyan)" stroke-width="8"/><circle cx="256" cy="256" r="18" fill="#e0f2fe"/><line x1="150" y1="362" x2="362" y2="150" stroke="#f8fafc" stroke-width="12" stroke-linecap="round"/><line x1="150" y1="362" x2="362" y2="150" stroke="#38bdf8" stroke-width="6" stroke-linecap="round"/></g>
                              <g stroke="#e0f2fe" stroke-width="2.5" opacity="0.8"><path d="M 360 130 L 360 154 M 348 142 L 372 142 M 351 133 L 369 151 M 351 151 L 369 133" /></g>
                              <g transform="translate(85, 335)" filter="url(#aboutProGlow)"><rect x="0" y="0" width="112" height="50" rx="14" fill="#0d121e" stroke="url(#aboutProGradient)" stroke-width="3.5"/><text x="56" y="34" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="25" fill="url(#aboutProGradient)" text-anchor="middle" letter-spacing="3.5">PRO</text></g>
                            </svg>
                        </div>
                        <div class="hx-about2-copy">
                            <div class="hx-about2-kicker">CONTROL CENTER</div>
                            <div class="hx-about2-title">Hide Web Elements <span>PRO</span></div>
                            <div class="hx-about2-desc">Control the page layer with precise hide, edit, overlay, media, navigation, cookie and recovery tools.</div>
                            <div class="hx-about2-meta"><span class="hx-about2-live-dot" id="about-live-dot"></span><span id="about-runtime-status">Running</span><span>•</span><span id="about-domain-status">Current page</span></div>
                        </div>
                    </section>

                    <section class="hx-about2-status">
                        <div class="hx-about2-section-head"><div><b>Live status</b><span>Auto-refreshes while this tab is open</span></div><span class="hx-about2-state-pill" id="about-active-summary">Checking…</span></div>
                        <div class="hx-about2-status-grid" id="about-status-grid"></div>
                        <div class="hx-about2-updated" id="about-updated-at"></div>
                    </section>

                    <section class="hx-about2-section">
                        <div class="hx-about2-section-head"><div><b>Core capabilities</b><span>What each tool is designed to control</span></div></div>
                        <div class="hx-about2-cap-grid">
                            <div class="hx-about2-cap"><i>🎯</i><div><b>Hide</b><span>Target elements and save Site, Page or Global rules.</span></div></div>
                            <div class="hx-about2-cap"><i>✏️</i><div><b>Edit</b><span>Rewrite text/values or replace media while preserving site structure.</span></div></div>
                            <div class="hx-about2-cap"><i>👁️</i><div><b>Reveal / Blur</b><span>Recover hidden and blurred page content without rebuilding the page.</span></div></div>
                            <div class="hx-about2-cap"><i>🖱️</i><div><b>Right‑Click</b><span>Restore the browser context menu and long‑press behavior.</span></div></div>
                            <div class="hx-about2-cap"><i>↕️</i><div><b>Scroll Recovery</b><span>Release detected page-level scroll locks when enabled.</span></div></div>
                            <div class="hx-about2-cap"><i>🚫</i><div><b>Overlays</b><span>Auto-close modals and run Anti‑Paywall / Anti‑Adblock levels.</span></div></div>
                            <div class="hx-about2-cap"><i>❄️</i><div><b>Navigation Freeze</b><span>Ask, block, same-domain or allow navigation behavior.</span></div></div>
                            <div class="hx-about2-cap"><i>🍪</i><div><b>Cookies</b><span>Inspect, edit, create, remove and back up script-visible cookies.</span></div></div>
                            <div class="hx-about2-cap"><i>🔗</i><div><b>Link & Media Lab</b><span>Extract, inspect and work with page links and media.</span></div></div>
                            <div class="hx-about2-cap"><i>⏩</i><div><b>Time Tools</b><span>Smart countdown/ad-skip handling plus manual +30 seconds.</span></div></div>
                        </div>
                    </section>

                    <section class="hx-about2-section">
                        <div class="hx-about2-section-head"><div><b>Anti‑Paywall levels</b><span>Choose aggressiveness without changing the rest of the toolkit</span></div></div>
                        <div class="hx-about2-levels"><div><strong>OFF</strong><span>Disabled</span></div><div><strong>WEAK</strong><span>High-confidence blockers</span></div><div><strong>NORMAL</strong><span>Balanced detection</span></div><div><strong>EXTREME</strong><span>Aggressive + re-scan</span></div></div>
                    </section>

                    <section class="hx-about2-foot"><span>Local-first controls</span><span>•</span><span>Mobile + touch aware</span><span>•</span><span>Shadow UI isolated</span><span>•</span><span>Reduced-motion aware</span></section>
                </div>
            ` }
        ];

        tabs.forEach((tab, index) => {
            const btn = document.createElement('button');
            btn.className = 'tab-btn' + (index === 0 ? ' active' : '');
            btn.dataset.tab = tab.id;
            btn.textContent = tab.label;
            btn.title = tab.label;
            btn.type = 'button';
            btn.setAttribute('role', 'tab');
            btn.setAttribute('aria-selected', String(index === 0));
            btn.setAttribute('aria-controls', tab.id);
            sidebar.appendChild(btn);

            const contentDiv = document.createElement('div');
            contentDiv.className = 'tab-content' + (index === 0 ? ' active' : '');
            contentDiv.id = tab.id;
            contentDiv.innerHTML = tab.html;
            content.appendChild(contentDiv);
        });

        sidebar.addEventListener('click', (e) => {
            const btn = e.target.closest('.tab-btn');
            if (!btn) return;
            const tabId = btn.dataset.tab;
            sidebar.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
            content.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
            btn.classList.add('active');
            sidebar.querySelectorAll('.tab-btn').forEach(b => b.setAttribute('aria-selected', String(b === btn)));
            const contentDiv = content.querySelector('#' + tabId);
            if (contentDiv) contentDiv.classList.add('active');
            if (tabId === 'tab-about') updateAboutDashboard();
        });
    }

    // ---------- Shadow UI Events ----------
    // Lightweight live-filter for the Rules/Freeze list panels. Wired once per
    // input; renderList() re-applies it after every re-render since it rebuilds
    // the list containers' innerHTML.
    function wireListFilter(input, containerIds) {
        if (!input) return;
        const apply = () => {
            const q = input.value.trim().toLowerCase();
            containerIds.forEach(id => {
                const c = shadowBy(id);
                if (!c) return;
                c.querySelectorAll(':scope > .list-item').forEach(row => {
                    const txt = (row.querySelector('.rule-text')?.getAttribute('title') || row.querySelector('.rule-text')?.textContent || row.textContent || '').toLowerCase();
                    row.style.display = (!q || txt.includes(q)) ? '' : 'none';
                });
            });
        };
        input.oninput = apply;
        input._applyFilter = apply;
    }

    function setupShadowUIEvents() {
        shadowBy('close-p').onclick = e => { if (e) { e.stopPropagation(); e.preventDefault(); } turnOffHideMode(); closeAllMenus(e, true); };

        setupCustomDropdown(shadowBy('freeze-custom-panel-dropdown'), CACHE.freezeMemory, val => {
            CACHE.freezeMemory = val; sv('hider_freeze_memory', val);
            const label = FREEZE_LABELS[val] || val;
            const hintEl = shadowBy('freeze-mode-hint');
            if (hintEl) hintEl.textContent = FREEZE_HINTS[val] || '';
            if (val === 'allow_all') { disableFreezeMode(); showToast(`🟢 Freeze Mode Disabled (Allow All)`); }
            else showToast(`❄️ Memory updated: ${label}`);
            updateFreezeStatusCard();
        });

        shadowBy('btn-reset-block-confirm').onclick = () => { sv('hider_skip_block_confirm', false); showToast('🔄 "Always Block" confirmation re-enabled'); };

        wireListFilter(shadowBy('rules-search'), ['list-custom-rules', 'list-site', 'list-link']);
        wireListFilter(shadowBy('domains-search'), ['list-blocked-domains', 'list-allowed-domains']);
        wireListFilter(shadowBy('edit-search'), ['list-edit-global', 'list-edit-site', 'list-edit-page']);

        const paywallLevelSelect = shadowBy('anti-paywall-level-select');
        if (paywallLevelSelect) {
            setupCustomDropdown(paywallLevelSelect, CACHE.antiPaywallLevel, val => {
                CACHE.antiPaywallLevel = PAYWALL_LEVEL_CONFIG[val] ? val : 'off';
                sv('hider_anti_paywall_level', CACHE.antiPaywallLevel);
                applyAllSettings();
                const valueEl = shadowBy('anti-paywall-level-value');
                const hintEl = shadowBy('anti-paywall-hint');
                if (valueEl) valueEl.textContent = PAYWALL_LEVEL_LABELS[CACHE.antiPaywallLevel];
                if (hintEl) hintEl.textContent = PAYWALL_LEVEL_HINTS[CACHE.antiPaywallLevel];
                showToast(`🚫 Anti-Paywall: ${PAYWALL_LEVEL_LABELS[CACHE.antiPaywallLevel]}`);
            }, PAYWALL_LEVEL_LABELS);
            const valueEl = shadowBy('anti-paywall-level-value');
            const hintEl = shadowBy('anti-paywall-hint');
            if (valueEl) valueEl.textContent = PAYWALL_LEVEL_LABELS[CACHE.antiPaywallLevel] || 'Off';
            if (hintEl) hintEl.textContent = PAYWALL_LEVEL_HINTS[CACHE.antiPaywallLevel] || PAYWALL_LEVEL_HINTS.off;
        }

        const chkModal = shadowBy('chk-auto-close-modals');
        if (chkModal) {
            chkModal.onchange = e => {
                CACHE.autoCloseModals = e.target.checked;
                sv('hider_auto_close_modals', CACHE.autoCloseModals);
                applyAllSettings();
                showToast(`🗑️ Auto-Close Modals: ${CACHE.autoCloseModals ? 'ON' : 'OFF'}`);
            };
        }

        const chkAutoCloseLogins = shadowBy('chk-auto-close-logins');
        if (chkAutoCloseLogins) {
            chkAutoCloseLogins.onchange = e => {
                CACHE.autoCloseLogins = e.target.checked;
                sv('hider_auto_close_logins', CACHE.autoCloseLogins);
                applyAllSettings();
                showToast(`🔓 Auto-Close Logins: ${CACHE.autoCloseLogins ? 'ON' : 'OFF'}`);
            };
        }

        const cookieMode = shadowBy('cookie-consent-mode-select');
        if (cookieMode) {
            const cookieLabels = { ask: 'Ask', accept: 'Accept', reject: 'Reject' };
            setupCustomDropdown(cookieMode, CACHE.cookieConsentMode, val => {
                CACHE.cookieConsentMode = cookieLabels[val] ? val : 'ask';
                sv('hider_cookie_consent_mode', CACHE.cookieConsentMode);
                applyAllSettings();
                const valueEl = shadowBy('cookie-consent-mode-value');
                if (valueEl) valueEl.textContent = cookieLabels[CACHE.cookieConsentMode];
                showToast(`🍪 Cookie mode: ${cookieLabels[CACHE.cookieConsentMode]}`);
            }, cookieLabels);
            const valueEl = shadowBy('cookie-consent-mode-value');
            if (valueEl) valueEl.textContent = cookieLabels[CACHE.cookieConsentMode] || 'Ask';
        }

        const chkScroll = shadowBy('chk-auto-scroll');
        if (chkScroll) {
            chkScroll.onchange = e => {
                CACHE.autoScroll = e.target.checked;
                sv('hider_auto_scroll', CACHE.autoScroll);
                if (CACHE.autoScroll) {
                    startScrollDefeater();
                    showToast('🔓 Auto Anti-Scroll Lock enabled');
                updateAboutDashboard();
                } else {
                    stopScrollDefeater();
                    showToast('🔒 Auto Anti-Scroll Lock disabled');
                updateAboutDashboard();
                }
            };
        }

        const chkContext = shadowBy('chk-enable-contextmenu');
        if (chkContext) {
            chkContext.onchange = e => {
                CACHE.enableContextMenu = e.target.checked;
                sv('hider_enable_contextmenu', CACHE.enableContextMenu);
                updateContextMenuStyles();
                showToast(`🖱️ Auto Right-Click/Long-Press: ${CACHE.enableContextMenu ? 'ON' : 'OFF'}`);
                updateAboutDashboard();
            };
        }

        const chkBlur = shadowBy('chk-auto-remove-blur');
        if (chkBlur) {
            chkBlur.onchange = e => {
                CACHE.autoRemoveBlur = e.target.checked;
                sv('hider_auto_remove_blur', CACHE.autoRemoveBlur);
                if (CACHE.autoRemoveBlur) {
                    scheduleBlurRemoval();
                    showToast('👁️ Auto Remove Blur enabled (aggressive)');
                updateAboutDashboard();
                } else {
                    stopBlurRemoval();
                    showToast('👁️ Auto Remove Blur disabled');
                updateAboutDashboard();
                }
            };
        }

        const autoSkipChk = shadowBy('chk-auto-time-skipper');
        if (autoSkipChk) {
            autoSkipChk.onchange = e => {
                CACHE.autoTimeSkipper = e.target.checked;
                sv('hider_auto_time_skipper', CACHE.autoTimeSkipper);
                if (CACHE.autoTimeSkipper) {
                    startAutoSkipMonitoring();
                    showToast('⏩ Auto Time Skipper enabled (smart)');
                updateAboutDashboard();
                } else {
                    stopAutoSkipMonitoring();
                    showToast('⏩ Auto Time Skipper disabled');
                updateAboutDashboard();
                }
            };
        }

        const dockShowAll = shadowBy('dock-show-all');
        if (dockShowAll) dockShowAll.onclick = e => { e.stopPropagation(); setDockButtonsVisible('all'); };

        const dockHideOptional = shadowBy('dock-hide-optional');
        if (dockHideOptional) dockHideOptional.onclick = e => { e.stopPropagation(); setDockButtonsVisible('none'); };

        const dockEl = shadowBy('hider-main-dock'), mainBtn = shadowBy('btn-toggle-dock');
        const savedY = gv('hider_dock_y', null); if (savedY) dockEl.style.top = savedY;
        dockEl.addEventListener('mouseleave', () => dockEl.classList.remove('manual-hidden'));

        let dockStartX, dockStartY, dockInitY, dockMoved = false;
        const onDockMove = e => {
            if (!isDraggingDock) return;
            const p = e.touches ? e.touches[0] : e, dy = p.clientY - dockStartY;
            if (Math.hypot(p.clientX - dockStartX, dy) > 8) {
                dockMoved = true; if (e.cancelable) e.preventDefault();
                dockEl.style.top = `${Math.max(0, Math.min(dockInitY + dy, win.innerHeight - dockEl.offsetHeight))}px`;
            }
        };

        const onDockEnd = () => {
            if (isDraggingDock) { isDraggingDock = false; dockEl.style.transition = ''; if (dockMoved) sv('hider_dock_y', dockEl.style.top); }
            win.removeEventListener('mousemove', onDockMove); win.removeEventListener('mouseup', onDockEnd);
            win.removeEventListener('touchmove', onDockMove); win.removeEventListener('touchend', onDockEnd); win.removeEventListener('touchcancel', onDockEnd);
        };

        const onDockStart = e => {
            if (e.target.tagName === 'BUTTON' && e.target.id !== 'btn-toggle-dock') return;
            const p = e.touches ? e.touches[0] : e;
            dockStartX = p.clientX; dockStartY = p.clientY; dockInitY = dockEl.getBoundingClientRect().top;
            isDraggingDock = true; dockMoved = false; dockEl.style.transition = 'none';
            win.addEventListener('mousemove', onDockMove, { passive: false }); win.addEventListener('mouseup', onDockEnd);
            win.addEventListener('touchmove', onDockMove, { passive: false }); win.addEventListener('touchend', onDockEnd); win.addEventListener('touchcancel', onDockEnd);
        };
        mainBtn.addEventListener('mousedown', onDockStart, { passive: false });
        mainBtn.addEventListener('touchstart', onDockStart, { passive: false });

        mainBtn.onclick = e => {
            e.stopPropagation(); if (dockMoved) { dockMoved = false; return; }
            if (timers.collapseTimer) { clearTimeout(timers.collapseTimer); timers.collapseTimer = null; }
            const menu = shadowBy('hider-dock-menu'), isOpening = !menu.classList.contains('is-open');

            menu.classList.toggle('is-open', isOpening);
            mainBtn.classList.toggle('expanded', isOpening);
            dockEl.classList.toggle('expanded', isOpening);
            dockEl.classList.toggle('is-collapsed', !isOpening);

            if (!isOpening) {
                turnOffHideMode();
                const panel = shadowBy('hider-panel');
                if (panel.classList.contains('is-visible')) { panel.classList.remove('is-visible'); setTimeout(()=> panel.style.display='none', 300); }
                shadowBy('btn-manage')?.classList.remove('active');
                dockEl.classList.add('manual-hidden');
                timers.collapseTimer = setTimeout(() => { dockEl.classList.add('is-collapsed'); timers.collapseTimer = null; }, 1000);
            } else dockEl.classList.remove('manual-hidden');
        };

        const btnScope = shadowBy('btn-scope');
        btnScope.onclick = e => {
            e.stopPropagation();
            const scopes = ['site', 'link', 'global'];
            let idx = scopes.indexOf(currentScope);
            idx = (idx + 1) % scopes.length;
            currentScope = scopes[idx];
            btnScope.querySelector('span').textContent = currentScope.toUpperCase();
            btnScope.classList.toggle('scope-link', currentScope === 'link');
            btnScope.classList.toggle('scope-global', currentScope === 'global');
            const label = currentScope === 'site' ? '🌐 Site-wide' : currentScope === 'link' ? '📄 Page-only' : '🌍 Global';
            showToast(`Scope: ${label}`);
            broadcastState();
        };

        shadowBy('btn-reveal-quick').onclick = (e) => {
            e.stopPropagation();
            revealHiddenElements();
        };

        shadowBy('btn-links').onclick = (e) => {
            e.stopPropagation();
            closePeerPanels('links');
            toggleLinkPanel();
        };

        shadowBy('btn-skip-30').onclick = (e) => {
            e.stopPropagation();
            skip30Seconds();
        };

        const addRuleBtn = shadowBy('add-rule-btn');
        if (addRuleBtn) {
            addRuleBtn.onclick = () => {
                showRuleOverlay({ mode: 'add', scope: 'global' });
            };
        }

        const addAllowedDomain = () => {
            const input = shadowBy('manual-allowed-domain-input'), d = cleanDomain(input.value);
            if (d && !CACHE.allowedDomainsSet.has(d)) { CACHE.allowedDomainsList.push(d); CACHE.allowedDomainsSet.add(d); sv('hider_allowed_domains', CACHE.allowedDomainsList); showToast(`🟢 Allowed: ${d}`); }
            input.value = ''; renderList();
        };
        shadowBy('add-allowed-domain-btn').onclick = addAllowedDomain; shadowBy('manual-allowed-domain-input').onkeypress = e => e.key === 'Enter' && addAllowedDomain();

        const addDomain = () => {
            const input = shadowBy('manual-domain-input'), d = cleanDomain(input.value);
            if (d && !CACHE.blockedDomainsSet.has(d)) { CACHE.blockedDomainsList.push(d); CACHE.blockedDomainsSet.add(d); sv('hider_blocked_domains', CACHE.blockedDomainsList); showToast(`🚫 Blocked: ${d}`); }
            input.value = ''; renderList();
        };
        shadowBy('add-domain-btn').onclick = addDomain; shadowBy('manual-domain-input').onkeypress = e => e.key === 'Enter' && addDomain();

        shadowBy('btn-select').onclick = e => {
            e.stopPropagation();
            if (isSelecting && selectionMode === 'edit') {
                if (previewElement && editOriginalCaptured) restoreOriginalEditContent(previewElement);
                // Switch synchronously so the async media/session cleanup cannot
                // race the new Hide mode and turn it back off.
                exitEditMode(false);
                selectionMode = 'hide';
                isSelecting = true;
            } else if (isSelecting && selectionMode === 'hide') {
                isSelecting = false;
                clearSelectionState();
            } else {
                selectionMode = 'hide';
                isSelecting = true;
            }
            e.currentTarget.classList.toggle('active', isSelecting && selectionMode==='hide');
            e.currentTarget.setAttribute('aria-pressed',String(isSelecting && selectionMode==='hide'));
            shadowBy('btn-edit')?.classList.remove('active');
            shadowBy('btn-edit')?.setAttribute('aria-pressed','false');
            const p = shadowBy('hider-panel');
            if (isSelecting) {
                if(p.classList.contains('is-visible')) { p.classList.remove('is-visible'); setTimeout(()=> p.style.display='none', 300); } shadowBy('btn-manage').classList.remove('active');
                showToast('🎯 Selection mode ON – Click element to hide');
            } else {
                clearSelectionState();
                showToast('🎯 Selection mode OFF');
            }
            broadcastState();
        };

        shadowBy('btn-edit').onclick = e => {
            e.stopPropagation();
            if(!shadowRoot) return;
            // Edit and Hide are mutually exclusive. End Hide first, then let
            // enterEditMode() establish the Edit state exactly once.
            if (isSelecting && selectionMode === 'hide') {
                isSelecting = false;
                clearSelectionState();
                shadowBy('btn-select')?.classList.remove('active');
                shadowBy('btn-select')?.setAttribute('aria-pressed','false');
            }
            closePeerPanels('none');
            enterEditMode();
        };

        const btnNewEdit = shadowBy('btn-new-edit');
        if (btnNewEdit) {
            btnNewEdit.onclick = e => {
                e.stopPropagation();
                if (!shadowRoot) return;
                if (isSelecting && selectionMode === 'hide') {
                    isSelecting = false;
                    clearSelectionState();
                    shadowBy('btn-select')?.classList.remove('active');
                    shadowBy('btn-select')?.setAttribute('aria-pressed', 'false');
                }
                const p = shadowBy('hider-panel');
                if (p?.classList.contains('is-visible')) {
                    p.classList.remove('is-visible');
                    setTimeout(() => { if (!p.classList.contains('is-visible')) p.style.display = 'none'; }, 220);
                }
                shadowBy('btn-manage')?.classList.remove('active');
                enterEditMode();
                shadowBy('btn-edit')?.classList.add('active');
                shadowBy('btn-edit')?.setAttribute('aria-pressed', 'true');
                broadcastState();
                showToast('✏️ Tap the element you want to edit');
            };
        }

        const clearEditGlobal = shadowBy('clear-edit-global');
        if (clearEditGlobal) {
            clearEditGlobal.onclick = () => {
                if (confirm('Delete all global edits?')) {
                    writeEditRules('global', []);
                    setupEditObserver();
                    renderList();
                    showToast('🧹 Global edits cleared');
                }
            };
        }

        function closePeerPanels(except='') {
            const panel = shadowBy('hider-panel');
            const linkPanel = linkPanelEl || shadowBy('hider-link-panel');
            if (except !== 'manage' && panel?.classList.contains('is-visible')) {
                panel.classList.remove('is-visible');
                setTimeout(() => { if (!panel.classList.contains('is-visible')) panel.style.display='none'; }, 220);
                shadowBy('btn-manage')?.classList.remove('active');
            }
            if (except !== 'links' && linkPanel?.classList.contains('is-visible')) {
                linkPanel.classList.remove('is-visible');
                setTimeout(() => { if (!linkPanel.classList.contains('is-visible')) linkPanel.style.display='none'; }, 220);
            }
        }

        const btnFreeze = shadowBy('btn-freeze');
        btnFreeze.onclick = e => {
            e.stopPropagation(); isFrozen = !isFrozen; CACHE.isFrozen = isFrozen; sv('hider_freeze_global', isFrozen);
            if (isFrozen && CACHE.freezeMemory === 'allow_all') { CACHE.freezeMemory = 'ask'; sv('hider_freeze_memory', 'ask'); }
            btnFreeze.classList.toggle('is-frozen', isFrozen); if (isFrozen) triggerFreezeFx();
            showToast(isFrozen ? '🥶 Freeze ON' : '🔥 Freeze OFF'); updateAboutDashboard(); updateFreezeStatusCard(); broadcastState();
        };

        const freezeToggleBtn = shadowBy('freeze-toggle-btn');
        if (freezeToggleBtn) {
            freezeToggleBtn.onclick = e => {
                e.stopPropagation();
                shadowBy('btn-freeze')?.click();
            };
        }

        const quickBlockSite = shadowBy('freeze-quick-block-site');
        if (quickBlockSite) {
            quickBlockSite.onclick = () => {
                const d = CURRENT_DOMAIN || cleanDomain(location.href);
                if (!d) return;
                if (CACHE.blockedDomainsSet.has(d)) { showToast(`🚫 ${d} is already blocked`); return; }
                CACHE.allowedDomainsList = CACHE.allowedDomainsList.filter(x => x !== d);
                CACHE.allowedDomainsSet.delete(d);
                sv('hider_allowed_domains', CACHE.allowedDomainsList);
                CACHE.blockedDomainsList.push(d); CACHE.blockedDomainsSet.add(d);
                sv('hider_blocked_domains', CACHE.blockedDomainsList);
                renderList();
                showToast(`🚫 Blocked: ${d}`);
            };
        }
        const quickAllowSite = shadowBy('freeze-quick-allow-site');
        if (quickAllowSite) {
            quickAllowSite.onclick = () => {
                const d = CURRENT_DOMAIN || cleanDomain(location.href);
                if (!d) return;
                if (CACHE.allowedDomainsSet.has(d)) { showToast(`🟢 ${d} is already allowed`); return; }
                CACHE.blockedDomainsList = CACHE.blockedDomainsList.filter(x => x !== d);
                CACHE.blockedDomainsSet.delete(d);
                sv('hider_blocked_domains', CACHE.blockedDomainsList);
                CACHE.allowedDomainsList.push(d); CACHE.allowedDomainsSet.add(d);
                sv('hider_allowed_domains', CACHE.allowedDomainsList);
                renderList();
                showToast(`🟢 Allowed: ${d}`);
            };
        }

        const pauseAllCustom = shadowBy('pause-all-custom');
        if (pauseAllCustom) {
            pauseAllCustom.onclick = () => {
                if (!CACHE.customRules.length) { showToast('No global rules to pause'); return; }
                CACHE.customRules.forEach(r => r.enabled = false);
                sv('hider_custom_rules_v4', CACHE.customRules);
                requestUpdateStyles(); renderList();
                showToast('⏸️ All global rules paused');
            };
        }
        const resumeAllCustom = shadowBy('resume-all-custom');
        if (resumeAllCustom) {
            resumeAllCustom.onclick = () => {
                if (!CACHE.customRules.length) { showToast('No global rules to resume'); return; }
                CACHE.customRules.forEach(r => r.enabled = true);
                sv('hider_custom_rules_v4', CACHE.customRules);
                requestUpdateStyles(); renderList();
                showToast('▶️ All global rules resumed');
            };
        }

        shadowBy('btn-manage').onclick = e => {
            e.stopPropagation();
            const p = shadowBy('hider-panel');
            if (!p) return;
            const isOpen = p.classList.contains('is-visible');
            if (isOpen) {
                p.classList.remove('is-visible');
                setTimeout(() => { if (!p.classList.contains('is-visible')) p.style.display='none'; }, 220);
                e.currentTarget.classList.remove('active');
                return;
            }
            // Opening Control always exits page-element selection cleanly, then opens
            // the panel after any peer panel has been dismissed.
            if (isSelecting) {
                if (selectionMode === 'edit') exitEditMode(true);
                else { isSelecting=false; shadowBy('btn-select')?.classList.remove('active'); clearSelectionState(); broadcastState(); }
            }
            closePeerPanels('manage');
            p.style.display='flex';
            void p.offsetWidth;
            p.classList.add('is-visible');
            e.currentTarget.classList.add('active');
            renderList();
        };

        shadowBy('clear-log-btn').onclick = e => { if (e) e.stopPropagation(); CACHE.logs = []; sv('hider_global_logs', []); renderList(); showToast('🧹 Logs cleared'); };

        shadowBy('clear-custom-rules').onclick = () => {
            if (confirm('Delete all custom rules?')) {
                CACHE.customRules = [];
                sv('hider_custom_rules_v4', CACHE.customRules);
                renderList(); requestUpdateStyles();
                showToast('🧹 Custom rules cleared');
            }
        };
        shadowBy('clear-site-rules').onclick = () => {
            const key = 'hider_site_' + location.hostname;
            if (confirm('Delete all site-wide rules?')) {
                sv(key, []);
                renderList(); requestUpdateStyles();
                showToast('🧹 Site rules cleared');
            }
        };
        shadowBy('clear-page-rules').onclick = () => {
            const key = 'hider_link_' + cleanUrl();
            if (confirm('Delete all page-only rules?')) {
                sv(key, []);
                renderList(); requestUpdateStyles();
                showToast('🧹 Page rules cleared');
            }
        };

        const exportBtn = shadowBy('btn-export-settings');
        const importBtn = shadowBy('btn-import-settings');
        const fileInput = shadowBy('import-file-input');
        if (exportBtn) exportBtn.onclick = () => {
            const data = getAllSettings();
            const json = JSON.stringify(data, null, 2);
            const blob = new Blob([json], { type: 'application/json' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `hider_backup_${new Date().toISOString().slice(0,10)}.json`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
            showToast('📤 Settings exported');
        };
        if (importBtn) importBtn.onclick = () => fileInput?.click();
        if (fileInput) {
            fileInput.onchange = function() {
                if (this.files && this.files[0]) {
                    const reader = new FileReader();
                    reader.onload = function(e) {
                        try {
                            const data = JSON.parse(e.target.result);
                            let count = 0;
                            for (const [key, val] of Object.entries(data)) {
                                if (key.startsWith('hider_')) {
                                    sv(key, val);
                                    count++;
                                }
                            }
                            syncCache();
                            requestUpdateStyles();
                            renderList();
                            applyDockButtonVisibility();
                            showToast(`📥 Imported ${count} settings`);
                        } catch (err) {
                            showToast('❌ Invalid JSON file');
                        }
                    };
                    reader.readAsText(this.files[0]);
                    this.value = '';
                }
            };
        }

        // ---------- COOKIE WORKSPACE 15.0 ----------
        const cookieListEl = shadowBy('cookie-list');
        const cookieCountEl = shadowBy('cookie-count');
        const cookieSearch = shadowBy('cookie-search');
        const cookieAddNewBtn = shadowBy('cookie-add-new');
        const cookieNewEditor = shadowBy('cookie-new-editor');
        const cookieNewCancel = shadowBy('cookie-new-cancel');
        const cookieAddBtn = shadowBy('cookie-add');
        const cookieNameInput = shadowBy('cookie-new-name');
        const cookieValueInput = shadowBy('cookie-new-value');
        const cookiePathInput = shadowBy('cookie-new-path');
        const cookieExpiryInput = shadowBy('cookie-new-expiry');
        const cookieSecureInput = shadowBy('cookie-new-secure');
        const cookieSameSiteInput = shadowBy('cookie-new-samesite');
        const cookieClearAll = shadowBy('cookie-clear-all');
        const cookieExportBtn = shadowBy('cookie-export');
        const cookieImportBtn = shadowBy('cookie-import');
        const cookieImportFile = shadowBy('cookie-import-file');
        const cookieRefreshBtn = shadowBy('cookie-refresh');
        const cookieApiStatus = shadowBy('cookie-api-status');
        const cookieHostLabel = shadowBy('cookie-host-label');

        const cookieStoreApi = (typeof win.cookieStore !== 'undefined' && win.cookieStore) || (typeof cookieStore !== 'undefined' ? cookieStore : null);
        if (cookieApiStatus) {
            cookieApiStatus.textContent = cookieStoreApi ? 'Cookie Store API' : 'document.cookie fallback';
            cookieApiStatus.style.color = cookieStoreApi ? '#6ee7b7' : '#fcd34d';
        }
        if (cookieHostLabel) cookieHostLabel.textContent = location.hostname;

        let cookieCache = [];
        let cookieEditOpen = null;

        function normalizeCookie(c) {
            return {
                name: String(c?.name ?? ''), value: String(c?.value ?? ''), domain: c?.domain || location.hostname,
                path: c?.path || '/', expires: c?.expires ? new Date(c.expires).getTime() : null,
                secure: !!c?.secure, sameSite: (c?.sameSite || 'lax').toLowerCase(), httpOnly: !!c?.httpOnly
            };
        }

        function parseDocumentCookies() {
            return document.cookie.split(';').map(x => x.trim()).filter(Boolean).map(x => {
                const eq = x.indexOf('=');
                return normalizeCookie({ name: eq >= 0 ? x.slice(0, eq) : x, value: eq >= 0 ? x.slice(eq + 1) : '' });
            });
        }

        async function readCookies() {
            try {
                if (cookieStoreApi?.getAll) {
                    const all = await cookieStoreApi.getAll();
                    return all.map(normalizeCookie).filter(c => c.name);
                }
            } catch (err) { console.debug('[Hide Web Elements Pro] Cookie Store read fallback:', err); }
            return parseDocumentCookies();
        }

        function cookieMatchesFilter(c, filter) {
            if (!filter) return true;
            const q = filter.toLowerCase();
            return c.name.toLowerCase().includes(q) || c.value.toLowerCase().includes(q) || String(c.path).toLowerCase().includes(q);
        }

        function formatCookieExpiry(ts) {
            if (!ts) return 'Session';
            const d = new Date(ts);
            return Number.isNaN(d.getTime()) ? 'Session' : d.toLocaleString();
        }

        function renderCookieRows(filter='') {
            if (!cookieListEl) return;
            const filtered = cookieCache.filter(c => cookieMatchesFilter(c, filter));
            if (cookieCountEl) cookieCountEl.textContent = filtered.length;
            cookieListEl.innerHTML = '';
            if (!filtered.length) {
                cookieListEl.innerHTML = `<div class="hx-empty"><div style="font-size:20px;opacity:.45;">🍪</div><div style="font-size:9px;margin-top:5px;">${cookieCache.length ? 'No cookies match this search.' : 'No script-visible cookies for this site.'}</div></div>`;
                return;
            }
            const frag = doc.createDocumentFragment();
            filtered.forEach(c => {
                const row = doc.createElement('div');
                row.className='hx-cookie-row';
                row.style.cssText='display:flex;flex-direction:column;gap:5px;padding:8px;border-radius:10px;background:rgba(255,255,255,.025);border:1px solid rgba(148,163,184,.08);';
                const top=doc.createElement('div'); top.style.cssText='display:flex;align-items:center;gap:7px;';
                const name=doc.createElement('div'); name.textContent=c.name; name.style.cssText='font-size:10px;font-weight:900;color:#7dd3fc;word-break:break-all;flex:1;';
                const badge=doc.createElement('span'); badge.className='hx-chip'; badge.textContent=c.httpOnly?'HttpOnly':'Script-visible';
                top.append(name,badge);
                const val=doc.createElement('div'); val.className='hx-cookie-value'; val.textContent=c.value; val.title=c.value; val.style.cssText='font-size:8px;color:#cbd5e1;word-break:break-all;max-height:34px;overflow:auto;';
                const meta=doc.createElement('div'); meta.style.cssText='display:flex;gap:5px;flex-wrap:wrap;align-items:center;';
                [['Path',c.path],['Domain',c.domain],['Expires',formatCookieExpiry(c.expires)],['SameSite',c.sameSite],['Secure',c.secure?'yes':'no']].forEach(([k,v])=>{const x=doc.createElement('span');x.className='hx-chip';x.textContent=`${k}: ${v}`;meta.appendChild(x);});
                const actions=doc.createElement('div'); actions.style.cssText='display:flex;gap:4px;justify-content:flex-end;';
                const edit=doc.createElement('button'); edit.className='hider-btn-small btn-blue'; edit.textContent='Edit'; edit.style.height='22px';
                const del=doc.createElement('button'); del.className='hider-btn-small btn-red'; del.textContent='Delete'; del.style.height='22px';
                edit.onclick=e=>{e.stopPropagation(); openCookieEditor(row,c);};
                del.onclick=async e=>{e.stopPropagation(); await deleteCookie(c);};
                actions.append(edit,del);
                row.append(top,val,meta,actions);
                frag.appendChild(row);
            });
            cookieListEl.appendChild(frag);
        }

        function closeCookieEditor() { if (cookieEditOpen?.remove) cookieEditOpen.remove(); cookieEditOpen=null; }

        function openCookieEditor(row,c) {
            closeCookieEditor();
            const editor=doc.createElement('div'); editor.className='hx-card'; editor.style.cssText='padding:9px;margin-top:2px;background:rgba(56,189,248,.045);border-color:rgba(56,189,248,.14);';
            editor.innerHTML=`<div style="font-size:9px;font-weight:900;color:#e2e8f0;margin-bottom:6px;">Edit cookie</div>
              <div style="display:grid;grid-template-columns:1fr 1.3fr;gap:5px;">
                <input class="hx-input ce-name" style="height:26px;padding:0 6px;font-size:8px;" value="${escapeHtmlAttr(c.name)}">
                <input class="hx-input ce-value" style="height:26px;padding:0 6px;font-size:8px;" value="${escapeHtmlAttr(c.value)}">
                <input class="hx-input ce-path" style="height:26px;padding:0 6px;font-size:8px;" value="${escapeHtmlAttr(c.path)}">
                <input class="hx-input ce-expiry" type="datetime-local" style="height:26px;padding:0 6px;font-size:8px;" value="${c.expires?toDateTimeLocal(c.expires):''}">
              </div>
              <div style="display:flex;gap:7px;align-items:center;flex-wrap:wrap;margin-top:6px;">
                <label style="font-size:8px;color:#94a3b8;display:flex;gap:3px;align-items:center;"><input class="ce-secure" type="checkbox" ${c.secure?'checked':''}> Secure</label>
                <select class="hx-input ce-samesite" style="width:92px;height:24px;padding:0 5px;font-size:8px;"><option value="lax">Lax</option><option value="strict">Strict</option><option value="none">None</option></select>
                <button class="hider-btn-small btn-green ce-save" style="height:24px;margin-left:auto;">Save</button>
                <button class="hider-btn-small btn-gray ce-cancel" style="height:24px;">Cancel</button>
              </div>`;
            row.appendChild(editor); cookieEditOpen=editor;
            editor.querySelector('.ce-samesite').value=c.sameSite||'lax';
            editor.querySelector('.ce-cancel').onclick=e=>{e.stopPropagation();closeCookieEditor();};
            editor.querySelector('.ce-save').onclick=async e=>{
                e.stopPropagation();
                const next=normalizeCookie({name:editor.querySelector('.ce-name').value.trim(),value:editor.querySelector('.ce-value').value,domain:c.domain,path:editor.querySelector('.ce-path').value.trim()||'/',expires:editor.querySelector('.ce-expiry').value?new Date(editor.querySelector('.ce-expiry').value).getTime():null,secure:editor.querySelector('.ce-secure').checked,sameSite:editor.querySelector('.ce-samesite').value});
                if (!next.name) return showToast('⚠️ Cookie name cannot be empty');
                const ok=await replaceCookie(c,next); if(ok){closeCookieEditor();await refreshCookies();}
            };
        }

        function escapeHtmlAttr(v){ return String(v).replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }
        function toDateTimeLocal(ts){ const d=new Date(ts); const p=n=>String(n).padStart(2,'0'); return `${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())}T${p(d.getHours())}:${p(d.getMinutes())}`; }

        async function setCookie(c) {
            try {
                if (cookieStoreApi?.set) {
                    const opts={name:c.name,value:c.value,path:c.path||'/',secure:!!c.secure,sameSite:c.sameSite||'lax'};
                    if (c.domain && c.domain !== location.hostname) opts.domain=c.domain;
                    if (c.expires) opts.expires=c.expires;
                    await cookieStoreApi.set(opts); return true;
                }
            } catch(err){ console.debug('[Hide Web Elements Pro] Cookie Store set failed:',err); }
            try {
                let str=`${encodeURIComponent(c.name)}=${encodeURIComponent(c.value)}; path=${c.path||'/'}`;
                if(c.domain) str+=`; domain=${c.domain}`;
                if(c.expires) str+=`; expires=${new Date(c.expires).toUTCString()}`;
                if(c.secure) str+='; Secure';
                if(c.sameSite) str+=`; SameSite=${c.sameSite}`;
                document.cookie=str; return true;
            }catch(err){showToast('❌ Browser rejected this cookie change');return false;}
        }

        async function deleteCookie(c) {
            if (!confirm(`Delete cookie "${c.name}"?`)) return false;
            try {
                if (cookieStoreApi?.delete) {
                    await cookieStoreApi.delete({name:c.name,domain:c.domain,path:c.path||'/'});
                } else {
                    const domains=[c.domain,undefined,location.hostname].filter((v,i,a)=>v && a.indexOf(v)===i);
                    for(const d of domains){ let s=`${encodeURIComponent(c.name)}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${c.path||'/'}`; if(d)s+=`; domain=${d}`; document.cookie=s; }
                }
                showToast(`🗑️ Deleted ${c.name}`); await refreshCookies(); return true;
            } catch(err){ console.debug('[Hide Web Elements Pro] Cookie delete failed:',err); showToast('❌ Could not delete cookie'); return false; }
        }

        async function replaceCookie(oldC,newC) {
            try { await deleteCookieSilently(oldC); const ok=await setCookie(newC); showToast(ok?`✅ Updated ${newC.name}`:'❌ Update failed'); return ok; } catch(err){showToast('❌ Update failed');return false;}
        }
        async function deleteCookieSilently(c){
            if(cookieStoreApi?.delete){ try{await cookieStoreApi.delete({name:c.name,domain:c.domain,path:c.path||'/'});return;}catch{} }
            try{ let s=`${encodeURIComponent(c.name)}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${c.path||'/'}`; if(c.domain)s+=`; domain=${c.domain}`; document.cookie=s; }catch{}
        }

        async function createCookie() {
            const name=cookieNameInput?.value.trim()||'', value=cookieValueInput?.value??'', path=cookiePathInput?.value.trim()||'/';
            if(!name)return showToast('⚠️ Enter cookie name');
            const expires=cookieExpiryInput?.value?new Date(cookieExpiryInput.value).getTime():null;
            if(cookieExpiryInput?.value && !Number.isFinite(expires))return showToast('⚠️ Invalid expiry');
            const ok=await setCookie({name,value,path,domain:location.hostname,expires,secure:!!cookieSecureInput?.checked,sameSite:cookieSameSiteInput?.value||'lax'});
            if(ok){
                [cookieNameInput,cookieValueInput].forEach(x=>{if(x)x.value='';});
                if(cookiePathInput) cookiePathInput.value='/';
                if(cookieExpiryInput) cookieExpiryInput.value='';
                if(cookieSecureInput) cookieSecureInput.checked=false;
                if(cookieSameSiteInput) cookieSameSiteInput.value='lax';
                closeNewCookieComposer();
                showToast(`🍪 Created ${name}`);
                await refreshCookies();
            }
        }

        async function clearAllCookies() {
            if(!cookieCache.length || !confirm(`Delete all ${cookieCache.length} visible cookies for ${location.hostname}?`))return;
            for(const c of [...cookieCache]) await deleteCookieSilently(c);
            showToast(`🧹 Delete requested for ${cookieCache.length} cookies`); await refreshCookies();
        }

        async function exportCookies() {
            const data={version:2,domain:location.hostname,exportedAt:new Date().toISOString(),cookies:cookieCache};
            const blob=new Blob([JSON.stringify(data,null,2)],{type:'application/json'}),url=URL.createObjectURL(blob),a=doc.createElement('a');
            a.href=url;a.download=`cookies_${location.hostname}_${new Date().toISOString().slice(0,10)}.json`;doc.body.appendChild(a);a.click();a.remove();URL.revokeObjectURL(url);showToast('📤 Cookies exported');
        }

        async function importCookies(file) {
            try {
                const data=JSON.parse(await file.text()); const list=Array.isArray(data)?data:(Array.isArray(data.cookies)?data.cookies:[]); if(!list.length)throw new Error('No cookies');
                let ok=0; for(const raw of list){const c=normalizeCookie({...raw,domain:raw.domain||location.hostname});if(c.name&&await setCookie(c))ok++;}
                await refreshCookies(); showToast(`📥 Imported ${ok}/${list.length} cookies`);
            }catch(err){showToast('❌ Invalid cookie JSON');}
        }

        async function refreshCookies() {
            closeCookieEditor(); cookieCache=await readCookies(); renderCookieRows(cookieSearch?.value||'');
        }
        function closeNewCookieComposer(clearFields = true) {
            if (cookieNewEditor) cookieNewEditor.hidden = true;
            cookieAddNewBtn?.setAttribute('aria-expanded', 'false');
            if (clearFields) {
                if (cookieNameInput) cookieNameInput.value = '';
                if (cookieValueInput) cookieValueInput.value = '';
                if (cookiePathInput) cookiePathInput.value = '/';
                if (cookieExpiryInput) cookieExpiryInput.value = '';
                if (cookieSecureInput) cookieSecureInput.checked = false;
                if (cookieSameSiteInput) cookieSameSiteInput.value = 'lax';
            }
        }

        if (cookieAddNewBtn) cookieAddNewBtn.onclick = e => {
            e.stopPropagation();
            const open = !!cookieNewEditor && cookieNewEditor.hidden;
            if (cookieNewEditor) cookieNewEditor.hidden = !open;
            cookieAddNewBtn.setAttribute('aria-expanded', String(open));
            if (open) {
                cookieNameInput?.focus();
                cookieAddNewBtn.textContent = '✕ Close';
                cookieAddNewBtn.classList.remove('btn-green');
                cookieAddNewBtn.classList.add('btn-gray');
            } else {
                closeNewCookieComposer(true);
                cookieAddNewBtn.textContent = '+ Add New';
                cookieAddNewBtn.classList.remove('btn-gray');
                cookieAddNewBtn.classList.add('btn-green');
            }
        };
        if (cookieNewCancel) cookieNewCancel.onclick = e => {
            e.stopPropagation();
            closeNewCookieComposer(true);
            if (cookieAddNewBtn) {
                cookieAddNewBtn.textContent = '+ Add New';
                cookieAddNewBtn.classList.remove('btn-gray');
                cookieAddNewBtn.classList.add('btn-green');
            }
        };
        if(cookieAddBtn)cookieAddBtn.onclick=createCookie;
        if(cookieRefreshBtn)cookieRefreshBtn.onclick=refreshCookies;
        if(cookieClearAll)cookieClearAll.onclick=clearAllCookies;
        if(cookieExportBtn)cookieExportBtn.onclick=exportCookies;
        if(cookieImportBtn)cookieImportBtn.onclick=()=>cookieImportFile?.click();
        if(cookieImportFile)cookieImportFile.onchange=async()=>{if(cookieImportFile.files?.[0]){await importCookies(cookieImportFile.files[0]);cookieImportFile.value='';}};
        if(cookieSearch)cookieSearch.oninput=()=>renderCookieRows(cookieSearch.value);
        [cookieNameInput,cookieValueInput,cookiePathInput].forEach(i=>{
            if (i) i.onkeydown = e => {
                if (e.key === 'Enter') { e.preventDefault(); createCookie(); }
            };
        });
        closeNewCookieComposer(true);
        refreshCookies();
        // ---------- End of Cookie Workspace ----------

        function getAllSettings() {
            const settings = {};
            const knownKeys = [
                'hider_freeze_memory', 'hider_freeze_global', 'hider_blocked_domains',
                'hider_allowed_domains', 'hider_custom_rules_v4', 'hider_auto_time_skipper',
                'hider_auto_scroll', 'hider_enable_contextmenu', 'hider_auto_remove_blur',
                'hider_hidden_dock_buttons', 'hider_global_logs',
                'hider_last_log_clear_day', 'hider_skip_block_confirm', 'hider_dock_y',
                'hider_anti_paywall_level', 'hider_auto_close_modals', 'hider_cookie_consent_mode',
                'hider_auto_close_logins', 'hider_edit_rules_v1'
            ];
            knownKeys.forEach(k => {
                const val = gv(k, undefined);
                if (val !== undefined) settings[k] = val;
            });
            try {
                for (let i = 0; i < localStorage.length; i++) {
                    const key = localStorage.key(i);
                    if (key && (key.startsWith('hider_site_') || key.startsWith('hider_link_') || key.startsWith('hider_edit_site_') || key.startsWith('hider_edit_link_'))) {
                        const val = localStorage.getItem(key);
                        try { settings[key] = JSON.parse(val); } catch { settings[key] = val; }
                    }
                }
            } catch {}
            return settings;
        }
    }

    // ---------- Render List ----------
    function renderList() {
        if (!shadowRoot) return;
        if (!CACHE.logs) CACHE.logs = gv('hider_global_logs', []);
        const siteKey = 'hider_site_' + location.hostname, linkKey = 'hider_link_' + cleanUrl();
        const siteData = gv(siteKey, []), linkData = gv(linkKey, []);

        const cCustom = shadowBy('list-custom-rules'), cAllowed = shadowBy('list-allowed-domains'), cDomains = shadowBy('list-blocked-domains'), cSite = shadowBy('list-site'), cLink = shadowBy('list-link'), cLog = shadowBy('list-blocked-log');
        const cEditGlobal=shadowBy('list-edit-global'), cEditSite=shadowBy('list-edit-site'), cEditPage=shadowBy('list-edit-page');
        if (!cSite || !cLink) return;

        ['cnt-custom', 'cnt-allowed', 'cnt-domains', 'cnt-logs', 'cnt-site', 'cnt-link'].forEach((id, i) => {
            const el = shadowBy(id);
            if(el) el.textContent = [CACHE.customRules.length, CACHE.allowedDomainsList.length, CACHE.blockedDomainsList.length, CACHE.logs.length, siteData.length, linkData.length][i];
        });

        const buildFrag = (arr, emptyMsg, renderItem) => {
            const frag = doc.createDocumentFragment();
            if (!arr.length) { const d = doc.createElement('div'); d.style.cssText = 'font-size:9px!important;color:#94a3b8!important;padding:4px!important;text-align:center!important;border:1px dashed rgba(255,255,255,0.12)!important;border-radius:6px!important;'; d.textContent = emptyMsg; frag.appendChild(d); return frag; }
            arr.forEach((item, i) => frag.appendChild(renderItem(item, i))); return frag;
        };

        if (cCustom) {
            cCustom.innerHTML = '';
            cCustom.appendChild(buildFrag(CACHE.customRules, 'No global rules yet \u2014 tap ➕ Add Rule to type a CSS selector.', (rule, idx) => {
                const enabled = rule.enabled !== false;
                const div = doc.createElement('div'); div.className = 'list-item';
                div.style.opacity = enabled ? '1' : '.55';
                div.innerHTML = `<span class="rule-text" title="${rule.selector}">${rule.selector} <span style="color:${rule.target === '*' ? '#38bdf8' : '#34d399'}!important; font-weight:bold!important;">[${rule.target}]</span>${enabled ? '' : ' <span style="color:#94a3b8!important;font-weight:900!important;">[PAUSED]</span>'}</span><div style="display:flex;gap:2px"><button class="hider-btn-small ${enabled ? 'btn-gray' : 'btn-green'} btn-toggle" title="${enabled ? 'Pause rule' : 'Resume rule'}">${enabled ? '⏸️' : '▶️'}</button><button class="hider-btn-small btn-blue btn-edit" title="Edit rule">✏️</button><button class="hider-btn-small btn-red btn-del" title="Delete rule">✖</button></div>`;
                div.querySelector('.btn-toggle').onclick = () => {
                    rule.enabled = !enabled;
                    sv('hider_custom_rules_v4', CACHE.customRules);
                    requestUpdateStyles(); renderList();
                    showToast(rule.enabled ? '▶️ Rule resumed' : '⏸️ Rule paused');
                };
                div.querySelector('.btn-edit').onclick = () => {
                    showRuleOverlay({
                        mode: 'edit',
                        selector: rule.selector,
                        scope: 'global',
                        target: rule.target,
                        editInfo: { listType: 'custom', id: rule.id, index: idx }
                    });
                };
                div.querySelector('.btn-del').onclick = () => {
                    CACHE.customRules = CACHE.customRules.filter(r => r.id !== rule.id);
                    sv('hider_custom_rules_v4', CACHE.customRules);
                    requestUpdateStyles(); renderList();
                    showToast('🗑️ Rule removed');
                };
                return div;
            }));
        }

        if (cAllowed) {
            cAllowed.innerHTML = '';
            cAllowed.appendChild(buildFrag(CACHE.allowedDomainsList, 'No allowed domains', (d, i) => {
                const div = doc.createElement('div'); div.className = 'list-item'; div.innerHTML = `<span class="rule-text" title="${d}">${d}</span><button class="hider-btn-small btn-red">✖</button>`;
                div.querySelector('button').onclick = () => {
                    CACHE.allowedDomainsList.splice(i, 1);
                    CACHE.allowedDomainsSet.delete(cleanDomain(d));
                    sv('hider_allowed_domains', CACHE.allowedDomainsList);
                    renderList();
                    showToast('🟢 Allowed domain removed');
                };
                return div;
            }));
        }

        if (cDomains) {
            cDomains.innerHTML = '';
            cDomains.appendChild(buildFrag(CACHE.blockedDomainsList, 'No blocked domains', (d, i) => {
                const div = doc.createElement('div'); div.className = 'list-item'; div.innerHTML = `<span class="rule-text" title="${d}">${d}</span><button class="hider-btn-small btn-red">✖</button>`;
                div.querySelector('button').onclick = () => {
                    CACHE.blockedDomainsList.splice(i, 1);
                    CACHE.blockedDomainsSet.delete(cleanDomain(d));
                    sv('hider_blocked_domains', CACHE.blockedDomainsList);
                    renderList();
                    showToast('🚫 Blocked domain removed');
                };
                return div;
            }));
        }

        const openEditRuleInMenu=(row,rule,scope)=>{
            const host=row?.parentElement;
            if(!host)return;
            host.querySelectorAll('.hx-edit-menu-editor').forEach(x=>x.remove());
            const targetEl=(()=>{try{return rule?.selector?doc.querySelector(rule.selector):null;}catch{return null;}})();
            const editor=doc.createElement('div'); editor.className='hx-card hx-edit-menu-editor'; editor.style.cssText='margin:5px 0 2px;padding:10px;border-color:rgba(56,189,248,.16);background:linear-gradient(145deg,rgba(56,189,248,.055),rgba(167,139,250,.035));';
            const head=doc.createElement('div'); head.style.cssText='display:flex;justify-content:space-between;gap:8px;align-items:flex-start;margin-bottom:7px;';
            const title=doc.createElement('div'); title.textContent='Edit saved rule'; title.style.cssText='font-size:10px;font-weight:900;color:#eaf7ff;';
            const badge=doc.createElement('span'); badge.className='hx-chip'; badge.textContent=(rule.kind||'text').toUpperCase()+' · '+scope.toUpperCase(); head.append(title,badge); editor.appendChild(head);
            const preview=doc.createElement('div'); preview.className='hx-edit-live-preview'; preview.style.cssText='min-height:42px;padding:9px 10px;border-radius:10px;border:1px solid rgba(148,163,184,.10);background:rgba(2,6,23,.36);margin-bottom:7px;overflow:auto;';
            let mediaFile=null, mediaUrl=null, input=null;
            const typography=rule.typography||(targetEl?captureEditTypography(targetEl):null); if(typography)applyEditTypography(preview,typography);
            if(rule.kind==='media'){
                const mediaTag=targetEl?.tagName?.toLowerCase()==='video'?'video':targetEl?.tagName?.toLowerCase()==='audio'?'audio':'img';
                const media=doc.createElement(mediaTag); media.style.cssText='display:block;max-width:100%;max-height:180px;margin:auto;object-fit:contain;'; preview.textContent=''; preview.appendChild(media);
                if(rule.mediaRef){getEditMedia(rule.mediaRef).then(b=>{if(!b)return;try{const u=URL.createObjectURL(b);media.src=u;}catch{}});}
                else media.src=rule.value||'';
                const row1=doc.createElement('div'); row1.style.cssText='display:grid;grid-template-columns:1fr 1fr;gap:5px;';
                const choose=doc.createElement('button'); choose.className='hider-edit-source-btn'; choose.textContent='📁 Choose File';
                mediaFile=doc.createElement('input'); mediaFile.type='file'; mediaFile.accept='image/*,video/*,audio/*'; mediaFile.hidden=true;
                choose.onclick=e=>{e.stopPropagation();mediaFile.click();}; mediaFile.onchange=()=>{const f=mediaFile.files?.[0];if(!f)return;const u=URL.createObjectURL(f);mediaUrl=u;media.src=u;};
                const urlBtn=doc.createElement('button'); urlBtn.className='hider-edit-source-btn'; urlBtn.textContent='🔗 URL';
                const urlInput=doc.createElement('input'); urlInput.className='hider-edit-url'; urlInput.placeholder='Paste media URL…'; urlInput.value=rule.value||''; urlInput.hidden=!(rule.value||'');
                urlBtn.onclick=e=>{e.stopPropagation();urlInput.hidden=!urlInput.hidden;if(!urlInput.hidden)urlInput.focus();}; urlInput.oninput=()=>{mediaUrl=urlInput.value.trim();media.src=mediaUrl;};
                row1.append(choose,urlBtn); editor.append(row1,urlInput); editor.appendChild(preview);
            }else{
                input=doc.createElement(rule.kind==='value'?'input':'textarea'); input.className='hx-input'; input.style.cssText='width:100%;min-height:38px;padding:8px;border-radius:9px;font-size:9px;';
                input.value=rule.kind==='value'?(rule.value||''):(rule.value||''); input.rows=3;
                const updatePreview=()=>{preview.innerHTML='';if(targetEl&&rule.kind==='text'){preview.appendChild(buildTypographyAwarePreview(targetEl,input.value||'Preview',typography,rule.textPatches));}else{preview.textContent=input.value||'Preview';if(typography)applyEditTypography(preview,typography);}}; input.oninput=updatePreview; updatePreview(); editor.appendChild(input); editor.appendChild(preview);
            }
            const actions=doc.createElement('div'); actions.style.cssText='display:flex;justify-content:flex-end;gap:5px;margin-top:7px;';
            const cancel=doc.createElement('button'); cancel.className='hider-btn-small btn-gray'; cancel.textContent='❌'; cancel.title='Cancel';
            const save=doc.createElement('button'); save.className='hider-btn-small btn-green'; save.textContent='✅'; save.title='Save changes';
            cancel.onclick=e=>{e.stopPropagation();editor.remove();};
            save.onclick=async e=>{e.stopPropagation();
                const rules=readEditRules(scope); const idx=rules.findIndex(x=>x.id===rule.id); if(idx<0){editor.remove();return;}
                const oldMediaRef=rules[idx].mediaRef||''; let next={...rules[idx],updatedAt:Date.now(),typography:rule.typography||typography||null};
                if(rule.kind==='media'){
                    let ref=''; let value=(mediaUrl!==null?mediaUrl:(urlInput?.value||rule.value||'').trim());
                    if(mediaFile?.files?.[0]){const id='editmedia_'+Date.now()+'_'+Math.random().toString(36).slice(2,7);if(await putEditMedia(id,mediaFile.files[0]))ref=id;}
                    next.mediaRef=ref; next.value=ref?'':value;
                    if(ref){const b=await getEditMedia(ref);if(b&&media.src){try{URL.revokeObjectURL(media.src.startsWith('blob:')?media.src:'')}catch{}}}
                }else{next.value=String(input?.value??rule.value??''); if(next.kind==='text'&&targetEl){const firstNode=findPrimaryTextNode(targetEl); next.textPatches=[{index:0,path:getTextNodePath(targetEl,firstNode),value:next.value}].filter(x=>Number.isInteger(x.index)||Array.isArray(x.path));next.textNodePath=next.textPatches[0]?.path||rule.textNodePath||null;next.textTypography=getEditableTextNodes(targetEl).map((t,index)=>({index,path:getTextNodePath(targetEl,t),typography:captureEditTypography(t.parentElement||targetEl)})).filter(x=>x.typography);next.html='';}}
                rules[idx]=next; writeEditRules(scope,rules); if(oldMediaRef&&oldMediaRef!==next.mediaRef)await deleteEditMedia(oldMediaRef); setupEditObserver(); renderList(); showToast('✅ Saved edit updated');
            };
            actions.append(cancel,save); editor.appendChild(actions); host.appendChild(editor); row.scrollIntoView?.({block:'nearest'}); return true;
        };

        const renderEditList=(c,arr,empty)=>{if(!c)return;c.innerHTML='';if(!arr.length){const d=doc.createElement('div');d.className='hx-empty';d.textContent=empty;c.appendChild(d);return;}arr.forEach(r=>{const d=doc.createElement('div');d.className='list-item hx-edit-rule-row';const wrap=doc.createElement('div');wrap.style.cssText='min-width:0;flex:1;';const t=doc.createElement('span');t.className='rule-text';t.title=r.selector;t.textContent=`${r.kind==='media'?'MEDIA':r.kind==='value'?'VALUE':'TEXT'} · ${r.selector}`;const v=doc.createElement('div');v.className='hx-edit-rule-value';v.textContent=r.kind==='media'?(r.mediaRef?'Stored media':'URL media'):(r.kind==='value'?(r.value||''):(typeof r.value==='string'?r.value:''));wrap.append(t,v);const actions=doc.createElement('div');actions.style.cssText='display:flex;gap:4px;flex:0 0 auto;';const edit=doc.createElement('button');edit.className='hider-btn-small btn-blue';edit.textContent='✎';edit.title='Edit this saved edit';edit.onclick=e=>{e.stopPropagation();openEditRuleInMenu(d,r,r.scope||'site');};const del=doc.createElement('button');del.className='hider-btn-small btn-red';del.textContent='✖';del.title='Delete saved edit';del.onclick=async()=>{writeEditRules(r.scope||'site',readEditRules(r.scope||'site').filter(x=>x.id!==r.id));if(r.mediaRef)await deleteEditMedia(r.mediaRef);setupEditObserver();renderList();};actions.append(edit,del);d.append(wrap,actions);c.appendChild(d);});};
        const editGlobalArr=readEditRules('global'), editSiteArr=readEditRules('site'), editPageArr=readEditRules('link');
        ['cnt-edit-global','cnt-edit-site','cnt-edit-page'].forEach((id,i)=>{const el=shadowBy(id); if(el) el.textContent=[editGlobalArr.length,editSiteArr.length,editPageArr.length][i];});
        renderEditList(cEditGlobal,editGlobalArr,'No global edits yet.');
        renderEditList(cEditSite,editSiteArr,'No site edits \u2014 tap ➕ New Edit above, or the Edit dock button, then pick an element.');
        renderEditList(cEditPage,editPageArr,'No page edits yet.');
        const clearEditCurrent=shadowBy('clear-edit-current');if(clearEditCurrent)clearEditCurrent.onclick=()=>{sv(EDIT_SITE_PREFIX+location.hostname,[]);sv(EDIT_LINK_PREFIX+cleanUrl(),[]);setupEditObserver();renderList();showToast('🧹 Current edits cleared');};

        if (cLog) {
            cLog.innerHTML = '';
            cLog.appendChild(buildFrag(CACHE.logs, 'No logs today', item => {
                const row = doc.createElement('div'); row.style.cssText = 'font-size:9px!important;border-bottom:1px solid rgba(255,255,255,0.08)!important;padding:2px 0!important;';
                row.innerHTML = `<div style="display:flex;justify-content:space-between;color:#6ee7b7!important;font-weight:700!important;"><span>${item.type}</span><span style="color:#94a3b8!important;font-weight:normal!important;">${item.time}</span></div><div style="color:#cbd5e1!important;word-break:break-all!important;font-family:monospace!important;opacity:0.8;">${item.url}</div>`; return row;
            }));
        }

        const renderEditableHiddenItems = (data, key, container) => {
            container.innerHTML = '';
            container.appendChild(buildFrag(data, 'None', (sel, i) => {
                const div = doc.createElement('div'); div.className = 'list-item';
                div.innerHTML = `<span class="rule-text" title="${sel}">${sel}</span><div style="display:flex;gap:2px;align-items:center"><button class="hider-btn-small btn-blue btn-edit" title="Edit Rule Inline">✏️</button><button class="hider-btn-small btn-purple btn-wild" title="Convert Wildcard">🪄</button><button class="hider-btn-small btn-red btn-del" title="Delete Rule">✖</button></div>`;
                const textSpan = div.querySelector('.rule-text'), editBtn = div.querySelector('.btn-edit');

                editBtn.onclick = () => {
                    let scope = 'site';
                    let target = location.hostname;
                    if (key === linkKey) {
                        scope = 'link';
                        target = cleanUrl();
                    }
                    const listType = (key === siteKey) ? 'site' : 'link';
                    showRuleOverlay({
                        mode: 'edit',
                        selector: sel,
                        scope: scope,
                        target: target,
                        editInfo: { listType: listType, index: i }
                    });
                };

                div.querySelector('.btn-wild').onclick = () => {
                    data[i] = convertToWildcardSelector(data[i]);
                    sv(key, data); requestUpdateStyles(); renderList();
                    showToast(`🪄 Wildcard applied`);
                };
                div.querySelector('.btn-del').onclick = () => {
                    const removed = data.splice(i, 1)[0]; sv(key, data);
                    requestUpdateStyles(); renderList();
                    showToast('🗑️ Hidden rule removed');
                };
                return div;
            }));
        };

        renderEditableHiddenItems(siteData, siteKey, cSite); renderEditableHiddenItems(linkData, linkKey, cLink);

        // Re-apply any active search filters since the containers above were
        // just rebuilt from scratch (innerHTML reset clears row visibility state).
        shadowBy('rules-search')?._applyFilter?.();
        shadowBy('domains-search')?._applyFilter?.();
        shadowBy('edit-search')?._applyFilter?.();

        updateFreezeStatusCard();
        renderDockButtonOptions();
        applyDockButtonVisibility();
    }

    // ---------- Navigation Click Handler ----------
    function handleNavigationClick(e) {
        const path = e.composedPath?.() || [];
        if (isSelecting || path.some(el => el.id === UI_HOST_ID || el.id === STEPPER_BAR_ID)) return;
        const link = e.target.closest('a[href], area[href]');
        if (link?.href) {
            const rawHref = link.getAttribute('href') || '';
            if (rawHref.startsWith('#') || rawHref.toLowerCase().startsWith('javascript:')) return;
            const targetUrl = link.href;
            if (isDomainBlocked(targetUrl)) {
                e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
                logBlockedAttempt(targetUrl, 'Blocked Link Click'); simulateAdWindowSuccess(); showToast('⛔ Force Blocked'); return;
            }
            if (!isFrozen || isDomainAllowed(targetUrl)) return;

            e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
            const isNewTab = link.target === '_blank' || e.ctrlKey || e.metaKey || e.button === 1;
            handleFreezeNavigation(targetUrl, 'Link Click', () => {
                userApprovedNavigation = true; if (isNewTab) win.open(targetUrl, '_blank'); else win.location.href = targetUrl;
                setTimeout(() => userApprovedNavigation = false, 300);
            }, simulateAdWindowSuccess);
        }
    }

    // ---------- Scroll auto-close ----------
    // Never close the script UI merely because the user scrolled the page.
    // Page scrolling is unrelated to our dock/menu state and doing this breaks
    // real site search boxes, navigation drawers and sticky panels.
    function setupScrollAutoClose() {
        // Preserve the original working behavior: scrolling the page closes
        // script-owned menus/dock UI. Use RAF to avoid repeated close work on
        // high-frequency mobile scroll events. Do not touch site-owned UI.
        win.addEventListener('scroll', () => {
            if (scrollAnimationFrame) return;
            scrollAnimationFrame = win.requestAnimationFrame(() => {
                scrollAnimationFrame = null;
                if (isSelecting || isDraggingDock || isDraggingStepper) return;
                closeAllMenus(null);
                closePreviewModal();
            });
        }, { passive: true, capture: true });
    }

    // ---------- Selection mode blockers ----------
    ['mousedown', 'pointerdown', 'mouseup'].forEach(evtType => {
        window.addEventListener(evtType, e => {
            if (!isSelecting) return;
            const path=e.composedPath?.()||[];
            if (path.some(el => el.id === UI_HOST_ID || el.id === STEPPER_BAR_ID)) return;
            if(selectionMode==='edit'&&editEditingActive&&previewElement&&path.includes(previewElement)) return;
            e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
        }, true);
    });

    // ---------- Click / mobile tap handling ----------
    // Close script UI on a genuine outside activation, but NEVER on a scroll gesture.
    // Mobile browsers may synthesize a click after touchend, so the gesture state is
    // shared by both handlers and a single tap is handled only once.
    let outsideTouchX = 0, outsideTouchY = 0;
    let outsideTouchMoved = false;
    let outsideTouchActive = false;
    let outsideTouchIsUI = false;
    let lastTouchCloseAt = 0;

    const getEventPath = e => {
        try { return e?.composedPath?.() || []; } catch { return []; }
    };

    const pathIsHiderUI = path => path.some(el => el && (
        el.id === UI_HOST_ID || el.id === STEPPER_BAR_ID ||
        (el.closest && el.closest('#' + UI_HOST_ID))
    ));

    const closeMenusFromOutsideActivation = e => {
        if (isSelecting || isDraggingDock || isDraggingStepper) return;
        const path = getEventPath(e);
        if (pathIsHiderUI(path)) return;
        closeAllMenus(e);
        shadowRoot?.querySelectorAll('.h-custom-select').forEach(c => c.classList.remove('is-open'));
    };

    window.addEventListener('touchstart', e => {
        const t = e.touches?.[0];
        if (!t) return;
        outsideTouchX = t.clientX;
        outsideTouchY = t.clientY;
        outsideTouchMoved = false;
        outsideTouchActive = true;
        outsideTouchIsUI = pathIsHiderUI(getEventPath(e));
    }, { passive: true, capture: true });

    window.addEventListener('touchmove', e => {
        if (!outsideTouchActive) return;
        const t = e.touches?.[0];
        if (!t) return;
        const distance = Math.hypot(t.clientX - outsideTouchX, t.clientY - outsideTouchY);
        if (distance > 12) outsideTouchMoved = true;
    }, { passive: true, capture: true });

    window.addEventListener('touchcancel', () => {
        outsideTouchActive = false;
        outsideTouchMoved = false;
        outsideTouchIsUI = false;
    }, { passive: true, capture: true });

    window.addEventListener('touchend', e => {
        if (!outsideTouchActive) return;
        const wasMoved = outsideTouchMoved;
        const wasUI = outsideTouchIsUI || pathIsHiderUI(getEventPath(e));
        outsideTouchActive = false;
        outsideTouchMoved = false;
        outsideTouchIsUI = false;

        // A swipe/scroll is never an outside activation.
        if (wasMoved || wasUI) return;

        lastTouchCloseAt = Date.now();
        closeMenusFromOutsideActivation(e);
    }, { passive: true, capture: true });

    // Desktop clicks and the click synthesized by a mobile tap.
    window.addEventListener('click', e => {
        const path = getEventPath(e);
        const isUI = pathIsHiderUI(path);
        if (!isUI) {
            // If this click was synthesized from our already-processed touch tap,
            // don't execute the close operation twice. Navigation handling below is
            // still allowed to run normally.
            if (Date.now() - lastTouchCloseAt > 500) {
                closeMenusFromOutsideActivation(e);
            }
            shadowRoot?.querySelectorAll('.h-custom-select').forEach(c => c.classList.remove('is-open'));
        }
        if (isUI) return;

        handleNavigationClick(e);
        if (!isSelecting) return;

        e.preventDefault(); e.stopPropagation();
        const target = e.target?.nodeType === Node.ELEMENT_NODE ? e.target : e.target?.parentElement;
        if(!target || target === doc.documentElement || target === doc.body && selectionMode==='edit') return;
        if (previewElement === target) { if(selectionMode==='edit') ensureEditControlPanel(); else confirmHideSelectedElement(); }
        else {
            previewElement?.classList.remove('hider-preview-highlight'); stepperStack = [];
            previewElement = target;
            editOriginalCaptured=false;
            previewElement.classList.add('hider-preview-highlight');
            renderTouchStepperUI();
            if(selectionMode==='edit') {
                ensureEditControlPanel();
                if(typeof win.requestAnimationFrame==='function') {
                    win.requestAnimationFrame(() => {
                        if(isSelecting&&selectionMode==='edit'&&previewElement===target) ensureEditControlPanel();
                    });
                } else {
                    setTimeout(() => { if(isSelecting&&selectionMode==='edit'&&previewElement===target) ensureEditControlPanel(); },0);
                }
            }
        }
    }, true);

    window.addEventListener('auxclick', handleNavigationClick, true);

    window.addEventListener('submit', e => {
        const path = e.composedPath?.() || [];
        if (path.some(el => el.id === UI_HOST_ID || el.id === STEPPER_BAR_ID)) return;
        const form = e.target, action = form.action || location.href;
        if (isDomainBlocked(action)) {
            e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
            logBlockedAttempt(action, 'Blocked Form Submit'); simulateAdWindowSuccess(); showToast('⛔ Blocked Form'); return;
        }
        if (!isFrozen || isDomainAllowed(action)) return;
        e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
        handleFreezeNavigation(action, 'Form Submit', () => { userApprovedNavigation = true; form.submit(); setTimeout(() => userApprovedNavigation = false, 300); }, simulateAdWindowSuccess);
    }, true);

    window.addEventListener('touchstart', e => {
        if (!e.touches?.[0]) return;
        const x = e.touches[0].clientX;
        // Only mark edge touches as navigation intent. Ordinary taps/scrolls must not
        // alter freeze state or interfere with the script UI.
        if (x <= 24 || x >= (win.innerWidth - 24)) {
            userApprovedNavigation = true;
            setTimeout(() => { userApprovedNavigation = false; }, 900);
        }
    }, { passive: true, capture: true });

    // ---------- History navigation ----------
    ['back', 'forward', 'go'].forEach(method => {
        const orig = history[method];
        if (orig) { history[method] = function() { userApprovedNavigation = true; setTimeout(() => { userApprovedNavigation = false; }, 1000); return orig.apply(this, arguments); }; }
    });

    try { win.navigation?.addEventListener('navigate', e => { if (e.navigationType === 'traverse' || e.navigationType === 'reload') { userApprovedNavigation = true; setTimeout(() => { userApprovedNavigation = false; }, 1000); } }); } catch {}

    win.addEventListener('beforeunload', e => {
        if (userApprovedNavigation) return;
        if (isFrozen && !isDomainAllowed(location.href) && (CACHE.freezeMemory === 'ask' || CACHE.freezeMemory === 'block_all')) { e.preventDefault(); return (e.returnValue = 'Page navigation is currently frozen site-wide.'); }
    }, true);

    // ---------- URL change detection (SMART) ----------
    const checkUrlChange = () => {
        if (location.href !== lastUrl) {
            lastUrl = location.href;
            updateCurrentLocCache();
            setupEditObserver();
            requestUpdateStyles(false);
            if (shadowBy('hider-panel')?.classList.contains('is-visible')) renderList();
        }
    };

    window.addEventListener('pageshow', (e) => {
        if (e.persisted || e.type === 'pageshow') {
            requestUpdateStyles(true);
        }
    }, { passive: true });

    ['pushState', 'replaceState'].forEach(fn => {
        const orig = history[fn];
        if (orig) history[fn] = function() {
            orig.apply(this, arguments);
            checkUrlChange();
        };
    });
    window.addEventListener('popstate', () => {
        userApprovedNavigation = true;
        checkUrlChange();
        setTimeout(() => { userApprovedNavigation = false; }, 500);
    }, { passive: true });
    window.addEventListener('hashchange', checkUrlChange, { passive: true });

    // ---------- Low-power heartbeat ----------
    function setupLowPowerHeartbeat() {
        const scheduleIdle = fn => (win.requestIdleCallback ? win.requestIdleCallback(fn, { timeout: 2000 }) : setTimeout(fn, 1000));
        const performHealthCheck = () => {
            if (isTop && !doc.getElementById(UI_HOST_ID)) createShadowUI();
            if (!doc.getElementById('hider-dynamic-styles')) requestUpdateStyles();
            if (!isTop) try { window.top.postMessage({ type: 'HIDER_REQUEST_STATE' }, '*'); } catch {}
            scheduleIdle(performHealthCheck);
        };
        scheduleIdle(performHealthCheck);
    }

    // ---------- Init ----------
    function init() {
        updateCurrentLocCache();
        installInterceptors();
        createShadowUI();
        requestUpdateStyles(true);
        setupScrollAutoClose();
        setupLowPowerHeartbeat();
        setupAboutLiveRefresh();
        setupProtectionObserver();
        applyAllSettings();
        if (CACHE.autoTimeSkipper && featuresEnabled && !isMediaSensitiveDomain()) {
            startAutoSkipMonitoring();
        }
    }

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