Hide Web Elements Pro

Stealth element hider, Shadow DOM UI, persistent freeze, link extractor, time skipper, enhanced reveal, dock button visibility, stable Reveal & Unblock Engine, plus media downloader with preview. Automatic Protection. Now with Anti-Paywall, Auto-Close Modals (smart skip for essential UI incl. side menus), Auto-Accept Age Verification, Auto-Close Logins, Cookie Bypass, Bulk Filter Lists, and improved UI.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

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

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

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

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name         Hide Web Elements Pro
// @version      14.1
// @description  Stealth element hider, Shadow DOM UI, persistent freeze, link extractor, time skipper, enhanced reveal, dock button visibility, stable Reveal & Unblock Engine, plus media downloader with preview. Automatic Protection. Now with Anti-Paywall, Auto-Close Modals (smart skip for essential UI incl. side menus), Auto-Accept Age Verification, Auto-Close Logins, Cookie Bypass, Bulk Filter Lists, and improved UI.
// @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,
        antiPaywall: gv('hider_anti_paywall', false),
        autoCloseModals: gv('hider_auto_close_modals', false),
        cookieConsentMode: gv('hider_cookie_consent_mode', 'ask'),
        autoAcceptAge: gv('hider_auto_accept_age', false),
        autoCloseLogins: gv('hider_auto_close_logins', false),
        filterLists: gv('hider_filter_lists', [])
    };

    // ---------- Dock Button Visibility ----------
    const DOCK_BUTTONS = [
        { id: 'btn-select', label: '🎯 Hide' },
        { id: 'btn-scope', label: '🌐 Scope' },
        { id: 'btn-reveal-quick', label: '👁️ Reveal' },
        { id: 'btn-links', label: '🔗 Links' },
        { id: 'btn-skip-30', label: '⏩ +30s' },
        { id: 'btn-freeze', label: '❄️ Freeze' }
    ];

    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');
        if (!container) return;
        const hidden = new Set(getHiddenDockButtons());
        container.innerHTML = '';
        container.style.cssText = 'display:grid!important;grid-template-columns:repeat(auto-fill,minmax(80px,1fr))!important;gap:4px!important;';
        DOCK_BUTTONS.forEach(btn => {
            const label = document.createElement('label');
            label.style.cssText = 'font-size:9px!important;color:#cbd5e1!important;display:flex!important;align-items:center!important;gap:4px!important;cursor:pointer!important;user-select:none!important;background:rgba(255,255,255,0.05)!important;padding:2px 6px!important;border-radius:4px!important;border:1px solid rgba(255,255,255,0.06)!important;';
            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.dataset.btnId = btn.id;
            checkbox.checked = !hidden.has(btn.id);
            checkbox.style.cssText = 'accent-color:#38bdf8;cursor:pointer;width:12px!important;height:12px!important;flex-shrink:0!important;';
            checkbox.addEventListener('change', function() {
                const id = this.dataset.btnId;
                let hiddenArr = getHiddenDockButtons();
                if (this.checked) {
                    hiddenArr = hiddenArr.filter(h => h !== id);
                } else {
                    if (!hiddenArr.includes(id)) hiddenArr.push(id);
                }
                setHiddenDockButtons(hiddenArr);
                applyDockButtonVisibility();
            });
            label.appendChild(checkbox);
            const span = document.createElement('span');
            span.textContent = btn.label;
            span.style.cssText = 'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;';
            label.appendChild(span);
            container.appendChild(label);
        });
    }

    // ---------- 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;

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

    // ---------- Auto Time Skipper State ----------
    let autoSkipInterval = null;
    let autoSkipEmptyCount = 0;
    const AUTO_SKIP_INTERVAL_MS = 1000;
    const AUTO_SKIP_MAX_EMPTY = 4;

    // ---------- Cleanup ----------
    const timers = {
        scrollInterval: null,
        blurInterval: null,
        protectionPoller: null,
        logSaveTimer: null,
        collapseTimer: null,
        paywallObserverTimer: null,
        modalObserverTimer: null,
        cookieObserverTimer: null
    };
    const observers = {
        protectionObserver: null,
        blurObserver: null,
        urlChangeObserver: null,
        paywallObserver: null,
        modalObserver: null,
        cookieObserver: null,
        adSkipObserver: null,
        headMutationObserver: 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;
            }
        });
        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();
    }

    window.addEventListener('beforeunload', dispose);

    // ---------- Context Menu Override ----------
    const contextMenuHandler = function(e) {
        if (!CACHE.enableContextMenu) return;
        const path = e.composedPath ? e.composedPath() : [];
        if (path.some(el => el.id === UI_HOST_ID || (el.closest && el.closest('#' + UI_HOST_ID)))) {
            e.stopPropagation();
            return;
        }
    };
    document.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 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 = ['facebook.com', 'fb.com', 'facebook'];
    let blacklistToastShown = false;

    function isFeatureBlacklisted() {
        if (!CURRENT_DOMAIN) return false;
        return FEATURE_BLACKLIST.some(domain => 
            CURRENT_DOMAIN.includes(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) {
            applyAllSettings();
            requestUpdateStyles();
        }
    }

    function setupProtectionObserver() {
        if (observers.protectionObserver) return;
        observers.protectionObserver = new MutationObserver(() => {
            const was = isProtected;
            updateProtectionFlag();
            if (was !== isProtected) {
                applyAllSettings();
                requestUpdateStyles();
            }
        });
        observers.protectionObserver.observe(doc.documentElement, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeOldValue: false
        });

        let checks = 0;
        const rapidInterval = setInterval(() => {
            checks++;
            const was = isProtected;
            updateProtectionFlag();
            if (was !== isProtected) {
                applyAllSettings();
                requestUpdateStyles();
            }
            if (checks >= 10) clearInterval(rapidInterval);
        }, 1000);
        timers.protectionPoller = rapidInterval;

        if (!window.__hider_protection_poller) {
            window.__hider_protection_poller = setInterval(() => {
                const was = isProtected;
                updateProtectionFlag();
                if (was !== isProtected) {
                    applyAllSettings();
                    requestUpdateStyles();
                }
            }, 5000);
        }
    }

    // ---------- Scroll Defeater ----------
    function forceEnableScroll() {
        if (!CACHE.autoScroll) return;
        if (isFeatureBlacklisted() || !featuresEnabled) return;
        const html = doc.documentElement, body = doc.body;
        if (!html && !body) return;
        if (!styleElements.scrollStyleEl) {
            styleElements.scrollStyleEl = doc.createElement('style');
            styleElements.scrollStyleEl.id = 'hider-force-scroll-style';
            (doc.head || doc.documentElement)?.appendChild(styleElements.scrollStyleEl);
        }
        styleElements.scrollStyleEl.textContent = `
            html, body {
                overflow: auto !important;
                overflow-x: auto !important;
                overflow-y: auto !important;
                position: static !important;
                height: auto !important;
                max-height: none !important;
                touch-action: auto !important;
                -webkit-overflow-scrolling: touch !important;
            }
        `;
    }

    function checkAndAutoUnblockScroll() {
        if (!CACHE.autoScroll || isFeatureBlacklisted() || !featuresEnabled) {
            stopScrollDefeater();
            return;
        }
        const html = doc.documentElement, body = doc.body;
        if (!html || !body) return;
        try {
            const hStyle = win.getComputedStyle(html), bStyle = win.getComputedStyle(body);
            if (
                hStyle.overflow === 'hidden' || hStyle.overflowY === 'hidden' ||
                bStyle.overflow === 'hidden' || bStyle.overflowY === 'hidden' ||
                bStyle.position === 'fixed' || hStyle.position === 'fixed'
            ) {
                forceEnableScroll();
            }
        } catch {}
    }

    function startScrollDefeater() {
        if (isFeatureBlacklisted() || !featuresEnabled) {
            stopScrollDefeater();
            return;
        }
        if (timers.scrollInterval) clearInterval(timers.scrollInterval);
        if (CACHE.autoScroll) {
            forceEnableScroll();
            timers.scrollInterval = setInterval(checkAndAutoUnblockScroll, 2000);
        }
    }

    function stopScrollDefeater() {
        if (timers.scrollInterval) {
            clearInterval(timers.scrollInterval);
            timers.scrollInterval = null;
        }
        if (styleElements.scrollStyleEl) {
            styleElements.scrollStyleEl.remove();
            styleElements.scrollStyleEl = 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 removeBlurFromElements() {
        if (!CACHE.autoRemoveBlur || isFeatureBlacklisted() || !featuresEnabled) {
            stopBlurRemoval();
            return;
        }
        const all = doc.querySelectorAll('*');
        const uiHost = doc.getElementById(UI_HOST_ID);
        for (const el of all) {
            if (el === uiHost || (el.closest && el.closest('#' + UI_HOST_ID))) continue;
            try {
                const style = win.getComputedStyle(el);
                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');
                }
                if (el.style.filter && el.style.filter.includes('blur')) {
                    el.style.setProperty('filter', 'none', 'important');
                }
                if (el.style.backdropFilter && el.style.backdropFilter.includes('blur')) {
                    el.style.setProperty('backdrop-filter', 'none', 'important');
                    el.style.setProperty('-webkit-backdrop-filter', 'none', 'important');
                }
            } catch {}
        }
    }

    function scheduleBlurRemoval() {
        if (isFeatureBlacklisted() || !featuresEnabled) {
            stopBlurRemoval();
            return;
        }
        if (CACHE.autoRemoveBlur && !styleElements.blurGlobalStyle) {
            styleElements.blurGlobalStyle = doc.createElement('style');
            styleElements.blurGlobalStyle.id = 'hider-blur-global-style';
            styleElements.blurGlobalStyle.textContent = `
                *:not(#hider-ui-root):not(#hider-ui-root *) {
                    filter: none !important;
                    backdrop-filter: none !important;
                    -webkit-backdrop-filter: none !important;
                }
            `;
            (doc.head || doc.documentElement)?.appendChild(styleElements.blurGlobalStyle);
        } else if (!CACHE.autoRemoveBlur && styleElements.blurGlobalStyle) {
            styleElements.blurGlobalStyle.remove();
            styleElements.blurGlobalStyle = null;
        }

        if (timers.blurInterval) clearInterval(timers.blurInterval);
        if (CACHE.autoRemoveBlur) {
            removeBlurFromElements();
            timers.blurInterval = setInterval(removeBlurFromElements, 2000);
            if (!observers.blurObserver) {
                observers.blurObserver = new MutationObserver(() => {
                    if (CACHE.autoRemoveBlur) {
                        removeBlurFromElements();
                    }
                });
                observers.blurObserver.observe(doc.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });
            }
        } else {
            if (observers.blurObserver) {
                observers.blurObserver.disconnect();
                observers.blurObserver = null;
            }
        }
    }

    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;
    }

    // ================================================================
    //  REWRITTEN ANTI-PAYWALL / ANTI-ADBLOCK ENGINE (SMARTER)
    // ================================================================
    function setupPaywallBypass() {
        if (observers.paywallObserver) {
            observers.paywallObserver.disconnect();
            observers.paywallObserver = null;
        }
        if (!CACHE.antiPaywall || !featuresEnabled || isFeatureBlacklisted()) return;

        const overlaySelectors = [
            '.paywall', '.adblock-overlay', '.premium-overlay', '.subscribe-overlay',
            '.gate', '.wall', '.restricted', '.locked',
            '[class*="paywall"]', '[id*="paywall"]', '[class*="adblock"]', '[id*="adblock"]',
            '[class*="premium"]', '[id*="premium"]', '[class*="subscribe"]', '[id*="subscribe"]',
            '[class*="overlay"]', '[id*="overlay"]', '[class*="modal"]', '[id*="modal"]'
        ];

        const paywallKeywords = ['adblock', 'paywall', 'premium', 'subscribe', 'whitelist',
                                 'disable adblock', 'ad blocker', 'subscription', 'unlock',
                                 'membership', 'register', 'sign up', 'log in'];

        function isPaywallElement(el) {
            if (!el || el === doc.documentElement || el === doc.body) return false;
            if (el.closest && el.closest('#' + UI_HOST_ID)) return false;
            if (isMainContentElement(el)) return false;
            if (isSidePanel(el)) return false;

            const style = win.getComputedStyle(el);
            const pos = style.position;
            if (pos !== 'fixed' && pos !== 'absolute') return false;

            const rect = el.getBoundingClientRect();
            const vw = win.innerWidth, vh = win.innerHeight;
            const area = rect.width * rect.height;
            const vpArea = vw * vh;
            const coverage = area / vpArea;
            if (coverage < 0.05) return false;

            let score = 0;
            let z = parseInt(style.zIndex, 10) || 0;
            if (z >= 100) score += 1;
            const bg = style.backgroundColor || style.background;
            const hasDarkBg = bg && (bg.includes('rgba(0,0,0') || bg.includes('#000') || bg.includes('black'));
            if (hasDarkBg) score += 2;
            const hasBlur = style.backdropFilter && style.backdropFilter.includes('blur');
            if (hasBlur) score += 2;
            const text = el.textContent.toLowerCase();
            let keywordCount = 0;
            paywallKeywords.forEach(kw => { if (text.includes(kw)) keywordCount++; });
            if (keywordCount >= 2) score += 3;
            else if (keywordCount === 1) score += 1;
            const buttons = el.querySelectorAll('button, a[role="button"], input[type="button"], input[type="submit"]');
            let actionBtn = false;
            for (const btn of buttons) {
                const btnText = btn.textContent.toLowerCase();
                if (btnText.includes('accept') || btnText.includes('agree') || btnText.includes('continue') ||
                    btnText.includes('subscribe') || btnText.includes('unlock')) {
                    actionBtn = true;
                    break;
                }
            }
            if (actionBtn) score += 2;
            if (coverage > 0.6) score += 2;
            const hasCloseBtn = el.querySelector('[aria-label*="close"], .close, .dismiss, [class*="close"]');
            if (hasCloseBtn) score -= 1;
            return score >= 5;
        }

        function removePaywallElement(el) {
            if (!el || el === doc.documentElement || el === doc.body) return;
            if (el.closest && el.closest('#' + UI_HOST_ID)) return;
            if (isMainContentElement(el)) return;
            try {
                el.style.setProperty('display', 'none', 'important');
                el.style.setProperty('visibility', 'hidden', 'important');
                forceEnableScroll();
            } catch (e) { /* ignore */ }
        }

        function scanForPaywalls(node) {
            if (node.nodeType === Node.ELEMENT_NODE) {
                if (isPaywallElement(node)) {
                    removePaywallElement(node);
                    return;
                }
                const children = node.querySelectorAll ? node.querySelectorAll('*') : [];
                for (const child of children) {
                    if (isPaywallElement(child)) {
                        removePaywallElement(child);
                    }
                }
            }
        }

        let paywallTimeout = null;
        const paywallObserverCallback = (mutations) => {
            if (paywallTimeout) return;
            paywallTimeout = setTimeout(() => {
                paywallTimeout = null;
                for (const mutation of mutations) {
                    if (mutation.type === 'childList') {
                        mutation.addedNodes.forEach(node => scanForPaywalls(node));
                    }
                }
            }, 200);
        };

        observers.paywallObserver = new MutationObserver(paywallObserverCallback);
        observers.paywallObserver.observe(doc.documentElement, { childList: true, subtree: true });

        const allElements = doc.querySelectorAll('*');
        for (const el of allElements) {
            if (isPaywallElement(el)) {
                removePaywallElement(el);
            }
        }
        forceEnableScroll();

        setTimeout(() => {
            const allElements2 = doc.querySelectorAll('*');
            for (const el of allElements2) {
                if (isPaywallElement(el)) {
                    removePaywallElement(el);
                }
            }
            forceEnableScroll();
        }, 2000);
    }

    // ================================================================
    //  UPGRADED AGE VERIFICATION DETECTION & AUTO-FILL
    // ================================================================
    function isAgeVerificationOrLogin(modal) {
        if (!modal) return false;
        const text = (modal.textContent || '').toLowerCase();
        
        // Keywords specific to age verification
        const ageKeywords = [
            'age', 'verify', 'verification', '18', 'over 18', 'adult',
            'are you 18', 'confirm age', 'age gate', 'age check',
            'you must be 18', 'adult content', 'age restricted',
            'birthday', 'date of birth', 'dob'
        ];
        const aria = (modal.getAttribute('aria-label') || '').toLowerCase();
        const title = (modal.getAttribute('title') || '').toLowerCase();
        const role = modal.getAttribute('role') || '';
        const classId = (modal.className + ' ' + modal.id).toLowerCase();
        const combined = text + ' ' + aria + ' ' + title + ' ' + classId + ' ' + role;

        // Check for specific class names
        const ageClassPatterns = [
            'age-gate', 'age-verification', 'age-check', 'age-verify',
            'adult-verification', 'age-modal', 'age-overlay',
            'birthday-verification', 'dob-verification'
        ];
        for (const pattern of ageClassPatterns) {
            if (combined.includes(pattern)) return true;
        }

        // Check for date input fields (day/month/year selects or date input)
        const hasDateFields = modal.querySelector('select.day, select.month, select.year, input[type="date"]');
        if (hasDateFields) {
            // If there are date fields and age-related keywords, it's age verification
            if (ageKeywords.some(kw => combined.includes(kw))) return true;
        }

        // Check for "Enter" / "Confirm" button with age keywords
        const buttons = modal.querySelectorAll('button, a[role="button"], input[type="button"], input[type="submit"]');
        let hasAgeButton = false;
        for (const btn of buttons) {
            const btnText = btn.textContent.toLowerCase();
            const btnAria = (btn.getAttribute('aria-label') || '').toLowerCase();
            const btnCombined = btnText + ' ' + btnAria;
            if (btnCombined.includes('enter') || btnCombined.includes('confirm') || 
                btnCombined.includes('verify') || btnCombined.includes('i am') ||
                btnCombined.includes('proceed') || btnCombined.includes('continue')) {
                if (ageKeywords.some(kw => combined.includes(kw))) {
                    hasAgeButton = true;
                    break;
                }
            }
        }

        if (hasAgeButton) return true;

        // Fallback: if it looks like a centered modal with a dark backdrop and age keywords
        const style = win.getComputedStyle(modal);
        const pos = style.position;
        if (pos === 'fixed' || pos === 'absolute') {
            const rect = modal.getBoundingClientRect();
            const vw = win.innerWidth, vh = win.innerHeight;
            const widthRatio = rect.width / vw;
            const heightRatio = rect.height / vh;
            // Centered modal (between 30% and 80% width, 20% to 80% height)
            if (widthRatio > 0.2 && widthRatio < 0.8 && heightRatio > 0.1 && heightRatio < 0.9) {
                const bg = style.backgroundColor || style.background;
                const hasDarkBg = bg && (bg.includes('rgba(0,0,0') || bg.includes('#000') || bg.includes('black'));
                if (hasDarkBg && ageKeywords.some(kw => combined.includes(kw))) {
                    return true;
                }
            }
        }

        return false;
    }

    function fillAgeFields(container) {
        if (!container) return false;
        let filled = false;

        // 1. Input[type="date"]
        const dateInputs = container.querySelectorAll('input[type="date"]');
        for (const input of dateInputs) {
            if (!input.value) {
                input.value = '2001-01-01';
                input.dispatchEvent(new Event('input', { bubbles: true }));
                input.dispatchEvent(new Event('change', { bubbles: true }));
                filled = true;
            }
        }

        // 2. Select dropdowns for day/month/year
        const selects = container.querySelectorAll('select');
        let daySelect = null, monthSelect = null, yearSelect = null;
        for (const sel of selects) {
            const name = (sel.name || '').toLowerCase();
            const id = (sel.id || '').toLowerCase();
            const combined = name + ' ' + id;
            if (combined.includes('day') || combined.includes('dd') || combined.includes('date')) {
                daySelect = sel;
            } else if (combined.includes('month') || combined.includes('mm')) {
                monthSelect = sel;
            } else if (combined.includes('year') || combined.includes('yyyy') || combined.includes('yy')) {
                yearSelect = sel;
            }
        }

        // Try to find selects by label/placeholder/aria-label
        if (!daySelect || !monthSelect || !yearSelect) {
            for (const sel of selects) {
                const label = sel.getAttribute('aria-label') || sel.getAttribute('placeholder') || '';
                const lower = label.toLowerCase();
                if (!daySelect && (lower.includes('day') || lower.includes('date'))) daySelect = sel;
                else if (!monthSelect && lower.includes('month')) monthSelect = sel;
                else if (!yearSelect && (lower.includes('year') || lower.includes('yyyy'))) yearSelect = sel;
            }
        }

        // Set day → 1
        if (daySelect && daySelect.options.length > 1) {
            let found = false;
            for (let opt of daySelect.options) {
                if (opt.value === '1' || opt.value === '01' || opt.text.trim() === '1' || opt.text.trim() === '01') {
                    daySelect.selectedIndex = opt.index;
                    found = true;
                    break;
                }
            }
            if (!found) daySelect.selectedIndex = 1;
            daySelect.dispatchEvent(new Event('change', { bubbles: true }));
            filled = true;
        }

        // Set month → January (1)
        if (monthSelect && monthSelect.options.length > 1) {
            for (let opt of monthSelect.options) {
                if (opt.value === '1' || opt.value === '01' || opt.text.toLowerCase().includes('jan')) {
                    monthSelect.selectedIndex = opt.index;
                    break;
                }
            }
            monthSelect.dispatchEvent(new Event('change', { bubbles: true }));
            filled = true;
        }

        // Set year → 2001 (or the earliest available if 2001 not present)
        if (yearSelect && yearSelect.options.length > 1) {
            let yearSet = false;
            for (let opt of yearSelect.options) {
                if (opt.value === '2001') {
                    yearSelect.selectedIndex = opt.index;
                    yearSet = true;
                    break;
                }
            }
            if (!yearSet && yearSelect.options.length > 0) {
                // Pick the first option that looks like a year (e.g., 1990-2010)
                const years = [];
                for (let opt of yearSelect.options) {
                    const val = parseInt(opt.value, 10);
                    if (!isNaN(val) && val > 1900 && val < 2030) {
                        years.push({ value: val, index: opt.index });
                    }
                }
                if (years.length > 0) {
                    // Pick the median year or the earliest that is at least 18 years ago
                    const now = new Date().getFullYear();
                    const minYear = now - 100; // allow up to 100 years ago
                    const maxYear = now - 18; // must be at least 18
                    let best = years[0];
                    for (const y of years) {
                        if (y.value >= maxYear && y.value <= now) {
                            best = y;
                            break;
                        }
                    }
                    yearSelect.selectedIndex = best.index;
                } else {
                    yearSelect.selectedIndex = 1; // fallback
                }
            }
            yearSelect.dispatchEvent(new Event('change', { bubbles: true }));
            filled = true;
        }

        // 3. Text/number inputs for age
        const ageInputs = container.querySelectorAll('input[type="text"], input[type="number"]');
        for (const input of ageInputs) {
            const name = (input.name || '').toLowerCase();
            const placeholder = (input.placeholder || '').toLowerCase();
            const combined = name + ' ' + placeholder;
            if (combined.includes('age') || combined.includes('birth') || combined.includes('dob') || combined.includes('birthday')) {
                if (!input.value) {
                    input.value = '18'; // or '2001-01-01' if they expect a date
                    input.dispatchEvent(new Event('input', { bubbles: true }));
                    input.dispatchEvent(new Event('change', { bubbles: true }));
                    filled = true;
                }
            }
        }

        return filled;
    }

    function findAcceptButton(modal) {
        const buttons = modal.querySelectorAll('button, a[role="button"], input[type="button"], input[type="submit"]');
        const acceptKeywords = ['accept', 'enter', 'yes', 'i am over 18', 'over 18', 'continue', 'proceed', 'verify', 'confirm', 'i am 18', 'enter site', 'go to site'];
        for (const btn of buttons) {
            const text = btn.textContent.trim().toLowerCase();
            const aria = (btn.getAttribute('aria-label') || '').toLowerCase();
            const combined = text + ' ' + aria;
            if (acceptKeywords.some(kw => combined.includes(kw))) {
                return btn;
            }
        }
        // Look for any button that is not "close" or "cancel"
        for (const btn of buttons) {
            const text = btn.textContent.trim().toLowerCase();
            if (text && !text.includes('close') && !text.includes('cancel') && !text.includes('dismiss')) {
                return btn;
            }
        }
        return null;
    }

    // ================================================================
    //  AUTO-CLOSE MODALS & OVERLAYS ENGINE (SMART & SITE‑AWARE)
    // ================================================================
    function setupModalAutoClose() {
        if (observers.modalObserver) {
            observers.modalObserver.disconnect();
            observers.modalObserver = null;
        }
        if (!CACHE.autoCloseModals || !featuresEnabled || isFeatureBlacklisted()) return;

        const modalSelectors = [
            '[role="dialog"]', '[role="alertdialog"]', '.modal', '.popup', '.lightbox',
            '[class*="modal"]', '[id*="modal"]', '[class*="popup"]', '[id*="popup"]',
            '[class*="overlay"]', '[id*="overlay"]', '.modal-overlay', '.modal-backdrop'
        ];

        const closeKeywords = ['close', 'dismiss', 'cancel', '×', 'x', 'got it', 'ok', 'continue'];

        function isNavigationOrMenu(modal) {
            const role = modal.getAttribute('role');
            if (role && ['navigation', 'menu', 'listbox', 'tree', 'menubar', 'tablist'].includes(role)) {
                return true;
            }
            const label = (modal.getAttribute('aria-label') || '').toLowerCase();
            if (label.includes('navigation') || label.includes('menu') || label.includes('sidebar') || label.includes('drawer')) {
                return true;
            }
            const classId = (modal.className + ' ' + modal.id).toLowerCase();
            if (/(menu|sidebar|drawer|nav|navigation|sidepanel|offcanvas|slide[-_]in|slide[-_]out)/i.test(classId)) {
                return true;
            }
            const links = modal.querySelectorAll('a');
            if (links.length > 3) {
                const style = win.getComputedStyle(modal);
                const pos = style.position;
                if (pos === 'fixed' || pos === 'absolute') {
                    const rect = modal.getBoundingClientRect();
                    const vw = window.innerWidth;
                    const vh = window.innerHeight;
                    if ((rect.left < 50 || (vw - rect.right) < 50) && rect.width < vw * 0.5) {
                        return true;
                    }
                }
            }
            const parent = modal.parentElement;
            if (parent && parent.matches && parent.matches('.sidebar, .menu, .nav, .drawer, .offcanvas, [role="navigation"]')) {
                return true;
            }
            return false;
        }

        function isEssentialUI(modal) {
            if (isSidePanel(modal)) return true;
            if (isNavigationOrMenu(modal)) return true;
            const rect = modal.getBoundingClientRect();
            const vw = window.innerWidth;
            const vh = window.innerHeight;
            const widthRatio = rect.width / vw;
            const heightRatio = rect.height / vh;
            const isLeft = rect.left < 10;
            const isRight = (vw - rect.right) < 10;
            if ((isLeft || isRight) && widthRatio < 0.5 && heightRatio > 0.3) return true;
            if (modal.querySelector('input, textarea, select')) {
                const text = (modal.textContent || '').toLowerCase();
                if (text.includes('subscribe') || text.includes('paywall') || text.includes('unlock') || text.includes('membership')) {
                    return false;
                }
                if (CACHE.autoCloseLogins) return false;
                return true;
            }
            if (widthRatio < 0.3 || heightRatio < 0.3) return true;
            if (modal.matches && modal.matches('.menu, .dropdown, .panel, .sidebar, .drawer, [role="menu"], [role="listbox"], [role="navigation"]')) return true;
            if (modal.querySelector('input[type="search"], input[placeholder*="search"], .search-input')) return true;
            return false;
        }

        function findCloseButton(modal) {
            const buttons = modal.querySelectorAll('button, a[role="button"], input[type="button"], input[type="submit"]');
            for (const btn of buttons) {
                const text = btn.textContent.trim().toLowerCase();
                const aria = (btn.getAttribute('aria-label') || '').toLowerCase();
                if (closeKeywords.some(kw => text.includes(kw) || aria.includes(kw))) {
                    return btn;
                }
            }
            const closeEl = modal.querySelector('.close, .dismiss, [aria-label*="close"], [aria-label*="Close"]');
            return closeEl || null;
        }

        function tryCloseModal(modal) {
            if (!modal || modal === doc.documentElement || modal === doc.body) return false;
            if (modal.closest && modal.closest('#' + UI_HOST_ID)) return false;
            if (isMainContentElement(modal)) return false;

            if (isSidePanel(modal)) return false;

            // ---- AGE VERIFICATION HANDLING ----
            if (isAgeVerificationOrLogin(modal)) {
                if (CACHE.autoAcceptAge) {
                    // Fill date fields
                    fillAgeFields(modal);
                    const acceptBtn = findAcceptButton(modal);
                    if (acceptBtn) {
                        try { acceptBtn.click(); return true; } catch {}
                    }
                }
                return false; // don't close automatically unless we clicked
            }

            // ---- LOGIN HANDLING ----
            if (CACHE.autoCloseLogins) {
                // If it's a login modal, try to close it
                const text = (modal.textContent || '').toLowerCase();
                if (text.includes('login') || text.includes('sign in') || text.includes('log in') || text.includes('register')) {
                    const closeBtn = findCloseButton(modal);
                    if (closeBtn) {
                        try { closeBtn.click(); return true; } catch {}
                    }
                }
            }

            // ---- REGULAR MODAL CLOSE ----
            if (isNavigationOrMenu(modal) || isEssentialUI(modal)) return false;

            if (modal.querySelector('input[type="text"], input[type="search"], textarea, select')) {
                const text = modal.textContent.toLowerCase();
                if (!text.includes('subscribe') && !text.includes('paywall') && !text.includes('unlock')) {
                    return false;
                }
            }

            const rect = modal.getBoundingClientRect();
            const vw = window.innerWidth, vh = window.innerHeight;
            const areaRatio = (rect.width * rect.height) / (vw * vh);
            if (areaRatio < 0.3) {
                const style = win.getComputedStyle(modal);
                const bg = style.backgroundColor || style.background;
                const hasDarkBg = bg && (bg.includes('rgba(0,0,0') || bg.includes('#000') || bg.includes('black'));
                const text = (modal.textContent || '').toLowerCase();
                const isAdOrPaywall = text.includes('ad') || text.includes('subscribe') || text.includes('unlock');
                if (!hasDarkBg && !isAdOrPaywall) return false;
            }

            const closeBtn = findCloseButton(modal);
            if (closeBtn) {
                try { closeBtn.click(); return true; } catch {}
            }
            if (modal.matches('.modal-backdrop, .modal-overlay, .overlay')) {
                try { modal.style.setProperty('display', 'none', 'important'); return true; } catch {}
            }
            const parent = modal.parentElement;
            if (parent && parent.matches && parent.matches('.modal-backdrop, .modal-overlay, .overlay')) {
                try { parent.style.setProperty('display', 'none', 'important'); return true; } catch {}
            }
            return false;
        }

        function scanForModals() {
            const modals = doc.querySelectorAll(modalSelectors.join(','));
            for (const modal of modals) {
                tryCloseModal(modal);
            }
        }

        let modalTimeout = null;
        const modalObserverCallback = () => {
            if (modalTimeout) return;
            modalTimeout = setTimeout(() => {
                modalTimeout = null;
                scanForModals();
            }, 250);
        };

        observers.modalObserver = new MutationObserver(modalObserverCallback);
        observers.modalObserver.observe(doc.documentElement, { childList: true, subtree: true });

        setTimeout(scanForModals, 500);
        setTimeout(scanForModals, 1500);
        setTimeout(scanForModals, 3000);
    }

    // ---------- 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) {
            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;
        CACHE.antiPaywall = gv('hider_anti_paywall', false);
        CACHE.autoCloseModals = gv('hider_auto_close_modals', false);
        CACHE.cookieConsentMode = gv('hider_cookie_consent_mode', 'ask');
        CACHE.autoAcceptAge = gv('hider_auto_accept_age', false);
        CACHE.autoCloseLogins = gv('hider_auto_close_logins', false);
        CACHE.filterLists = gv('hider_filter_lists', []);
        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');
        broadcastState();
    }

    // ---------- Stealth Engine (SMART: no class, just proxy) ----------
    const styleProxyCache = new WeakMap();
    try {
        const origGetComputedStyle = win.getComputedStyle;
        win.getComputedStyle = 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: 
                                    const val = target[prop];
                                    return typeof val === 'function' ? val.bind(target) : val;
                            }
                        }
                    });
                    styleProxyCache.set(style, cachedProxy);
                }
                return cachedProxy;
            }
            return style;
        };
    } 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() {
        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'));
            v.play()?.catch?.(() => {});
        });
    }

    function triggerVideoResumeChain() {
        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)'); };
                if (origR) lp.replace = function(u) { return checkAndInterceptNav(u, origR, this, 'Redirect (replace)'); };
                if (hrefDesc?.set) {
                    try {
                        Object.defineProperty(lp, 'href', {
                            set(u) { checkAndInterceptNav(u, hrefDesc.set, this, 'Redirect (href)'); },
                            get() { return hrefDesc.get.call(this); }
                        });
                    } catch {}
                }
            }

            const origClick = HTMLAnchorElement.prototype.click;
            HTMLAnchorElement.prototype.click = 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);
            };

            const origOpen = win.open;
            win.open = 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);
            };
        } 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, 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, currentScope, isFrozen } = e.data);
            CACHE.isFrozen = isFrozen;
            syncCache(); requestUpdateStyles();
            shadowBy('btn-select')?.classList.toggle('active', isSelecting);
            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', 'hider_auto_close_modals', 'hider_cookie_consent_mode', 'hider_auto_accept_age', '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) 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) 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 });
    }

    // ---------- 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 path = []; let curr = el;
        while (curr && curr.nodeType === 1 && curr.tagName.toLowerCase() !== 'html') {
            let tag = curr.tagName.toLowerCase();
            if (tag === 'body') { path.unshift('body'); break; }
            if (curr.id && !curr.id.startsWith('hider-') && !/^\d+$/.test(curr.id) && curr.id.length < 18) { path.unshift(`#${safeCSSEscape(curr.id)}`); break; }
            const rawC = typeof curr.className === 'string' ? curr.className : curr.getAttribute('class') || '';
            const classes = rawC.trim().split(/\s+/).filter(c => c.length > 1 && !c.startsWith('hider-') && !/^[a-zA-Z0-9]{10,}$/.test(c) && !/^hover:/i.test(c));
            if (classes.length) { tag += `.${safeCSSEscape(classes[0])}` + (classes[1] ? `.${safeCSSEscape(classes[1])}` : ''); }
            else {
                let idx = 1, sib = curr.previousElementSibling;
                while (sib) { if (sib.tagName === curr.tagName) idx++; sib = sib.previousElementSibling; }
                tag += `:nth-of-type(${idx})`;
            }
            path.unshift(tag); curr = curr.parentElement;
        }
        return path.join(' > ');
    }

    // ---------- 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) {
            isSelecting = false; shadowBy('btn-select')?.classList.remove('active');
            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;
    }

    // ---------- Stepper UI ----------
    function renderTouchStepperUI() {
        if (!shadowRoot) return;
        let stepper = shadowBy(STEPPER_BAR_ID);
        if (!previewElement) { stepper?.remove(); return; }
        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');
        }

        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;

        stepper.innerHTML = `
            <div id="hider-drag-handle" class="h-drag-dots" title="Drag Selector Bar">⠿</div>
            <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>
            <div class="h-stepper-row" style="display:flex;flex-direction:column;gap:4px;width:100%;">
                <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'));

        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();
            }
        };
        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 Dropdown ----------
    function setupCustomDropdown(container, initialValue, onChangeCallback) {
        if (!container) return;
        const trigger = container.querySelector('.h-custom-trigger'), textSpan = container.querySelector('.h-custom-value-text'), options = container.querySelectorAll('.h-custom-opt');
        let currentVal = initialValue || 'ask'; textSpan.textContent = FREEZE_LABELS[currentVal] || FREEZE_LABELS['ask'];

        options.forEach(opt => {
            opt.classList.toggle('is-selected', opt.getAttribute('data-val') === currentVal);
            opt.onclick = e => {
                e.stopPropagation(); currentVal = opt.getAttribute('data-val');
                textSpan.textContent = FREEZE_LABELS[currentVal] || opt.textContent.trim();
                options.forEach(o => o.classList.toggle('is-selected', o === opt)); container.classList.remove('is-open'); onChangeCallback?.(currentVal);
            };
        });
        trigger.onclick = e => {
            e.stopPropagation(); const isOpen = container.classList.contains('is-open');
            shadowRoot.querySelectorAll('.h-custom-select').forEach(c => c.classList.remove('is-open'));
            if (!isOpen) container.classList.add('is-open');
        };
    }

    // ---------- 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));

        doc.querySelectorAll('*').forEach(el => {
            const style = win.getComputedStyle(el);
            if (style.filter && style.filter.includes('blur')) {
                targets.add(el);
            }
            if (style.backdropFilter && style.backdropFilter.includes('blur')) {
                targets.add(el);
            }
            if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') {
                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 {}
        });

        let timerCount = 0;
        const timerElements = doc.querySelectorAll(
            '[class*="timer"], [class*="countdown"], [id*="timer"], [id*="countdown"], ' +
            '[class*="time"], [id*="time"], [class*="remaining"], [id*="remaining"]'
        );
        timerElements.forEach(el => {
            const text = el.textContent.trim();
            if (/^\d{1,2}:\d{2}$/.test(text) || /^\d+\s*(s|sec|seconds?)$/i.test(text) || /^\d{1,2}:\d{2}\s*$/.test(text)) {
                el.textContent = '0';
                el.dispatchEvent(new Event('input', { bubbles: true }));
                timerCount++;
            }
        });

        doc.querySelectorAll('*:not([class*="timer"]):not([id*="timer"]):not([class*="countdown"]):not([id*="countdown"])')
            .forEach(el => {
                const text = el.textContent.trim();
                if (/^(?:[0-9]{1,2}:[0-5][0-9]|[1-9][0-9]?s?)$/i.test(text)) {
                    el.textContent = '0';
                    el.dispatchEvent(new Event('input', { bubbles: true }));
                    timerCount++;
                }
            });

        let clickCount = 0;
        const skipBtns = doc.querySelectorAll('button, a[role="button"], [role="button"]');
        skipBtns.forEach(btn => {
            const text = btn.textContent.trim().toLowerCase();
            if (text && (text.includes('skip') || text.includes('close') || text.includes('dismiss'))) {
                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 checkAndSkipTimers() {
        if (!CACHE.autoTimeSkipper || !featuresEnabled) return false;
        let found = false;

        const timerSelectors = [
            '[class*="timer"]', '[class*="countdown"]', '[id*="timer"]', '[id*="countdown"]',
            '[class*="time"]', '[id*="time"]', '[class*="remaining"]', '[id*="remaining"]',
            '[data-timer]', '[data-countdown]', '[aria-label*="time"]', '[aria-label*="countdown"]'
        ];
        const timerElements = doc.querySelectorAll(timerSelectors.join(','));
        for (const el of timerElements) {
            if (isInsideMedia(el)) continue;
            const text = el.textContent.trim();
            if (/^\d{1,2}:\d{2}$/.test(text) || 
                /^\d+\s*(s|sec|seconds?)$/i.test(text) || 
                /^\d{1,2}:\d{2}\s*$/.test(text) ||
                /^\d+\s*second/i.test(text)) {
                el.textContent = '0';
                el.dispatchEvent(new Event('input', { bubbles: true }));
                found = true;
            }
        }

        const allElements = doc.querySelectorAll('*');
        for (const el of allElements) {
            if (isInsideMedia(el)) continue;
            if (el.matches && el.matches(timerSelectors.join(','))) continue;
            const text = el.textContent.trim();
            if (/^\d{1,2}:\d{2}$/.test(text) || /^\d+\s*(s|sec|seconds?)$/i.test(text)) {
                const parent = el.parentElement;
                if (parent && (parent.matches && parent.matches('[class*="timer"], [class*="countdown"], [id*="timer"], [id*="countdown"]'))) {
                    el.textContent = '0';
                    el.dispatchEvent(new Event('input', { bubbles: true }));
                    found = true;
                }
            }
        }

        return found;
    }

    function skipVideoAds() {
        if (!CACHE.autoTimeSkipper || !featuresEnabled) return false;
        let skipped = false;

        const adContainers = doc.querySelectorAll([
            '.ad-container', '.video-ads', '.ad-player', '.ad-overlay',
            '[id*="ad"]', '[id*="video-ad"]', '[id*="ad-container"]',
            '.ytp-ad-overlay', '.ytp-ad-player-overlay', '.ytp-ad-image-overlay',
            '.ytp-ad-text-overlay', '.ytp-ad-skip-button-container',
            '.vjs-ad-overlay', '.vjs-ad-container',
            '.jwplayer-ads', '.jwplayer-ads-container',
            '.preroll-ads', '.ad-iframe', '.ad-banner'
        ].join(','));
        
        for (const ad of adContainers) {
            const skipBtns = ad.querySelectorAll('button, a[role="button"], [role="button"]');
            for (const btn of skipBtns) {
                const text = btn.textContent.trim().toLowerCase();
                if (text && (text.includes('skip') || text.includes('close') || text.includes('dismiss') || text.includes('×'))) {
                    const rect = btn.getBoundingClientRect();
                    if (rect.width > 0 && rect.height > 0) {
                        try { btn.click(); skipped = true; } catch {}
                    }
                }
            }
            const skipTexts = ad.querySelectorAll('*');
            for (const el of skipTexts) {
                const txt = el.textContent.trim().toLowerCase();
                if (txt && (txt.includes('skip ad') || txt.includes('skip video') || txt.includes('skip in'))) {
                    const parentBtn = el.closest('button, a[role="button"], [role="button"]');
                    if (parentBtn) {
                        try { parentBtn.click(); skipped = true; } catch {}
                    }
                }
            }
        }

        const genericSkipBtns = doc.querySelectorAll('button, a[role="button"], [role="button"]');
        for (const btn of genericSkipBtns) {
            const text = btn.textContent.trim().toLowerCase();
            if (text && (text.includes('skip ad') || text.includes('skip video') || text.includes('skip this ad'))) {
                const rect = btn.getBoundingClientRect();
                if (rect.width > 0 && rect.height > 0) {
                    try { btn.click(); skipped = true; } catch {}
                }
            }
        }

        return skipped;
    }

    function autoSkipLoop() {
        let found = false;
        if (checkAndSkipTimers()) found = true;
        if (skipVideoAds()) found = true;

        if (found) {
            autoSkipEmptyCount = 0;
        } else {
            autoSkipEmptyCount++;
            if (autoSkipEmptyCount >= AUTO_SKIP_MAX_EMPTY) {
                stopAutoSkipMonitoring();
            }
        }
    }

    function startAutoSkipMonitoring() {
        if (autoSkipInterval) {
            clearInterval(autoSkipInterval);
            autoSkipInterval = null;
        }
        autoSkipEmptyCount = 0;
        autoSkipLoop();
        autoSkipInterval = setInterval(autoSkipLoop, AUTO_SKIP_INTERVAL_MS);
    }

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

    // ========== AGGRESSIVE PAUSE ==========
    function pauseAllVideos() {
        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 = url.toLowerCase();
        if (lower.startsWith('blob:')) 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', '.ogg', '.wma'
        ];
        return mediaExts.some(ext => lower.includes(ext));
    }

    function getMediaType(url) {
        if (!url) return null;
        const lower = url.toLowerCase();
        const imgExts = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp', '.ico', '.tiff', '.tif', '.avif', '.heic', '.heif'];
        if (imgExts.some(ext => lower.includes(ext))) return 'image';
        const vidExts = ['.mp4', '.webm', '.ogg', '.ogv', '.mov', '.avi', '.mkv', '.ts', '.m4v', '.wmv', '.flv', '.m3u8'];
        if (vidExts.some(ext => lower.includes(ext))) return 'video';
        const audExts = ['.mp3', '.wav', '.flac', '.m4a', '.aac', '.ogg', '.wma'];
        if (audExts.some(ext => lower.includes(ext))) return 'audio';
        if (lower.startsWith('blob:')) return 'image';
        return null;
    }

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

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

        function addLink(url, text, type = 'link') {
            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 = 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;
                    }
                    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;
                    if (src) {
                        const text = el.getAttribute('title') || el.getAttribute('aria-label') || el.getAttribute('alt') || el.textContent.trim() || src;
                        addLink(src, text, 'media');
                    }
                    el.querySelectorAll('source').forEach(source => {
                        const s = source.getAttribute('src');
                        if (s) {
                            const label = source.getAttribute('label') || source.getAttribute('title') || s;
                            addLink(s, label, 'media');
                        }
                    });
                    const poster = el.getAttribute('poster');
                    if (poster && isMediaUrl(poster)) {
                        addLink(poster, 'Poster image', 'media');
                    }
                }

                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');
                    }
                    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');
                    }
                    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;
            }

            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 (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; } 
        `;
        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-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>Menu</span></button>
            </div>
        </div>

        <div id="hider-panel" class="h-glass">
            <div class="panel-header">
                <span class="title">Hide Web Elements Pro</span>
                <button class="close-btn" id="close-p">✖</button>
            </div>
            <div class="panel-body">
                <div class="panel-sidebar" id="panel-sidebar"></div>
                <div class="panel-content" id="panel-content"></div>
            </div>
        </div>`;

        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 buildPanelTabs() {
        const sidebar = shadowBy('panel-sidebar');
        const content = shadowBy('panel-content');
        if (!sidebar || !content) return;

        const tabs = [
            { id: 'tab-tools', label: '🛠️ Tools', 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 style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;">
                        <input type="checkbox" id="chk-auto-scroll" ${CACHE.autoScroll?'checked':''} style="accent-color:#38bdf8;"> Auto Anti‑Scroll Lock
                    </label>
                    <label style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;">
                        <input type="checkbox" id="chk-enable-contextmenu" ${CACHE.enableContextMenu?'checked':''} style="accent-color:#38bdf8;"> Auto Right‑Click / Long‑Press
                    </label>
                    <label style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;">
                        <input type="checkbox" id="chk-auto-remove-blur" ${CACHE.autoRemoveBlur?'checked':''} style="accent-color:#38bdf8;"> Auto Remove Blur
                    </label>
                    <label style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;margin-top:2px;">
                        <input type="checkbox" id="chk-auto-time-skipper" ${CACHE.autoTimeSkipper?'checked':''} style="accent-color:#f59e0b;"> Auto Time Skipper (Smart)
                    </label>

                    <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>
                    <label style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;">
                        <input type="checkbox" id="chk-anti-paywall" ${CACHE.antiPaywall?'checked':''} style="accent-color:#f59e0b;"> Anti‑Paywall / Anti‑Adblock
                    </label>
                    <label style="font-size:10px;color:#cbd5e1;display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;">
                        <input type="checkbox" id="chk-auto-close-modals" ${CACHE.autoCloseModals?'checked':''} style="accent-color:#f59e0b;"> Auto‑Close Modals & Overlays
                    </label>
                    <label 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 type="checkbox" id="chk-auto-accept-age" ${CACHE.autoAcceptAge?'checked':''} style="accent-color:#f59e0b;"> Auto‑Accept Age Verification
                    </label>
                    <label 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 type="checkbox" id="chk-auto-close-logins" ${CACHE.autoCloseLogins?'checked':''} style="accent-color:#f59e0b;"> Auto‑Close Logins
                    </label>
                    <div style="display:flex;align-items:center;gap:6px;margin-top:2px;">
                        <span style="font-size:10px;color:#94a3b8;">🍪 Cookie Consent:</span>
                        <select id="cookie-consent-mode" style="background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.14);border-radius:6px;color:#fff;padding:2px 6px;font-size:9px;height:22px;flex:1;">
                            <option value="ask" ${CACHE.cookieConsentMode === 'ask' ? 'selected' : ''}>Ask</option>
                            <option value="accept" ${CACHE.cookieConsentMode === 'accept' ? 'selected' : ''}>Accept</option>
                            <option value="reject" ${CACHE.cookieConsentMode === 'reject' ? 'selected' : ''}>Reject</option>
                        </select>
                    </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 id="dock-buttons-list" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(80px,1fr));gap:4px;"></div>
                </div>
            ` },
            { id: 'tab-rules', label: '✏️ Rules', html: `
                <div style="display:flex;flex-direction:column;gap:4px;">
                    <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:2px;">
                        <span style="font-size:10px;color:#94a3b8;font-weight:700;">Custom Rules (<span id="cnt-custom">0</span>)</span>
                        <button class="hider-btn-small btn-blue" id="add-rule-btn" style="height:24px;padding:0 8px;">➕ Add Rule</button>
                    </div>
                    <div id="list-custom-rules" style="display:flex;flex-direction:column;gap:3px;"></div>
                    <div style="border-top:1px solid rgba(255,255,255,0.06);padding-top:4px;margin-top:4px;">
                        <div style="display:flex;justify-content:space-between;font-size:10px;color:#94a3b8;">
                            <span>🌐 Site‑Wide (<span id="cnt-site">0</span>)</span>
                            <button class="hider-btn-small btn-red" id="clear-site-rules" style="font-size:8px;padding:1px 5px;height:18px;">Clear All</button>
                        </div>
                        <div id="list-site" style="display:flex;flex-direction:column;gap:3px;"></div>
                    </div>
                    <div style="border-top:1px solid rgba(255,255,255,0.06);padding-top:4px;">
                        <div style="display:flex;justify-content:space-between;font-size:10px;color:#94a3b8;">
                            <span>📄 Page‑Only (<span id="cnt-link">0</span>)</span>
                            <button class="hider-btn-small btn-red" id="clear-page-rules" style="font-size:8px;padding:1px 5px;height:18px;">Clear All</button>
                        </div>
                        <div id="list-link" style="display:flex;flex-direction:column;gap:3px;"></div>
                    </div>
                    <div style="margin-top:4px;text-align:right;">
                        <button class="hider-btn-small btn-red" id="clear-custom-rules" style="font-size:8px;padding:1px 5px;height:18px;">Clear All Custom Rules</button>
                    </div>
                </div>
            ` },
            { id: 'tab-freeze', label: '❄️ Freeze', 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;">Freeze Behaviour</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>
                    <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;">Reset "Don't Ask Block" Prompt</button>
                    <div style="font-size:9px;color:#94a3b8;text-transform:uppercase;letter-spacing:0.5px;font-weight:700;margin-top:8px;border-top:1px solid rgba(255,255,255,0.06);padding-top:6px;">🚫 Blocked Domains</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" style="display:flex;flex-direction:column;gap:3px;"></div>
                    <div style="font-size:9px;color:#94a3b8;text-transform:uppercase;letter-spacing:0.5px;font-weight:700;margin-top:8px;border-top:1px solid rgba(255,255,255,0.06);padding-top:6px;">🟢 Allowed Domains</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" style="display:flex;flex-direction:column;gap:3px;"></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: '💾 Export', 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>

                <!-- ========== COOKIE MANAGER (without edit) ========== -->
                <div style="border-top:1px solid rgba(255,255,255,0.06);padding-top:8px;margin-top:4px;">
                    <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;">
                        <span style="font-size:11px;font-weight:700;color:#f8fafc;">🍪 Cookies (<span id="cookie-count">0</span>)</span>
                        <input type="text" id="cookie-search" placeholder="🔍 Filter by name..." 
                               style="background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);border-radius:6px;color:#fff;padding:2px 6px;font-size:9px;height:22px;width:140px;">
                    </div>
                    <div id="cookie-list" style="display:flex;flex-direction:column;gap:3px;max-height:160px;overflow-y:auto;margin-bottom:6px;"></div>

                    <!-- Add cookie row -->
                    <div style="display:flex;gap:4px;flex-wrap:wrap;align-items:center;background:rgba(255,255,255,0.04);padding:4px;border-radius:6px;border:1px solid rgba(255,255,255,0.08);">
                        <input type="text" id="cookie-new-name" placeholder="name" style="flex:1;min-width:60px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);border-radius:6px;color:#fff;padding:2px 6px;font-size:9px;height:24px;">
                        <input type="text" id="cookie-new-value" placeholder="value" style="flex:2;min-width:80px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);border-radius:6px;color:#fff;padding:2px 6px;font-size:9px;height:24px;">
                        <input type="number" id="cookie-new-expiry" placeholder="days (opt)" min="0" step="1" style="width:60px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);border-radius:6px;color:#fff;padding:2px 6px;font-size:9px;height:24px;">
                        <button class="hider-btn-small btn-green" id="cookie-add" style="height:24px;padding:0 10px;">➕ Add</button>
                    </div>

                    <!-- Action buttons -->
                    <div style="display:flex;gap:4px;margin-top:4px;flex-wrap:wrap;">
                        <button class="hider-btn-small btn-red" id="cookie-clear-all" style="height:24px;padding:0 10px;">🗑️ Clear All</button>
                        <button class="hider-btn-small btn-blue" id="cookie-export" style="height:24px;padding:0 10px;">📤 Export</button>
                        <button class="hider-btn-small btn-purple" id="cookie-import" style="height:24px;padding:0 10px;">📥 Import</button>
                        <input type="file" id="cookie-import-file" accept=".json" style="display:none;">
                    </div>
                </div>
            ` },
            { id: 'tab-about', label: 'ℹ️ About', html: `
                <div style="font-size:10px;color:#cbd5e1;line-height:1.6;padding:4px 0;">
                    <div style="display:flex;align-items:center;gap:12px;margin-bottom:12px;">
                        <div style="width:48px;height:48px;flex-shrink:0;">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="48" height="48">
                                <defs>
                                    <radialGradient id="aboutBg" cx="50%" cy="50%" r="50%">
                                        <stop offset="0%" stop-color="#1e293b" />
                                        <stop offset="100%" stop-color="#0d121e" />
                                    </radialGradient>
                                    <linearGradient id="aboutNeon" x1="0%" y1="0%" x2="100%" y2="100%">
                                        <stop offset="0%" stop-color="#7dd3fc" />
                                        <stop offset="100%" stop-color="#0284c7" />
                                    </linearGradient>
                                    <linearGradient id="aboutPro" x1="0%" y1="0%" x2="100%" y2="100%">
                                        <stop offset="0%" stop-color="#fbbf24" />
                                        <stop offset="100%" stop-color="#f59e0b" />
                                    </linearGradient>
                                </defs>
                                <circle cx="256" cy="256" r="220" fill="url(#aboutBg)" stroke="url(#aboutNeon)" stroke-width="4"/>
                                <path d="M 136 256 C 180 176, 332 176, 376 256 C 332 336, 180 336, 136 256 Z" 
                                      fill="none" stroke="url(#aboutNeon)" stroke-width="10"/>
                                <circle cx="256" cy="256" r="40" fill="#0d121e" stroke="url(#aboutNeon)" stroke-width="6"/>
                                <circle cx="256" cy="256" r="14" fill="#e0f2fe"/>
                                <line x1="150" y1="362" x2="362" y2="150" stroke="#f8fafc" stroke-width="10"/>
                                <line x1="150" y1="362" x2="362" y2="150" stroke="#38bdf8" stroke-width="4"/>
                                <text x="256" y="425" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="28" fill="url(#aboutPro)" text-anchor="middle" letter-spacing="4">PRO</text>
                            </svg>
                        </div>
                        <div>
                            <h3 style="font-size:14px;font-weight:800;color:#f8fafc;margin:0;">Hide Web Elements</h3>
                            <p style="font-size:10px;color:#94a3b8;margin:2px 0 0;"><strong style="color:gold;">Pro</strong> version • by KTZ</p>
                        </div>
                    </div>
                    <p style="font-size:10px;color:#94a3b8;margin:0 0 8px;">A powerful element hider with advanced navigation control, media extraction, and automatic challenge protection.</p>

                    <div style="display:grid;grid-template-columns:1fr 1fr;gap:6px;margin:8px 0;">
                        <div style="background:rgba(255,255,255,0.04);border-radius:6px;padding:6px 8px;border:1px solid rgba(255,255,255,0.06);">
                            <div style="font-size:11px;font-weight:700;color:#38bdf8;">🎯 Hide</div>
                            <div style="font-size:9px;color:#94a3b8;">Site, page, or global hiding</div>
                        </div>
                        <div style="background:rgba(255,255,255,0.04);border-radius:6px;padding:6px 8px;border:1px solid rgba(255,255,255,0.06);">
                            <div style="font-size:11px;font-weight:700;color:#34d399;">❄️ Freeze</div>
                            <div style="font-size:9px;color:#94a3b8;">Block/allow navigation</div>
                        </div>
                        <div style="background:rgba(255,255,255,0.04);border-radius:6px;padding:6px 8px;border:1px solid rgba(255,255,255,0.06);">
                            <div style="font-size:11px;font-weight:700;color:#a855f7;">🔗 Links</div>
                            <div style="font-size:9px;color:#94a3b8;">Extract & download media</div>
                        </div>
                        <div style="background:rgba(255,255,255,0.04);border-radius:6px;padding:6px 8px;border:1px solid rgba(255,255,255,0.06);">
                            <div style="font-size:11px;font-weight:700;color:#f59e0b;">⏩ Time Skipper</div>
                            <div style="font-size:9px;color:#94a3b8;">Jump forward 30s</div>
                        </div>
                        <div style="background:rgba(255,255,255,0.04);border-radius:6px;padding:6px 8px;border:1px solid rgba(255,255,255,0.06);">
                            <div style="font-size:11px;font-weight:700;color:#f43f5e;">👁️ Reveal</div>
                            <div style="font-size:9px;color:#94a3b8;">Unhide overlays & blur</div>
                        </div>
                        <div style="background:rgba(255,255,255,0.04);border-radius:6px;padding:6px 8px;border:1px solid rgba(255,255,255,0.06);">
                            <div style="font-size:11px;font-weight:700;color:#8b5cf6;">🛡️ Protection</div>
                            <div style="font-size:9px;color:#94a3b8;">Cloudflare/anti‑bot</div>
                        </div>
                    </div>

                    <div style="margin:8px 0;border-top:1px solid rgba(255,255,255,0.06);padding-top:8px;">
                        <div style="display:flex;gap:12px;flex-wrap:wrap;">
                            <div><span style="font-weight:700;color:#38bdf8;">Anti‑Paywall</span> <span style="color:#94a3b8;">•</span> <span style="color:#94a3b8;">Removes overlays</span></div>
                            <div><span style="font-weight:700;color:#38bdf8;">Auto‑Close Modals</span> <span style="color:#94a3b8;">•</span> <span style="color:#94a3b8;">Smart skip</span></div>
                            <div><span style="font-weight:700;color:#38bdf8;">Cookie Bypass</span> <span style="color:#94a3b8;">•</span> <span style="color:#94a3b8;">Accept/Reject</span></div>
                            <div><span style="font-weight:700;color:#38bdf8;">Media Downloader</span> <span style="color:#94a3b8;">•</span> <span style="color:#94a3b8;">Preview & save</span></div>
                        </div>
                    </div>

                    <div style="margin:8px 0;border-top:1px solid rgba(255,255,255,0.06);padding-top:8px;">
                        <div style="font-size:9px;color:#94a3b8;">
                            <span style="font-weight:700;color:#e2e8f0;">🔒 Protection:</span> Pauses features on Cloudflare challenges, resumes automatically.
                        </div>
                        <div style="font-size:9px;color:#94a3b8;margin-top:2px;">
                            <span style="font-weight:700;color:#e2e8f0;">💾 Storage:</span> All settings persist across restarts (GM_setValue/localStorage).
                        </div>
                        <div style="font-size:9px;color:#94a3b8;margin-top:2px;">
                            <span style="font-weight:700;color:#e2e8f0;">⌨️ Shortcuts:</span> <kbd style="background:rgba(255,255,255,0.08);padding:0 4px;border-radius:3px;">Esc</kbd> cancel selection/close panels • <kbd style="background:rgba(255,255,255,0.08);padding:0 4px;border-radius:3px;">Ctrl+Click</kbd> bypass freeze
                        </div>
                    </div>

                    <div style="margin-top:8px;font-size:8px;color:#64748b;text-align:center;border-top:1px solid rgba(255,255,255,0.06);padding-top:6px;">
                        Open source under MIT • Made with ❤️
                    </div>
                </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;
            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');
            const contentDiv = content.querySelector('#' + tabId);
            if (contentDiv) contentDiv.classList.add('active');
        });
    }

    // ---------- Shadow UI Events ----------
    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;
            if (val === 'allow_all') { disableFreezeMode(); showToast(`🟢 Freeze Mode Disabled (Allow All)`); } 
            else showToast(`❄️ Memory updated: ${label}`);
        });

        shadowBy('btn-reset-block-confirm').onclick = () => { sv('hider_skip_block_confirm', false); showToast('🔄 Reset Block Domain confirmation!'); };

        const chkPaywall = shadowBy('chk-anti-paywall');
        if (chkPaywall) {
            chkPaywall.onchange = e => {
                CACHE.antiPaywall = e.target.checked;
                sv('hider_anti_paywall', CACHE.antiPaywall);
                applyAllSettings();
                showToast(`🚫 Anti-Paywall: ${CACHE.antiPaywall ? 'ON' : '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 chkAutoAcceptAge = shadowBy('chk-auto-accept-age');
        if (chkAutoAcceptAge) {
            chkAutoAcceptAge.onchange = e => {
                CACHE.autoAcceptAge = e.target.checked;
                sv('hider_auto_accept_age', CACHE.autoAcceptAge);
                applyAllSettings();
                showToast(`✅ Auto-Accept Age: ${CACHE.autoAcceptAge ? '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');
        if (cookieMode) {
            cookieMode.onchange = e => {
                CACHE.cookieConsentMode = e.target.value;
                sv('hider_cookie_consent_mode', CACHE.cookieConsentMode);
                applyAllSettings();
                showToast(`🍪 Cookie mode: ${CACHE.cookieConsentMode === 'accept' ? 'Accept' : CACHE.cookieConsentMode === 'reject' ? 'Reject' : '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');
                } else {
                    stopScrollDefeater();
                    showToast('🔒 Auto Anti-Scroll Lock disabled');
                }
            };
        }

        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'}`);
            };
        }

        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)');
                } else {
                    stopBlurRemoval();
                    showToast('👁️ Auto Remove Blur disabled');
                }
            };
        }

        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)');
                } else {
                    stopAutoSkipMonitoring();
                    showToast('⏩ Auto Time Skipper disabled');
                }
            };
        }

        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();
            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(); isSelecting = !isSelecting; e.currentTarget.classList.toggle('active', isSelecting);
            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();
        };

        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'); broadcastState();
        };

        shadowBy('btn-manage').onclick = e => {
            e.stopPropagation(); const p = shadowBy('hider-panel'), isHidden = p.style.display === 'none' || p.style.display === '';
            
            if (isHidden) {
                p.style.display = 'flex';
                void p.offsetWidth;
                p.classList.add('is-visible');
                e.currentTarget.classList.add('active');
                turnOffHideMode(); renderList();
            } else {
                p.classList.remove('is-visible');
                setTimeout(() => p.style.display = 'none', 300);
                e.currentTarget.classList.remove('active');
            }
        };

        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 MANAGER (without edit) ----------
        const cookieListEl = shadowBy('cookie-list');
        const cookieCountEl = shadowBy('cookie-count');
        const cookieSearch = shadowBy('cookie-search');
        const cookieAddBtn = shadowBy('cookie-add');
        const cookieNameInput = shadowBy('cookie-new-name');
        const cookieValueInput = shadowBy('cookie-new-value');
        const cookieExpiryInput = shadowBy('cookie-new-expiry');
        const cookieClearAll = shadowBy('cookie-clear-all');
        const cookieExportBtn = shadowBy('cookie-export');
        const cookieImportBtn = shadowBy('cookie-import');
        const cookieImportFile = shadowBy('cookie-import-file');

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

        function renderCookies(filter = '') {
            if (!cookieListEl) return;
            const cookies = getCookies();
            const filtered = filter ? cookies.filter(c => c.name.toLowerCase().includes(filter.toLowerCase())) : cookies;
            cookieCountEl.textContent = filtered.length;

            if (filtered.length === 0) {
                cookieListEl.innerHTML = `<div style="font-size:9px;color:#94a3b8;text-align:center;padding:4px;">${cookies.length ? 'No matching cookies' : 'No cookies for this domain.'}</div>`;
                return;
            }

            cookieListEl.innerHTML = '';
            filtered.forEach(c => {
                const row = document.createElement('div');
                row.style.cssText = 'display:flex;align-items:center;gap:4px;font-size:9px;padding:2px 4px;background:rgba(255,255,255,.04);border-radius:4px;border:1px solid rgba(255,255,255,0.06);';
                const nameSpan = document.createElement('span');
                nameSpan.textContent = c.name;
                nameSpan.style.cssText = 'font-weight:700;color:#38bdf8;min-width:60px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
                const valSpan = document.createElement('span');
                valSpan.textContent = c.value;
                valSpan.style.cssText = 'flex:1;color:#e2e8f0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';

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

                // Delete button only (no edit)
                const delBtn = document.createElement('button');
                delBtn.className = 'hider-btn-small btn-red';
                delBtn.textContent = '✖';
                delBtn.style.cssText = 'padding:0 4px;height:16px;font-size:7px;';
                delBtn.onclick = (e) => {
                    e.stopPropagation();
                    if (confirm(`Delete cookie "${c.name}"?`)) {
                        // Try multiple deletion variants
                        document.cookie = `${c.name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${location.hostname}`;
                        document.cookie = `${c.name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
                        document.cookie = `${c.name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
                        renderCookies(cookieSearch ? cookieSearch.value : '');
                        showToast(`🍪 Deleted cookie: ${c.name}`);
                    }
                };
                btnGroup.appendChild(delBtn);
                row.appendChild(nameSpan);
                row.appendChild(valSpan);
                row.appendChild(btnGroup);
                cookieListEl.appendChild(row);
            });
        }

        // Add cookie
        function addCookie() {
            const name = cookieNameInput ? cookieNameInput.value.trim() : '';
            const value = cookieValueInput ? cookieValueInput.value.trim() : '';
            const days = cookieExpiryInput ? parseInt(cookieExpiryInput.value, 10) : 0;
            if (!name) { showToast('⚠️ Enter cookie name'); return; }
            let cookieStr = `${name}=${value}; path=/; domain=${location.hostname}`;
            if (days > 0) {
                const exp = new Date(Date.now() + days * 24 * 60 * 60 * 1000);
                cookieStr += `; expires=${exp.toUTCString()}`;
            }
            document.cookie = cookieStr;
            if (cookieNameInput) cookieNameInput.value = '';
            if (cookieValueInput) cookieValueInput.value = '';
            if (cookieExpiryInput) cookieExpiryInput.value = '';
            renderCookies(cookieSearch ? cookieSearch.value : '');
            showToast(`🍪 Added cookie: ${name}`);
        }

        // Clear all cookies for current domain
        function clearAllCookies() {
            if (!confirm('Delete ALL cookies for this domain?')) return;
            const cookies = getCookies();
            cookies.forEach(c => {
                document.cookie = `${c.name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${location.hostname}`;
                document.cookie = `${c.name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
                document.cookie = `${c.name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
            });
            renderCookies(cookieSearch ? cookieSearch.value : '');
            showToast(`🗑️ Cleared ${cookies.length} cookies`);
        }

        // Export cookies
        function exportCookies() {
            const cookies = getCookies();
            const json = JSON.stringify(cookies, 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 = `cookies_${location.hostname}_${new Date().toISOString().slice(0,10)}.json`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
            showToast('🍪 Cookies exported');
        }

        // Import cookies
        function importCookies(file) {
            const reader = new FileReader();
            reader.onload = function(e) {
                try {
                    const data = JSON.parse(e.target.result);
                    if (!Array.isArray(data)) throw new Error('Not an array');
                    data.forEach(c => {
                        if (c.name && c.value !== undefined) {
                            document.cookie = `${c.name}=${c.value}; path=/; domain=${location.hostname}`;
                        }
                    });
                    renderCookies(cookieSearch ? cookieSearch.value : '');
                    showToast(`🍪 Imported ${data.length} cookies`);
                } catch (err) {
                    showToast('❌ Invalid cookie JSON');
                }
            };
            reader.readAsText(file);
        }

        // Event listeners
        if (cookieAddBtn) cookieAddBtn.onclick = addCookie;
        if (cookieNameInput) cookieNameInput.onkeypress = e => e.key === 'Enter' && addCookie();
        if (cookieValueInput) cookieValueInput.onkeypress = e => e.key === 'Enter' && addCookie();
        if (cookieExpiryInput) cookieExpiryInput.onkeypress = e => e.key === 'Enter' && addCookie();
        if (cookieClearAll) cookieClearAll.onclick = clearAllCookies;
        if (cookieExportBtn) cookieExportBtn.onclick = exportCookies;
        if (cookieImportBtn) cookieImportBtn.onclick = () => cookieImportFile?.click();
        if (cookieImportFile) {
            cookieImportFile.onchange = function() {
                if (this.files && this.files[0]) {
                    importCookies(this.files[0]);
                    this.value = '';
                }
            };
        }
        if (cookieSearch) {
            cookieSearch.oninput = function() {
                renderCookies(this.value);
            };
        }

        // Initial render
        renderCookies();

        // ---------- End of Cookie Manager ----------

        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', 'hider_auto_close_modals', 'hider_cookie_consent_mode',
                'hider_auto_accept_age', 'hider_auto_close_logins'
            ];
            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_'))) {
                        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');
        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 custom rules', (rule, idx) => {
                const div = doc.createElement('div'); div.className = 'list-item';
                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></span><div style="display:flex;gap:2px"><button class="hider-btn-small btn-blue btn-edit">✏️</button><button class="hider-btn-small btn-red btn-del">✖</button></div>`;
                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;
            }));
        }

        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);

        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 ----------
    function setupScrollAutoClose() {
        win.addEventListener('scroll', () => {
            if (scrollAnimationFrame) return;
            scrollAnimationFrame = win.requestAnimationFrame(() => {
                scrollAnimationFrame = null;
                closeAllMenus(null);
                closePreviewModal();
            });
        }, { passive: true, capture: true });
    }

    // ---------- Keyboard shortcuts ----------
    window.addEventListener('keydown', e => { if (e.key === 'Escape') { if (isSelecting) { turnOffHideMode(); showToast('🎯 Selection mode cancelled'); } else { closeAllMenus(null, true); closePreviewModal(); } } }, true);

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

    // ---------- Click handling for selection ----------
    window.addEventListener('click', e => {
        const path = e.composedPath?.() || [];
        const isUI = path.some(el => el.id === UI_HOST_ID || el.id === STEPPER_BAR_ID);
        
        if (!isUI) { closeAllMenus(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();
        if (previewElement === e.target) confirmHideSelectedElement();
        else {
            previewElement?.classList.remove('hider-preview-highlight'); stepperStack = [];
            previewElement = e.target; previewElement.classList.add('hider-preview-highlight'); renderTouchStepperUI();
        }
    }, 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;
        if (x <= 40 || x >= (win.innerWidth - 40)) { userApprovedNavigation = true; setTimeout(() => { userApprovedNavigation = false; }, 1500); }
    }, { 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();
            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();
        setupProtectionObserver();
        applyAllSettings();
        if (CACHE.autoTimeSkipper && featuresEnabled) {
            startAutoSkipMonitoring();
        }
    }

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