Greasy Fork is available in English.

YouTube 終極工具

下載高品質影片/音訊,還原消失的回复,以及更多 YouTube 和 YouTube Music 的 VIP 功能。

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

Advertisement:

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

Advertisement:

// ==UserScript==
// @name         YouTube Ultimate Tools
// @name:vi      Bộ Công Cụ YouTube Tối Ưu
// @name:es      Herramientas Definitivas de YouTube
// @name:fr      Outils Ultimes YouTube
// @name:de      Ultimative YouTube-Tools
// @name:pt      Ferramentas Definitivas do YouTube
// @name:ru      YouTube Ultimate Инструменты
// @name:ja      YouTube アルティメット ツール
// @name:zh-CN   YouTube 终极工具
// @name:zh-TW   YouTube 終極工具
// @name:ko      YouTube 얼티밋 도구
// @name:it      Strumenti Definitivi per YouTube
// @description  Download high-quality video/audio, return dislikes, and more VIP features for YouTube and YouTube Music.
// @description:vi Tải video/audio chất lượng cao, hiện nút dislike, và nhiều tính năng VIP khác cho YouTube và YouTube Music.
// @description:es Descarga videos/audio de alta calidad, recupera dislikes y más funciones VIP para YouTube và YouTube Music.
// @description:fr Téléchargez des vidéos/audio de haute qualità, récupérez les dislikes et plus de fonctionnalités VIP pour YouTube và YouTube Music.
// @description:de Laden Sie hochwertige Videos/Audio herunter, stellen Sie Dislikes wieder her und weitere VIP-Funktionen für YouTube và YouTube Music.
// @description:pt Baixe vídeos/áudio de alta qualidade, recupere dislikes e mais recursos VIP para YouTube và YouTube Music.
// @description:ru Скачивайте видео/аудио высокого качества, возвращайте дизлайки и другие VIP-функции для YouTube и YouTube Music.
// @description:ja 高品質なビデオ/オーディオのダウンロード、低評価の表示、YouTubeおよびYouTube Music向けのVIP機能。
// @description:zh-CN 下载高质量视频/音频,还原消失的回复,以及更多 YouTube 和 YouTube Music 的 VIP 功能。
// @description:zh-TW 下載高品質影片/音訊,還原消失的回复,以及更多 YouTube 和 YouTube Music 的 VIP 功能。
// @description:ko 고품질 비디오/오디오 다운로드, 싫어요 표시, YouTube 및 YouTube Music을 위한 더 많은 VIP 기능.
// @description:it Scarica video/audio di alta qualità, ripristina i dislike e altre funzioni VIP per YouTube e YouTube Music.
// @homepage     https://greasyfork.org/users/1597067-nguyen-ngocanh
// @version      0.0.6.0
// @author       Akari, DeveloperMDCM
// @contributor  nvbangg
// @match        *://www.youtube.com/*
// @match        *://music.youtube.com/*
// @match        *://*.music.youtube.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant        GM_info
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        unsafeWindow
// @run-at       document-end
// @grant        GM_registerMenuCommand
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/js/iziToast.min.js
// @compatible   chrome
// @compatible   firefox
// @compatible   opera
// @compatible   safari
// @compatible   edge
// @license      GPL-3.0
// @namespace    https://greasyfork.org/users/1597067-nguyen-ngocanh
// @keywords     youtube, download, mp3, mp4, high quality, return dislikes, tools
// ==/UserScript==

(function () {
    'use strict';
    let validoUrl = document.location.href;
    const isYTMusic = location.hostname === 'music.youtube.com';
    const SETTINGS_KEY = isYTMusic ? 'ytmSettingsMDCM' : 'ytSettingsMDCM';
    const $e = (el) => document.querySelector(el); // any element
    const $id = (el) => document.getElementById(el); // element by id
    const $m = (el) => document.querySelectorAll(el); // multiple all elements
    const $cl = (el) => document.createElement(el); // create element
    const $sp = (el, pty) => document.documentElement.style.setProperty(el, pty); // set property variable css
    const $ap = (el) => document.body.appendChild(el); // append element
    const apiDislikes = "https://returnyoutubedislikeapi.com/Votes?videoId="; // Api dislikes
    const apiGoogleTranslate = "https://translate.googleapis.com/translate_a/t"; // Api google translate
    let selectedBgColor = "#252525"; // Background color menu default
    let selectedTextColor = "#ffffff"; // Text color menu default
    let selectedBgAccentColor = "#ff0000"; // Accent color menu default
    const urlSharedCode = "https://greasyfork.org/scripts/576162-youtube-ultimate-tools";
    const API_URL_AUDIO_VIDEO = "https://p.savenow.to/ajax/download.php?copyright=0&allow_extended_duration=1&" // API URL AUDIO VIDEO
    const API_KEY_DEVELOPERMDCM = 'dfcb6d76f2f6a9894gjkege8a4ab232222'; // API KEY FOR DOWNLOAD AUDIO VIDEO
    // Download API fallbacks (region/session issues)
    const DOWNLOAD_API_FALLBACK_BASES = [
        "https://p.savenow.to",
        "https://p.lbserver.xyz",
    ];
    // Alternative provider fallback
    const DUBS_START_ENDPOINT = "https://dubs.io/wp-json/tools/v1/download-video";
    const DUBS_STATUS_ENDPOINT = "https://dubs.io/wp-json/tools/v1/status-video";

    // for translate comments video

    const languagesTranslate = {
        "vi": "Vietnamese",
        "en": "English",
        "es": "Spanish",
        "fr": "French",
        "ja": "Japanese",
        "zh-CN": "Chinese (Simplified)",
        "ko": "Korean",
        "ru": "Russian",
        "de": "German",
        "pt": "Portuguese",
        "zh-TW": "Chinese (Traditional)",
        "it": "Italian"
    };



    // var for wave
    let currentVideo = null;

    let waveStyle = 'dinamica';
    let audioCtx = null;
    let analyser = null;
    let source = null;
    let animationId = null;
    let canvas = null;
    let ctx = null;
    let controlPanel = null;
    let bufferLength = 0;
    let dataArray = null;
    let smoothedData = [];
    let isSetup = false;
    const smoothingFactor = 0.05;
    const canvasHeight = 240;
    const scale = canvasHeight / 90;

    const PROCESSED_FLAG = 'wave_visualizer_processed';


    // ------------------------------
    // PERF: runtime guards + dynamic style (avoid style/event/interval leaks)

    let validoBotones = true;

    // ------------------------------
    const __ytToolsRuntime = {
        dynamicStyleEl: null,
        dynamicCssLast: '',
        settingsLoaded: false,
        bookmarkClickHandlerInitialized: false,
        bookmarksPanelOpen: false,
        continueWatching: {
            enabled: false,
            map: null,
            flushT: null,
            boundVideo: null,
            boundVideoId: null,
            lastSaveAt: 0,
            lastSavedTime: -1,
            lastKnownVideoId: null,
            navHandlerInitialized: false,
            panelOpen: false,
            clickHandlerInitialized: false,
            pagehideHandlerInitialized: false,
            handlers: null,
        },
        shortsChannelName: {
            enabled: false,
            observer: null,
            io: null,
            scanT: null,
            cache: new Map(), // videoId -> channelName
            inflight: new Map(), // videoId -> Promise<string>
            fetchChain: Promise.resolve(),
        },
        dislikesCache: {
            videoId: null,
            dislikes: null,
            ts: 0,
        },
        downloadClickHandlerInitialized: false,
        shortsObserver: null,
        statsObserver: null,
        statsIntervalId: null,
        lockupCachedStatsObserver: null,
        lockupCachedStatsObserveTarget: null,
        lockupCachedStatsIntervalId: null,
        updateShortsViewsButton: function () { },
        updateShortsRatingButton: function () { },
        nonstopPlayback: {
            enabled: false,
            hiddenDescriptor: null,
            visibilityStateDescriptor: null,
            blockVisibilityEvent: null,
            keepAliveTimer: null,
        },
        audioOnly: {
            enabled: false,
            lastArtUrl: '',
            refreshTimer: null,
        },
    };


    function setDynamicCss(cssText = '') {
        if (!__ytToolsRuntime.dynamicStyleEl) {
            const style = document.createElement('style');
            style.id = 'yt-tools-mdcm-dynamic-style';
            document.head.appendChild(style);
            __ytToolsRuntime.dynamicStyleEl = style;
        }
        if (__ytToolsRuntime.dynamicCssLast === cssText) return;
        __ytToolsRuntime.dynamicCssLast = cssText;
        __ytToolsRuntime.dynamicStyleEl.textContent = cssText;
    }


    function paramsVideoURL() {
        const parametrosURL = new URLSearchParams(window.location.search);
        return parametrosURL.get('v');
    }

    function isWatchPage() {
        return window.location.href.includes('youtube.com/watch');
    }

    function checkDarkModeActive() {
        const htmlElement = document.documentElement;
        const isDarkModeYT = htmlElement.hasAttribute('dark') || htmlElement.getAttribute('style')?.includes('color-scheme: dark');
        const isDarkModeYTM = document.querySelector('ytmusic-app')?.hasAttribute('dark');
        return !!(isDarkModeYT || isDarkModeYTM);
    }

    function FormatterNumber(num, digits) {
        const lookup = [
            { value: 1, symbol: "" },
            { value: 1e3, symbol: "k" },
            { value: 1e6, symbol: "M" },
            { value: 1e9, symbol: "G" },
            { value: 1e12, symbol: "T" },
            { value: 1e15, symbol: "P" },
            { value: 1e18, symbol: "E" }
        ];
        const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
        const item = lookup.slice().reverse().find(function (item) {
            return num >= item.value;
        });
        return item ? (num / item.value).toFixed(digits).replace(rx, "$1") + item.symbol : "0";
    }

    const scheduleApplySettings = (() => {
        let t = null;
        return () => {
            // Prevent overwriting saved config with defaults before loadSettings finishes.
            if (!__ytToolsRuntime.settingsLoaded) return;
            clearTimeout(t);
            t = setTimeout(() => {
                try {
                    applySettings();
                } catch (err) {
                    console.error('applySettings error:', err);
                }
            }, 120);
        };
    })();


    // Create a Trusted Types policy
    let policy = null;
    try {
        const tt = (typeof unsafeWindow !== 'undefined' ? unsafeWindow.trustedTypes : window.trustedTypes);
        if (tt) {
            try {
                policy = tt.createPolicy('yt-tools-mdcm', {
                    createHTML: (s) => s
                });
            } catch (e) {
                policy = tt.defaultPolicy || null;
            }
        }
    } catch (e) {
        policy = null;
    }

    function safeHTML(str) {
        if (policy && typeof policy.createHTML === 'function') return policy.createHTML(str);
        return str;
    }
    // ------------------------------
    // Feature helpers: videoId / channelId / storage

    // ------------------------------
    const STORAGE_KEYS_MDCM = {
        BOOKMARKS: 'ytBookmarksMDCM',
        CONTINUE_WATCHING: 'ytContinueWatchingMDCM',
        SHORTS_CHANNEL_CACHE: 'ytShortsChannelCacheMDCM',
        LIKES_DISLIKES_CACHE: 'ytLikesDislikesCacheMDCM',
        VERSION_CHECK_LAST: 'ytVersionCheckLastMDCM',
    };

    const UPDATE_META_URL = 'https://update.greasyfork.org/scripts/576162/YouTube%20Ultimate%20Tools.meta.js';
    const VERSION_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // once per day

    const SHORTS_CHANNEL_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
    const LIKES_DISLIKES_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
    const PERSISTED_CACHE_MAX_ENTRIES = 500;

    function getShortsChannelFromPersistedCache(videoId) {
        try {
            const map = readJsonGM(STORAGE_KEYS_MDCM.SHORTS_CHANNEL_CACHE, {});
            const entry = map?.[videoId];
            if (!entry || typeof entry.channelName !== 'string') return null;
            const age = Date.now() - (Number(entry.ts) || 0);
            if (age > SHORTS_CHANNEL_TTL_MS) return null;
            return entry.channelName;
        } catch (e) {
            return null;
        }
    }

    function setShortsChannelToPersistedCache(videoId, channelName) {
        if (!videoId || typeof channelName !== 'string') return;
        try {
            const map = readJsonGM(STORAGE_KEYS_MDCM.SHORTS_CHANNEL_CACHE, {});
            map[videoId] = {
                channelName,
                ts: Date.now()
            };
            const entries = Object.entries(map).sort((a, b) => (Number(b[1]?.ts) || 0) - (Number(a[1]?.ts) || 0));
            const pruned = Object.fromEntries(entries.slice(0, PERSISTED_CACHE_MAX_ENTRIES));
            writeJsonGM(STORAGE_KEYS_MDCM.SHORTS_CHANNEL_CACHE, pruned);
        } catch (e) { }
    }

    function getLikesDislikesFromPersistedCache(videoId) {
        try {
            const map = readJsonGM(STORAGE_KEYS_MDCM.LIKES_DISLIKES_CACHE, {});
            const entry = map?.[videoId];
            if (!entry) return null;
            const age = Date.now() - (Number(entry.ts) || 0);
            if (age > LIKES_DISLIKES_TTL_MS) return null;
            const dislikes = Number(entry.dislikes);
            const likes = Number(entry.likes);
            const viewCount = Number(entry.viewCount);
            const rating = Number(entry.rating);
            return {
                likes: Number.isFinite(likes) ? likes : null,
                dislikes: Number.isFinite(dislikes) ? dislikes : null,
                viewCount: Number.isFinite(viewCount) ? viewCount : null,
                rating: Number.isFinite(rating) && rating >= 0 && rating <= 5 ? rating : null,
            };
        } catch (e) {
            return null;
        }
    }

    function setLikesDislikesToPersistedCache(videoId, likes, dislikes, viewCount, rating) {
        if (!videoId) return;
        try {
            const map = readJsonGM(STORAGE_KEYS_MDCM.LIKES_DISLIKES_CACHE, {});
            map[videoId] = {
                likes: likes ?? null,
                dislikes: dislikes ?? null,
                viewCount: viewCount ?? null,
                rating: rating ?? null,
                ts: Date.now()
            };
            const entries = Object.entries(map).sort((a, b) => (Number(b[1]?.ts) || 0) - (Number(a[1]?.ts) || 0));
            const pruned = Object.fromEntries(entries.slice(0, Math.min(PERSISTED_CACHE_MAX_ENTRIES, 300)));
            writeJsonGM(STORAGE_KEYS_MDCM.LIKES_DISLIKES_CACHE, pruned);
        } catch (e) { }
    }

    function getCurrentVideoId() {
        try {
            if (location.pathname.startsWith('/shorts/')) {
                const parts = location.pathname.split('/').filter(Boolean);
                return parts[1] || null;
            }
            if (location.href.includes('youtube.com/watch')) {
                return paramsVideoURL();
            }
            return null;
        } catch (e) {
            return null;
        }
    }


    function readJsonGM(key, fallback) {
        try {
            const raw = GM_getValue(key, '');
            if (!raw) return fallback;
            return JSON.parse(raw);
        } catch (e) {
            return fallback;
        }
    }

    function writeJsonGM(key, value) {
        try {
            GM_setValue(key, JSON.stringify(value));
        } catch (e) {
            console.error('writeJsonGM error:', e);
        }
    }

    const AUDIO_ONLY_TAB_OVERRIDE_KEY = 'ytToolsAudioOnlyTabOverrideMDCM';

    // Feature source/inspiration:
    // Nonstop & Audio Only for YouTube & YouTube Music
    // Author: nvbangg / Nguyen Van Bang
    // Repo: https://github.com/nvbangg/Nonstop_Audio_Only_for_Youtube_YTMusic
    // Greasy Fork: https://greasyfork.org/scripts/546130
    // Source license: GPL-3.0. This userscript implements an independent adaptation of the behavior.
    function applyNonstopPlayback(enabled) {
        const rt = __ytToolsRuntime.nonstopPlayback;
        if (enabled && rt.enabled) return;
        if (!enabled && !rt.enabled) return;

        if (enabled) {
            rt.enabled = true;
            rt.hiddenDescriptor = Object.getOwnPropertyDescriptor(document, 'hidden') || null;
            rt.visibilityStateDescriptor = Object.getOwnPropertyDescriptor(document, 'visibilityState') || null;
            try {
                Object.defineProperties(document, {
                    hidden: { configurable: true, get: () => false },
                    visibilityState: { configurable: true, get: () => 'visible' },
                });
            } catch (e) {
                console.warn('[YT Tools] Could not override visibility state:', e);
            }

            rt.blockVisibilityEvent = (event) => {
                event.stopImmediatePropagation();
            };
            document.addEventListener('visibilitychange', rt.blockVisibilityEvent, true);
            window.addEventListener('visibilitychange', rt.blockVisibilityEvent, true);

            const refreshActivity = () => {
                try {
                    const pageWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
                    if ('_lact' in pageWindow) pageWindow._lact = Date.now();
                } catch (e) { }
            };
            refreshActivity();
            rt.keepAliveTimer = setInterval(refreshActivity, 60000);
            return;
        }

        rt.enabled = false;
        if (rt.blockVisibilityEvent) {
            document.removeEventListener('visibilitychange', rt.blockVisibilityEvent, true);
            window.removeEventListener('visibilitychange', rt.blockVisibilityEvent, true);
            rt.blockVisibilityEvent = null;
        }
        if (rt.keepAliveTimer) {
            clearInterval(rt.keepAliveTimer);
            rt.keepAliveTimer = null;
        }
        try {
            if (rt.hiddenDescriptor) Object.defineProperty(document, 'hidden', rt.hiddenDescriptor);
            else delete document.hidden;
            if (rt.visibilityStateDescriptor) Object.defineProperty(document, 'visibilityState', rt.visibilityStateDescriptor);
            else delete document.visibilityState;
        } catch (e) { }
        rt.hiddenDescriptor = null;
        rt.visibilityStateDescriptor = null;
    }

    function getAudioOnlyTabOverride() {
        const value = sessionStorage.getItem(AUDIO_ONLY_TAB_OVERRIDE_KEY);
        if (value === 'true') return true;
        if (value === 'false') return false;
        return null;
    }

    function setAudioOnlyTabOverride(enabled, defaultEnabled) {
        if (!!enabled === !!defaultEnabled) {
            sessionStorage.removeItem(AUDIO_ONLY_TAB_OVERRIDE_KEY);
            return;
        }
        sessionStorage.setItem(AUDIO_ONLY_TAB_OVERRIDE_KEY, enabled ? 'true' : 'false');
    }

    function getEffectiveAudioOnly(settings) {
        const override = getAudioOnlyTabOverride();
        return override === null ? !!settings?.audioOnly : override;
    }

    function syncAudioOnlyTabCheckbox(settings) {
        const tabToggle = $id('audio-only-tab-toggle');
        if (!tabToggle) return;
        tabToggle.checked = getEffectiveAudioOnly(settings);
        tabToggle.title = getAudioOnlyTabOverride() === null ?
            'Following the global Audio-only mode setting' :
            'Audio-only override is active for this browser tab';
    }

    function getActiveAudioOnlyVideo() {
        const videos = Array.from(document.querySelectorAll('video'));
        if (isYTMusic) return videos[0] || null;
        return videos.find((video) => {
            const rect = video.getBoundingClientRect();
            return rect.width > 0 && rect.height > 0;
        }) || videos[0] || null;
    }

    async function getAudioOnlyThumbnailUrl() {
        try {
            const moviePlayer = document.getElementById('movie_player');
            if (moviePlayer && typeof moviePlayer.getVideoData === 'function') {
                const data = moviePlayer.getVideoData();
                if (data?.video_id) return `https://i.ytimg.com/vi/${data.video_id}/hqdefault.jpg`;
            }
        } catch (e) { }

        const videoId = getCurrentVideoId() || paramsVideoURL();
        if (!videoId) return '';
        const host = isYTMusic ? 'i1.ytimg.com' : 'img.youtube.com';
        return `https://${host}/vi/${videoId}/hqdefault.jpg`;
    }

    async function applyAudioOnlyMode(enabled) {
        const rt = __ytToolsRuntime.audioOnly;
        rt.enabled = !!enabled;
        document.body.classList.toggle('yt-tools-audio-only-active', rt.enabled);

        document.querySelectorAll('.yt-tools-audio-only-video').forEach((el) => el.classList.remove('yt-tools-audio-only-video'));
        document.querySelectorAll('.yt-tools-audio-only-player').forEach((el) => el.classList.remove('yt-tools-audio-only-player'));

        if (!rt.enabled) {
            rt.lastArtUrl = '';
            setAudioOnlyBackground('');
            if (rt.refreshTimer) {
                clearInterval(rt.refreshTimer);
                rt.refreshTimer = null;
            }
            return;
        }

        const video = getActiveAudioOnlyVideo();
        const player = video?.parentNode?.parentNode || video?.parentElement || null;
        if (video) video.classList.add('yt-tools-audio-only-video');
        if (player) player.classList.add('yt-tools-audio-only-player');

        const artUrl = await getAudioOnlyThumbnailUrl();
        if (artUrl && artUrl !== rt.lastArtUrl) {
            rt.lastArtUrl = artUrl;
            setAudioOnlyBackground(artUrl);
        }

        if (!rt.refreshTimer) {
            rt.refreshTimer = setInterval(() => {
                if (document.visibilityState !== 'visible') return;
                const settings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
                applyAudioOnlyMode(getEffectiveAudioOnly(settings));
            }, 3000);
        }
    }

    function setAudioOnlyBackground(url) {
        let style = $id('yt-tools-audio-only-style');
        if (!style) {
            style = document.createElement('style');
            style.id = 'yt-tools-audio-only-style';
            document.documentElement.appendChild(style);
        }
        style.textContent = url ? `.yt-tools-audio-only-player{background-image:url("${url}")!important;}` : '';
    }

    function isVersionNewer(latestStr, currentStr) {
        if (!latestStr || !currentStr) return false;
        const parse = (s) => String(s).trim().split('.').map((n) => parseInt(n, 10) || 0);
        const a = parse(latestStr);
        const b = parse(currentStr);
        const len = Math.max(a.length, b.length);
        for (let i = 0; i < len; i++) {
            const x = a[i] || 0;
            const y = b[i] || 0;
            if (x > y) return true;
            if (x < y) return false;
        }
        return false;
    }

    async function checkNewVersion() {
        try {
            const last = GM_getValue(STORAGE_KEYS_MDCM.VERSION_CHECK_LAST, 0);
            if (Date.now() - last < VERSION_CHECK_INTERVAL_MS) return;
            GM_setValue(STORAGE_KEYS_MDCM.VERSION_CHECK_LAST, Date.now());

            const res = await fetch(UPDATE_META_URL, {
                cache: 'no-store'
            });
            if (!res.ok) return;
            const text = await res.text();
            const m = text.match(/@version\s+([\d.]+)/);
            if (!m) return;
            const latestVer = m[1].trim();
            const currentVer = (typeof GM_info !== 'undefined' && GM_info.script && GM_info.script.version) ?
                String(GM_info.script.version).trim() :
                '';
            if (!currentVer || !isVersionNewer(latestVer, currentVer)) return;

            const updateUrl = 'https://update.greasyfork.org/scripts/576162/YouTube%20Ultimate%20Tools.user.js';
            iziToast.show({
                title: 'New Update',
                message: 'A new version YoutubeTools is available.',
                buttons: [
                    ['<button>View Now</button>', function (instance, toast) {
                        window.open(updateUrl, '_blank');
                        instance.hide({
                            transitionOut: 'fadeOut'
                        }, toast, 'button');
                    }, true] // true = focus
                ]
            });
        } catch (e) {
            // silent: network or parse error
        }
    }

    function formatTimeShort(sec) {
        const s = Math.max(0, Math.floor(Number(sec) || 0));
        const h = Math.floor(s / 3600);
        const m = Math.floor((s % 3600) / 60);
        const r = s % 60;
        return h > 0 ? `${h}:${String(m).padStart(2, '0')}:${String(r).padStart(2, '0')}` : `${m}:${String(r).padStart(2, '0')}`;
    }




    // ------------------------------
    // Feature: History / Continue watching (per video)

    // ------------------------------
    function getMainVideoEl() {
        return (
            document.querySelector('#movie_player video.video-stream.html5-main-video') ||
            document.querySelector('ytd-player video.video-stream.html5-main-video') ||
            document.querySelector('video.video-stream.html5-main-video') ||
            document.querySelector('video')
        );
    }

    function getCurrentVideoMeta() {
        try {
            // DOM first (updates earlier on SPA navigation)
            const domTitle =
                $e('ytd-watch-metadata h1 yt-formatted-string')?.textContent?.trim() ||
                $e('h1.ytd-watch-metadata yt-formatted-string')?.textContent?.trim() ||
                '';
            const domAuthor =
                $e('#owner ytd-channel-name a, ytd-video-owner-renderer ytd-channel-name a, #text-container.ytd-channel-name a')?.textContent?.trim() ||
                $e('#owner a[href^="/@"], #owner a[href^="/channel/"]')?.textContent?.trim() ||
                '';
            const titleFromDom = (domTitle || document.title || '').replace(/\s*-\s*YouTube\s*$/i, '').trim();
            const authorFromDom = (domAuthor || '').trim();

            const w = (typeof unsafeWindow !== 'undefined' && unsafeWindow) ? unsafeWindow : window;
            const pr = w?.ytInitialPlayerResponse || window.ytInitialPlayerResponse;
            const vd = pr?.videoDetails || null;
            const title = (titleFromDom || vd?.title || document.title || '').replace(/\s*-\s*YouTube\s*$/i, '').trim();
            const author = (authorFromDom || vd?.author || '').trim();
            const thumbs = vd?.thumbnail?.thumbnails;
            const thumb = Array.isArray(thumbs) ? (thumbs[thumbs.length - 1]?.url || '') : '';
            return {
                title,
                author,
                thumb
            };
        } catch (e) {
            return {
                title: '',
                author: '',
                thumb: ''
            };
        }
    }

    function ensureContinueWatchingMapLoaded() {
        const rt = __ytToolsRuntime.continueWatching;
        if (!rt.map) rt.map = readJsonGM(STORAGE_KEYS_MDCM.CONTINUE_WATCHING, {});
        if (typeof rt.map !== 'object' || !rt.map) rt.map = {};
        return rt.map;
    }

    function pruneContinueWatchingMap(map, maxEntries = 200) {
        try {
            const entries = Object.entries(map || {}).filter(([, v]) => v && typeof v === 'object');
            entries.sort((a, b) => (Number(b[1].updatedAt) || 0) - (Number(a[1].updatedAt) || 0));
            const keep = entries.slice(0, maxEntries);
            const next = {};
            for (const [k, v] of keep) next[k] = v;
            return next;
        } catch (e) {
            return map || {};
        }
    }

    function scheduleContinueWatchingFlush() {
        const rt = __ytToolsRuntime.continueWatching;
        clearTimeout(rt.flushT);
        rt.flushT = setTimeout(() => {
            try {
                if (!rt.map) return;
                rt.map = pruneContinueWatchingMap(rt.map, 200);
                writeJsonGM(STORAGE_KEYS_MDCM.CONTINUE_WATCHING, rt.map);
            } catch (e) { }
        }, 800);
    }

    function clearContinueWatchingForVideo(videoId) {
        if (!videoId) return;
        const rt = __ytToolsRuntime.continueWatching;
        const map = ensureContinueWatchingMapLoaded();
        if (map && Object.prototype.hasOwnProperty.call(map, videoId)) {
            delete map[videoId];
            rt.map = map;
            scheduleContinueWatchingFlush();
        }
    }

    function setContinueWatchingForVideo(videoId, seconds, durationSec) {
        if (!videoId) return;
        const rt = __ytToolsRuntime.continueWatching;
        const map = ensureContinueWatchingMapLoaded();
        const t = Math.max(0, Math.floor(Number(seconds) || 0));
        const d = Math.max(0, Math.floor(Number(durationSec) || 0));
        const prev = map[videoId] && typeof map[videoId] === 'object' ? map[videoId] : {};
        const meta = getCurrentVideoMeta();
        map[videoId] = {
            t,
            d,
            updatedAt: Date.now(),
            title: meta.title || prev.title || '',
            author: meta.author || prev.author || '',
            thumb: meta.thumb || prev.thumb || '',
        };
        rt.map = map;
        scheduleContinueWatchingFlush();
    }

    function getContinueWatchingTime(videoId) {
        if (!videoId) return null;
        const map = ensureContinueWatchingMapLoaded();
        const entry = map?.[videoId];
        const t = Number(entry?.t);
        return Number.isFinite(t) ? t : null;
    }

    function updateContinueWatchingButton() {
        const rt = __ytToolsRuntime.continueWatching;
        const enabled = !!rt.enabled;
        if (!enabled || !isWatchPage()) return;

        const videoId = getCurrentVideoId();
        if (!videoId) return;

        const v = getMainVideoEl();
        const t = getContinueWatchingTime(videoId);
        const dur = Number(v?.duration);
        const hasDur = Number.isFinite(dur) && dur > 0;

        if (!t || t < 5) return;

        if (hasDur && t >= (dur - 5)) {
            clearContinueWatchingForVideo(videoId);
            return;
        }
    }

    function updateContinueWatchingHistoryUi() {
        const rt = __ytToolsRuntime.continueWatching;
        const btn = $id('yt-cw-history-toggle');
        const panel = $id('yt-continue-watching-panel');
        if (!btn || !panel) return;

        const enabled = !!rt.enabled;
        if (!enabled || !isWatchPage()) {
            btn.style.display = 'none';
            panel.style.display = 'none';
            return;
        }

        btn.style.display = 'inline-flex';
        panel.style.display = rt.panelOpen ? 'block' : 'none';
    }

    function cssEscapeLite(s) {
        const str = String(s || '');
        if (typeof CSS !== 'undefined' && CSS.escape) return CSS.escape(str);
        // minimal escape for attribute selector
        return str.replace(/["\\]/g, '\\$&');
    }

    function updateContinueWatchingPanelRow(videoId) {
        try {
            const rt = __ytToolsRuntime.continueWatching;
            if (!rt.enabled || !rt.panelOpen || !isWatchPage()) return false;
            const panel = $id('yt-continue-watching-panel');
            if (!panel) return false;

            const key = cssEscapeLite(videoId);
            const row = panel.querySelector(`.yt-cw-item[data-video-id="${key}"]`);
            if (!row) return false;

            const entry = ensureContinueWatchingMapLoaded()?.[videoId];
            const t = Number(entry?.t);
            if (!Number.isFinite(t)) return false;

            const meta = row.querySelector('.yt-cw-meta');
            if (!meta) return false;
            const author = String(entry?.author || '').trim();
            meta.textContent = `${formatTimeShort(t)}${author ? ` • ${author}` : ''}`;
            return true;
        } catch (e) {
            return false;
        }
    }

    function navigateToWatchSpa(videoId, seconds) {
        const t = Number(seconds);
        const url = `/watch?v=${encodeURIComponent(videoId)}${Number.isFinite(t) ? `&t=${Math.max(0, Math.floor(t))}s` : ''}`;
        try {
            const a = document.createElement('a');
            a.href = url;
            a.target = '_self';
            a.rel = 'noopener';
            a.style.display = 'none';
            document.body.appendChild(a);
            a.click();
            a.remove();
            return;
        } catch (e) { }
        location.href = url;
    }

    function renderContinueWatchingPanel() {
        const panel = $id('yt-continue-watching-panel');
        if (!panel) return;

        const rt = __ytToolsRuntime.continueWatching;
        if (!rt.enabled || !rt.panelOpen || !isWatchPage()) {
            panel.style.display = 'none';
            return;
        }

        const map = pruneContinueWatchingMap(ensureContinueWatchingMapLoaded(), 200);
        rt.map = map;
        const currentVid = getCurrentVideoId();

        const entries = Object.entries(map)
            .map(([videoId, v]) => ({
                videoId,
                ...v
            }))
            .filter((e) => e.videoId && Number.isFinite(Number(e.t)) && Number(e.t) >= 5)
            .sort((a, b) => (Number(b.updatedAt) || 0) - (Number(a.updatedAt) || 0))
            .slice(0, 25);

        panel.replaceChildren();

        const header = document.createElement('div');
        header.className = 'yt-cw-header';

        const hTitle = document.createElement('div');
        hTitle.className = 'yt-cw-header-title';
        hTitle.textContent = 'Continue watching';

        const clearAll = document.createElement('button');
        clearAll.type = 'button';
        clearAll.className = 'yt-cw-clear';
        clearAll.textContent = 'Clear';
        clearAll.dataset.cwAction = 'clearAll';

        header.appendChild(hTitle);
        header.appendChild(clearAll);
        panel.appendChild(header);

        if (!entries.length) {
            const empty = document.createElement('div');
            empty.className = 'yt-cw-empty';
            empty.textContent = 'No history yet. Watch a bit, then reopen any video.';
            panel.appendChild(empty);
            return;
        }

        for (const e of entries) {
            const item = document.createElement('div');
            item.className = 'yt-cw-item';
            item.dataset.videoId = e.videoId;

            const thumbWrap = document.createElement('div');
            thumbWrap.className = 'yt-cw-thumb-wrap';
            const img = document.createElement('img');
            img.className = 'yt-cw-thumb';
            img.loading = 'lazy';
            img.decoding = 'async';
            img.alt = '';
            const thumbSrc = (e.thumb || '').trim() || `https://i.ytimg.com/vi/${encodeURIComponent(e.videoId)}/hqdefault.jpg`;
            img.src = thumbSrc;
            thumbWrap.appendChild(img);

            const info = document.createElement('div');
            info.className = 'yt-cw-info';

            const title = document.createElement('div');
            title.className = 'yt-cw-title';
            const safeTitle = (e.title || '').trim();
            title.textContent = safeTitle ? safeTitle : e.videoId;

            const meta = document.createElement('div');
            meta.className = 'yt-cw-meta';
            const author = (e.author || '').trim();
            meta.textContent = `${formatTimeShort(e.t)}${author ? ` • ${author}` : ''}`;

            info.appendChild(title);
            info.appendChild(meta);

            const actions = document.createElement('div');
            actions.className = 'yt-cw-actions';

            const tSec = Math.max(0, Math.floor(Number(e.t) || 0));
            let go = null;
            if (currentVid && currentVid === e.videoId) {
                const seek = document.createElement('button');
                seek.type = 'button';
                seek.className = 'yt-cw-go';
                seek.textContent = 'Resume';
                seek.dataset.cwAction = 'seek';
                seek.dataset.t = String(tSec);
                go = seek;
            } else {
                const a = document.createElement('a');
                a.className = 'yt-simple-endpoint yt-cw-go';
                a.textContent = 'Resume';
                a.href = `/watch?v=${encodeURIComponent(e.videoId)}&t=${tSec}s`;
                a.target = '_self';
                a.rel = 'noopener';
                go = a;
            }

            const del = document.createElement('button');
            del.type = 'button';
            del.className = 'yt-cw-del';
            del.textContent = '✕';
            del.title = 'Delete';
            del.dataset.cwAction = 'del';
            del.dataset.videoId = e.videoId;

            actions.appendChild(go);
            actions.appendChild(del);

            item.appendChild(thumbWrap);
            item.appendChild(info);
            item.appendChild(actions);
            panel.appendChild(item);
        }
    }

    function setupContinueWatchingFeature(enabled) {
        const rt = __ytToolsRuntime.continueWatching;
        rt.enabled = !!enabled;

        // Keep UI in sync across YouTube SPA navigations
        if (!rt.navHandlerInitialized) {
            rt.navHandlerInitialized = true;
            const onNav = () => {
                try {
                    const vid = getCurrentVideoId();
                    if (rt.lastKnownVideoId !== vid) {
                        rt.lastKnownVideoId = vid;
                        // reset throttles so new video can save properly
                        rt.lastSaveAt = 0;
                        rt.lastSavedTime = -1;
                        rt.boundVideoId = vid;
                        updateContinueWatchingButton();
                        updateContinueWatchingHistoryUi();
                        if (rt.panelOpen) renderContinueWatchingPanel();
                    } else {
                        updateContinueWatchingButton();
                        updateContinueWatchingHistoryUi();
                        if (rt.panelOpen) renderContinueWatchingPanel();
                    }
                } catch (e) { }
            };
            window.addEventListener('yt-navigate-finish', onNav, true);
            window.addEventListener('popstate', onNav, true);
            window.addEventListener('hashchange', onNav, true);
        }

        // Ensure click handler only once
        if (!rt.clickHandlerInitialized) {
            rt.clickHandlerInitialized = true;
            document.addEventListener('click', (e) => {
                const target = e.target;
                if (!(target instanceof Element)) return;
                const historyBtn = target.closest('#yt-cw-history-toggle');
                const cwActionBtn = target.closest('[data-cw-action]');

                if (historyBtn) {
                    e.preventDefault();
                    e.stopPropagation();
                    rt.panelOpen = !rt.panelOpen;
                    updateContinueWatchingHistoryUi();
                    if (rt.panelOpen) renderContinueWatchingPanel(); // render only when opened
                    return;
                }

                if (cwActionBtn) {
                    const action = cwActionBtn.getAttribute('data-cw-action');
                    if (!action) return;
                    e.preventDefault();
                    e.stopPropagation();
                    if (action === 'clearAll') {
                        rt.map = {};
                        writeJsonGM(STORAGE_KEYS_MDCM.CONTINUE_WATCHING, {});
                        renderContinueWatchingPanel();
                        updateContinueWatchingButton();
                        try {
                            Notify('success', 'History cleared');
                        } catch (e2) { }
                        return;
                    }
                    if (action === 'del') {
                        const vid = cwActionBtn.getAttribute('data-video-id') || '';
                        if (vid) clearContinueWatchingForVideo(vid);
                        renderContinueWatchingPanel();
                        updateContinueWatchingButton();
                        return;
                    }
                    if (action === 'seek') {
                        const t = Number(cwActionBtn.getAttribute('data-t'));
                        const v = getMainVideoEl();
                        if (!v || !Number.isFinite(t)) return;
                        v.currentTime = Math.max(0, t);
                        v.play?.().catch(() => { });
                        try {
                            Notify('success', `Resume: ${formatTimeShort(t)}`);
                        } catch (e2) { }
                        updateContinueWatchingButton();
                        return;
                    }
                }
            }, true);
        }

        // Save on tab close / navigation (once)
        if (!rt.pagehideHandlerInitialized) {
            rt.pagehideHandlerInitialized = true;
            window.addEventListener('pagehide', () => {
                try {
                    if (!rt.enabled) return;
                    if (!isWatchPage()) return;
                    const vid = getCurrentVideoId();
                    const v = getMainVideoEl();
                    if (!vid || !v) return;
                    const t = Number(v.currentTime);
                    const d = Number(v.duration);
                    if (Number.isFinite(t) && t >= 5) setContinueWatchingForVideo(vid, t, d);
                    // best-effort immediate flush
                    if (rt.flushT) {
                        clearTimeout(rt.flushT);
                        rt.flushT = null;
                    }
                    if (rt.map) writeJsonGM(STORAGE_KEYS_MDCM.CONTINUE_WATCHING, pruneContinueWatchingMap(rt.map, 200));
                } catch (e) { }
            }, {
                capture: true
            });
        }

        const historyBtn = $id('yt-cw-history-toggle');
        const panel = $id('yt-continue-watching-panel');
        if (historyBtn && !rt.enabled) historyBtn.style.display = 'none';
        if (panel && !rt.enabled) panel.style.display = 'none';

        // Not on watch page: detach video listeners and hide
        if (!rt.enabled || !isWatchPage()) {
            try {
                if (rt.boundVideo && rt.handlers) {
                    rt.boundVideo.removeEventListener('timeupdate', rt.handlers.timeupdate);
                    rt.boundVideo.removeEventListener('pause', rt.handlers.pause);
                    rt.boundVideo.removeEventListener('ended', rt.handlers.ended);
                    rt.boundVideo.removeEventListener('loadedmetadata', rt.handlers.loadedmetadata);
                    rt.boundVideo.removeEventListener('seeked', rt.handlers.seeked);
                }
            } catch (e) { }
            rt.boundVideo = null;
            rt.boundVideoId = null;
            rt.handlers = null;
            updateContinueWatchingButton();
            updateContinueWatchingHistoryUi();
            return;
        }

        const v = getMainVideoEl();
        const videoId = getCurrentVideoId();
        if (!v || !videoId) {
            updateContinueWatchingButton();
            updateContinueWatchingHistoryUi();
            return;
        }

        // VideoId can change while YouTube reuses the same <video> element
        if (rt.boundVideoId !== videoId) {
            rt.boundVideoId = videoId;
            rt.lastSaveAt = 0;
            rt.lastSavedTime = -1;
        }

        // If video element changed, rebind listeners (avoid leaks)
        if (rt.boundVideo && rt.boundVideo !== v && rt.handlers) {
            try {
                rt.boundVideo.removeEventListener('timeupdate', rt.handlers.timeupdate);
                rt.boundVideo.removeEventListener('pause', rt.handlers.pause);
                rt.boundVideo.removeEventListener('ended', rt.handlers.ended);
                rt.boundVideo.removeEventListener('loadedmetadata', rt.handlers.loadedmetadata);
                rt.boundVideo.removeEventListener('seeked', rt.handlers.seeked);
            } catch (e) { }
            rt.boundVideo = null;
            rt.boundVideoId = null;
            rt.handlers = null;
        }

        rt.boundVideo = v;
        rt.boundVideoId = videoId;

        if (!rt.handlers) {
            rt.handlers = {
                timeupdate: () => {
                    try {
                        if (!rt.enabled) return;
                        const vid = getCurrentVideoId();
                        if (!vid) return;
                        const now = Date.now();
                        if (now - rt.lastSaveAt < 5000) return; // throttle
                        if (v.paused) return;
                        const t = Number(v.currentTime);
                        const d = Number(v.duration);
                        if (!Number.isFinite(t)) return;
                        if (Math.abs(t - rt.lastSavedTime) < 2) return;
                        rt.lastSaveAt = now;
                        rt.lastSavedTime = t;
                        if (t < 5) return;
                        setContinueWatchingForVideo(vid, t, d);
                        updateContinueWatchingButton();
                        // Avoid re-rendering the whole panel every few seconds.
                        // If panel is open and row exists, just update its text.
                        if (rt.panelOpen) {
                            if (!updateContinueWatchingPanelRow(vid)) renderContinueWatchingPanel();
                        }
                    } catch (e) { }
                },
                pause: () => {
                    try {
                        if (!rt.enabled) return;
                        const vid = getCurrentVideoId();
                        if (!vid) return;
                        const t = Number(v.currentTime);
                        const d = Number(v.duration);
                        if (!Number.isFinite(t)) return;
                        if (t < 5) {
                            clearContinueWatchingForVideo(vid);
                        } else {
                            setContinueWatchingForVideo(vid, t, d);
                        }
                        updateContinueWatchingButton();
                        if (rt.panelOpen) {
                            if (!updateContinueWatchingPanelRow(vid)) renderContinueWatchingPanel();
                        }
                    } catch (e) { }
                },
                ended: () => {
                    try {
                        const vid = getCurrentVideoId();
                        if (vid) clearContinueWatchingForVideo(vid);
                        updateContinueWatchingButton();
                        if (rt.panelOpen) renderContinueWatchingPanel();
                    } catch (e) { }
                },
                loadedmetadata: () => {
                    updateContinueWatchingButton();
                    if (rt.panelOpen) renderContinueWatchingPanel();
                },
                seeked: () => {
                    updateContinueWatchingButton();
                    const vid = getCurrentVideoId();
                    if (rt.panelOpen && vid) updateContinueWatchingPanelRow(vid);
                },
            };

            v.addEventListener('timeupdate', rt.handlers.timeupdate, {
                passive: true
            });
            v.addEventListener('pause', rt.handlers.pause, {
                passive: true
            });
            v.addEventListener('ended', rt.handlers.ended, {
                passive: true
            });
            v.addEventListener('loadedmetadata', rt.handlers.loadedmetadata, {
                passive: true
            });
            v.addEventListener('seeked', rt.handlers.seeked, {
                passive: true
            });
        }

        updateContinueWatchingButton();
        updateContinueWatchingHistoryUi();
    }


    // ------------------------------
    // Feature: Show channel name on Shorts list (Home / feeds)
    // Adapted from: @𝖢𝖸 𝖥𝗎𝗇𝗀

    // ------------------------------
    function setupShortsChannelNameFeature(enabled) {
        __ytToolsRuntime.shortsChannelName.enabled = !!enabled;
        document.documentElement.dataset.mdcmShortsChannelName = enabled ? '1' : '0';

        // Disable: stop observers to reduce overhead
        if (!enabled) {
            try {
                __ytToolsRuntime.shortsChannelName.observer?.disconnect?.();
            } catch (e) { }
            try {
                __ytToolsRuntime.shortsChannelName.io?.disconnect?.();
            } catch (e) { }
            __ytToolsRuntime.shortsChannelName.observer = null;
            __ytToolsRuntime.shortsChannelName.io = null;
            clearTimeout(__ytToolsRuntime.shortsChannelName.scanT);
            __ytToolsRuntime.shortsChannelName.scanT = null;
            return;
        }

        const rt = __ytToolsRuntime.shortsChannelName;

        const getShortsVideoIdFromItem = (item) => {
            const a = item.querySelector('a[href^="/shorts/"]');
            const href = a?.getAttribute('href') || '';
            const m = href.match(/\/shorts\/([^/?]+)/);
            return m?.[1] || null;
        };

        const findSubhead = (item) => {
            return item.querySelector(
                '.ShortsLockupViewModelHostOutsideMetadataSubhead,' +
                ' .shortsLockupViewModelHostOutsideMetadataSubhead,' +
                ' .ShortsLockupViewModelHostMetadataSubhead,' +
                ' .shortsLockupViewModelHostMetadataSubhead'
            );
        };

        const ensureLabel = (subhead) => {
            const parent = subhead?.parentElement;
            if (!parent) return null;
            let el = parent.querySelector('.yt-tools-shorts-channel-name');
            if (!el) {
                el = document.createElement('div');
                el.className = 'yt-tools-shorts-channel-name';
                el.textContent = '';
                parent.insertBefore(el, subhead);
            }
            return el;
        };

        const tryExtractChannelNameFromDom = (item) => {
            const a = item.querySelector('a[href^="/@"], a[href^="/channel/"]');
            const name = (a?.textContent || a?.getAttribute('title') || '').trim();
            return name || null;
        };

        const fetchChannelNameFromWatch = (videoId) => {
            rt.fetchChain = rt.fetchChain.then(async () => {
                if (rt.cache.has(videoId)) return rt.cache.get(videoId);
                let res = null;
                try {
                    res = await fetch(`/watch?v=${videoId}`, {
                        method: 'GET',
                        credentials: 'same-origin',
                        cache: 'force-cache',
                    });
                } catch (e) {
                    return '';
                }
                if (!res?.ok) return '';
                const html = await res.text();

                const idx = html.indexOf('itemprop="author"');
                if (idx < 0) return '';
                const start = html.lastIndexOf('<span', idx);
                const end = html.indexOf('</span>', idx);
                if (start < 0 || end < 0) return '';
                const chunk = html.slice(start, end + 7);

                const doc = new DOMParser().parseFromString(chunk, 'text/html');
                const link = doc.querySelector('link[itemprop="name"]');
                return (link?.getAttribute('content') || '').trim();
            });
            return rt.fetchChain;
        };

        const getChannelName = (videoId, item) => {
            const cached = rt.cache.get(videoId);
            if (cached) return Promise.resolve(cached);

            const persisted = getShortsChannelFromPersistedCache(videoId);
            if (persisted) {
                rt.cache.set(videoId, persisted);
                return Promise.resolve(persisted);
            }

            const domName = tryExtractChannelNameFromDom(item);
            if (domName) {
                rt.cache.set(videoId, domName);
                setShortsChannelToPersistedCache(videoId, domName);
                return Promise.resolve(domName);
            }

            const inflight = rt.inflight.get(videoId);
            if (inflight) return inflight;

            const p = fetchChannelNameFromWatch(videoId)
                .then((name) => {
                    const finalName = (name || '').trim();
                    if (finalName) {
                        rt.cache.set(videoId, finalName);
                        setShortsChannelToPersistedCache(videoId, finalName);
                    }
                    return finalName;
                })
                .finally(() => {
                    rt.inflight.delete(videoId);
                });
            rt.inflight.set(videoId, p);
            return p;
        };

        const processItem = (item) => {
            if (!(item instanceof Element)) return;
            if (item.dataset.ytToolsShortsChannelProcessed === '1') return;

            const subhead = findSubhead(item);
            if (!subhead) return;

            const videoId = getShortsVideoIdFromItem(item);
            if (!videoId) return;

            item.dataset.ytToolsShortsChannelProcessed = '1';
            item.dataset.ytToolsShortsVideoId = videoId;

            const label = ensureLabel(subhead);
            if (!label) return;
            label.textContent = '';

            rt.io?.observe(item);
        };

        if (!rt.io) {
            rt.io = new IntersectionObserver((entries) => {
                for (const entry of entries) {
                    if (!entry.isIntersecting) continue;
                    const item = entry.target;
                    const videoId = item?.dataset?.ytToolsShortsVideoId;
                    const subhead = findSubhead(item);
                    const label = subhead?.parentElement?.querySelector?.('.yt-tools-shorts-channel-name');

                    if (!videoId || !label) {
                        rt.io.unobserve(item);
                        continue;
                    }

                    getChannelName(videoId, item)
                        .then((name) => {
                            if (name) label.textContent = name;
                        })
                        .finally(() => {
                            rt.io.unobserve(item);
                        });
                }
            }, {
                threshold: 0.15
            });
        }

        const scan = () => {
            clearTimeout(rt.scanT);
            rt.scanT = setTimeout(() => {
                document
                    .querySelectorAll('ytm-shorts-lockup-view-model, ytm-shorts-lockup-view-model-v2')
                    .forEach(processItem);
            }, 120);
        };

        if (!rt.observer) {
            rt.observer = new MutationObserver(scan);
            const observeTarget = document.querySelector('#page-manager') || document.body;
            rt.observer.observe(observeTarget, {
                childList: true,
                subtree: true
            });
        }

        scan();
    }


    // ------------------------------
    // Feature: Show cached rating/likes/dislikes on video cards (watch related + home/search)

    // ------------------------------
    function getVideoIdFromLockup(lockup) {
        const a = lockup.querySelector('a[href*="watch?v="]');
        if (a) {
            const m = (a.getAttribute('href') || '').match(/[?&]v=([^&]+)/);
            if (m) return m[1];
        }
        const el = lockup.querySelector('[class*="content-id-"]');
        if (el) {
            const m = el.className.match(/content-id-([A-Za-z0-9_-]+)/);
            if (m) return m[1];
        }
        return null;
    }

    function createSvgIconFromString(svgString, sizePx) {
        const div = document.createElement('div');
        div.innerHTML = safeHTML(svgString.trim());
        const svg = div.firstElementChild;
        if (!svg) return null;
        svg.setAttribute('width', String(sizePx || 14));
        svg.setAttribute('height', String(sizePx || 14));
        svg.style.display = 'inline-block';
        svg.style.verticalAlign = 'middle';
        svg.style.marginRight = '2px';
        return svg;
    }

    const LOCKUP_RATING_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-star"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 17.75l-6.172 3.245l1.179 -6.873l-5 -4.867l6.9 -1l3.086 -6.253l3.086 6.253l6.9 1l-5 4.867l1.179 6.873l-6.158 -3.245" /></svg>';
    const LOCKUP_LIKE_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-thumb-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7a1 1 0 0 1 1 -1h3a4 4 0 0 0 4 -4v-1a2 2 0 0 1 4 0v5h3a2 2 0 0 1 2 2l-1 5a2 3 0 0 1 -2 2h-7a3 3 0 0 1 -3 -3" /></svg>';
    const LOCKUP_DISLIKE_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-thumb-down"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 13v-8a1 1 0 0 0 -1 -1h-2a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h3a4 4 0 0 1 4 4v1a2 2 0 0 0 4 0v-5h3a2 2 0 0 0 2 -2l-1 -5a2 3 0 0 0 -2 -2h-7a3 3 0 0 0 -3 3" /></svg>';

    function injectLockupCachedStats() {
        if (!window.location.href.includes('youtube.com')) return;
        document.querySelectorAll('yt-lockup-view-model').forEach((lockup) => {
            if (lockup.hasAttribute('data-yt-tools-lockup-stats')) return;
            const videoId = getVideoIdFromLockup(lockup);
            if (!videoId) return;
            const cached = getLikesDislikesFromPersistedCache(videoId);
            if (!cached) return;
            const hasRating = cached.rating != null;
            const hasLikes = cached.likes != null;
            const hasDislikes = cached.dislikes != null;
            if (!hasRating && !hasLikes && !hasDislikes) return;
            const meta = lockup.querySelector('yt-content-metadata-view-model');
            if (!meta) return;
            const row = document.createElement('div');
            row.className = 'yt-content-metadata-view-model__metadata-row';
            row.setAttribute('data-yt-tools-lockup-stats-row', '1');
            const wrap = document.createElement('span');
            wrap.className = 'yt-core-attributed-string yt-content-metadata-view-model__metadata-text yt-core-attributed-string--white-space-pre-wrap yt-core-attributed-string--link-inherit-color';
            wrap.setAttribute('dir', 'auto');
            wrap.setAttribute('role', 'text');
            const sep = () => {
                const s = document.createTextNode(' · ');
                return s;
            };
            if (hasRating) {
                const ratingIcon = createSvgIconFromString(LOCKUP_RATING_SVG, 14);
                if (ratingIcon) wrap.appendChild(ratingIcon);
                wrap.appendChild(document.createTextNode(' ' + cached.rating.toFixed(1)));
                if (hasLikes || hasDislikes) wrap.appendChild(sep());
            }
            if (hasLikes) {
                const likeIcon = createSvgIconFromString(LOCKUP_LIKE_SVG, 14);
                if (likeIcon) wrap.appendChild(likeIcon);
                wrap.appendChild(document.createTextNode(' ' + FormatterNumber(cached.likes, 0)));
                if (hasDislikes) wrap.appendChild(sep());
            }
            if (hasDislikes) {
                const dislikeIcon = createSvgIconFromString(LOCKUP_DISLIKE_SVG, 14);
                if (dislikeIcon) wrap.appendChild(dislikeIcon);
                wrap.appendChild(document.createTextNode(' ' + FormatterNumber(cached.dislikes, 0)));
            }
            row.appendChild(wrap);
            meta.appendChild(row);
            lockup.setAttribute('data-yt-tools-lockup-stats', videoId);
        });
    }

    function getVideoIdFromShortsLockup(item) {
        if (item.dataset.ytToolsShortsVideoId) return item.dataset.ytToolsShortsVideoId;
        var a = item.querySelector('a[href^="/shorts/"]');
        if (!a) return null;
        var m = (a.getAttribute('href') || '').match(/\/shorts\/([^/?]+)/);
        return m ? m[1] : null;
    }

    function injectShortsLockupCachedStats() {
        if (!window.location.href.includes('youtube.com')) return;
        // Process inner lockup (has metadata); v2 wraps it and would duplicate
        document.querySelectorAll('ytm-shorts-lockup-view-model').forEach(function (item) {
            if (item.hasAttribute('data-yt-tools-shorts-stats')) return;
            var videoId = getVideoIdFromShortsLockup(item);
            if (!videoId) return;
            var cached = getLikesDislikesFromPersistedCache(videoId);
            if (!cached) return;
            var hasLikes = cached.likes != null;
            var hasDislikes = cached.dislikes != null;
            if (!hasLikes && !hasDislikes) return;
            var subhead = item.querySelector(
                '.ShortsLockupViewModelHostOutsideMetadataSubhead,' +
                '.shortsLockupViewModelHostOutsideMetadataSubhead,' +
                '.ShortsLockupViewModelHostMetadataSubhead,' +
                '.shortsLockupViewModelHostMetadataSubhead'
            );
            if (!subhead || !subhead.parentElement) return;
            var wrap = document.createElement('span');
            wrap.className = 'yt-core-attributed-string yt-content-metadata-view-model__metadata-text yt-core-attributed-string--white-space-pre-wrap yt-core-attributed-string--link-inherit-color yt-tools-shorts-stats-row';
            wrap.setAttribute('dir', 'auto');
            wrap.setAttribute('role', 'text');
            wrap.setAttribute('style', 'color: #aaa !important;');
            var sep = function () {
                return document.createTextNode(' \u00b7 ');
            };
            if (hasLikes) {
                var likeIcon = createSvgIconFromString(LOCKUP_LIKE_SVG, 12);
                if (likeIcon) {
                    likeIcon.style.setProperty('color', '#aaa', 'important');
                    wrap.appendChild(likeIcon);
                }
                wrap.appendChild(document.createTextNode(' ' + FormatterNumber(cached.likes, 0)));
                if (hasDislikes) wrap.appendChild(sep());
            }
            if (hasDislikes) {
                var dislikeIcon = createSvgIconFromString(LOCKUP_DISLIKE_SVG, 12);
                if (dislikeIcon) {
                    dislikeIcon.style.setProperty('color', '#aaa', 'important');
                    wrap.appendChild(dislikeIcon);
                }
                wrap.appendChild(document.createTextNode(' ' + FormatterNumber(cached.dislikes, 0)));
            }
            var row = document.createElement('div');
            row.className = 'yt-tools-shorts-stats-wrap';
            row.setAttribute('style', 'color: #aaa !important;');
            row.appendChild(wrap);
            subhead.parentElement.appendChild(row);
            item.setAttribute('data-yt-tools-shorts-stats', videoId);
        });
    }

    function createLockupStatsObserver(target) {
        var lockupStatsDebounceT = null;
        var lockupStatsScheduled = false;
        var obs = new MutationObserver(function () {
            if (lockupStatsScheduled) return;
            lockupStatsScheduled = true;
            clearTimeout(lockupStatsDebounceT);
            lockupStatsDebounceT = setTimeout(function () {
                lockupStatsScheduled = false;
                if (!window.location.href.includes('youtube.com')) return;
                injectLockupCachedStats();
                injectShortsLockupCachedStats();
                // Single extra pass for late-rendered lockups (reduced from 3 passes)
                setTimeout(function () {
                    if (!window.location.href.includes('youtube.com')) return;
                    if (!hasUnprocessedLockups()) return;
                    injectLockupCachedStats();
                    injectShortsLockupCachedStats();
                }, 1200);
            }, 280);
        });
        obs.observe(target, {
            childList: true,
            subtree: true
        });
        return obs;
    }

    function retargetLockupStatsObserverIfNeeded() {
        if (!window.location.href.includes('youtube.com/watch')) return;
        var secondary = document.getElementById('secondary') || document.querySelector('ytd-watch-next-secondary-results-renderer');
        if (!secondary || !secondary.parentNode) return;
        if (__ytToolsRuntime.lockupCachedStatsObserveTarget === secondary) return;
        var obs = __ytToolsRuntime.lockupCachedStatsObserver;
        if (!obs) return;
        obs.disconnect();
        __ytToolsRuntime.lockupCachedStatsObserver = createLockupStatsObserver(secondary);
        __ytToolsRuntime.lockupCachedStatsObserveTarget = secondary;
    }

    function hasUnprocessedLockups() {
        var normal = document.querySelectorAll('yt-lockup-view-model:not([data-yt-tools-lockup-stats])').length > 0;
        var shorts = document.querySelectorAll('ytm-shorts-lockup-view-model:not([data-yt-tools-shorts-stats])').length > 0;
        return normal || shorts;
    }

    function runLockupCachedStatsCatchUp() {
        if (!window.location.href.includes('youtube.com')) return;
        if (document.visibilityState !== 'visible') return;
        if (!hasUnprocessedLockups()) return;
        injectLockupCachedStats();
        injectShortsLockupCachedStats();
    }

    function setupLockupCachedStats() {
        if (!window.location.href.includes('youtube.com')) return;
        injectLockupCachedStats();
        injectShortsLockupCachedStats();
        var secondary = document.getElementById('secondary') || document.querySelector('ytd-watch-next-secondary-results-renderer');
        var observeTarget = secondary && secondary.parentNode ? secondary : document.body;
        if (__ytToolsRuntime.lockupCachedStatsObserver) {
            if (observeTarget !== __ytToolsRuntime.lockupCachedStatsObserveTarget) {
                __ytToolsRuntime.lockupCachedStatsObserver.disconnect();
                __ytToolsRuntime.lockupCachedStatsObserver = createLockupStatsObserver(observeTarget);
                __ytToolsRuntime.lockupCachedStatsObserveTarget = observeTarget;
            }
            return;
        }
        __ytToolsRuntime.lockupCachedStatsObserver = createLockupStatsObserver(observeTarget);
        __ytToolsRuntime.lockupCachedStatsObserveTarget = observeTarget;
        // Catch-up interval: apply stats to any new cards (scroll, filters, SPA) every 1.8s when there are unprocessed lockups
        if (!__ytToolsRuntime.lockupCachedStatsIntervalId) {
            __ytToolsRuntime.lockupCachedStatsIntervalId = setInterval(runLockupCachedStatsCatchUp, 1800);
        }
    }


    // ------------------------------
    // Feature: Bookmarks per video (persisted)

    // ------------------------------
    function getBookmarksForVideo(videoId) {
        const all = readJsonGM(STORAGE_KEYS_MDCM.BOOKMARKS, {});
        const list = Array.isArray(all[videoId]) ? all[videoId] : [];
        return {
            all,
            list
        };
    }

    function saveBookmark(videoId, seconds, label) {
        const {
            all,
            list
        } = getBookmarksForVideo(videoId);
        const t = Math.max(0, Math.floor(Number(seconds) || 0));
        const exists = list.some(b => b && b.t === t);
        const item = {
            t,
            label: (label || formatTimeShort(t)).trim(),
            createdAt: Date.now()
        };
        const nextList = exists ? list.map(b => (b.t === t ? item : b)) : [...list, item];
        nextList.sort((a, b) => a.t - b.t);
        all[videoId] = nextList;
        writeJsonGM(STORAGE_KEYS_MDCM.BOOKMARKS, all);
    }

    function deleteBookmark(videoId, seconds) {
        const {
            all,
            list
        } = getBookmarksForVideo(videoId);
        const t = Math.max(0, Math.floor(Number(seconds) || 0));
        all[videoId] = list.filter(b => b && b.t !== t);
        writeJsonGM(STORAGE_KEYS_MDCM.BOOKMARKS, all);
    }

    function renderBookmarksPanel(videoId) {
        const panel = $id('yt-bookmarks-panel');
        if (!panel) return;

        const {
            list
        } = getBookmarksForVideo(videoId);
        if (!list.length) {
            panel.innerHTML = safeHTML(`<div class="yt-bm-empty">No bookmarks yet. Click ★ to save one.</div>`);
            return;
        }

        panel.innerHTML = safeHTML(list
            .map((b) => {
                const time = formatTimeShort(b.t);
                const safeLabel = (b.label || time).replace(/</g, '&lt;').replace(/>/g, '&gt;');
                return `
          <div class="yt-bm-item">
            <button type="button" class="yt-bm-go" data-action="go" data-t="${b.t}" title="Go to ${time}">${time}</button>
            <div class="yt-bm-label" title="${safeLabel}">${safeLabel}</div>
            <button type="button" class="yt-bm-del" data-action="del" data-t="${b.t}" title="Delete">✕</button>
          </div>
        `;
            })
            .join(''));
    }

    function applyBookmarksIfEnabled(settings) {
        const addBtn = $id('yt-bookmark-add');
        const toggleBtn = $id('yt-bookmark-toggle');
        const panel = $id('yt-bookmarks-panel');

        if (!addBtn || !toggleBtn || !panel) return;

        const enabled = !!settings?.bookmarks;
        addBtn.style.display = enabled ? 'inline-flex' : 'none';
        toggleBtn.style.display = enabled ? 'inline-flex' : 'none';
        panel.style.display = enabled && __ytToolsRuntime.bookmarksPanelOpen ? 'block' : 'none';

        if (!enabled) return;

        const videoId = getCurrentVideoId();
        if (!videoId) return;
        renderBookmarksPanel(videoId);

        if (__ytToolsRuntime.bookmarkClickHandlerInitialized) return;
        __ytToolsRuntime.bookmarkClickHandlerInitialized = true;

        document.addEventListener('click', (e) => {
            const target = e.target;
            if (!(target instanceof Element)) return;

            const add = target.closest('#yt-bookmark-add');
            const tog = target.closest('#yt-bookmark-toggle');
            const actionBtn = target.closest('[data-action][data-t]');

            if (add) {
                e.preventDefault();
                e.stopPropagation();
                const v = $e('video');
                const vid = getCurrentVideoId();
                if (!v || !vid) return;
                const t = Math.floor(v.currentTime || 0);
                const defaultLabel = formatTimeShort(t);
                const label = prompt('Bookmark name (optional):', defaultLabel) || defaultLabel;
                saveBookmark(vid, t, label);
                __ytToolsRuntime.bookmarksPanelOpen = true;
                panel.style.display = 'block';
                renderBookmarksPanel(vid);
                Notify('success', `Bookmark saved at ${defaultLabel}`);
                return;
            }

            if (tog) {
                e.preventDefault();
                e.stopPropagation();
                __ytToolsRuntime.bookmarksPanelOpen = !__ytToolsRuntime.bookmarksPanelOpen;
                panel.style.display = __ytToolsRuntime.bookmarksPanelOpen ? 'block' : 'none';
                const vid = getCurrentVideoId();
                if (vid && __ytToolsRuntime.bookmarksPanelOpen) renderBookmarksPanel(vid);
                return;
            }

            if (actionBtn) {
                e.preventDefault();
                e.stopPropagation();
                const action = actionBtn.getAttribute('data-action');
                const t = Number(actionBtn.getAttribute('data-t'));
                const v = $e('video');
                const vid = getCurrentVideoId();
                if (!v || !vid) return;
                if (action === 'go') {
                    v.currentTime = Math.max(0, t || 0);
                    v.play?.().catch(() => { });
                } else if (action === 'del') {
                    deleteBookmark(vid, t);
                    renderBookmarksPanel(vid);
                }
            }
        });
    }


    // ------------------------------
    // Feature: Like vs Dislike bar

    // ------------------------------
    function parseCountText(text) {
        if (!text) return null;
        const s0 = String(text).trim().toLowerCase();
        if (!s0) return null;
        let mult = 1;
        let s = s0.replace(/\s+/g, '');
        if (s.includes('mil')) {
            mult = 1000;
            s = s.replace('mil', '');
        } else if (s.includes('k')) {
            mult = 1000;
            s = s.replace('k', '');
        } else if (s.includes('m')) {
            mult = 1000000;
            s = s.replace('m', '');
        }
        // normalize decimal separators
        s = s.replace(/[^\d.,]/g, '');
        if (!s) return null;
        // If both separators exist, assume last is decimal
        const lastDot = s.lastIndexOf('.');
        const lastComma = s.lastIndexOf(',');
        let nStr = s;
        if (lastDot !== -1 && lastComma !== -1) {
            const dec = Math.max(lastDot, lastComma);
            const intPart = s.slice(0, dec).replace(/[.,]/g, '');
            const decPart = s.slice(dec + 1);
            nStr = `${intPart}.${decPart}`;
        } else {
            // Use dot as decimal
            nStr = s.replace(',', '.');
        }
        const num = Number.parseFloat(nStr);
        if (!Number.isFinite(num)) return null;
        return Math.round(num * mult);
    }

    async function ensureDislikesForCurrentVideo() {
        const videoId = getCurrentVideoId();
        if (!videoId) return null;
        const now = Date.now();
        if (__ytToolsRuntime.dislikesCache.videoId === videoId && __ytToolsRuntime.dislikesCache.dislikes != null && (now - __ytToolsRuntime.dislikesCache.ts) < 10 * 60 * 1000) {
            return __ytToolsRuntime.dislikesCache;
        }
        const persisted = getLikesDislikesFromPersistedCache(videoId);
        if (persisted && persisted.dislikes != null) {
            __ytToolsRuntime.dislikesCache = {
                videoId,
                likes: persisted.likes,
                dislikes: persisted.dislikes,
                viewCount: persisted.viewCount,
                rating: persisted.rating,
                ts: now
            };
            return __ytToolsRuntime.dislikesCache;
        }
        try {
            const res = await fetch(`${apiDislikes}${videoId}`);
            const data = await res.json();
            const dislikes = Number(data?.dislikes);
            const likes = Number(data?.likes);
            const viewCount = Number(data?.viewCount);
            const rating = Number(data?.rating);
            const now = Date.now();

            if (Number.isFinite(dislikes)) {
                __ytToolsRuntime.dislikesCache = {
                    videoId,
                    likes: Number.isFinite(likes) ? likes : getLikesFromDom(),
                    dislikes,
                    viewCount,
                    rating,
                    ts: now
                };
                setLikesDislikesToPersistedCache(
                    videoId,
                    __ytToolsRuntime.dislikesCache.likes,
                    dislikes,
                    Number.isFinite(viewCount) ? viewCount : undefined,
                    (Number.isFinite(rating) && rating >= 0 && rating <= 5) ? rating : undefined
                );
                return __ytToolsRuntime.dislikesCache;
            }
        } catch (e) {
            console.error('[YT Tools] Error fetching dislikes:', e);
        }
        return null;
    }

    function getLikesFromDom() {
        // Try grab visible like count (YouTube UI varies a lot)
        const likeBtn =
            $e('#top-level-buttons-computed like-button-view-model button-view-model button') ||
            $e('#top-level-buttons-computed like-button-view-model button') ||
            $e('#top-level-buttons-computed ytd-toggle-button-renderer:nth-child(1)') ||
            $e('segmented-like-dislike-button-view-model like-button-view-model');
        if (!likeBtn) return null;

        // Prefer visible counter first; aria-label can include locale thousands separators (17.606) that are ambiguous.
        const candidates = [
            likeBtn.querySelector?.('.yt-spec-button-shape-next__button-text-content')?.textContent,
            likeBtn.textContent,
            likeBtn.getAttribute?.('aria-label'),
        ].filter(Boolean);

        for (const txt of candidates) {
            const n = parseCountText(txt);
            if (n != null) return n;
        }
        return null;
    }

    function updateLikeDislikeBar(likes, dislikes) {
        // Prefer placing it above the "copy description" button (as requested).
        const copyDesc = $id('button_copy_description');
        const host =
            $e('#top-level-buttons-computed') ||
            $e('ytd-watch-metadata #top-level-buttons-computed');
        if (!host && !copyDesc) return;

        let bar = $id('yt-like-dislike-bar-mdcm');
        if (!bar) {
            bar = document.createElement('div');
            bar.id = 'yt-like-dislike-bar-mdcm';
            bar.innerHTML = safeHTML(`<div class="like"></div><div class="dislike"></div>`);
            if (copyDesc) {
                copyDesc.insertAdjacentElement('beforebegin', bar);
            } else {
                host.appendChild(bar);
            }
        } else if (copyDesc && bar.previousElementSibling !== copyDesc) {
            // Keep it near the copy description area if the DOM changed
            try {
                copyDesc.insertAdjacentElement('beforebegin', bar);
            } catch (e) { }
        }

        if (!Number.isFinite(likes) || !Number.isFinite(dislikes) || likes + dislikes <= 0) {
            bar.style.display = 'none';
            return;
        }

        const total = likes + dislikes;
        const likePct = Math.max(0, Math.min(100, (likes / total) * 100));
        const dislikePct = 100 - likePct;
        bar.style.display = 'block';
        const likeEl = bar.querySelector('.like');
        const dislikeEl = bar.querySelector('.dislike');
        likeEl.style.width = `${likePct}%`;
        dislikeEl.style.width = `${dislikePct}%`;
        bar.title = `Likes: ${likes.toLocaleString()} | Dislikes: ${dislikes.toLocaleString()}`;
    }

    async function applyLikeDislikeBarIfEnabled(settings) {
        if (!settings?.likeDislikeBar) {
            const existing = $id('yt-like-dislike-bar-mdcm');
            if (existing) existing.style.display = 'none';
            return;
        }
        if (!window.location.href.includes('youtube.com/watch')) return;
        const videoId = getCurrentVideoId();
        if (!videoId) return;
        const data = await ensureDislikesForCurrentVideo();
        if (!data || data.likes == null || data.dislikes == null) return;
        updateLikeDislikeBar(data.likes, data.dislikes);
    }

    // Retry helper (YT often renders likes late; keep it lightweight)
    function scheduleLikeBarUpdate(settings, attempts = 4) {
        if (!settings?.likeDislikeBar) return;
        let i = 0;
        const tick = async () => {
            i += 1;
            await applyLikeDislikeBarIfEnabled(settings);
            const bar = $id('yt-like-dislike-bar-mdcm');
            if (bar && bar.style.display !== 'none') return;
            if (i < attempts) setTimeout(tick, 800);
        };
        setTimeout(tick, 300);
    }

    //   Dislikes video
    async function videoDislike() {
        if (isYTMusic) return;
        validoUrl = document.location.href;

        const validoVentana = $e('#below > ytd-watch-metadata > div');
        if (validoVentana != undefined && document.location.href.split('?v=')[0].includes('youtube.com/watch')) {
            let localVideoId = paramsVideoURL();
            if (!localVideoId) return;
            validoUrl = localVideoId;
            const data = await ensureDislikesForCurrentVideo();
            if (!data || data.dislikes == null) return;

            const dislikes = data.dislikes;
            const dislikes_btn = $e('#top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div > div > dislike-button-view-model > toggle-button-view-model > button-view-model > button');

            if (dislikes_btn != null) {
                const settings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));

                // Find or create our custom count element
                let textContent = dislikes_btn.querySelector('.yt-tools-dislike-count');
                if (!textContent) {
                    textContent = document.createElement('div');
                    textContent.className = 'ytSpecButtonShapeNextButtonTextContent yt-tools-dislike-count';

                    // Insert it after the icon container
                    const iconDiv = dislikes_btn.querySelector('.ytSpecButtonShapeNextIcon');
                    if (iconDiv) {
                        iconDiv.insertAdjacentElement('afterend', textContent);
                        // Convert button style to icon+text layout
                        dislikes_btn.classList.add('ytSpecButtonShapeNextIconLeading');
                        dislikes_btn.classList.remove('ytSpecButtonShapeNextIconButton');
                    } else {
                        dislikes_btn.appendChild(textContent);
                    }
                }

                if (settings.dislikes) {
                    textContent.textContent = FormatterNumber(dislikes, 0);
                    textContent.style.display = 'block';
                    showDislikes = true;
                } else {
                    textContent.style.display = 'none';
                    showDislikes = false;
                }

                const likes_btn =
                    $e('#top-level-buttons-computed like-button-view-model button-view-model button') ||
                    $e('#top-level-buttons-computed like-button-view-model button') ||
                    $e('#top-level-buttons-computed ytd-toggle-button-renderer:nth-child(1)') ||
                    $e('segmented-like-dislike-button-view-model like-button-view-model button');

                // Capture current state as "initial" for this data load
                const currentIsPressed = dislikes_btn.getAttribute('aria-pressed') === 'true';
                dislikes_btn.dataset.initialState = currentIsPressed;
                dislikes_btn.dataset.originalCount = dislikes;

                if (likes_btn) {
                    likes_btn.dataset.initialState = likes_btn.getAttribute('aria-pressed') === 'true';
                    likes_btn.dataset.originalCount = data.likes || 0;
                }

                const updateCount = () => {
                    // Dislikes calculation
                    const isDislikePressed = dislikes_btn.getAttribute('aria-pressed') === 'true';
                    const wasDislikePressed = dislikes_btn.dataset.initialState === 'true';
                    const originalDislikes = Number(dislikes_btn.dataset.originalCount);

                    let dislikeOffset = 0;
                    if (!wasDislikePressed && isDislikePressed) dislikeOffset = 1;
                    else if (wasDislikePressed && !isDislikePressed) dislikeOffset = -1;

                    const newDislikes = Math.max(0, originalDislikes + dislikeOffset);

                    // Likes calculation
                    let newLikes = data.likes || 0;
                    if (likes_btn) {
                        const isLikePressed = likes_btn.getAttribute('aria-pressed') === 'true';
                        const wasLikePressed = likes_btn.dataset.initialState === 'true';
                        const originalLikes = Number(likes_btn.dataset.originalCount);

                        let likeOffset = 0;
                        if (!wasLikePressed && isLikePressed) likeOffset = 1;
                        else if (wasLikePressed && !isLikePressed) likeOffset = -1;

                        newLikes = Math.max(0, originalLikes + likeOffset);
                    }

                    // Update run-time cache
                    if (__ytToolsRuntime.dislikesCache.videoId === localVideoId) {
                        __ytToolsRuntime.dislikesCache.dislikes = newDislikes;
                        __ytToolsRuntime.dislikesCache.likes = newLikes;

                        // Also persist it so F5 uses the updated count as "original"
                        setLikesDislikesToPersistedCache(
                            localVideoId,
                            newLikes,
                            newDislikes,
                            __ytToolsRuntime.dislikesCache.viewCount,
                            __ytToolsRuntime.dislikesCache.rating
                        );
                    }

                    if (settings.dislikes && textContent) {
                        textContent.textContent = FormatterNumber(newDislikes, 0);
                    }

                    // Sync the like/dislike bar immediately
                    if (settings.likeDislikeBar) {
                        updateLikeDislikeBar(newLikes, newDislikes);
                    }
                };

                // Initial update
                updateCount();

                // Use MutationObserver for robust state tracking (handles Like button clicks too)
                if (!dislikes_btn.dataset.observerInitialized) {
                    dislikes_btn.dataset.observerInitialized = 'true';

                    const observer = new MutationObserver((mutations) => {
                        for (const mutation of mutations) {
                            if (mutation.type === 'attributes' && mutation.attributeName === 'aria-pressed') {
                                updateCount();
                            }
                        }
                    });

                    observer.observe(dislikes_btn, { attributes: true, attributeFilter: ['aria-pressed'] });
                    if (likes_btn) observer.observe(likes_btn, { attributes: true, attributeFilter: ['aria-pressed'] });

                    // Also handle direct clicks just in case
                    dislikes_btn.addEventListener('click', () => {
                        setTimeout(updateCount, 150);
                    });
                    if (likes_btn) {
                        likes_btn.addEventListener('click', () => {
                            setTimeout(updateCount, 150);
                        });
                    }
                }

                try {
                    scheduleLikeBarUpdate(settings, 5);
                } catch (e) { }
            }
        }
    }

    // dislikes shorts + views button (viewCount from Return YouTube Dislike API)
    async function shortDislike() {
        validoUrl = document.location.href;
        const validoVentanaShort = $m(
            "#button-bar > reel-action-bar-view-model > dislike-button-view-model > toggle-button-view-model > button-view-model > label > div > span"
        );

        if (validoVentanaShort != undefined && document.location.href.split('/')[3] === 'shorts') {
            validoUrl = document.location.href.split('/')[4];
            let dislikes = null;
            let viewCount = null;
            let rating = null;
            const persisted = getLikesDislikesFromPersistedCache(validoUrl);
            if (persisted && persisted.dislikes != null) {
                dislikes = persisted.dislikes;
                viewCount = persisted.viewCount ?? null;
                rating = persisted.rating ?? null;
            } else {
                const urlShorts = `${apiDislikes}${validoUrl}`;
                try {
                    const respuesta = await fetch(urlShorts);
                    const datosShort = await respuesta.json();
                    dislikes = Number(datosShort?.dislikes);
                    viewCount = Number(datosShort?.viewCount);
                    rating = Number(datosShort?.rating);
                    if (Number.isFinite(dislikes)) setLikesDislikesToPersistedCache(validoUrl, undefined, dislikes, Number.isFinite(viewCount) ? viewCount : undefined, (Number.isFinite(rating) && rating >= 0 && rating <= 5) ? rating : undefined);
                } catch (error) {
                    console.log(error);
                }
            }
            if (dislikes != null) {
                const settings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
                for (let i = 0; i < validoVentanaShort.length; i++) {
                    const el = validoVentanaShort[i];
                    if (settings.dislikes) {
                        if (!el.dataset.originalLabel) el.dataset.originalLabel = el.textContent;
                        el.textContent = `${FormatterNumber(dislikes, 0)}`;
                    } else {
                        if (el.dataset.originalLabel) {
                            el.textContent = el.dataset.originalLabel;
                            delete el.dataset.originalLabel;
                        }
                    }
                }
            }
            if (__ytToolsRuntime.updateShortsViewsButton) __ytToolsRuntime.updateShortsViewsButton(validoUrl, viewCount);
            if (__ytToolsRuntime.updateShortsRatingButton) __ytToolsRuntime.updateShortsRatingButton(validoUrl, rating);
        }
    }

    let showDislikes = false;

    window.addEventListener('yt-navigate-finish', () => {
        if (isYTMusic) return; // Dislikes UI not available on YTM
        const svgDislike = $e('.svg-dislike-ico');
        if (!svgDislike && showDislikes) {
            setTimeout(async () => {
                await videoDislike();
                await shortDislike();
            }, 1500);
        }
    });





    // Styles for our enhancement panel

    const thumbnailVideo = `
  <button title="Image video" class="botones_div" type="button" id="imagen">

  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-photo-down" width="24"
    height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
    stroke-linecap="round" stroke-linejoin="round">
    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
    <path d="M15 8h.01"></path>
    <path d="M12.5 21h-6.5a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v6.5"></path>
    <path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l4 4"></path>
    <path d="M14 14l1 -1c.653 -.629 1.413 -.815 2.13 -.559"></path>
    <path d="M19 16v6"></path>
    <path d="M22 19l-3 3l-3 -3"></path>
  </svg>
</button>
  `;

    const repeatVideo = `
  <button title="Repeat video" class="botones_div" type="button" id="repeatvideo">

  <svg  xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-repeat" width="24"
    height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
    stroke-linecap="round" stroke-linejoin="round">
    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
    <path d="M4 12v-3a3 3 0 0 1 3 -3h13m-3 -3l3 3l-3 3"></path>
    <path d="M20 12v3a3 3 0 0 1 -3 3h-13m3 3l-3 -3l3 -3"></path>
  </svg>
</button>
  `;

    const downloadMP4Mp3 = `
  <button title="MP4" type="button" class="btn1 botones_div">
  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-download"
    width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
    stroke-linecap="round" stroke-linejoin="round">
    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
    <path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
    <path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
    <path d="M12 17v-6"></path>
    <path d="M9.5 14.5l2.5 2.5l2.5 -2.5"></path>
  </svg>
</button>
<button title="MP3" type="button" class="btn2 botones_div">

  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-music" width="24"
    height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
    stroke-linecap="round" stroke-linejoin="round">
    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
    <path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
    <path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
    <path d="M11 16m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path>
    <path d="M12 16l0 -5l2 1"></path>
  </svg>
</button>
<button title="Close" type="button" class="btn3 botones_div">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-circle-x" width="24"
  height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
  stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
  <path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0"></path>
  <path d="M10 10l4 4m0 -4l-4 4"></path>
</svg>
</button>
  `;

    const pictureToPicture = `
  <button title="Picture to picture" type="button" class="video_picture_to_picture botones_div">

  <svg width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11 19h-6a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v4" /><path d="M14 14m0 1a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v3a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z" /></svg>
</button>

  `;
    const screenShot = `
  <button title="Screenshot video" type="button" class="screenshot_video botones_div">
  <svg width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 8h.01" /><path d="M6 13l2.644 -2.644a1.21 1.21 0 0 1 1.712 0l3.644 3.644" /><path d="M13 13l1.644 -1.644a1.21 1.21 0 0 1 1.712 0l1.644 1.644" /><path d="M4 8v-2a2 2 0 0 1 2 -2h2" /><path d="M4 16v2a2 2 0 0 0 2 2h2" /><path d="M16 4h2a2 2 0 0 1 2 2v2" /><path d="M16 20h2a2 2 0 0 0 2 -2v-2" /></svg>
</button>

  `;

    const bookmarkAddBtn = `
  <button title="Add bookmark" type="button" id="yt-bookmark-add" class="botones_div">
    <svg width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
      <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
      <path d="M7 4h10a2 2 0 0 1 2 2v14l-7 -4l-7 4v-14a2 2 0 0 1 2 -2z" />
      <path d="M12 7v6" />
      <path d="M9 10h6" />
    </svg>
  </button>
  `;

    const bookmarkToggleBtn = `
  <button title="Show bookmarks" type="button" id="yt-bookmark-toggle" class="botones_div">
    <svg width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
      <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
      <path d="M9 6h11" />
      <path d="M9 12h11" />
      <path d="M9 18h11" />
      <path d="M5 6h.01" />
      <path d="M5 12h.01" />
      <path d="M5 18h.01" />
    </svg>
  </button>
  `;

    const continueWatchingHistoryBtn = `
  <button title="History" type="button" id="yt-cw-history-toggle" class="botones_div" style="display:none;">
    <svg width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
      <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
      <path d="M12 8v4l3 3" />
      <path d="M3 12a9 9 0 1 0 3 -6.7" />
      <path d="M3 4v4h4" />
    </svg>
  </button>
  `;

    const menuBotones = `
    <main class="yt-tools-container">
    <div class="container">
    <form>
      <div class="containerButtons">
      ${thumbnailVideo}
      ${!isYTMusic ? repeatVideo : ''}
      ${bookmarkAddBtn}
      ${bookmarkToggleBtn}
      ${continueWatchingHistoryBtn}
      ${downloadMP4Mp3}
      ${pictureToPicture}
      ${screenShot}
      </div>
      <div id="yt-bookmarks-panel" class="yt-bookmarks-panel" style="display:none;"></div>
      <div id="yt-continue-watching-panel" class="yt-continue-watching-panel" style="display:none;"></div>
      <div>
      </div>
    </form>

    </div>
    <div class="content_collapsible_colors" style="margin-top: 10px">

    <form class="formulariodescarga ocultarframe" action="">
    <div class="containerall">
    <select class="selectcalidades ocultarframe" required>
      <option selected disabled>Video Quality</option>
      <option value="144">144p MP4</option>
      <option value="240">240p MP4</option>
      <option value="360">360p MP4</option>
      <option value="480">480p MP4</option>
      <option value="720">720p HD MP4 Default</option>
      <option value="1080">1080p FULL HD MP4</option>
      <option value="1440">1440p 2K WEBM</option>
      <option value="4k">2160p 4K WEBM</option>
      <option value="8k">4320p 8K WEBM</option>
      </select>
      <div id="descargando" class="download-container ocultarframe">
        <button class="progress-retry-btn" title="Retry" style="display: none;">
        <i class="fa-solid fa-rotate-right"></i>
        </button>
        <button class="download-again-btn" title="Download again" style="display: none;">
        <i class="fa-solid fa-download"></i>
        </button>
        <div class="download-info">
          <span class="download-text">Download Video And Please Wait...</span>
          <span class="download-quality"></span>
        </div>
        <div class="download-actions">
          <button class="download-btn video-btn">Download</button>
          <button class="retry-btn" style="display: none;">Retry</button>
        </div>
        <div class="progress-container" style="display: none;">
          <div class="progress-bar">
            <div class="progress-fill"></div>
          </div>
          <span class="progress-text">0%</span>
        </div>
        <div class="download-footer">
          <a href="https://github.com/akari310/" target="_blank"> <i class="fa-brands fa-github"></i> by: Akari</a>
        </div>
        <h1 class="text-description-download">
          <span >Enable pop-ups on YouTube to download audio or video</span>
        </h1>
      </div>
    </div>
    </form>
    <form class="formulariodescargaaudio ocultarframe" action="">
    <div class="containerall">
    <select class="selectcalidadesaudio ocultarframeaudio" required>
      <option selected disabled>Audio Quality</option>
      <option value="flac">Audio FLAC UHQ</option>
      <option value="wav">Audio WAV UHQ</option>
      <option value="webm">Audio WEBM UHQ</option>
      <option value="mp3">Audio MP3 Default</option>
      <option value="m4a">Audio M4A</option>
      <option value="aac">Audio AAC</option>
      <option value="opus">Audio OPUS</option>
      <option value="ogg">Audio OGG</option>
      </select>
      <div id="descargandomp3" class="download-container ocultarframeaudio">
        <button class="progress-retry-btn" title="Retry" style="display: none;">
        <i class="fa-solid fa-rotate-right"></i>
        </button>
        <button class="download-again-btn" title="Download again" style="display: none;">
        <i class="fa-solid fa-download"></i>
        </button>
        <div class="download-info">
          <span class="download-text">Download Audio And Please Wait...</span>
          <span class="download-quality"></span>
        </div>
        <div class="download-actions">
          <button class="download-btn audio-btn">Download</button>
          <button class="retry-btn" style="display: none;">Retry</button>
        </div>
        <div class="progress-container" style="display: none;">
          <div class="progress-bar">
            <div class="progress-fill"></div>
          </div>
          <span class="progress-text">0%</span>
        </div>
         <div class="download-footer">
          <a href="https://github.com/akari310/" target="_blank"><i class="fa-brands fa-github"></i> by: Akari</a>
        </div>
         <h1 class="text-description-download">
          <span >Enable pop-ups on YouTube to download audio or video</span>
        </h1>
      </div>
    </div>
    </form>
      </main>
  `;

    function Notify(type = 'info', message = '', title = '') {
        const defaultTitles = {
            success: 'Success',
            error: 'Error',
            info: 'Information',
            warning: 'Warning',
        };

        if (isYTMusic || (window.trustedTypes && window.trustedTypes.defaultPolicy === null)) {
            // Avoid iziToast due to innerHTML TrustedTypes violation on strict environments
            let toast = document.getElementById('yt-tools-custom-toast');
            if (!toast) {
                toast = document.createElement('div');
                toast.id = 'yt-tools-custom-toast';
                toast.style.cssText = 'position:fixed;bottom:20px;left:20px;background:rgba(30,30,30,0.9);color:#fff;padding:12px 20px;border-radius:8px;z-index:99999;font-family:sans-serif;font-size:14px;box-shadow:0 4px 12px rgba(0,0,0,0.3);border-left:4px solid #ff0000;transition:opacity 0.3s;opacity:0;pointer-events:none;';
                document.body.appendChild(toast);
            }
            toast.textContent = (title || defaultTitles[type] || 'Notification') + ': ' + message;
            if (type === 'success') toast.style.borderLeftColor = '#22c55e';
            else if (type === 'error') toast.style.borderLeftColor = '#ef4444';
            else if (type === 'warning') toast.style.borderLeftColor = '#f59e0b';
            else toast.style.borderLeftColor = '#3b82f6';

            toast.style.opacity = '1';
            if (toast._timer) clearTimeout(toast._timer);
            toast._timer = setTimeout(() => { toast.style.opacity = '0'; }, 3000);
            return;
        }

        try {
            iziToast[type]({
                title: title || defaultTitles[type] || 'Notification',
                message: message,
                position: 'bottomLeft',
            });
        } catch (e) {
            console.warn('[yt-tools] iziToast failed:', e);
        }
    }

    // Helper: create SVG icon using DOM API (no innerHTML needed)
    function createSvgIcon(pathsData, size) {
        const sz = size || 24;
        const svgNS = 'http://www.w3.org/2000/svg';
        const svg = document.createElementNS(svgNS, 'svg');
        svg.setAttribute('width', String(sz));
        svg.setAttribute('height', String(sz));
        svg.setAttribute('viewBox', '0 0 24 24');
        svg.setAttribute('stroke-width', '2');
        svg.setAttribute('stroke', 'currentColor');
        svg.setAttribute('fill', 'none');
        svg.setAttribute('stroke-linecap', 'round');
        svg.setAttribute('stroke-linejoin', 'round');
        pathsData.forEach(d => {
            const p = document.createElementNS(svgNS, 'path');
            p.setAttribute('d', d);
            if (d === 'M0 0h24v24H0z') p.setAttribute('fill', 'none');
            svg.appendChild(p);
        });
        return svg;
    }

    // Helper: create a toolbar button with SVG icon
    function makeToolBtn(title, id, className, paths) {
        const btn = document.createElement('button');
        btn.title = title;
        btn.type = 'button';
        if (id) btn.id = id;
        btn.className = (className ? className + ' ' : '') + 'botones_div';
        btn.appendChild(createSvgIcon(paths));
        return btn;
    }


    GM_addStyle(`
       @import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css");
      @import url("https://cdn.jsdelivr.net/npm/[email protected]/dist/css/iziToast.min.css");
      :root {
              --primary-custom: #ff0000 !important;
              --bg-dark-custom: #1a1a1a !important;
              --bg-card-custom: #252525 !important;
              --text-custom: #ffffff !important;
              --text-custom-secondary: #9e9e9e !important;
              --accent-custom: #ff4444 !important;
          }
        #panel-overlay {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            background: rgba(0, 0, 0, 0.3);
            z-index: 9998;
            backdrop-filter: blur(2px);
        }
        #yt-enhancement-panel {
            z-index: 9999 !important;
        }
        body .container-mdcm {
              font-family: "Inter", -apple-system, sans-serif;
              color: var(--yt-enhance-menu-text, var(--text-custom));
        }
        #toggle-button:hover {
          background-color: rgba(255,255,255,0.1);
          border-radius: 50%;
          opacity: 1 !important;
          }
        .container-mdcm {
            width: 420px;
            max-width: 420px;
            background: rgba(30, 30, 30, 0.6) !important;
            border-radius: 16px 16px 0 0;
            box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
            backdrop-filter: blur(16px);
            -webkit-backdrop-filter: blur(16px);
            border: 1px solid rgba(255, 255, 255, 0.1);
            display: flex;
            flex-direction: column;
            max-height: 80vh;
            overflow-y: auto;
            overflow-x: hidden;
            height: auto;
        }

        #shareDropdown {
        display: none;
        position: absolute;
        top: 50px;
        right: 100px;
        background-color: var(--yt-enhance-menu-bg, #252525);
        border-radius: 6px;
        padding: 10px;
        box-shadow: rgba(0, 0, 0, 0.2) 0px 4px 12px;
        z-index: 11;
        }
        #shareDropdown a {
        color: var(--text-custom);
        text-decoration: none;
        line-height: 2;
        font-size: 14px;
        }
        #shareDropdown a:hover {
        color: var(--primary-custom);
        }
        .header-mdcm {
            padding: 12px 16px;
            border-bottom: 1px solid rgba(255,255,255,0.1);
            position: sticky;
            top: 0;
            background-color: var(--yt-enhance-menu-bg, #252525);
            border-radius: 16px 16px 0 0;
            z-index: 10;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .header-mdcm h1 {
            font-size: 16px;
            margin: 0;
            font-weight: 600;
            display: flex;
            align-items: center;
            gap: 8px;
        }


        .header-mdcm i {
         color: var(--primary-custom)
        }


        .icons-mdcm {
            display: flex;
            gap: 4px;
        }
        .icons-mdcm i {
          color: var(--yt-enhance-menu-accent, var(--text-custom));
        }


        .icon-btn-mdcm {
            background: rgba(255,255,255,0.1);
            border: none;
            color: var(--text-custom);
            width: 28px;
            height: 28px;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.3s;
        }

        .icon-btn-mdcm:hover {
            background: rgba(255,255,255,0.2);
            transform: translateY(-2px);
        }

        .icon-btn-mdcm i {
         color: var(--text-custom);
         outline: none;
         text-decoration: none;
        }

        .tabs-mdcm {
            padding: 10px 12px;
            margin: 10px 0;
            position: sticky;
            top: 50px;
            background-color: var(--yt-enhance-menu-bg, #252525);
            z-index: 10;
            display: flex;
            gap: 8px;
            -ms-overflow-style: none;
            padding-bottom: 8px;
        }



        .tabs-mdcm::-webkit-scrollbar {
            height: 0px;
            background-color: transparent;
        }

        .tabs-mdcm:hover::-webkit-scrollbar {
            height: 6px;
        }

        .tabs-mdcm::-webkit-scrollbar-thumb {
            background-color: rgba(255, 0, 0, 0.5);
            border-radius: 3px;
        }

        .tabs-mdcm::-webkit-scrollbar-track {
            background-color: transparent;
        }

        .tab-mdcm {
            padding: 6px 10px;
            border: none;
            background: rgba(255,255,255,0.05);
            cursor: pointer;
            font-size: 12px;
            color: var(--text-custom-secondary);
            border-radius: 6px;
            transition: all 0.3s;
            flex: 1;
            display: flex;
            align-items: center;
            gap: 6px;
            flex-shrink: 0;
            justify-content: center;
            white-space: nowrap;
        }

        .tab-mdcm svg {
            width: 14px;
            height: 14px;
            fill: currentColor;
        }

        .tab-mdcm.active {
            background: var(--yt-enhance-menu-accent, var(--primary-custom)) !important;
            color: var(--text-custom);
            font-weight: 500;
            box-shadow: 0 4px 12px rgba(255,0,0,0.2);
        }

        .tab-mdcm:hover:not(.active) {
            background: rgba(255,255,255,0.1);
            transform: translateY(-1px);
        }

        .options-mdcm {
            flex: 1;
            overflow-y: auto;
            padding: 0 16px 0;
            scrollbar-width: thin;
            scrollbar-color: var(--primary-custom) var(--bg-dark-custom);
            max-height: 300px;
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
            gap: 8px;
        }

        .options-settings-mdcm {
            flex: 1;
            overflow-y: auto;
            padding: 0 16px 0;
            scrollbar-width: thin;
            scrollbar-color: var(--primary-custom) var(--bg-dark-custom);
            max-height: 300px;
            display: grid;
            gap: 8px;
        }

         .card-items-end {
          display: flex;
          justify-content: space-between;
          align-items: center;
          width: 175px;
        }

         .radio-mdcm {
            width: 14px;
            height: 14px;
            accent-color: var(--primary-custom);
        }

        .color-picker-mdcm {
            width: 50px;
            height: 24px;
            border: 1px solid rgba(255, 255, 255, 0.2);
            background: rgba(255, 255, 255, 0.1);
            border-radius: 4px;
            cursor: pointer;
            transition: all 0.3s;
        }

        .color-picker-mdcm:hover {
            background: rgba(255, 255, 255, 0.2);
        }

        .options-mdcm::-webkit-scrollbar, .options-settings-mdcm::-webkit-scrollbar {
            width: 6px;
        }

        .options-mdcm::-webkit-scrollbar-track, .options-settings-mdcm::-webkit-scrollbar-track {
            background: var(--bg-dark-custom);
            border-radius: 3px;
        }

        .options-mdcm::-webkit-scrollbar-thumb, .options-settings-mdcm::-webkit-scrollbar-thumb {
            background: var(--primary-custom);
            border-radius: 3px;
        }

        .options-mdcm::-webkit-scrollbar-thumb:hover, .options-settings-mdcm::-webkit-scrollbar-thumb:hover {
            background: var(--accent-custom);
        }

        .options-mdcm::after, .options-settings-mdcm::after {
            content: '';
            display: block;
        }

        .option-mdcm {
            display: grid;
            grid-template-columns: auto 1fr;
            align-items: center;
            margin-bottom: 0;
            padding: 5px;
            background: rgba(255,255,255,0.05);
            border-radius: 6px;
            transition: all 0.3s;
            border: 1px solid rgba(255,255,255,0.05);
            color: var(--text-custom);
            gap: 6px;
        }

        .option-mdcm:hover {
            background: rgba(255,255,255,0.08);
            border-color: rgba(255,255,255,0.1);
        }
        .option-settings-mdcm {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 0;
          padding: 6px;
          background: rgba(255, 255, 255, 0.05);
          border-radius: 6px;
          transition: all 0.3s;
          border: 1px solid rgba(255, 255, 255, 0.05);
          gap: 6px;
        }

        .option-settings-mdcm:hover {
            background: rgba(255,255,255,0.08);
            border-color: rgba(255,255,255,0.1);
        }
        /* Themes Grid 2 Columns */
        .themes-grid-mdcm {
            display: grid !important;
            grid-template-columns: 1fr 1fr !important;
            gap: 8px !important;
        }
        .themes-grid-mdcm .theme-option {
            margin-bottom: 0 !important;
        }
            .tab-content {
            display: none;
        }
            .tab-content.active {
                display: block;
                margin-bottom: 10px;
            }

        .checkbox-mdcm {
            width: 14px;
            height: 14px;
            accent-color: var(--yt-enhance-menu-accent, var(--primary-custom)) !important;
        }

        .yt-tools-audio-only-player {
            background-color: #000 !important;
            background-repeat: no-repeat !important;
            background-position: center !important;
            background-size: cover !important;
        }

        .yt-tools-audio-only-video {
            opacity: 0 !important;
        }

        label {
            font-size: 12px;
            color: var(--text-custom);
        }

        .slider-container-mdcm {
            background: rgba(255,255,255,0.05);
            padding: 10px;
            border-radius: 6px;
        }

        .slider-mdcm {
            width: 100%;
            height: 3px;
            accent-color: var(--yt-enhance-menu-accent, var(--primary-custom)) !important;
            margin: 10px 0;
        }

        .reset-btn-mdcm {
            padding: 5px 10px;
            border: 1px solid rgba(255,255,255,0.2);
            background: rgba(255,255,255,0.1);
            color: var(--text-custom);
            border-radius: 4px;
            cursor: pointer;
            font-size: 11px;
            transition: all 0.3s;
        }

        .reset-btn-mdcm:hover {
            background: rgba(255,255,255,0.2);
        }

        .quality-selector-mdcm select {
            position: relative;
            padding: 3px;
            outline: none;
            border-radius: 4px;
            border: 1px solid rgba(255,255,255,0.2);
            background: var(--yt-enhance-menu-accent, var(--primary-custom)) !important;
            color: var(--text-custom);
            width: fit-content;
            appearance: none;
            cursor: pointer;
            font-size: 11px;
        }


        .quality-selector-mdcm {
            background: rgba(255,255,255,0.05);
            padding: 10px;
            border-radius: 6px;
        }

        .select-wrapper-mdcm {
          position: relative;
          display: inline-block;
        }

        .select-wrapper-mdcm select {
          -webkit-appearance: auto;
          -moz-appearance: auto;
        }

        .actions-mdcm {
            position: sticky;
            top: 0;
            padding: 12px 16px;
            backdrop-filter: blur(16px);
            -webkit-backdrop-filter: blur(16px);
            background: rgba(30, 30, 30, 0.6) !important;
            border-bottom: 1px solid rgba(255, 255, 255, 0.1);
            display: flex;
            gap: 6px;
            width: 390px;
            border-radius: 0 0 16px 16px;
            justify-content: space-between;
            align-items: center;
        }

        .action-buttons-mdcm {
            display: flex;
            gap: 6px;
        }

        .action-btn-mdcm {
            flex: 1;
            padding: 8px;
            border: none;
            border-radius: 6px;
            background: var(--primary-custom);
            color: var(--text-custom);
            cursor: pointer;
            font-size: 12px;
            font-weight: 500;
            transition: all 0.3s;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 4px;
            box-shadow: 0 4px 12px rgba(255,0,0,0.2);
        }

        .action-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 16px rgba(255,0,0,0.3);
        }

        textarea.textarea-mdcm {
            width: 100%;
            height: 50px;
            margin-top: 10px;
            margin-bottom: 12px;
            padding: 8px;
            background: rgba(255,255,255,0.05);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 6px;
            color: var(--text-custom);
            font-size: 11px;
            resize: none;
            transition: all 0.3s;
        }

        textarea.textarea-mdcm:focus {
            outline: none;
            border-color: var(--primary-custom);
            background: rgba(255,255,255,0.08);
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .container-mdcm {
            animation: fadeIn 0.3s ease-out;
        }

        .developer-mdcm {
            font-size: 10px;
            color: var(--text-custom-secondary);
        }

        .developer-mdcm a {
            color: var(--primary-custom);
            text-decoration: none;
        }

        /* Styles for the import/export area */
        #importExportArea {
            display: none;
            padding: 16px;
            margin: 0px;
            background-color: var(--yt-enhance-menu-bg, #252525);
            border-radius: 16px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
        }

        #importExportArea.active {
            display: block;
            margin-top: 10px;
        }

        /* Style the textarea */
        #importExportArea textarea {
            width: 370px;
            height: 20px;
            margin-bottom: 10px;
            padding: 8px;
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 6px;
            background-color: rgba(255, 255, 255, 0.05);
            color: var(--text-custom);
            font-size: 12px;
            resize: vertical;
        }

        /* Style the buttons */
        #importExportArea .action-buttons-mdcm  {
            display: flex;
            justify-content: space-between;
            gap: 10px;
        }

        #importExportArea .action-btn-mdcm {
            flex: 1;
            padding: 10px 16px;
            border: none;
            border-radius: 6px;
            background-color: var(--primary-custom);
            color: var(--text-custom);
            font-size: 14px;
            font-weight: 500;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }

        #importExportArea .action-btn-mdcm:hover {
            background-color: var(--accent-custom);
        }

        .ocultarframe, .ocultarframeaudio {
            display: none !important;
        }

        .yt-tools-container {
            width: 100% !important;
            display: flex !important;
            justify-content: center !important;
            margin: 0 !important;
        }

        .yt-tools-inner-container {
            width: 100% !important;
            display: flex !important;
            flex-direction: column !important;
            align-items: center !important;
        }

        /* Layout & Alignment Fixes */
        .yt-tools-form {
            display: flex !important;
            flex-direction: column !important;
            align-items: center !important;
            justify-content: center !important;
            width: 100% !important;
            gap: 2px !important;
        }

        .containerButtons {
            display: flex !important;
            justify-content: center !important;
            align-items: center !important;
            gap: 12px !important;
            width: 100% !important;
            flex-wrap: wrap !important;
        }

        .selectcalidades, .selectcalidadesaudio {
            background: rgba(30, 30, 30, 0.9) !important;
            backdrop-filter: blur(12px) !important;
            -webkit-backdrop-filter: blur(12px) !important;
            border: 1px solid rgba(255, 255, 255, 0.1) !important;
            color: #ffffff !important;
            padding: 0 20px !important;
            height: 40px !important;
            line-height: 40px !important;
            border-radius: 10px !important;
            font-family: "Inter", -apple-system, sans-serif !important;
            font-size: 14px !important;
            font-weight: 600 !important;
            cursor: pointer !important;
            outline: none !important;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4) !important;
            transition: all 0.3s ease !important;
            margin: 0 auto !important;
            display: block !important;
            min-width: 280px !important;
            max-width: 350px !important;
            appearance: none !important;
            -webkit-appearance: none !important;
            text-align: center !important;
            text-align-last: center !important; /* Support for some browsers */
            position: relative;
        }

        .selectcalidades:hover, .selectcalidadesaudio:hover {
            border-color: #ff0000 !important;
            background: rgba(45, 45, 45, 0.95) !important;
            transform: translateY(-2px);
            box-shadow: 0 12px 40px rgba(255, 0, 0, 0.15) !important;
        }

        .selectcalidades option, .selectcalidadesaudio option {
            background: #1e1e1e !important;
            color: #ffffff !important;
            padding: 12px !important;
            text-align: center !important;
        }

        .formulariodescarga, .formulariodescargaaudio {
            width: 100% !important;
            margin: 0 !important;
            display: none !important; /* Hidden by default */
            justify-content: center !important;
            align-items: center !important;
        }

        .containerall {
            width: 100% !important;
            display: flex !important;
            flex-direction: column !important;
            align-items: center !important;
            gap: 2px !important;
        }

        /* Regular YouTube specific spacing (VIP) */
        ytd-watch-metadata .yt-tools-inner-container {
            gap: 10px !important;
        }

        ytd-watch-metadata .containerall {
            gap: 0px !important;
            padding-bottom: 0 !important;
        }

        ytd-watch-metadata .yt-tools-container {
            margin-bottom: -8px !important;
        }

        ytd-watch-metadata .content_collapsible_colors {
            margin-top: 0 !important;
        }

        ytd-watch-metadata .download-container {
            width: 90% !important;
            max-width: 450px !important;
            padding: 7px !important;
            border-radius: 12px !important;
            margin: 5px auto !important;
            display: flex !important;
            flex-direction: column !important;
            transition: all 0.3s ease;
            position: relative;
        }

      #yt-stats {
      position: fixed;
      top: 60px;
      right: 20px;
      background: #1a1a1a;
      color: white;
      padding: 15px;
      border-radius: 10px;
      width: 320px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.4);
      font-family: Arial, sans-serif;
      display: none;
      }
  #yt-stats-toggle {
      font-size: 12px;
      color: #fff;
      padding: 12px 20px;
      border-radius: 5px;
      cursor: pointer;
  }
  .stat-row {
      margin: 15px 0;
  }
  .progress {
      height: 6px;
      overflow: hidden;
      background: #333;
      border-radius: 3px;
      margin: 8px 0;
  }
  .progress-bar {
      height: 100%;
      transition: width 0.3s;
  }
  .total-bar { background: #44aaff !important; }
  .video-bar { background: #00ff88 !important; }
  .shorts-bar { background: #ff4444 !important; }
  #cinematics {
    position: absolute !important;
    width: 90vw !important;
    height: 100vh ;
  }
    #cinematics div {
        position: fixed;
      inset: 0px;
      pointer-events: none;
      transform: scale(1.5, 2);
  }
      #cinematics > div > div > canvas:nth-child(1), #cinematics > div > div > canvas:nth-child(2) {
   position: absolute !important;
    width: 90vw !important;
    height: 100vh ;
      }

    /* .html5-video-player.unstarted-mode {
       background-image: url('https://avatars.githubusercontent.com/u/54366580?v=4');
       background-repeat: no-repeat;
       background-position: 50% 50%;
       display: flex;
       justify-content: center;
       align-items: center;
    } */

        #yt-enhancement-panel {
            position: fixed;
            top: 60px;
            right: 20px;
            z-index: 9999;
        }

        .color-picker {
            width: 100%;
            margin: 0;
            padding: 0;
            border: none;
            background: none;
        }
        .slider {
            width: 100%;
        }
         #toggle-panel {
            z-index: 10000;
            color: white;
            padding: 5px;
            border: none;
            cursor: pointer;
            display: flex;
            justify-content: center;
            transition: all 0.5s ease;
            width: 43px;
            border-radius: 100px;
        }

        #icon-menu-settings {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 24px;
        height: 24px;
        padding: 7px;
        font-size: 20px;
        color: var(--yt-spec-icon-inactive);
        cursor: pointer;
        user-select: none;
        filter: drop-shadow(2px 4px 6px black);
        }

        .theme-option {
            margin-bottom: 15px;
        }
        .theme-option label {
            display: flex;
            align-items: center;
        }
       .theme-option {
    position: relative;
    width: auto;
    margin-bottom: 10px;
    padding: 10px;
    border-radius: 4px;
    cursor: pointer;
}

.theme-preview {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: 10px;
    border: 1px solid #000;
    z-index: 1;
}

.theme-option input[type="radio"] {
    position: relative;
    z-index: 2;
    margin-right: 10px;
    cursor: pointer;
}

.theme-name {
    position: relative;
    z-index: 2;
    font-size: 15px;
    color: #fff;
}

.theme-option label {
    display: flex;
    align-items: center;
    width: 100%;
    position: relative;
    z-index: 2;
}

  .buttons-tranlate, .select-traductor {
        background: #000;
        font-size: 10px;
        border: none;
        color: #fbf4f4 !important;
        padding: 3px 0;
        margin-left: 10px;
        width: 70px;
        border-radius: 10px;
        }
        .buttons-tranlate:hover {
        cursor: pointer;
        background-color: #6b6b6b;
        }
         button.botones_div {
         margin: 0;
         padding: 0;
         }
         button.botones_div:hover {
         cursor: pointer;
         color: #6b6b6b !important;
         }

        .tab-button:hover {
          background-color: #ec3203 !important;
          color: #ffffff !important;
          cursor: pointer;
        }

        .traductor-container {
            display: inline-block;
            align-items: center;
            gap: 8px;
            margin-top: 4px;
          }

        #eyes {
      opacity: 0;
      position: absolute;
      height: 24px;
      left: 0;
      width: 24px;
    }

    /* width */
    .container-mdcm ::-webkit-scrollbar {
      width: 4px;
      height: 10px;
    }

    /* Track */
    .container-mdcm ::-webkit-scrollbar-track {
      background: #d5d5d5;

    }

    /* Handle */
    .container-mdcm ::-webkit-scrollbar-thumb {
      background: #000;

    }

    .color-boxes {
      display: flex;
      gap: 8px;
    }
    .color-box {
      width: 20px;
      height: 20px;
      border: 1px solid rgb(221 221 221 / 60%);
      border-radius: 4px;
      cursor: pointer;
    }
    .color-box.selected {
      border: 2px solid var(--primary-custom);
      filter: drop-shadow(0px 1px 6px red);
    }

    .containerButtons {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: wrap;
      gap: 10px;
    }
    .containerButtons > button:hover {
      cursor: pointer;
    }

        /* Download Container Styles */
        .download-container {
          width: 90% !important;
          max-width: 450px !important;
          padding: 16px !important;
          border-radius: 12px !important;
          margin: 10px auto !important;
          display: flex !important;
          flex-direction: column !important;
          transition: all 0.3s ease;
          position: relative;
        }

        .download-container.video {
          background: linear-gradient(135deg, #ff4444, #cc0000);
          color: white;
        }

        .download-container.audio {
          background: linear-gradient(135deg, #00cc44, #009933);
          color: white;
        }

        .download-info {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 8px;
        }

        .download-text {
          font-weight: 600;
          font-size: 14px;
        }

        .download-quality {
          font-size: 12px;
          opacity: 0.9;
        }

        .progress-container {
          display: flex;
          align-items: center;
          gap: 10px;
          margin-bottom: 6px;
        }

        .progress-bar {
          flex: 1;
          height: 6px;
          background: rgba(255, 255, 255, 0.3);
          border-radius: 3px;
          overflow: hidden;
        }

        .progress-fill {
          height: 100%;
          background: rgba(255, 255, 255, 0.8);
          border-radius: 3px;
          width: 0%;
          transition: width 0.3s ease;
        }

        .progress-text {
          font-size: 12px;
          font-weight: 500;
          min-width: 30px;
        }

        .download-footer {
          font-size: 10px;
          opacity: 0.7;
          text-align: center;
        }
        .download-footer a {
          text-decoration: none;
          color: #fff;
        }

        .download-container.completed {
          color: #fff;
          background: linear-gradient(135deg, #00cc44, #009933) !important;
        }

        .download-container.completed .download-text {
          font-weight: 700;
        }

      /* Bookmarks panel (under video buttons) */
      .yt-bookmarks-panel {
        margin-top: 10px;
        background: rgba(255,255,255,0.06);
        border: 1px solid rgba(255,255,255,0.12);
        border-radius: 10px;
        padding: 8px;
      }
      .yt-bm-empty {
        font-size: 12px;
        color: var(--text-custom-secondary);
      }
      .yt-bm-item {
        display: grid;
        grid-template-columns: auto 1fr auto;
        gap: 8px;
        align-items: center;
        padding: 6px;
        border-radius: 8px;
      }
      .yt-bm-item:hover {
        background: rgba(255,255,255,0.06);
      }
      .yt-bm-go {
        border: none;
        border-radius: 6px;
        padding: 4px 8px;
        background: rgba(34,197,94,0.2);
        color: #fff;
        cursor: pointer;
        font-size: 12px;
        white-space: nowrap;
      }
      .yt-bm-label {
        font-size: 12px;
        color: var(--text-custom);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      .yt-bm-del {
        border: none;
        border-radius: 6px;
        padding: 4px 8px;
        background: rgba(239,68,68,0.2);
        color: #fff;
        cursor: pointer;
        font-size: 12px;
      }

      /* Continue watching panel (under video buttons) */
      .yt-continue-watching-panel {
        margin-top: 10px;
        background: rgba(255,255,255,0.06);
        border: 1px solid rgba(255,255,255,0.12);
        border-radius: 10px;
        padding: 8px;
      }
      .yt-cw-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        margin-bottom: 8px;
      }
      .yt-cw-header-title {
        font-size: 12px;
        font-weight: 600;
        color: var(--text-custom, #fff);
      }
      .yt-cw-clear {
        border: none;
        border-radius: 6px;
        padding: 4px 8px;
        background: rgba(239,68,68,0.18);
        color: #fff;
        cursor: pointer;
        font-size: 12px;
      }
      .yt-cw-empty {
        font-size: 12px;
        color: var(--text-custom-secondary, #aaa);
      }
      .yt-cw-item {
        display: grid;
        grid-template-columns: auto 1fr auto;
        gap: 10px;
        align-items: center;
        padding: 8px;
        border-radius: 10px;
      }
      .yt-cw-item:hover {
        background: rgba(255,255,255,0.06);
      }
      .yt-cw-thumb-wrap {
        width: 72px;
        height: 40px;
        border-radius: 8px;
        overflow: hidden;
        background: rgba(255,255,255,0.08);
        flex: none;
      }
      .yt-cw-thumb {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
      }
      .yt-cw-title {
        font-size: 12px;
        font-weight: 600;
        color: var(--text-custom, #fff);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        max-width: 520px;
      }
      .yt-cw-meta {
        font-size: 12px;
        color: var(--text-custom-secondary, #aaa);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      .yt-cw-actions {
        display: flex;
        align-items: center;
        gap: 8px;
      }
      .yt-cw-go {
        border: none;
        border-radius: 6px;
        padding: 4px 8px;
        background: rgba(34,197,94,0.2);
        color: #fff;
        cursor: pointer;
        font-size: 12px;
        white-space: nowrap;
      }
      .yt-cw-del {
        border: none;
        border-radius: 6px;
        padding: 4px 8px;
        background: rgba(239,68,68,0.2);
        color: #fff;
        cursor: pointer;
        font-size: 12px;
      }

      /* Shorts channel name label (Home/feed Shorts lockups) */
      html:not([data-mdcm-shorts-channel-name="1"]) .yt-tools-shorts-channel-name {
        display: none !important;
      }
      .yt-tools-shorts-channel-name {
        font-size: 12px;
        line-height: 1.2;
        color: var(--yt-spec-text-secondary, #aaa);
        margin-bottom: 2px;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      .yt-tools-shorts-stats-wrap {
        margin-top: 4px;
        font-size: 11px;
        line-height: 1.2;
        color: var(--yt-spec-text-secondary, #aaa);
      }
      .yt-tools-shorts-stats-wrap .yt-tools-shorts-stats-row {
        display: inline-flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 2px;
      }

      /* Like vs dislike bar (under likes/dislikes) */
      #yt-like-dislike-bar-mdcm {
        height: 6px;
        border-radius: 999px;
        overflow: hidden;
        margin-top: 6px;
        background: rgba(255,255,255,0.12);
        max-width: 305px;
      }
      #yt-like-dislike-bar-mdcm .like {
        height: 100%;
        background: #22c55e;
        float: left;
      }
      #yt-like-dislike-bar-mdcm .dislike {
        height: 100%;
        background: #ef4444;
        float: left;
      }

        .progress-retry-btn {
          position: absolute;
          top: 8px;
          left: 8px;
          right: auto;
          width: 24px;
          height: 24px;
          border: none;
          border-radius: 50%;
          background: rgba(255, 255, 255, 0.2);
          color: white;
          cursor: pointer;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 12px;
          transition: all 0.3s ease;
        }

        .progress-retry-btn:hover {
          background: rgba(255, 255, 255, 0.3);
          transform: scale(1.1);
        }

        .download-again-btn {
          position: absolute;
          top: 8px;
          left: 8px;
          right: auto;
          width: 24px;
          height: 24px;
          border: none;
          border-radius: 50%;
          background: rgba(34, 197, 94, 0.35);
          color: white;
          cursor: pointer;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 12px;
          transition: all 0.3s ease;
        }

        .download-again-btn:hover {
          background: rgba(34, 197, 94, 0.5);
          transform: scale(1.1);
        }

        .download-container {
          position: relative;
        }

        .download-actions {
          display: flex;
          gap: 8px;
          margin-bottom: 8px;
        }

        .download-btn {
          flex: 1;
          padding: 8px 16px;
          border: none;
          border-radius: 4px;
          font-weight: 600;
          font-size: 12px;
          cursor: pointer;
          transition: all 0.3s ease;
          color: white;
        }

        .download-btn.video-btn {
          background: linear-gradient(135deg, #ff6666, #ff4444);
        }

        .download-btn.audio-btn {
          background: linear-gradient(135deg, #00dd55, #00cc44);
        }

        .download-btn:hover {
          transform: translateY(-1px);
          box-shadow: 0 4px 8px rgba(0,0,0,0.2);
        }

        .download-info {
          padding-left: 28px !important; /* Space for buttons on the left */
        }

        .download-btn:disabled {
          opacity: 0.6;
          cursor: not-allowed;
          transform: none;
        }

        .retry-btn {
          padding: 8px 16px;
          border: none;
          border-radius: 4px;
          font-weight: 600;
          font-size: 12px;
          cursor: pointer;
          transition: all 0.3s ease;
          background: linear-gradient(135deg, #ffaa00, #ff8800);
          color: white;
        }

        .retry-btn:hover {
          transform: translateY(-1px);
          box-shadow: 0 4px 8px rgba(0,0,0,0.2);
    }

      body {
      padding: 0;
      margin: 0;
      overflow-y: scroll;
      overflow-x: hidden;
      }
      .style-scope.ytd-comments {
      overflow-y: auto;
      overflow-x: hidden;
      height: auto;
      }
      ytd-comment-view-model[is-reply] #author-thumbnail.ytd-comment-view-model yt-img-shadow.ytd-comment-view-model, ytd-comment-view-model[is-creator-reply] #author-thumbnail.ytd-comment-view-model yt-img-shadow.ytd-comment-view-model {
        width: 40px;
        height: 40px;
        border-radius: 50%;
      }
        #author-thumbnail img.yt-img-shadow {
        border-radius: 50% !important;
        }
        #author-thumbnail.ytd-comment-view-model yt-img-shadow.ytd-comment-view-model {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          overflow: visible;
        }
      ytd-item-section-renderer.ytd-watch-next-secondary-results-renderer {
        --ytd-item-section-item-margin: 8px;
        overflow-y: auto;
        overflow-x: hidden;
        height: auto;
      }
      .right-section.ytcp-header {
      display: flex;
      flex: 1;
      align-items: center;
      gap: 45px;
      justify-content: end;
    }
      #meta.ytd-playlist-panel-video-renderer {
    min-width: 0;
    padding: 0 8px;
    /* display: flexbox; */
    display: flex;
    flex-direction: column-reverse;
    flex: 1;
    flex-basis: 0.000000001px;
}

    .containerall {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      padding-bottom: 30px;
      max-width: 800px;
      margin: auto;
    }
    .container .botoncalidades {
      margin: 3px 2px;
      width: 24.6%;
    }

    .botoncalidades:first-child {
      background-color: #0af;
    }

    .botoncalidades:last-child {
      background-color: red;
      width: 100px;
    }

    .selectcalidades,
    .botoncalidades,
    .selectcalidadesaudio {
      width: 50%;
      height: 27.8px;
      background-color: #fff;
      color: #000;
      font-size: 25px;
      text-align: center;
      border: 1px solid black;
      border-radius: 10px;
      border: none;
      font-size: 20px;
      margin: 2px 2px;
    }

    .botoncalidades {
      width: 70px;
      height: 30px;
      background-color: rgb(4, 156, 22);
      border: 0px solid #000;
      color: #fff;
      font-size: 20px;
      border-radius: 10px;
      margin: 2px 2px;
    }

    .botoncalidades:hover,
    .bntcontainer:hover {
      cursor: pointer;
    }

   .ocultarframe,
    .ocultarframeaudio {
      display: none;
    }
      .checked_updates {
      cursor: pointer;
      }

      #export-config, #import-config {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 10px;
        background-color: var(--yt-enhance-menu-accent, var(--primary-custom)) !important;
        color: #ffffff;
        border: none;
        padding: 5px;
      }
        #export-config:hover, #import-config:hover {
          background-color: #ff0000;
          color: #ffffff;
          cursor: pointer;
        }

        .yt-image-avatar-download {
          position: absolute;
          bottom: -10px;
          right: -14px;
          border: none;
          z-index: 1000;
          background: transparent;
          filter: drop-shadow(1px 0 6px red);
          color: var(--ytcp-text-primary);
          cursor: pointer;
        }

        .custom-classic-btn {
          display: flex;
          align-items: center;
          justify-content: center;
          background-color: rgba(255,255,255,0.1);
          border-radius: 50%;
          border: none;
          width: 48px;
          height: 48px;
          color: var(--yt-spec-icon-inactive);
          font-size: 24px;
          margin: 0px 8px;
          cursor: pointer;
        }
        .custom-classic-btn:hover {
          background-color: rgba(255,255,255,0.2);
        }
        .background-image-container {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 8px;
        margin: 10px 0;
      }

      .background-image-preview {
        width: 160px;
        height: 90px;
        border-radius: 10px;
        background-size: cover;
        background-position: center;
        border: 2px solid #444;
        position: relative;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: box-shadow 0.2s;
        box-shadow: 0 2px 8px rgba(0,0,0,0.08);
        overflow: hidden;
      }

      .background-image-preview:hover .background-image-overlay {
        opacity: 1;
      }

      .background-image-overlay {
        position: absolute;
        top: 0; left: 0; right: 0; bottom: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        color: #fff;
        background: rgba(0,0,0,0.35);
        font-size: 18px;
        opacity: 0;
        transition: opacity 0.2s;
        pointer-events: none;
      }

      .background-image-preview:hover .background-image-overlay,
      .background-image-preview:focus .background-image-overlay {
        opacity: 1;
      }

      .background-image-overlay i {
        font-size: 28px;
        margin-bottom: 4px;
      }

      .background-image-text {
        font-size: 13px;
        font-weight: 500;
        text-shadow: 0 1px 4px #000;
      }

      .remove-background-image {
        position: absolute;
        top: 6px;
        right: 6px;
        background: #e74c3c;
        color: #fff;
        border: none;
        border-radius: 50%;
        width: 26px;
        height: 26px;
        font-size: 18px;
        cursor: pointer;
        z-index: 2;
        display: none;
        align-items: center;
        justify-content: center;
        padding: 0;
        line-height: 1;
        box-shadow: 0 2px 8px rgba(0,0,0,0.15);
        transition: background 0.2s;
      }
      .remove-background-image:hover {
        background: #c0392b;
      }
      .background-image-preview.has-image .remove-background-image {
        display: flex;
      }

      ytd-feed-filter-chip-bar-renderer[not-sticky] #chips-wrapper.ytd-feed-filter-chip-bar-renderer {
        padding: 10px;
      }
      .text-description-download {
        font-size: 12px;
        text-align: center;
        margin-top: 10px;
        }
        /* === FIX: Căn giữa thanh công cụ khi bật Cinematic Mode === */
    ytd-watch-flexy[cinematic-container-initialized] #primary-inner {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    ytd-watch-flexy[cinematic-container-initialized] .yt-tools-container {
      /* Đảm bảo thanh công cụ không bị quá rộng so với video */
      width: 100%;
      max-width: var(--ytd-watch-flexy-max-player-width, 1280px);
    }

    /* === YouTube Music specific styles === */
    #ytm-side-panel-wrapper {
      display: flex !important;
      flex-direction: column !important;
      align-items: center !important;
      justify-content: center !important;
      width: 100% !important;
      margin: 0 0 12px 0 !important;
      padding: 4px 0 !important;
      box-sizing: border-box !important;
      overflow: hidden !important;
      border-radius: 16px !important;
    }

    ytmusic-player-page #side-panel {
      margin-left: 16px !important;
      margin-bottom: 24px !important;
      padding: 0 !important;
      background: transparent !important;
      border: none !important;
      box-shadow: none !important;
    }

    .ytm-side-panel-divider {
      width: 92%;
      height: 1px;
      background: rgba(255, 255, 255, 0.1);
      margin: 4px 0;
    }

    /* Blur Mode (Standard with subtle blur) */
    body.ytm-style-blur #ytm-side-panel-wrapper,
    body.ytm-style-blur ytmusic-player-page #side-panel ytmusic-tab-renderer {
      background: rgba(20, 20, 20, 0.6) !important;
      backdrop-filter: blur(20px) !important;
      -webkit-backdrop-filter: blur(20px) !important;
      border: 1px solid rgba(255, 255, 255, 0.08) !important;
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4) !important;
      border-radius: 16px !important;
    }

    /* Liquid Mode (Fixed Apple Style) */
    body.ytm-style-liquid #ytm-side-panel-wrapper,
    body.ytm-style-liquid ytmusic-player-page #side-panel ytmusic-tab-renderer {
      background: rgba(25, 25, 25, 0.45) !important;
      backdrop-filter: blur(24px) saturate(180%) !important;
      -webkit-backdrop-filter: blur(24px) saturate(180%) !important;
      border: 1px solid rgba(255, 255, 255, 0.15) !important;
      border-top: 1px solid rgba(255, 255, 255, 0.25) !important;
      box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.4), inset 0 1px 1px rgba(255, 255, 255, 0.1) !important;
      border-radius: 16px !important;
    }

    /* Transparent Mode */
    body.ytm-style-transparent #ytm-side-panel-wrapper,
    body.ytm-style-transparent ytmusic-player-page #side-panel ytmusic-tab-renderer {
      background: transparent !important;
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
      border: none !important;
      box-shadow: none !important;
    }

    /* YouTube watch playlist panel: reuse the same 3 style choices as YTM. */
    body.ytm-style-blur ytd-watch-flexy ytd-playlist-panel-renderer#playlist {
      background: rgba(20, 20, 20, 0.62) !important;
      backdrop-filter: blur(20px) saturate(140%) !important;
      -webkit-backdrop-filter: blur(20px) saturate(140%) !important;
      border: 1px solid rgba(255, 255, 255, 0.08) !important;
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.38) !important;
      border-radius: 16px !important;
      overflow: hidden !important;
    }

    body.ytm-style-liquid ytd-watch-flexy ytd-playlist-panel-renderer#playlist {
      background: rgba(25, 25, 25, 0.45) !important;
      backdrop-filter: blur(24px) saturate(180%) !important;
      -webkit-backdrop-filter: blur(24px) saturate(180%) !important;
      border: 1px solid rgba(255, 255, 255, 0.15) !important;
      border-top-color: rgba(255, 255, 255, 0.25) !important;
      box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), inset 0 1px 1px rgba(255, 255, 255, 0.1) !important;
      border-radius: 16px !important;
      overflow: hidden !important;
    }

    body.ytm-style-transparent ytd-watch-flexy ytd-playlist-panel-renderer#playlist {
      background: transparent !important;
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
      border: none !important;
      box-shadow: none !important;
    }

    body.ytm-style-blur ytd-watch-flexy ytd-playlist-panel-renderer#playlist > #container,
    body.ytm-style-liquid ytd-watch-flexy ytd-playlist-panel-renderer#playlist > #container,
    body.ytm-style-transparent ytd-watch-flexy ytd-playlist-panel-renderer#playlist > #container,
    body.ytm-style-blur ytd-watch-flexy ytd-playlist-panel-renderer#playlist #items,
    body.ytm-style-liquid ytd-watch-flexy ytd-playlist-panel-renderer#playlist #items,
    body.ytm-style-transparent ytd-watch-flexy ytd-playlist-panel-renderer#playlist #items {
      background: transparent !important;
    }

    body.ytm-style-blur ytd-watch-flexy ytd-playlist-panel-renderer#playlist .header,
    body.ytm-style-liquid ytd-watch-flexy ytd-playlist-panel-renderer#playlist .header {
      background: rgba(255, 255, 255, 0.04) !important;
      border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important;
    }

    body.ytm-style-transparent ytd-watch-flexy ytd-playlist-panel-renderer#playlist .header {
      background: transparent !important;
      border-bottom: none !important;
    }

    body.ytm-style-blur ytd-watch-flexy ytd-playlist-panel-renderer#playlist ytd-playlist-panel-video-renderer,
    body.ytm-style-liquid ytd-watch-flexy ytd-playlist-panel-renderer#playlist ytd-playlist-panel-video-renderer {
      background: transparent !important;
    }

    body.ytm-style-blur ytd-watch-flexy ytd-playlist-panel-renderer#playlist ytd-playlist-panel-video-renderer:hover #container,
    body.ytm-style-liquid ytd-watch-flexy ytd-playlist-panel-renderer#playlist ytd-playlist-panel-video-renderer:hover #container {
      background: rgba(255, 255, 255, 0.08) !important;
    }

    body.ytm-style-blur ytd-watch-flexy ytd-playlist-panel-renderer#playlist ytd-thumbnail,
    body.ytm-style-liquid ytd-watch-flexy ytd-playlist-panel-renderer#playlist ytd-thumbnail {
      border-radius: 8px !important;
      overflow: hidden !important;
    }

    body.ytm-style-blur ytd-watch-flexy ytd-playlist-panel-renderer#playlist #meta,
    body.ytm-style-liquid ytd-watch-flexy ytd-playlist-panel-renderer#playlist #meta,
    body.ytm-style-transparent ytd-watch-flexy ytd-playlist-panel-renderer#playlist #meta {
      min-width: 0 !important;
    }

    /* Inner Container Resets */
    html[dark] .yt-tools-container,
    ytmusic-app .yt-tools-container,
    ytmusic-app #side-panel ytmusic-tab-renderer,
    ytmusic-app ytmusic-search-box,
    ytmusic-app #side-panel > .tab-header-container,
    tp-yt-paper-tabs.tab-header-container,
    #tabsContainer.tp-yt-paper-tabs,
    tp-yt-paper-tab.tab-header,
    .tab-content.tp-yt-paper-tab {
      background: transparent !important;
      background-color: transparent !important;
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
      border: none !important;
      box-shadow: none !important;
      margin: 0 !important;
    }

    .yt-tools-container {
      width: 100% !important;
      display: flex !important;
      align-items: center !important;
      justify-content: center !important;
      padding: 0 !important;
    }

    .tab-header-container {
      width: 100% !important;
      display: flex !important;
      align-items: center !important;
      justify-content: center !important;
      padding: 4px 0 !important;
    }

    /* Fix YTM side-panel queue layout */
    ytmusic-app #side-panel {
      padding: 8px 12px;
      box-sizing: border-box;
    }
    ytmusic-app #side-panel ytmusic-queue-header-renderer .container-name {
      padding: 0 8px;
    }
    ytmusic-app #side-panel ytmusic-player-queue-item .song-info {
      padding-right: 4px;
    }
    ytmusic-app #side-panel ytmusic-tab-renderer {
      border-radius: 16px !important;
      overflow-x: hidden !important;
      overflow-y: auto !important;
      width: 100% !important;
      box-sizing: border-box !important;
      padding: 12px 0 12px 12px !important;
      margin-bottom: 12px !important;
    }

    /* Make the YTM Search Box premium and glassmorphic (Feature requested by user) */
    ytmusic-app ytmusic-search-box {
      border-radius: 16px !important;
    }
    html[dark] ytmusic-app ytmusic-search-box #input-box,
    ytmusic-app ytmusic-search-box #input-box {
      background: transparent !important;
    }

    /* Tab headers — rounded corners & spacing */
    ytmusic-app #side-panel > .tab-header-container {
      border-radius: 16px !important;
      overflow: hidden !important;
      padding: 4px 8px;
      margin: 0 0 8px 0 !important;
      width: 100% !important;
      box-sizing: border-box !important;
    }

    /* Compact button layout for narrow YTM side panel */
    ytmusic-app .containerButtons {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: wrap;
      gap: 4px;
    }

    ytmusic-app .botones_div {
      background: rgba(255, 255, 255, 0.08) !important;
      border: 1px solid rgba(255, 255, 255, 0.12) !important;
      color: #fff !important;
      border-radius: 6px !important;
      padding: 5px 7px !important;
      transition: all 0.2s ease !important;
      line-height: 1 !important;
    }
    ytmusic-app .botones_div svg {
      width: 18px !important;
      height: 18px !important;
    }

    ytmusic-app .botones_div:hover {
      background: rgba(255, 0, 0, 0.25) !important;
      border-color: rgba(255, 0, 0, 0.4) !important;
      transform: translateY(-1px);
    }

    ytmusic-player-page #side-panel select,
    ytmusic-player-page #side-panel select option {
      background: #282828 !important;
      color: #fff !important;
      border: 1px solid rgba(255, 255, 255, 0.1) !important;
    }

    ytmusic-app .selectcalidades,
    ytmusic-app .selectcalidadesaudio {
      background: rgba(255, 255, 255, 0.1) !important;
      color: #fff !important;
      border: 1px solid rgba(255, 255, 255, 0.2) !important;
      border-radius: 6px !important;
      padding: 8px 8px 6px !important; /* Asymmetric padding for vertical centering */
      font-size: 12px !important;
      width: 100% !important;
      cursor: pointer !important;
      outline: none !important;
      height: 32px !important;
      line-height: normal !important;
    }

    ytmusic-app .download-container {
      width: 100% !important;
      background: rgba(0, 0, 0, 0.3) !important;
      border-radius: 6px !important;
      position: relative !important; /* Fix absolute positioned buttons (Retry/Again) */
      padding: 10px !important;
      box-sizing: border-box !important;
      margin-bottom: 0 !important;
    }

    ytmusic-app .content_collapsible_colors {
      margin-top: 8px !important;
    }

    .ytm-side-panel-divider {
      margin: 0 !important;
      border-bottom: 1px solid rgba(255, 255, 255, 0.1);
      height: 0;
      width: 100%;
    }

    ytmusic-app .containerall {
      padding-bottom: 10px !important;
    }

    ytmusic-app #toggle-button {
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      padding: 8px;
      margin-right: 4px;
    }

    ytmusic-app #icon-menu-settings {
      color: #fff;
      font-size: 20px;
      transition: transform 0.3s ease;
    }

    ytmusic-app #icon-menu-settings:hover {
      transform: rotate(90deg);
      color: #ff4444;
    }
    `);





    function buildYTMToolbar() {
        const main = document.createElement('main');
        main.className = 'yt-tools-container';

        const container = document.createElement('div');
        container.className = 'yt-tools-inner-container';

        const form = document.createElement('form');
        form.className = 'yt-tools-form';
        const btnsDiv = document.createElement('div');
        btnsDiv.className = 'containerButtons';

        // Thumbnail (Image download)
        btnsDiv.appendChild(makeToolBtn('Image video', 'imagen', '', [
            'M0 0h24v24H0z', 'M15 8h.01',
            'M12.5 21h-6.5a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v6.5',
            'M3 16l5 -5c.928 -.893 2.072 -.893 3 0l4 4',
            'M14 14l1 -1c.653 -.629 1.413 -.815 2.13 -.559',
            'M19 16v6', 'M22 19l-3 3l-3 -3'
        ]));

        // Repeat
        if (!isYTMusic) {
            btnsDiv.appendChild(makeToolBtn('Repeat video', 'repeatvideo', '', [
                'M0 0h24v24H0z',
                'M4 12v-3a3 3 0 0 1 3 -3h13m-3 -3l3 3l-3 3',
                'M20 12v3a3 3 0 0 1 -3 3h-13m3 3l-3 -3l3 -3'
            ]));
        }

        // Download MP4
        btnsDiv.appendChild(makeToolBtn('MP4', null, 'btn1', [
            'M0 0h24v24H0z', 'M14 3v4a1 1 0 0 0 1 1h4',
            'M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z',
            'M12 17v-6', 'M9.5 14.5l2.5 2.5l2.5 -2.5'
        ]));

        // Download MP3
        btnsDiv.appendChild(makeToolBtn('MP3', null, 'btn2', [
            'M0 0h24v24H0z', 'M14 3v4a1 1 0 0 0 1 1h4',
            'M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z',
            'M11 16m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0', 'M12 16l0 -5l2 1'
        ]));

        // Close
        btnsDiv.appendChild(makeToolBtn('Close', null, 'btn3', [
            'M0 0h24v24H0z',
            'M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0',
            'M10 10l4 4m0 -4l-4 4'
        ]));

        if (!isYTMusic) {
            // Add Bookmark
            btnsDiv.appendChild(makeToolBtn('Add bookmark', 'yt-bookmark-add', '', [
                'M0 0h24v24H0z',
                'M7 4h10a2 2 0 0 1 2 2v14l-7 -4l-7 4v-14a2 2 0 0 1 2 -2z',
                'M12 7v6', 'M9 10h6'
            ]));

            // Show Bookmarks
            btnsDiv.appendChild(makeToolBtn('Show bookmarks', 'yt-bookmark-toggle', '', [
                'M0 0h24v24H0z',
                'M9 6h11', 'M9 12h11', 'M9 18h11', 'M5 6h.01', 'M5 12h.01', 'M5 18h.01'
            ]));

            // History (Continue Watching)
            btnsDiv.appendChild(makeToolBtn('History', 'yt-cw-history-toggle', '', [
                'M0 0h24v24H0z',
                'M12 8v4l3 3', 'M3 12a9 9 0 1 0 3 -6.7', 'M3 4v4h4'
            ]));
        }

        // Picture-in-Picture
        btnsDiv.appendChild(makeToolBtn('Picture to picture', null, 'video_picture_to_picture', [
            'M0 0h24v24H0z',
            'M11 19h-6a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v4',
            'M14 14m0 1a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v3a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z'
        ]));

        // Screenshot
        btnsDiv.appendChild(makeToolBtn('Screenshot video', null, 'screenshot_video', [
            'M0 0h24v24H0z', 'M15 8h.01',
            'M6 13l2.644 -2.644a1.21 1.21 0 0 1 1.712 0l3.644 3.644',
            'M13 13l1.644 -1.644a1.21 1.21 0 0 1 1.712 0l1.644 1.644',
            'M4 8v-2a2 2 0 0 1 2 -2h2', 'M4 16v2a2 2 0 0 0 2 2h2',
            'M16 4h2a2 2 0 0 1 2 2v2', 'M16 20h2a2 2 0 0 0 2 -2v-2'
        ]));

        form.appendChild(btnsDiv);

        if (!isYTMusic) {
            const bookmarksPanel = document.createElement('div');
            bookmarksPanel.id = 'yt-bookmarks-panel';
            bookmarksPanel.className = 'yt-bookmarks-panel';
            bookmarksPanel.style.display = 'none';
            form.appendChild(bookmarksPanel);

            const historyPanel = document.createElement('div');
            historyPanel.id = 'yt-continue-watching-panel';
            historyPanel.className = 'yt-continue-watching-panel';
            historyPanel.style.display = 'none';
            form.appendChild(historyPanel);
        }

        // Download video quality select
        const videoForm = document.createElement('form');
        videoForm.className = 'formulariodescarga ocultarframe';
        const videoSelectDiv = document.createElement('div');
        videoSelectDiv.className = 'containerall';
        const videoSelect = document.createElement('select');
        videoSelect.className = 'selectcalidades ocultarframe';
        videoSelect.required = true;
        [['', 'Video Quality', true],
        ['144', '144p MP4'], ['240', '240p MP4'], ['360', '360p MP4'],
        ['480', '480p MP4'], ['720', '720p HD MP4 Default'],
        ['1080', '1080p FULL HD MP4'], ['1440', '1440p 2K WEBM'], ['4k', '2160p 4K WEBM'], ['8k', '4320p 8K WEBM']
        ].forEach(([val, text, dis]) => {
            const opt = document.createElement('option');
            opt.value = val;
            opt.textContent = text;
            if (dis) { opt.selected = true; opt.disabled = true; }
            videoSelect.appendChild(opt);
        });
        videoSelectDiv.appendChild(videoSelect);

        // Download video container
        const dlVideoContainer = document.createElement('div');
        dlVideoContainer.id = 'descargando';
        dlVideoContainer.className = 'download-container ocultarframe';

        const dlInfo = document.createElement('div');
        dlInfo.className = 'download-info';
        const dlText = document.createElement('span');
        dlText.className = 'download-text';
        dlText.textContent = 'Download Video And Please Wait...';
        const dlQuality = document.createElement('span');
        dlQuality.className = 'download-quality';
        dlInfo.appendChild(dlText);
        dlInfo.appendChild(dlQuality);

        const dlActions = document.createElement('div');
        dlActions.className = 'download-actions';
        const dlBtn = document.createElement('button');
        dlBtn.className = 'download-btn video-btn';
        dlBtn.textContent = 'Download';
        const retryBtn = document.createElement('button');
        retryBtn.className = 'retry-btn';
        retryBtn.style.display = 'none';
        retryBtn.textContent = 'Retry';
        dlActions.appendChild(dlBtn);
        dlActions.appendChild(retryBtn);

        const progressC = document.createElement('div');
        progressC.className = 'progress-container';
        progressC.style.display = 'none';
        const progressBar = document.createElement('div');
        progressBar.className = 'progress-bar';
        const progressFill = document.createElement('div');
        progressFill.className = 'progress-fill';
        progressBar.appendChild(progressFill);
        const progressText = document.createElement('span');
        progressText.className = 'progress-text';
        progressText.textContent = '0%';
        progressC.appendChild(progressBar);
        progressC.appendChild(progressText);

        // progress-retry-btn and download-again-btn (required by startDownloadVideoOrAudio)
        const progRetryBtn = document.createElement('button');
        progRetryBtn.className = 'progress-retry-btn';
        progRetryBtn.title = 'Retry';
        progRetryBtn.style.display = 'none';
        progRetryBtn.textContent = '↻';
        const dlAgainBtn = document.createElement('button');
        dlAgainBtn.className = 'download-again-btn';
        dlAgainBtn.title = 'Download again';
        dlAgainBtn.style.display = 'none';
        dlAgainBtn.textContent = '⬇';

        dlVideoContainer.appendChild(progRetryBtn);
        dlVideoContainer.appendChild(dlAgainBtn);
        dlVideoContainer.appendChild(dlInfo);
        dlVideoContainer.appendChild(dlActions);
        dlVideoContainer.appendChild(progressC);
        videoSelectDiv.appendChild(dlVideoContainer);
        videoForm.appendChild(videoSelectDiv);

        // Download audio quality select
        const audioForm = document.createElement('form');
        audioForm.className = 'formulariodescargaaudio ocultarframe';
        const audioSelectDiv = document.createElement('div');
        audioSelectDiv.className = 'containerall';
        const audioSelect = document.createElement('select');
        audioSelect.className = 'selectcalidadesaudio ocultarframeaudio';
        audioSelect.required = true;
        [['', 'Audio Quality', true],
        ['flac', 'Audio FLAC UHQ'], ['wav', 'Audio WAV UHQ'],
        ['webm', 'Audio WEBM UHQ'], ['mp3', 'Audio MP3 Default'],
        ['m4a', 'Audio M4A'], ['aac', 'Audio AAC'],
        ['opus', 'Audio OPUS'], ['ogg', 'Audio OGG']
        ].forEach(([val, text, dis]) => {
            const opt = document.createElement('option');
            opt.value = val;
            opt.textContent = text;
            if (dis) { opt.selected = true; opt.disabled = true; }
            audioSelect.appendChild(opt);
        });
        audioSelectDiv.appendChild(audioSelect);

        // Download audio container
        const dlAudioContainer = document.createElement('div');
        dlAudioContainer.id = 'descargandomp3';
        dlAudioContainer.className = 'download-container ocultarframeaudio';

        const dlInfoA = document.createElement('div');
        dlInfoA.className = 'download-info';
        const dlTextA = document.createElement('span');
        dlTextA.className = 'download-text';
        dlTextA.textContent = 'Download Audio And Please Wait...';
        const dlQualityA = document.createElement('span');
        dlQualityA.className = 'download-quality';
        dlInfoA.appendChild(dlTextA);
        dlInfoA.appendChild(dlQualityA);

        const dlActionsA = document.createElement('div');
        dlActionsA.className = 'download-actions';
        const dlBtnA = document.createElement('button');
        dlBtnA.className = 'download-btn audio-btn';
        dlBtnA.textContent = 'Download';
        const retryBtnA = document.createElement('button');
        retryBtnA.className = 'retry-btn';
        retryBtnA.style.display = 'none';
        retryBtnA.textContent = 'Retry';
        dlActionsA.appendChild(dlBtnA);
        dlActionsA.appendChild(retryBtnA);

        const progressCA = document.createElement('div');
        progressCA.className = 'progress-container';
        progressCA.style.display = 'none';
        const progressBarA = document.createElement('div');
        progressBarA.className = 'progress-bar';
        const progressFillA = document.createElement('div');
        progressFillA.className = 'progress-fill';
        progressBarA.appendChild(progressFillA);
        const progressTextA = document.createElement('span');
        progressTextA.className = 'progress-text';
        progressTextA.textContent = '0%';
        progressCA.appendChild(progressBarA);
        progressCA.appendChild(progressTextA);

        // progress-retry-btn and download-again-btn for audio
        const progRetryBtnA = document.createElement('button');
        progRetryBtnA.className = 'progress-retry-btn';
        progRetryBtnA.title = 'Retry';
        progRetryBtnA.style.display = 'none';
        progRetryBtnA.textContent = '↻';
        const dlAgainBtnA = document.createElement('button');
        dlAgainBtnA.className = 'download-again-btn';
        dlAgainBtnA.title = 'Download again';
        dlAgainBtnA.style.display = 'none';
        dlAgainBtnA.textContent = '⬇';

        dlAudioContainer.appendChild(progRetryBtnA);
        dlAudioContainer.appendChild(dlAgainBtnA);
        dlAudioContainer.appendChild(dlInfoA);
        dlAudioContainer.appendChild(dlActionsA);
        dlAudioContainer.appendChild(progressCA);
        audioSelectDiv.appendChild(dlAudioContainer);
        audioForm.appendChild(audioSelectDiv);

        const collapsible = document.createElement('div');
        collapsible.className = 'content_collapsible_colors';
        collapsible.style.marginTop = '2px';
        collapsible.appendChild(videoForm);
        collapsible.appendChild(audioForm);

        container.appendChild(form);
        container.appendChild(collapsible);
        main.appendChild(container);

        return main;
    }


    function renderizarButtons() {
        if (isYTMusic) {
            // YouTube Music: inject ABOVE the tab header container (Tiếp theo/Lời nhạc/Liên quan)
            const sidePanel = document.querySelector('#player-page #side-panel');
            const tabHeaders = sidePanel && sidePanel.querySelector('.tab-header-container');
            const addButton = tabHeaders || document.querySelector('#tab-renderer');

            // YTM loads lazily - if element not found, retry
            if (!addButton && validoBotones) {
                if (!renderizarButtons._ytmRetries) renderizarButtons._ytmRetries = 0;
                if (renderizarButtons._ytmRetries < 30) {
                    renderizarButtons._ytmRetries++;
                    setTimeout(renderizarButtons, 500);
                }
                return;
            }
            renderizarButtons._ytmRetries = 0;

            if (addButton && validoBotones) {
                validoBotones = false;

                const sidePanel = document.querySelector('ytmusic-player-page #side-panel');
                if (sidePanel) {
                    // CREATE A COMMON WRAPPER FOR TOOLS AND TAB HEADERS (Top Box)
                    let sideWrapper = $id('ytm-side-panel-wrapper');
                    if (!sideWrapper) {
                        sideWrapper = document.createElement('div');
                        sideWrapper.id = 'ytm-side-panel-wrapper';
                        sidePanel.insertBefore(sideWrapper, addButton);
                    }

                    const toolbar = buildYTMToolbar();
                    sideWrapper.appendChild(toolbar);

                    // ADD A LINE SEPARATOR
                    const line = document.createElement('div');
                    line.className = 'ytm-side-panel-divider';
                    sideWrapper.appendChild(line);

                    // MOVE THE TAB HEADER INTO THE TOP BOX
                    sideWrapper.appendChild(addButton);
                }
            }
        } else {
            // Regular YouTube
            const addButton = document.querySelector('.style-scope .ytd-watch-metadata');
            const addButton2 = document.querySelector('#contents');

            if (addButton && validoBotones) {
                const isVisible = addButton.offsetParent !== null;

                if (isVisible || addButton2) {
                    validoBotones = false;
                    const toolbar = buildYTMToolbar();
                    // Insert before metadata to be above descriptions/comments
                    addButton.parentNode.insertBefore(toolbar, addButton);
                }
            }
        }

        const formulariodescarga = $e('.formulariodescarga');
        const formulariodescargaaudio = $e('.formulariodescargaaudio');
        const btn1mp4 = $e('.btn1');
        const btn2mp3 = $e('.btn2');
        const btn3cancel = $e('.btn3');
        const selectcalidades = $e('.selectcalidades');
        const selectcalidadesaudio = $e('.selectcalidadesaudio');

        [formulariodescarga, formulariodescargaaudio].forEach(form => {
            if (!form) return;
            if (form.dataset.ytToolsPreventDefault === '1') return;
            form.addEventListener('click', e => e.preventDefault());
            form.dataset.ytToolsPreventDefault = '1';
        });

        if (selectcalidades && selectcalidades.dataset.ytToolsBound !== '1') {
            selectcalidades.dataset.ytToolsBound = '1';
            selectcalidades.addEventListener('change', e => {
                const quality = e.target.value;
                if (!quality) return; // Don't proceed if no quality selected

                const downloadContainer = $id('descargando');
                const downloadText = downloadContainer.querySelector('.download-text');
                const downloadQuality = downloadContainer.querySelector('.download-quality');
                const downloadBtn = downloadContainer.querySelector('.download-btn');
                const retryBtn = downloadContainer.querySelector('.retry-btn');
                const progressContainer = downloadContainer.querySelector('.progress-container');

                // Update UI
                downloadContainer.classList.add('video');
                downloadContainer.classList.remove('ocultarframe');
                downloadText.textContent = `Download ${quality.toUpperCase()} And Please Wait...`;
                downloadQuality.textContent = `${quality}p`;

                // Show download button, hide progress
                downloadBtn.style.display = 'block';
                retryBtn.style.display = 'none';
                progressContainer.style.display = 'none';

                // Store quality for later use
                downloadContainer.dataset.quality = quality;
                downloadContainer.dataset.type = 'video';
            });
        }

        if (selectcalidadesaudio && selectcalidadesaudio.dataset.ytToolsBound !== '1') {
            selectcalidadesaudio.dataset.ytToolsBound = '1';
            selectcalidadesaudio.addEventListener('change', e => {
                const format = e.target.value;
                if (!format) return; // Don't proceed if no format selected

                const downloadContainer = $id('descargandomp3');
                const downloadText = downloadContainer.querySelector('.download-text');
                const downloadQuality = downloadContainer.querySelector('.download-quality');
                const downloadBtn = downloadContainer.querySelector('.download-btn');
                const retryBtn = downloadContainer.querySelector('.retry-btn');
                const progressContainer = downloadContainer.querySelector('.progress-container');

                // Update UI
                downloadContainer.classList.add('audio');
                downloadContainer.classList.remove('ocultarframeaudio');
                downloadText.textContent = `Download ${format.toUpperCase()} And Please Wait...`;
                downloadQuality.textContent = format.toUpperCase();

                // Show download button, hide progress
                downloadBtn.style.display = 'block';
                retryBtn.style.display = 'none';
                progressContainer.style.display = 'none';

                // Store format for later use
                downloadContainer.dataset.quality = format;
                downloadContainer.dataset.type = 'audio';
            });
        }

        if (btn3cancel && btn3cancel.dataset.ytToolsBound !== '1') {
            btn3cancel.dataset.ytToolsBound = '1';
            btn3cancel.addEventListener('click', () => {
                // Hide all selects
                selectcalidades?.classList.add('ocultarframe');
                selectcalidadesaudio?.classList.add('ocultarframeaudio');

                // Hide all download containers
                const videoContainer = $id('descargando');
                const audioContainer = $id('descargandomp3');

                if (videoContainer) {
                    videoContainer.classList.add('ocultarframe');
                    videoContainer.classList.remove('video', 'audio', 'completed');
                    videoContainer.removeAttribute('data-quality');
                    videoContainer.removeAttribute('data-type');
                    videoContainer.removeAttribute('data-downloading');
                    videoContainer.removeAttribute('data-url-opened');
                    videoContainer.removeAttribute('data-last-download-url');
                    videoContainer.querySelector?.('.download-again-btn')?.style && (videoContainer.querySelector('.download-again-btn').style.display = 'none');
                }

                if (audioContainer) {
                    audioContainer.classList.add('ocultarframeaudio');
                    audioContainer.classList.remove('video', 'audio', 'completed');
                    audioContainer.removeAttribute('data-quality');
                    audioContainer.removeAttribute('data-type');
                    audioContainer.removeAttribute('data-downloading');
                    audioContainer.removeAttribute('data-url-opened');
                    audioContainer.removeAttribute('data-last-download-url');
                    audioContainer.querySelector?.('.download-again-btn')?.style && (audioContainer.querySelector('.download-again-btn').style.display = 'none');
                }

                // Hide all forms
                if (formulariodescarga) formulariodescarga.style.setProperty('display', 'none', 'important');
                if (formulariodescargaaudio) formulariodescargaaudio.style.setProperty('display', 'none', 'important');

                // Reset forms
                formulariodescarga?.reset();
                formulariodescargaaudio?.reset();
            });
        }

        // Add event listeners for download buttons (only once)
        if (!__ytToolsRuntime.downloadClickHandlerInitialized) {
            __ytToolsRuntime.downloadClickHandlerInitialized = true;
            document.addEventListener('click', (e) => {
                const target = e.target;
                if (!(target instanceof Element)) return;

                const clicked =
                    target.closest('.download-btn') ||
                    target.closest('.retry-btn') ||
                    target.closest('.progress-retry-btn') ||
                    target.closest('.download-again-btn');
                if (!clicked) return;

                const container = clicked.closest('.download-container');
                if (!container) return;

                const quality = container.dataset.quality;
                const type = container.dataset.type;
                // download-again just re-opens the last URL (no restart)
                if (clicked.classList.contains('download-again-btn')) {
                    const url = container.dataset.lastDownloadUrl;
                    if (url) window.open(url);
                    return;
                }
                if (!quality || !type) return;

                if (clicked.classList.contains('progress-retry-btn')) {
                    container.dataset.downloading = 'false';
                    container.dataset.urlOpened = 'false';
                    container.dataset.lastDownloadUrl = '';
                    container.querySelector?.('.download-again-btn')?.style && (container.querySelector('.download-again-btn').style.display = 'none');
                }
                startDownloadVideoOrAudio(quality, container);
            });
        }



        if (btn1mp4 && btn1mp4.dataset.ytToolsBound !== '1') {
            btn1mp4.dataset.ytToolsBound = '1';
            btn1mp4.addEventListener('click', () => {
                // Show video select, hide audio select
                selectcalidades?.classList.remove('ocultarframe');
                selectcalidadesaudio?.classList.add('ocultarframeaudio');

                // Hide all download containers
                const videoContainer = $id('descargando');
                const audioContainer = $id('descargandomp3');

                if (videoContainer) {
                    videoContainer.classList.add('ocultarframe');
                    videoContainer.classList.remove('video', 'audio', 'completed');
                    videoContainer.removeAttribute('data-quality');
                    videoContainer.removeAttribute('data-type');
                    videoContainer.removeAttribute('data-downloading');
                    videoContainer.removeAttribute('data-url-opened');
                }

                if (audioContainer) {
                    audioContainer.classList.add('ocultarframeaudio');
                    audioContainer.classList.remove('video', 'audio', 'completed');
                    audioContainer.removeAttribute('data-quality');
                    audioContainer.removeAttribute('data-type');
                    audioContainer.removeAttribute('data-downloading');
                    audioContainer.removeAttribute('data-url-opened');
                }

                // Show video form, hide audio form
                if (formulariodescarga) formulariodescarga.style.setProperty('display', 'flex', 'important');
                if (formulariodescargaaudio) formulariodescargaaudio.style.setProperty('display', 'none', 'important');

                // Reset forms
                formulariodescarga?.reset();
                formulariodescargaaudio?.reset();

                // On YTM: auto-select 720p and show download button immediately
                if (isYTMusic && selectcalidades) {
                    selectcalidades.value = '720';
                    selectcalidades.dispatchEvent(new Event('change', { bubbles: true }));
                }
            });
        }

        if (btn2mp3 && btn2mp3.dataset.ytToolsBound !== '1') {
            btn2mp3.dataset.ytToolsBound = '1';
            btn2mp3.addEventListener('click', () => {
                // Show audio select, hide video select
                selectcalidadesaudio?.classList.remove('ocultarframeaudio');
                selectcalidades?.classList.add('ocultarframe');

                // Hide all download containers
                const videoContainer = $id('descargando');
                const audioContainer = $id('descargandomp3');

                if (videoContainer) {
                    videoContainer.classList.add('ocultarframe');
                    videoContainer.classList.remove('video', 'audio', 'completed');
                    videoContainer.removeAttribute('data-quality');
                    videoContainer.removeAttribute('data-type');
                    videoContainer.removeAttribute('data-downloading');
                    videoContainer.removeAttribute('data-url-opened');
                }

                if (audioContainer) {
                    audioContainer.classList.add('ocultarframeaudio');
                    audioContainer.classList.remove('video', 'audio', 'completed');
                    audioContainer.removeAttribute('data-quality');
                    audioContainer.removeAttribute('data-type');
                    audioContainer.removeAttribute('data-downloading');
                    audioContainer.removeAttribute('data-url-opened');
                }

                // Show audio form, hide video form
                if (formulariodescargaaudio) formulariodescargaaudio.style.setProperty('display', 'flex', 'important');
                if (formulariodescarga) formulariodescarga.style.setProperty('display', 'none', 'important');

                // Reset forms
                formulariodescargaaudio?.reset();
                formulariodescarga?.reset();

                // On YTM: auto-select MP3 and show download button immediately
                if (isYTMusic && selectcalidadesaudio) {
                    selectcalidadesaudio.value = 'mp3';
                    selectcalidadesaudio.dispatchEvent(new Event('change', { bubbles: true }));
                }
            });
        }
        // Invertir contenido



        const btnImagen = $e('#imagen');

        // valido modo oscuro y venta de video
        // Repeat video button
        let countRepeat = 0; // count
        const repeat = $e('#repeatvideo'); // Repeat button
        const videoFull = isYTMusic
            ? $e('video')
            : $e('#movie_player > div.html5-video-container > video');
        if (repeat != undefined) {

            repeat.onclick = () => {
                if (
                    (isYTMusic ? videoFull : $e('#cinematics > div')) != undefined ||
                    videoFull != undefined
                ) {
                    countRepeat += 1;
                    switch (countRepeat) {
                        case 1:
                            const videoEl = isYTMusic ? $e('video') : document
                                .querySelector('#movie_player > div.html5-video-container > video');
                            videoEl?.setAttribute('loop', 'true');
                            if (isYTMusic) {
                                // On YTM, replace SVG icon using DOM API
                                const newSvg = createSvgIcon([
                                    'M0 0h24v24H0z',
                                    'M4 12v-3c0 -1.336 .873 -2.468 2.08 -2.856m3.92 -.144h10m-3 -3l3 3l-3 3',
                                    'M20 12v3a3 3 0 0 1 -.133 .886m-1.99 1.984a3 3 0 0 1 -.877 .13h-13m3 3l-3 -3l3 -3',
                                    'M3 3l18 18'
                                ]);
                                repeat.replaceChildren(newSvg);
                            } else {
                                const imarepeat = $e('.icon-tabler-repeat');
                                if (imarepeat) imarepeat.innerHTML = safeHTML(`  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-repeat-off" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
                    <path d="M4 12v-3c0 -1.336 .873 -2.468 2.08 -2.856m3.92 -.144h10m-3 -3l3 3l-3 3"></path>
                    <path d="M20 12v3a3 3 0 0 1 -.133 .886m-1.99 1.984a3 3 0 0 1 -.877 .13h-13m3 3l-3 -3l3 -3"></path>
                    <path d="M3 3l18 18"></path>
                 </svg> `);
                            }
                            break;
                        case 2:
                            countRepeat = 0;
                            const videoEl2 = isYTMusic ? $e('video') : document
                                .querySelector('#movie_player > div.html5-video-container > video');
                            videoEl2?.removeAttribute('loop');
                            if (isYTMusic) {
                                const newSvg2 = createSvgIcon([
                                    'M0 0h24v24H0z',
                                    'M4 12v-3a3 3 0 0 1 3 -3h13m-3 -3l3 3l-3 3',
                                    'M20 12v3a3 3 0 0 1 -3 3h-13m3 3l-3 -3l3 -3'
                                ]);
                                repeat.replaceChildren(newSvg2);
                            } else {
                                const imarepeat2 = $e('.icon-tabler-repeat');
                                if (imarepeat2) imarepeat2.innerHTML = safeHTML(` <svg  xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-repeat" width="24"
                    height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
                    stroke-linecap="round" stroke-linejoin="round">
                    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
                    <path d="M4 12v-3a3 3 0 0 1 3 -3h13m-3 -3l3 3l-3 3"></path>
                    <path d="M20 12v3a3 3 0 0 1 -3 3h-13m3 3l-3 -3l3 -3"></path>
                  </svg>`);
                            }
                            break;
                    }
                }
            }
        }

        // Background transparent

        const cinematica = $e('#cinematics > div');
        if (cinematica != undefined) {
            cinematica.style.cssText =
                'position: fixed; inset: 0px; pointer-events: none; transform: scale(1.5, 2)';
        }

        if (btnImagen != undefined) {
            btnImagen.onclick = () => {
                if (
                    $e('#cinematics > div') != undefined ||
                    videoFull != undefined
                ) {
                    const parametrosURL = new URLSearchParams(window.location.search);
                    let enlace = parametrosURL.get('v');

                    const imageUrl = `https://i.ytimg.com/vi/${enlace}/maxresdefault.jpg`;

                    fetch(imageUrl)
                        .then((response) => {
                            if (!response.ok) {
                                throw new Error(`HTTP error! Status: ${response.status}`);
                            }
                            return response.blob();
                        })
                        .then((blob) => {
                            const imageSizeKB = blob.size / 1024;

                            if (imageSizeKB >= 20) {
                                window.open(
                                    `https://i.ytimg.com/vi/${enlace}/maxresdefault.jpg`,
                                    'popUpWindow',
                                    'height=500,width=400,left=100,top=100,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no, status=yes'
                                );
                                const imageUrlObject = URL.createObjectURL(blob);

                                const enlaceDescarga = $cl('a');
                                enlaceDescarga.href = imageUrlObject;
                                const titleVideo = isYTMusic
                                    ? ($e('ytmusic-player-bar .title')?.textContent?.trim() || 'YouTube Music')
                                    : ($e('h1.style-scope.ytd-watch-metadata')?.innerText || 'video');
                                enlaceDescarga.download = `${titleVideo}_maxresdefault.jpg`;
                                enlaceDescarga.click();

                                URL.revokeObjectURL(imageUrlObject);
                            } else {
                                console.log(
                                    'La imagen no excede los 20 KB. No se descargará.'
                                );
                            }
                        })
                        .catch((error) => {
                            alert('No found image');
                            console.error('Error al obtener la imagen:', error);
                        });
                }
            };
        }
        // [REMOVED] Duplicate background image handler — handled at end of script (line ~6648+).

        const viewPictureToPicture = $e(
            '.video_picture_to_picture'
        );
        if (viewPictureToPicture != undefined) {
            viewPictureToPicture.onclick = () => {
                const video = $e('video');
                if ('pictureInPictureEnabled' in document) {
                    if (!document.pictureInPictureElement) {

                        video
                            .requestPictureInPicture()
                            .then(() => { })
                            .catch((error) => {
                                console.error(
                                    'Error al activar el modo Picture-in-Picture:',
                                    error
                                );
                            });
                    } else {
                        // video picture
                    }
                } else {
                    alert('Picture-in-Picture not supported');
                }
            };
        }
        const screenShotVideo = $e('.screenshot_video');
        if (screenShotVideo != undefined) {
            screenShotVideo.onclick = () => {
                const video = $e('video');
                const canvas = $cl('canvas');
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;
                const context = canvas.getContext('2d');
                context.drawImage(video, 0, 0, canvas.width, canvas.height);
                const imagenURL = canvas.toDataURL('image/png');
                const enlaceDescarga = $cl('a');
                enlaceDescarga.href = imagenURL;
                const titleVideo = isYTMusic
                    ? ($e('ytmusic-player-bar .title')?.textContent?.trim() || 'YouTube Music')
                    : ($e('h1.style-scope.ytd-watch-metadata')?.innerText || 'video');
                enlaceDescarga.download = `${video.currentTime.toFixed(
                    0
                )}s_${titleVideo}.png`;
                enlaceDescarga.click();
            };
        } else {
            const containerButtons = $e('.containerButtons');

            if (containerButtons != undefined) {
                containerButtons.innerHTML = safeHTML('');
            }
        }
        // [REMOVED] clearInterval(renderizarButtons) — was passing a function, not an interval ID.
    }




    function hideCanvas() {

        const canvas = $id('wave-visualizer-canvas');
        if (canvas) {
            canvas.style.opacity = '0';
            if (controlPanel) {
                controlPanel.style.opacity = '0';
            }
        }
    }

    function showCanvas() {
        const canvas = $id('wave-visualizer-canvas');
        if (audioCtx && audioCtx.state === 'suspended') {
            audioCtx.resume();
        }
        if (canvas) {
            canvas.style.opacity = '1';
            if (controlPanel) controlPanel.style.opacity = '1';
        }
    }



    async function startDownloadVideoOrAudio(format, container) {
        const videoURL = window.location.href;
        // Notify('info', 'Starting download...');

        // Check if already downloading
        if (container.dataset.downloading === 'true') {
            return;
        }

        // Stop any previous poller (avoid leaks on retry)
        try {
            if (container.__ytDownloadPoll) {
                clearInterval(container.__ytDownloadPoll);
                container.__ytDownloadPoll = null;
            }
        } catch (e) { }

        // Get UI elements from the container
        const downloadBtn = container.querySelector('.download-btn');
        const retryBtn = container.querySelector('.retry-btn');
        const progressRetryBtn = container.querySelector('.progress-retry-btn');
        const downloadAgainBtn = container.querySelector('.download-again-btn');
        const progressContainer = container.querySelector('.progress-container');
        const progressFill = container.querySelector('.progress-fill');
        const progressText = container.querySelector('.progress-text');
        const downloadText = container.querySelector('.download-text');

        // Set downloading flag
        container.dataset.downloading = 'true';
        container.dataset.urlOpened = 'false';
        container.dataset.lastDownloadUrl = '';

        // Update UI to show progress
        downloadBtn.style.display = 'none';
        retryBtn.style.display = 'none';
        progressRetryBtn.style.display = 'block';
        if (downloadAgainBtn) downloadAgainBtn.style.display = 'none';
        progressContainer.style.display = 'flex';
        progressFill.style.width = '0%';
        progressText.textContent = '0%';

        const fetchJsonWithTimeout = async (url, timeoutMs = 20000) => {
            const ctrl = new AbortController();
            const t = setTimeout(() => ctrl.abort(), timeoutMs);
            try {
                const res = await fetch(url, {
                    signal: ctrl.signal
                });
                if (!res.ok) throw new Error(`HTTP ${res.status}`);
                return await res.json();
            } finally {
                clearTimeout(t);
            }
        };

        const setErrorState = () => {
            retryBtn.style.display = 'block';
            progressContainer.style.display = 'none';
            progressRetryBtn.style.display = 'none';
            if (downloadAgainBtn) downloadAgainBtn.style.display = 'none';
            container.dataset.downloading = 'false';
            container.dataset.urlOpened = 'false';
            container.dataset.lastDownloadUrl = '';
        };

        const markCompleteAndOpen = (downloadUrl) => {
            if (!downloadUrl) {
                setErrorState();
                return;
            }
            // Save for the \"download again\" button
            container.dataset.lastDownloadUrl = String(downloadUrl);
            // Check if URL was already opened
            if (container.dataset.urlOpened === 'true') return;
            // Mark URL as opened
            container.dataset.urlOpened = 'true';
            // Update UI to show completion
            container.classList.add('completed');
            container.classList.remove('video', 'audio');
            downloadText.textContent = 'Download Complete!';
            progressFill.style.width = '100%';
            progressText.textContent = '100%';
            progressRetryBtn.style.display = 'none';
            if (downloadAgainBtn) downloadAgainBtn.style.display = 'flex';
            container.dataset.downloading = 'false';
            try {
                window.open(downloadUrl);
            } catch (e) {
                console.warn('Could not open download URL:', e);
            }
        };

        const pollProgressUrl = (progressURL) => {
            container.__ytDownloadPoll = setInterval(async () => {
                try {
                    const progressData = await fetchJsonWithTimeout(progressURL, 15000);

                    const progress = Math.min((Number(progressData.progress) || 0) / 10, 100);
                    progressFill.style.width = `${progress}%`;
                    progressText.textContent = `${Math.round(progress)}%`;

                    if (Number(progressData.progress) >= 1000 && progressData.download_url) {
                        clearInterval(container.__ytDownloadPoll);
                        container.__ytDownloadPoll = null;
                        markCompleteAndOpen(progressData.download_url);
                    }
                } catch (e) {
                    console.error('Error in progress:', e);
                    clearInterval(container.__ytDownloadPoll);
                    container.__ytDownloadPoll = null;
                    setErrorState();
                }
            }, 3000);
        };

        const trySaveNowProvider = async (baseUrl) => {
            const url = new URL('/ajax/download.php', baseUrl);
            url.searchParams.set('copyright', '0');
            url.searchParams.set('allow_extended_duration', '1');
            url.searchParams.set('format', String(format));
            url.searchParams.set('url', videoURL);
            url.searchParams.set('api', API_KEY_DEVELOPERMDCM);
            const data = await fetchJsonWithTimeout(url.toString(), 25000);
            if (!data?.success || !data?.progress_url) {
                throw new Error('SaveNow provider did not return success/progress_url');
            }
            return data;
        };

        const tryDubsProvider = async () => {
            const videoId = paramsVideoURL();
            if (!videoId) throw new Error('Missing videoId');

            const startUrl = new URL(DUBS_START_ENDPOINT);
            startUrl.searchParams.set('id', videoId);
            startUrl.searchParams.set('format', String(format));

            const startData = await fetchJsonWithTimeout(startUrl.toString(), 25000);
            if (!startData?.success || !startData?.progressId) {
                throw new Error('Dubs provider did not return success/progressId');
            }

            const statusUrl = new URL(DUBS_STATUS_ENDPOINT);
            statusUrl.searchParams.set('id', startData.progressId);

            container.__ytDownloadPoll = setInterval(async () => {
                try {
                    const st = await fetchJsonWithTimeout(statusUrl.toString(), 20000);
                    const rawProgress = Number(st?.progress) || 0; // 0..1000
                    const progress = Math.min(rawProgress / 10, 100);
                    progressFill.style.width = `${progress}%`;
                    progressText.textContent = `${Math.round(progress)}%`;

                    if (st?.finished && st?.downloadUrl) {
                        clearInterval(container.__ytDownloadPoll);
                        container.__ytDownloadPoll = null;
                        markCompleteAndOpen(st.downloadUrl);
                    }
                } catch (e) {
                    console.error('❌ Error polling dubs status:', e);
                    clearInterval(container.__ytDownloadPoll);
                    container.__ytDownloadPoll = null;
                    setErrorState();
                }
            }, 3000);
        };

        try {
            let started = null;
            let lastErr = null;

            for (const base of DOWNLOAD_API_FALLBACK_BASES) {
                try {
                    started = await trySaveNowProvider(base);
                    break;
                } catch (e) {
                    lastErr = e;
                }
            }

            if (started?.success && started?.progress_url) {
                pollProgressUrl(started.progress_url);
                return;
            }

            console.warn('SaveNow providers failed, falling back to dubs.io', lastErr);
            await tryDubsProvider();
        } catch (error) {
            setErrorState();
            console.error('❌ Error starting download:', error);
        }
    }






    // Define themes
    const themes = [{
        name: 'Default / Reload',
        gradient: '',
        textColor: '',
        raised: '',
        btnTranslate: '',
        CurrentProgressVideo: '',
        videoDuration: '',
        colorIcons: '',
        textLogo: '',
        primaryColor: '',
        secondaryColor: '',
    }, {
        name: 'Midnight Blue',
        gradient: 'linear-gradient(135deg, #1e3a8a, #3b82f6)',
        textColor: '#ffffff',
        raised: '#1e3a8a',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Forest Green',
        gradient: 'linear-gradient(135deg, #14532d, #22c55e)',
        textColor: '#ffffff',
        raised: '#14532d',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Sunset Orange',
        gradient: 'linear-gradient(135deg, #7c2d12, #f97316)',
        textColor: '#ffffff',
        raised: '#7c2d12',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Royal Purple',
        gradient: 'linear-gradient(135deg, #2e1065, #4c1d95)',
        textColor: '#ffffff',
        raised: '#4c1d95',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Cherry Blossom',
        gradient: 'linear-gradient(135deg, #a9005c, #fc008f)',
        textColor: '#ffffff',
        raised: '#fc008f',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Red Dark',
        gradient: 'linear-gradient(135deg, #790909, #f70131)',
        textColor: '#ffffff',
        raised: '#790909',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Raind ',
        gradient: 'linear-gradient(90deg, #3f5efb 0%, #fc466b 100%)',
        textColor: '#ffffff',
        raised: '#3f5efb',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Neon',
        gradient: 'linear-gradient(273deg, #ee49fd 0%, #6175ff 100%)',
        textColor: '#ffffff',
        raised: '#ee49fd',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Azure',
        gradient: 'linear-gradient(273deg, #0172af 0%, #74febd 100%)',
        textColor: '#ffffff',
        raised: '#0172af',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Butterfly',
        gradient: 'linear-gradient(273deg, #ff4060 0%, #fff16a 100%)',
        textColor: '#ffffff',
        raised: '#ff4060',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    }, {
        name: 'Colombia',
        gradient: 'linear-gradient(174deg, #fbf63f  0%, #0000bb 45%, #ff0000 99%)',
        textColor: '#ffffff',
        raised: '#0000bb',
        btnTranslate: '#000',
        CurrentProgressVideo: '#0f0',
        videoDuration: '#fff',
        colorIcons: '#fff',
        textLogo: '#f00',
    },];

    // Create our enhancement panel
    const panel = $cl('div');

    panel.id = 'yt-enhancement-panel';

    const panelOverlay = $cl('div');
    panelOverlay.id = 'panel-overlay';
    $ap(panelOverlay);

    // Generate theme options HTML
    const themeOptionsHTML = themes
        .map(
            (theme, index) => `
        <label >
          <div class="theme-option">
          <div class="theme-preview" style="background: ${theme.gradient};"></div>
          <input type="radio" name="theme" value="${index}" ${index === 0 ? 'checked' : ''
                }>
              <span style="${theme.name === 'Default / Reload Page' ? 'color: red; ' : ''}" class="theme-name">${theme.name}</span>
              </div>
        </label>
    `
        )
        .join('');

    const languageOptionsHTML = Object.entries(languagesTranslate)
        .map(([code, name]) => {
            const selected = code === 'en' ? 'selected' : '';
            return `<option value="${code}" ${selected}>${name}</option>`;
        })
        .join('');



    function checkDarkModeActive() {
        // YTM is always dark mode
        if (isYTMusic) return 'dark';

        const prefCookie = document.cookie.split('; ').find(c => c.startsWith('PREF='));
        if (!prefCookie) return 'light';

        const prefValue = prefCookie.substring(5);
        const params = new URLSearchParams(prefValue);

        const f6Value = params.get('f6');
        const darkModes = ['400', '4000000', '40000400', '40000000'];

        return darkModes.includes(f6Value) ? 'dark' : 'light';
    }


    let isDarkModeActive = checkDarkModeActive();


    // Use Trusted Types to set innerHTML
    const menuHTML = `
   <div class="container-mdcm">
    <div class="header-mdcm">
      <h1> <i class="fa-brands fa-youtube"></i> YouTube Tools</h1>
      <div class="icons-mdcm">
        <a href="https://update.greasyfork.org/scripts/576162/YouTube%20Ultimate%20Tools.user.js"
          target="_blank">
          <button class="icon-btn-mdcm">
            <i class="fa-solid fa-arrows-rotate"></i>
          </button>
        </a>
        <a href="https://github.com/akari310" target="_blank">
          <button class="icon-btn-mdcm">
            <i class="fa-brands fa-github"></i>
          </button>
        </a>
        <button class="icon-btn-mdcm" id="shareBtn-mdcm">
          <i class="fa-solid fa-share-alt"></i>
        </button>
        <button class="icon-btn-mdcm" id="importExportBtn">
          <i class="fa-solid fa-file-import"></i>
        </button>
        <button id="menu-settings-icon" class="icon-btn-mdcm tab-mdcm" data-tab="menu-settings">
          <i class="fa-solid fa-gear"></i>
        </button>
        <button class="icon-btn-mdcm close_menu_settings">
          <i class="fa-solid fa-xmark"></i>
        </button>
      </div>
    </div>

    <div class="tabs-mdcm">
      <button class="tab-mdcm active" data-tab="general">
        <i class="fa-solid fa-shield-halved"></i>
        General
      </button>
      <button class="tab-mdcm" data-tab="themes">
        <i class="fa-solid fa-palette"></i>
        Themes
      </button>
      <button class="tab-mdcm" data-tab="stats">
        <i class="fa-solid fa-square-poll-vertical"></i>
        Stats
      </button>
      <button class="tab-mdcm" data-tab="headers">
        <i class="fa-regular fa-newspaper"></i>
        Header
      </button>
    </div>


    <div id="general" class="tab-content active">

      <div class="options-mdcm">
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="hide-comments-toggle"> Hide Comments
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="hide-sidebar-toggle"> Hide Sidebar
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="autoplay-toggle"> Disable Autoplay
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="subtitles-toggle"> Disable Subtitles
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" checked id="dislikes-toggle"> Show Dislikes
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="like-dislike-bar-toggle"> Like vs Dislike bar
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="bookmarks-toggle"> Bookmarks (timestamps)
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="continue-watching-toggle"> Continue watching
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="shorts-channel-name-toggle"> Shorts: show channel name
          </div>
        </label>
        <label>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" checked id="nonstop-playback-toggle"> Nonstop playback
          </div>
        </label>
        <label>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="audio-only-toggle"> Audio-only mode
          </div>
        </label>
        <label>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="audio-only-tab-toggle"> Audio-only this tab
          </div>
        </label>
        <label>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="themes-toggle"> Active Themes
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="translation-toggle"> Translate comments
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="avatars-toggle"> Download avatars
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="reverse-mode-toggle"> Reverse mode
          </div>
        </label>
        <label>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="cinematic-lighting-toggle"> ${isYTMusic ? 'Ambient Mode' : 'Cinematic Mode'}
          </div>
        </label>
        <label>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" checked id="wave-visualizer-toggle"> Wave visualizer Beta
          </div>
        </label>
        <label ${!isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="custom-timeline-color-toggle"> Royal Purple Timeline
          </div>
        </label>
        <label ${isYTMusic ? 'style="display:none"' : ''}>
          <div class="option-mdcm">
            <input type="checkbox" class="checkbox-mdcm" id="sync-cinematic-toggle"> Sync Ambient Mode YT
          </div>
        </label>
        <div class="quality-selector-mdcm" style="grid-column: span 2;">
          <div class="select-wrapper-mdcm">
            <label>Side/Playlist Panel Style:
              <select class="tab-button-active" id="side-panel-style-select">
                <option value="blur">Blur</option>
                <option value="liquid">Liquid Glass</option>
                <option value="transparent">Transparent</option>
              </select>
            </label>
          </div>
        </div>
        <div class="quality-selector-mdcm" style="grid-column: span 2;">
          <div class="select-wrapper-mdcm">
            <label>Effect wave visualizer:
              <select class="tab-button-active" id="select-wave-visualizer-select">
                <option value="linea">Line smooth</option>
                <option value="barras">Vertical bars</option>
                <option value="curva">Curved</option>
                <option value="picos">Smooth peaks</option>
                <option value="solida">Solid wave</option>
                <option value="dinamica">Dynamic wave</option>
                <option value="montana">Smooth mountain</option>
              </select>
            </label>
          </div>
        </div>
        <div class="quality-selector-mdcm" style="grid-column: span 2;${isYTMusic ? ' display:none;' : ''}">
          <div class="select-wrapper-mdcm">
            <label>Default video player quality:
              <select class="tab-button-active" id="select-video-qualitys-select">
                <option value="user">User Default</option>
                <option value="">Auto</option>
                <option value="144">144</option>
                <option value="240">240</option>
                <option value="360">360</option>
                <option value="480">480</option>
                <option value="720">720</option>
                <option value="1080">1080</option>
                <option value="1440">1440</option>
                <option value="2160">2160</option>
                <option value="4320">4320</option>
              </select>
            </label>
          </div>
        </div>
        <div class="quality-selector-mdcm" style="grid-column: span 2;${isYTMusic ? ' display:none;' : ''}">
          <div class="select-wrapper-mdcm">
            <label>Language for translate comments:
              <select class="tab-button-active" id="select-languages-comments-select">
              ${languageOptionsHTML}
              </select>
            </label>
          </div>
        </div>
        <div class="slider-container-mdcm" style="grid-column: span 2;">
          <label>Video Player Size: <span id="player-size-value">100</span>%</label>
          <input type="range" id="player-size-slider" class="slider-mdcm" min="50" max="150" value="100">
          <button class="reset-btn-mdcm" id="reset-player-size">Reset video size</button>
        </div>
      </div>
    </div>

    <div id="themes" class="tab-content">
     <div id="background-image-container" class="background-image-container">
     <h4>Background Image</h4>
  <input type="file" id="background_image" accept="image/png, image/jpeg" style="display:none;" />
  <div id="background-image-preview" class="background-image-preview">
    <span class="background-image-overlay">
      <i class="fa fa-camera"></i>
      <span class="background-image-text">Select image</span>
    </span>
    <button id="remove-background-image" class="remove-background-image" title="Quitar fondo">&times;</button>
  </div>
</div>
      <div class="themes-hidden">
        <div class="options-mdcm" style="margin-bottom: 10px;">
          <div>
            <h4>Choose a Theme</h4>
            <p>Disable Mode Cinematic on General</p>
            ${isDarkModeActive === 'dark' ? '' : '<p style="color: red; margin: 10px 0;font-size: 11px;">Activate dark mode to use this option</p>'}
          </div>
        </div>
        <div class="options-mdcm">
          <label>
            <div class="theme-option option-mdcm">
              <input type="radio" class="radio-mdcm" name="theme" value="custom" checked>
              <span class="theme-name">Custom</span>
            </div>
          </label>
          <label>
            <div class="theme-option option-mdcm theme-selected-normal">
              <input type="radio" class="radio-mdcm" name="theme" value="normal">
              <span class="theme-name">Selected Themes</span>
            </div>
          </label>
        </div>
        <div class="themes-options">
          <div class="options-mdcm themes-grid-mdcm">
            ${themeOptionsHTML}
          </div>
        </div>
        <div class="theme-custom-options">
          <div class="options-mdcm">
            <div class="option-mdcm">
              <div class="card-items-end">
                <label>Progressbar Video:</label>
                <input type="color" id="progressbar-color-picker" class="color-picker-mdcm" value="#ff0000">
              </div>
            </div>
            <div class="option-mdcm">
              <div class="card-items-end">
                <label>Background Color:</label>
                <input type="color" id="bg-color-picker" class="color-picker-mdcm" value="#000000">
              </div>
            </div>
            <div class="option-mdcm">
              <div class="card-items-end">
                <label>Primary Color:</label>
                <input type="color" id="primary-color-picker" class="color-picker-mdcm" value="#ffffff">
              </div>
            </div>
            <div class="option-mdcm">
              <div class="card-items-end">
                <label>Secondary Color:</label>
                <input type="color" id="secondary-color-picker" class="color-picker-mdcm" value="#ffffff">
              </div>
            </div>
            <div class="option-mdcm">
              <div class="card-items-end">
                <label>Header Color:</label>
                <input type="color" id="header-color-picker" class="color-picker-mdcm" value="#000000">
              </div>
            </div>
            <div class="option-mdcm">
              <div class="card-items-end">
                <label>Icons Color:</label>
                <input type="color" id="icons-color-picker" class="color-picker-mdcm" value="#ffffff">
              </div>
            </div>
            <div class="option-mdcm">
              <div class="card-items-end">
                <label>Menu Color:</label>
                <input type="color" id="menu-color-picker" class="color-picker-mdcm" value="#000000">
              </div>
            </div>
            <div class="option-mdcm">
              <div class="card-items-end">
                <label>Line Color Preview:</label>
                <input type="color" id="line-color-picker" class="color-picker-mdcm" value="#ff0000">
              </div>
            </div>
            <div class="option-mdcm">
              <div class="card-items-end">
                <label>Time Color Preview:</label>
                <input type="color" id="time-color-picker" class="color-picker-mdcm" value="#ffffff">
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div id="stats" class="tab-content">
      <div id="yt-stats-toggle">
        <div class="stat-row">
          <div>Foreground Time</div>
          <div class="progress">
            <div class="progress-bar total-bar" id="usage-bar"></div>
          </div>
          <div id="total-time">0h 0m 0s</div>
        </div>
        <div class="stat-row">
          <div>Video Time</div>
          <div class="progress">
            <div class="progress-bar video-bar" id="video-bar"></div>
          </div>
          <div id="video-time">0h 0m 0s</div>
        </div>
        <div class="stat-row">
          <div>Shorts Time</div>
          <div class="progress">
            <div class="progress-bar shorts-bar" id="shorts-bar"></div>
          </div>
          <div id="shorts-time">0h 0m 0s</div>
        </div>
      </div>
    </div>

    <div id="headers" class="tab-content">
      <div class="options-mdcm">
        <label>Available in next update</label>
      </div>
    </div>


    <div id="menu-settings" class="tab-content">
      <div class="options-mdcm">
        <h4 style="margin: 10px 0">Menu Appearance</h4>
      </div>
      <div class="options-settings-mdcm">
        <div class="option-settings-mdcm">
          <label>Backgrounds:</label>
          <div class="color-boxes" id="bg-color-options">
            <div class="color-box" data-type="bg" data-value="#252525" style="background-color: #252525;"></div>
            <div class="color-box" data-type="bg" data-value="#1e1e1e" style="background-color: #1e1e1e;"></div>
            <div class="color-box" data-type="bg" data-value="#3a3a3a" style="background-color: #3a3a3a;"></div>
            <div class="color-box" data-type="bg" data-value="#4a4a4a" style="background-color: #4a4a4a;"></div>
            <div class="color-box" data-type="bg" data-value="#000000" style="background-color: #000000;"></div>
            <div class="color-box" data-type="bg" data-value="#00000000" style="background-color: #00000000;"></div>
            <div class="color-box" data-type="bg" data-value="#2d2d2d" style="background-color: #2d2d2d;"></div>
            <div class="color-box" data-type="bg" data-value="#444" style="background-color: #444;"></div>
          </div>
        </div>

        <div class="option-settings-mdcm">
          <label>Accent Colors:</label>
          <div class="color-boxes" id="bg-accent-color-options">
            <div class="color-box" data-type="accent" data-value="#ff0000" style="background-color: #ff0000;"></div>
            <div class="color-box" data-type="accent" data-value="#000000" style="background-color: #000000;"></div>
            <div class="color-box" data-type="accent" data-value="#009c37 " style="background-color: #009c37 ;"></div>
            <div class="color-box" data-type="accent" data-value="#0c02a0 " style="background-color: #0c02a0 ;"></div>
          </div>
        </div>

        <div class="option-settings-mdcm">
          <label>Titles Colors:</label>
          <div class="color-boxes" id="text-color-options">
            <div class="color-box" data-type="color" data-value="#ffffff" style="background-color: #ffffff;"></div>
            <div class="color-box" data-type="color" data-value="#cccccc" style="background-color: #cccccc;"></div>
            <div class="color-box" data-type="color" data-value="#b3b3b3" style="background-color: #b3b3b3;"></div>
            <div class="color-box" data-type="color" data-value="#00ffff" style="background-color: #00ffff;"></div>
            <div class="color-box" data-type="color" data-value="#00ff00" style="background-color: #00ff00;"></div>
            <div class="color-box" data-type="color" data-value="#ffff00" style="background-color: #ffff00;"></div>
            <div class="color-box" data-type="color" data-value="#ffcc00" style="background-color: #ffcc00;"></div>
            <div class="color-box" data-type="color" data-value="#ff66cc" style="background-color: #ff66cc;"></div>
          </div>
        </div>
      </div>
    </div>

    <div id="importExportArea">
      <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
        <h3>Import / Export Settings</h3>
        <button class="icon-btn-mdcm" id="closeImportExportBtn">
          <i class="fa-solid fa-xmark"></i>
        </button>
      </div>
      <textarea id="config-data" placeholder="Paste configuration here to import"></textarea>
      <div class="action-buttons-mdcm">
        <button id="export-config" class="action-btn-mdcm">Export</button>
        <button id="import-config" class="action-btn-mdcm">Import</button>
      </div>
    </div>

    <div id="shareDropdown">
      <a href="https://www.facebook.com/sharer/sharer.php?u=${urlSharedCode}" target="_blank" data-network="facebook"
        class="share-link"><i class="fa-brands fa-facebook"></i> Facebook</a><br>
      <a href="https://twitter.com/intent/tweet?url=${urlSharedCode}" target="_blank" data-network="twitter"
        class="share-link"><i class="fa-brands fa-twitter"></i> Twitter</a><br>
      <a href="https://api.whatsapp.com/send?text=${urlSharedCode}" target="_blank" data-network="whatsapp"
        class="share-link"><i class="fa-brands fa-whatsapp"></i> WhatsApp</a><br>
      <a href="https://www.linkedin.com/sharing/share-offsite/?url=${urlSharedCode}" target="_blank"
        data-network="linkedin" class="share-link"><i class="fa-brands fa-linkedin"></i> LinkedIn</a><br>
    </div>


  </div>
  <div class="actions-mdcm">
    <div class="developer-mdcm">
      <div style="font-size: 11px; opacity: 0.9; margin-top: 10px; border-top: 1px solid rgba(255,255,255,0.1); padding-top: 8px; line-height: 1.6;">
        Developed by <a href="https://github.com/akari310" target="_blank" style="color: #ff4444; text-decoration: none;"><i class="fa-brands fa-github"></i> Akari</a>.
        Base by <a href="https://github.com/DeveloperMDCM" target="_blank" style="color: #00aaff; text-decoration: none;"><i class="fa-brands fa-github"></i> MDCM</a>.
        Features from <a href="https://github.com/nvbangg" target="_blank" style="color: #00ffaa; text-decoration: none;"><i class="fa-brands fa-github"></i> nvbangg</a>.
      </div>
    </div>
    <span style="color: #fff" ;>v${GM_info.script.version}</span>
  </div>
  `;
    panel.innerHTML = safeHTML(menuHTML);

    $ap(panel);


    let headerObserver = null;
    function setupHeaderObserver() {
        if (headerObserver) return;
        const target = $e('#masthead-container') || $e('ytd-masthead') || document.body;
        headerObserver = new MutationObserver(() => {
            const icon = $id('icon-menu-settings');
            if (!icon || !document.body.contains(icon)) {
                addIcon();
            }
        });
        headerObserver.observe(target, { childList: true, subtree: true });
    }

    function addIcon() {
        const existing = $id('icon-menu-settings');
        if (existing && document.body.contains(existing)) return;
        if (existing) existing.closest('#toggle-button')?.remove();

        let anchor;
        if (isYTMusic) {
            anchor = $e('#right-content');
        } else {
            anchor = $e('ytd-topbar-menu-button-renderer') || $e('#buttons') || $e('#end');
        }
        if (!anchor) return;

        const toggleButton = $cl('div');
        toggleButton.id = 'toggle-button';
        toggleButton.style.display = 'flex';
        toggleButton.style.alignItems = 'center';
        toggleButton.style.justifyContent = 'center';
        toggleButton.style.cursor = 'pointer';
        toggleButton.style.marginRight = '8px';

        const icon = $cl('i');
        icon.id = 'icon-menu-settings';
        icon.classList.add('fa-solid', 'fa-gear');
        icon.style.fontSize = '20px';

        toggleButton.appendChild(icon);

        if (isYTMusic) {
            anchor.insertBefore(toggleButton, anchor.firstChild);
        } else {
            anchor.parentElement.insertBefore(toggleButton, anchor);
        }

        toggleButton.addEventListener('click', (e) => {
            e.stopPropagation();
            toggleMenu();
        });

        setupHeaderObserver();
    }

    let openMenu = false;
    function toggleMenu() {
        openMenu = !openMenu;
        panel.style.display = openMenu ? 'block' : 'none';
        panelOverlay.style.display = openMenu ? 'block' : 'none';
    }

    // Close panel when clicking the overlay
    panelOverlay.addEventListener('click', () => {
        if (openMenu) {
            toggleMenu();
        }
    });


    addIcon();
    const close_menu_settings = $e('.close_menu_settings');
    if (close_menu_settings) {
        close_menu_settings.addEventListener('click', () => {
            toggleMenu();
        });
    }

    // $ap(toggleButton);

    // Add change listener to the entire panel to save/apply settings immediately
    panel.addEventListener('change', (e) => {
        if (e.target.classList.contains('checkbox-mdcm') || e.target.tagName === 'SELECT' || e.target.tagName === 'INPUT') {
            saveSettings();
            if (typeof applySettings === 'function') {
                applySettings();
            }
        }
    });

    // Specific listeners for live updates of certain features
    $id('dislikes-toggle')?.addEventListener('change', () => {
        const st = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
        if (!st.dislikes) {
            // Hide dislikes if turned off
            const dislikes_content = $e('#top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div > div > dislike-button-view-model > toggle-button-view-model > button-view-model > button');
            if (dislikes_content) {
                // We don't have the original SVG easily, but we can at least hide our custom one or clear it
                // For now, let's just trigger a reload message or try to refresh the component
                // Actually, the user just wants it to go away.
                dislikes_content.style.width = '';
                // We'll let applySettings handle the bar, but for the button, we might need a refresh or more complex logic.
                // But let's try to at least call applySettings.
            }
        }
    });



    // Tab functionality
    const tabButtons = $m('.tab-mdcm');
    const tabContents = $m('.tab-content');

    tabButtons.forEach((button) => {
        button.addEventListener('click', () => {
            const tabName = button.getAttribute('data-tab');
            tabButtons.forEach((btn) => btn.classList.remove('active'));
            tabContents.forEach((content) => content.classList.remove('active'));
            button.classList.add('active');
            $id(tabName).classList.add('active');
        });
    });

    // Function to save settings
    function saveSettings() {
        const settings = {
            theme: $e('input[name="theme"]:checked').value,
            bgColorPicker: $id('bg-color-picker').value,
            progressbarColorPicker: $id('progressbar-color-picker').value,
            primaryColorPicker: $id('primary-color-picker').value,
            secondaryColorPicker: $id('secondary-color-picker').value,
            headerColorPicker: $id('header-color-picker').value,
            iconsColorPicker: $id('icons-color-picker').value,
            menuColorPicker: $id('menu-color-picker').value,
            lineColorPicker: $id('line-color-picker').value,
            timeColorPicker: $id('time-color-picker').value,
            dislikes: $id('dislikes-toggle').checked,
            likeDislikeBar: $id('like-dislike-bar-toggle').checked,
            bookmarks: $id('bookmarks-toggle').checked,
            continueWatching: $id('continue-watching-toggle').checked,
            shortsChannelName: $id('shorts-channel-name-toggle').checked,
            nonstopPlayback: $id('nonstop-playback-toggle') ? $id('nonstop-playback-toggle').checked : true,
            audioOnly: $id('audio-only-toggle') ? $id('audio-only-toggle').checked : false,
            themes: $id('themes-toggle').checked,
            translation: $id('translation-toggle').checked,
            avatars: $id('avatars-toggle').checked,
            reverseMode: $id('reverse-mode-toggle').checked,
            waveVisualizer: $id('wave-visualizer-toggle').checked,
            waveVisualizerSelected: $id('select-wave-visualizer-select').value,
            hideComments: $id('hide-comments-toggle').checked,
            hideSidebar: $id('hide-sidebar-toggle').checked,
            disableAutoplay: $id('autoplay-toggle').checked,
            cinematicLighting: $id('cinematic-lighting-toggle').checked,
            syncCinematic: $id('sync-cinematic-toggle') ? $id('sync-cinematic-toggle').checked : false, // NUEVO SETTING
            sidePanelStyle: $id('side-panel-style-select') ? $id('side-panel-style-select').value : 'normal',
            customTimelineColor: $id('custom-timeline-color-toggle') ? $id('custom-timeline-color-toggle').checked : false,
            disableSubtitles: $id('subtitles-toggle') ? $id('subtitles-toggle').checked : false,
            // fontSize: $id('font-size-slider').value,
            playerSize: $id('player-size-slider').value,
            selectVideoQuality: $id('select-video-qualitys-select').value,
            languagesComments: $id('select-languages-comments-select').value,
            // menuBgColor: $id('menu-bg-color-picker').value,
            // menuTextColor: $id('menu-text-color-picker').value,
            menu_akari: {
                bg: selectedBgColor,
                color: selectedTextColor,
                accent: selectedBgAccentColor
            }
            // menuFontSize: $id('menu-font-size-slider').value,
        };

        GM_setValue(SETTINGS_KEY, JSON.stringify(settings));
    }



    // Function to load settings
    function loadSettings() {
        const settings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
        // Mark as loaded early so applySettings/saveSettings don't overwrite persisted values with defaults.
        __ytToolsRuntime.settingsLoaded = true;

        if (settings.theme) {
            $e(`input[name="theme"][value="${settings.theme}"]`).checked = true;
        }
        const menuData = settings.menu_akari || settings.menu_developermdcm || {
            bg: "#252525",
            color: "#ffffff",
            accent: "#ff0000"
        };

        $id('bg-color-picker').value = settings.bgColorPicker || '#000000';
        $id('progressbar-color-picker').value = settings.progressbarColorPicker || '#ff0000';
        $id('primary-color-picker').value = settings.primaryColorPicker || '#ffffff';
        $id('secondary-color-picker').value = settings.secondaryColorPicker || '#ffffff';
        $id('header-color-picker').value = settings.headerColorPicker || '#000';
        $id('icons-color-picker').value = settings.iconsColorPicker || '#ffffff';
        $id('menu-color-picker').value = settings.menuColorPicker || '#000';
        $id('line-color-picker').value = settings.lineColorPicker || '#ff0000';
        $id('time-color-picker').value = settings.timeColorPicker || '#ffffff';
        $id('dislikes-toggle').checked = settings.dislikes || false;
        $id('like-dislike-bar-toggle').checked = settings.likeDislikeBar || false;
        $id('bookmarks-toggle').checked = settings.bookmarks || false;
        $id('continue-watching-toggle').checked = settings.continueWatching || false;
        $id('shorts-channel-name-toggle').checked = settings.shortsChannelName || false;
        if ($id('nonstop-playback-toggle')) $id('nonstop-playback-toggle').checked = settings.nonstopPlayback !== false;
        if ($id('audio-only-toggle')) $id('audio-only-toggle').checked = settings.audioOnly || false;
        syncAudioOnlyTabCheckbox(settings);
        $id('themes-toggle').checked = settings.themes || false;
        $id('translation-toggle').checked = settings.translation || false;
        $id('avatars-toggle').checked = settings.avatars || false;
        $id('reverse-mode-toggle').checked = settings.reverseMode || false;
        $id('wave-visualizer-toggle').checked = settings.waveVisualizer || false;
        $id('select-wave-visualizer-select').value = settings.waveVisualizerSelected || 'dinamica';
        $id('hide-comments-toggle').checked = settings.hideComments || false;
        $id('hide-sidebar-toggle').checked = settings.hideSidebar || false;
        $id('autoplay-toggle').checked = settings.disableAutoplay || false;
        $id('cinematic-lighting-toggle').checked = settings.cinematicLighting || false;
        if ($id('sync-cinematic-toggle')) $id('sync-cinematic-toggle').checked = settings.syncCinematic || false;
        if ($id('side-panel-style-select')) $id('side-panel-style-select').value = settings.sidePanelStyle || 'blur';
        if ($id('custom-timeline-color-toggle')) $id('custom-timeline-color-toggle').checked = settings.customTimelineColor || false;
        if ($id('subtitles-toggle')) $id('subtitles-toggle').checked = settings.disableSubtitles || false;
        $id('player-size-slider').value = settings.playerSize || 100;
        $id('select-video-qualitys-select').value = settings.selectVideoQuality || 'user';
        $id('select-languages-comments-select').value = settings.languagesComments || 'en';

        selectedBgColor = menuData.bg;
        selectedTextColor = menuData.color;
        selectedBgAccentColor = menuData.accent;


        $m('#bg-color-options .color-box').forEach(el => {
            el.classList.toggle('selected', el.dataset.value === selectedBgColor);
        });

        $m('#text-color-options .color-box').forEach(el => {
            el.classList.toggle('selected', el.dataset.value === selectedTextColor);
        });

        $m('#bg-accent-color-options .color-box').forEach(el => {
            el.classList.toggle('selected', el.dataset.value === selectedBgAccentColor);
        });

        // Apply menu colors
        $sp('--yt-enhance-menu-bg', selectedBgColor);
        $sp('--yt-enhance-menu-text', selectedTextColor);
        $sp('--yt-enhance-menu-accent', selectedBgAccentColor);
        updateSliderValues();

        setTimeout(() => {
            applySettings();
            if (settings.dislikes && !isYTMusic) {
                videoDislike();
                shortDislike();
                showDislikes = true;
            }

            if (!isYTMusic && window.location.href.includes('youtube.com/watch?v=')) {
                detectInitialCinematicState();
            }
        }, 500);
    }

    // Check if the video is in cinematic mode
    async function detectInitialCinematicState() {
        return new Promise((resolve) => {
            const waitForVideo = () => {
                const video = $e('video');
                const cinematicDiv = $id('cinematics');

                if (!video || !cinematicDiv || isNaN(video.duration) || video.duration === 0) {
                    setTimeout(waitForVideo, 500);
                    return;
                }

                const settings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
                if (!settings.syncCinematic) {
                    // apply cinematic toggle
                    const cinematicToggle = $id('cinematic-lighting-toggle');
                    if (cinematicToggle && cinematicDiv) {
                        cinematicDiv.style.display = cinematicToggle.checked ? 'block' : 'none';
                    }
                    resolve(false);
                    return;
                }

                const startTime = video.currentTime;
                const checkPlayback = () => {
                    if (video.currentTime >= startTime + 1) {
                        const isActive = isCinematicActive();

                        const cinematicToggle = $id('cinematic-lighting-toggle');
                        if (cinematicToggle && cinematicToggle.checked !== isActive) {
                            cinematicToggle.checked = isActive;
                            saveSettings();
                        }

                        resolve(isActive);
                    } else {
                        setTimeout(checkPlayback, 300);
                    }
                };

                checkPlayback();
            };

            waitForVideo();
        });
    }

    $m('.color-box').forEach(box => {
        box.addEventListener('click', () => {
            const type = box.dataset.type;
            const value = box.dataset.value;

            if (type === 'bg') {
                selectedBgColor = value;
                $sp('--yt-enhance-menu-bg', value);
                $m('#bg-color-options .color-box').forEach(el => {
                    el.classList.remove('selected');
                });
                box.classList.add('selected');
            } else if (type === 'color') {
                selectedTextColor = value;
                $sp('--yt-enhance-menu-text', value);
                $m('#text-color-options .color-box').forEach(el => {
                    el.classList.remove('selected');
                });
                box.classList.add('selected');
            } else if (type === 'accent') {
                selectedBgAccentColor = value;
                $sp('--yt-enhance-menu-accent', value);
                $m('#bg-accent-color-options .color-box').forEach(el => {
                    el.classList.remove('selected');
                });
                box.classList.add('selected');
            }
            saveSettings();
        });
    });


    function updateSliderValues() {
        $id('player-size-value').textContent = $id('player-size-slider').value;

    }

    $id('reset-player-size').addEventListener('click', () => {
        $id('player-size-slider').value = 100;
        updateSliderValues();
        applySettings();
    });

    // Initialize header buttons once
    function initializeHeaderButtons() {
        const shareBtn = $id('shareBtn-mdcm');
        const importExportBtn = $id('importExportBtn');
        const closeImportExportBtn = $id('closeImportExportBtn');

        if (shareBtn && !shareBtn.dataset.initialized) {
            shareBtn.dataset.initialized = 'true';
            shareBtn.addEventListener('click', function (event) {
                event.stopPropagation();
                const dropdown = $id('shareDropdown');
                if (dropdown) {
                    dropdown.style.display = dropdown.style.display === 'block' ? 'none' : 'block';
                }
            });
        }

        if (importExportBtn && !importExportBtn.dataset.initialized) {
            importExportBtn.dataset.initialized = 'true';
            importExportBtn.addEventListener('click', function () {
                const importExportArea = $id('importExportArea');
                if (importExportArea) {
                    importExportArea.classList.toggle('active');
                }
            });
        }

        if (closeImportExportBtn && !closeImportExportBtn.dataset.initialized) {
            closeImportExportBtn.dataset.initialized = 'true';
            closeImportExportBtn.addEventListener('click', function () {
                const importExportArea = $id('importExportArea');
                if (importExportArea) {
                    importExportArea.classList.remove('active');
                }
            });
        }
    }



    // Persistent check to ensure the gear icon survives YouTube's dynamic UI updates
    // setupHeaderObserver() is now called inside addIcon()
    // ------------------------------
    // YTM Ambient Mode — CSS background-image blur approach
    // Uses album art or video poster as a blurred full-screen background glow
    // Elements stay persistent for smooth transitions — only .active class toggles

    // ------------------------------

    const ytmAmbientMode = {
        active: false,
        _initialized: false, // true once DOM elements are created
        glowEl: null,
        styleEl: null,
        videoEl: null,
        _lastSrc: '',
        _pollId: null,

        // Find album art image URL from YTM player page
        _getArtUrl() {
            // 1. Rock-solid way: Get from YouTube Player API directly
            try {
                const mp = document.getElementById('movie_player');
                if (mp && typeof mp.getVideoData === 'function') {
                    const vData = mp.getVideoData();
                    if (vData && vData.video_id) {
                        return `https://i.ytimg.com/vi/${vData.video_id}/sddefault.jpg`;
                    }
                }
            } catch (e) { }

            // 2. Fallbacks
            const selectors = [
                '#song-image yt-img-shadow img',
                '#song-image img',
                'ytmusic-player-page #thumbnail img',
                '#player-page .thumbnail img',
                'ytmusic-player-bar .image img',
                'ytmusic-player-bar img'
            ];
            for (const sel of selectors) {
                const img = document.querySelector(sel);
                if (img && img.src && img.src.startsWith('http')) {
                    return img.src.replace(/=w\d+-h\d+/, '=w640-h640').replace(/=s\d+/, '=s640');
                }
            }
            const video = $e('video');
            if (video && video.poster) return video.poster;
            return null;
        },

        // Create DOM elements once (called only once, persists across show/hide)
        _ensureInit() {
            if (this._initialized) return;
            this._initialized = true;

            // Create the glow div
            this.glowEl = document.createElement('div');
            this.glowEl.id = 'ytm-ambient-glow';
            document.body.appendChild(this.glowEl);

            // Create the custom sidebar divider that perfectly fits the top/bottom bars
            this.dividerEl = document.createElement('div');
            this.dividerEl.id = 'ytm-custom-divider';
            document.body.appendChild(this.dividerEl);

            // Create style element
            this.styleEl = document.createElement('style');
            this.styleEl.id = 'ytm-ambient-style';
            this.styleEl.textContent = `
        #ytm-ambient-glow {
          position: fixed;
          top: -200px; left: -200px;
          width: calc(100vw + 400px);
          height: calc(100vh + 400px);
          pointer-events: none;
          z-index: -1;
          opacity: 0;
          background-size: cover;
          background-position: center;
          background-repeat: no-repeat;
          filter: blur(140px) saturate(2.2) brightness(0.9);
          transition: opacity 1.2s ease;
        }
        #ytm-ambient-glow.active {
          opacity: 0.7;
        }
        #ytm-custom-divider {
          position: fixed;
          width: 1px;
          background: rgba(255, 255, 255, 0.15);
          pointer-events: none;
          z-index: 2000;
          opacity: 0;
          transition: opacity 0.3s ease;
        }
        body.ytm-ambient-active #ytm-custom-divider.active {
          opacity: 1;
        }
        /* Make player page backgrounds transparent so glow shows through */
        body.ytm-ambient-active ytmusic-app,
        body.ytm-ambient-active ytmusic-app-layout,
        body.ytm-ambient-active #layout {
          background-color: transparent !important;
          background: transparent !important;
          transition: background-color 0.6s ease;
        }
        body.ytm-ambient-active ytmusic-player-page,
        body.ytm-ambient-active #player-page,
        body.ytm-ambient-active ytmusic-player-page #main-panel,
        body.ytm-ambient-active .background-gradient {
          background-color: transparent !important;
          background: transparent !important;
          background-image: none !important;
        }
        /* Make nav bar, player bar, and side drawer transparent so the aura blends behind them smoothly */
        body.ytm-ambient-active #nav-bar-background,
        body.ytm-ambient-active #player-bar-background,
        body.ytm-ambient-active ytmusic-nav-bar,
        body.ytm-ambient-active ytmusic-player-bar,
        body.ytm-ambient-active tp-yt-app-drawer,
        body.ytm-ambient-active tp-yt-app-drawer #contentContainer,
        body.ytm-ambient-active #guide-wrapper,
        body.ytm-ambient-active #guide-content,
        body.ytm-ambient-active ytmusic-guide-renderer,
        body.ytm-ambient-active #mini-guide-background,
        body.ytm-ambient-active #mini-guide {
          background: transparent !important;
          background-color: transparent !important;
          background-image: none !important;
        }
        /* Remove borders that piece through the player bar when transparent */
        body.ytm-ambient-active tp-yt-app-drawer,
        body.ytm-ambient-active tp-yt-app-drawer #contentContainer,
        body.ytm-ambient-active #guide-wrapper,
        body.ytm-ambient-active #guide-content,
        body.ytm-ambient-active ytmusic-guide-renderer,
        body.ytm-ambient-active #mini-guide-background {
          border: none !important;
          border-right: none !important;
          box-shadow: none !important;
        }
        /* Hide home/browse pages when player is open so they don't bleed through or block the glow */
        body.ytm-ambient-active ytmusic-browse-response {
          visibility: hidden !important;
          opacity: 0 !important;
        }


      `;
            document.head.appendChild(this.styleEl);
        },

        // Show ambient (fast — just toggle class + update art)
        show() {
            if (!isYTMusic) return;
            if (this.active) return;
            if (!window.location.href.includes('/watch')) return;

            this._ensureInit();
            this.active = true;

            // Update video reference
            this.videoEl = document.querySelector('video');

            if (this.glowEl) {
                this.glowEl.classList.add('active');
                document.body.classList.add('ytm-ambient-active');
            }

            this._updateArt();
            this._startPoll();
            this._startTracker();

            // Listen for play events (for art updates on song change)
            if (this.videoEl) {
                this.videoEl.removeEventListener('play', this._onPlay);
                this.videoEl.addEventListener('play', this._onPlay);
            }
        },

        // Hide ambient (fast — just toggle class, keep elements)
        hide() {
            this.active = false;
            if (this._pollId) {
                clearInterval(this._pollId);
                this._pollId = null;
            }
            if (this._trackerId) {
                cancelAnimationFrame(this._trackerId);
                this._trackerId = null;
            }
            if (this.glowEl) {
                this.glowEl.classList.remove('active');
                document.body.classList.remove('ytm-ambient-active');
            }
            if (this.dividerEl) {
                this.dividerEl.classList.remove('active');
            }
            if (this.videoEl) {
                this.videoEl.removeEventListener('play', this._onPlay);
                this.videoEl = null;
            }
        },

        // Full cleanup — remove all DOM elements (only when disabling feature)
        destroy() {
            this.hide();
            this._lastSrc = '';
            this._initialized = false;
            if (this.glowEl) {
                if (this.glowEl.parentNode) this.glowEl.parentNode.removeChild(this.glowEl);
                this.glowEl = null;
            }
            if (this.dividerEl) {
                if (this.dividerEl.parentNode) this.dividerEl.parentNode.removeChild(this.dividerEl);
                this.dividerEl = null;
            }
            if (this.styleEl) {
                if (this.styleEl.parentNode) this.styleEl.parentNode.removeChild(this.styleEl);
                this.styleEl = null;
            }
        },

        _startTracker() {
            if (this._trackerId) cancelAnimationFrame(this._trackerId);

            const self = this;
            function track() {
                if (!self.active) { self._trackerId = null; return; }

                const nav = document.querySelector('ytmusic-nav-bar');
                const player = document.querySelector('ytmusic-player-bar');
                const drawer = document.querySelector('tp-yt-app-drawer');
                const wrapper = document.querySelector('#guide-wrapper') || document.querySelector('#mini-guide-background');

                if (nav && player && drawer && wrapper && self.dividerEl) {
                    const navRect = nav.getBoundingClientRect();
                    const playerRect = player.getBoundingClientRect();
                    const wrapperRect = wrapper.getBoundingClientRect();

                    let leftPos = wrapperRect.right;
                    // Minor correction if right bound goes missing
                    if (leftPos <= 0 || !leftPos) leftPos = drawer.hasAttribute('opened') ? 240 : 72;

                    self.dividerEl.style.top = navRect.bottom + 'px';
                    self.dividerEl.style.height = (playerRect.top - navRect.bottom) + 'px';
                    self.dividerEl.style.left = leftPos + 'px';
                    self.dividerEl.classList.add('active');
                }

                self._trackerId = requestAnimationFrame(track);
            }

            this._trackerId = requestAnimationFrame(track);
        },

        // Legacy aliases for compatibility
        setup() { this.show(); },
        cleanup() { this.hide(); },

        _updateArt() {
            const url = this._getArtUrl();
            if (url && url !== this._lastSrc) {
                this._lastSrc = url;
                if (this.glowEl) {
                    this.glowEl.style.backgroundImage = `url("${url}")`;
                }
            }
        },

        _startPoll() {
            if (this._pollId) clearInterval(this._pollId);
            const self = this;
            this._pollId = setInterval(() => {
                if (!self.active) { clearInterval(self._pollId); self._pollId = null; return; }
                if (!window.location.href.includes('/watch')) {
                    self.hide();
                    return;
                }
                self._updateArt();
            }, 2000);
        },

        _onPlay: function () {
            if (!window.location.href.includes('/watch')) return;
            const g = document.getElementById('ytm-ambient-glow');
            if (g) {
                g.classList.add('active');
                document.body.classList.add('ytm-ambient-active');
            }
            ytmAmbientMode._updateArt();
        },
    };

    // Persistent ambient watcher — fast URL monitoring for smooth transitions
    if (isYTMusic) {
        let _ambientWatcherId = null;
        function startAmbientWatcher() {
            if (_ambientWatcherId) return;
            _ambientWatcherId = setInterval(() => {
                if (document.visibilityState !== 'visible') return;
                const s = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
                const onWatch = window.location.href.includes('/watch');
                if (!s.cinematicLighting) {
                    if (ytmAmbientMode.active) ytmAmbientMode.hide();
                    return;
                }
                if (onWatch && !ytmAmbientMode.active) {
                    ytmAmbientMode.show();
                } else if (!onWatch && ytmAmbientMode.active) {
                    ytmAmbientMode.hide();
                }
            }, 1500); // Reduced frequency from 800ms to 1500ms
        }
        setTimeout(startAmbientWatcher, 1500);

        // Also respond to YTM-specific events immediately
        document.addEventListener('yt-page-data-updated', () => {
            const settings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
            if (!settings.cinematicLighting) return;
            if (window.location.href.includes('/watch')) {
                if (!ytmAmbientMode.active) ytmAmbientMode.show();
                else ytmAmbientMode._updateArt(); // might be a new song
            } else if (ytmAmbientMode.active) {
                ytmAmbientMode.hide();
            }
        });
    }

    // Cinematic Lighting Control Functions

    function isWatchPage() {
        return window.location.href.includes('youtube.com/watch');
    }

    function isCinematicActive() {
        const cinematicDiv = document.getElementById('cinematics');
        if (!cinematicDiv) {
            return false;
        }

        const hasContent = cinematicDiv.innerHTML.trim() !== '';
        const hasCanvas = cinematicDiv.querySelector('canvas') !== null;
        const hasChildren = cinematicDiv.children.length > 0;

        const hasCinematicElements = cinematicDiv.querySelector('div[style*="position: fixed"]') !== null;

        return hasContent || hasCanvas || hasChildren || hasCinematicElements;
    }

    function toggleCinematicLighting() {
        const settingsButton = $e('.ytp-button.ytp-settings-button');
        if (!settingsButton) {
            console.log('[YT Tools] Settings button not found');
            return;
        }

        settingsButton.click();

        // Cinematic/ambient keywords in multiple languages for robust detection
        const cinematicKeywords = [
            'cinematic', 'lighting', 'cinema', 'ambient',
            'ch\u1EBF \u0111\u1ED9 \u0111i\u1EC7n \u1EA3nh', // Vietnamese: Chế độ điện ảnh
            '\u0111i\u1EC7n \u1EA3nh', // Vietnamese: điện ảnh
            'atmosph', 'ambiante', 'cin\u00E9ma', // French
            '\u30A2\u30F3\u30D3\u30A8\u30F3\u30C8', // Japanese
            '\uC2DC\uB124\uB9C8\uD2F1', // Korean
        ];

        const findAndClickCinematic = () => {
            const menuItems = $m('.ytp-menuitem');
            if (!menuItems || menuItems.length === 0) return false;

            for (let item of menuItems) {
                // Method 1: Look for toggle checkbox (cinematic is the only toggle-type menu item)
                const toggleCheckbox = item.querySelector('.ytp-menuitem-toggle-checkbox');
                if (toggleCheckbox) {
                    console.log('[YT Tools] Found cinematic/ambient toggle item (by checkbox)');
                    item.click();
                    return true;
                }
            }

            // Method 2: Match by localized text keywords
            for (let item of menuItems) {
                const text = (item.textContent || '').toLowerCase();
                for (const kw of cinematicKeywords) {
                    if (text.includes(kw)) {
                        console.log('[YT Tools] Found cinematic option by keyword:', kw);
                        item.click();
                        return true;
                    }
                }
            }

            // Method 3: Match by SVG icon path
            for (let item of menuItems) {
                const icon = item.querySelector('.ytp-menuitem-icon svg path');
                if (icon && (icon.getAttribute('d')?.includes('M21 7v10H3V7') ||
                    icon.getAttribute('d')?.includes('M12 2C6.48 2 2 6.48 2 12'))) {
                    console.log('[YT Tools] Found cinematic option by SVG path');
                    item.click();
                    return true;
                }
            }

            return false;
        };

        const closeMenu = () => {
            const menu = $e('.ytp-settings-menu');
            if (menu) document.body.click();
        };

        // Use polling instead of MutationObserver for more reliable detection
        let attempts = 0;
        const maxAttempts = 20;
        const pollInterval = setInterval(() => {
            attempts++;
            if (findAndClickCinematic()) {
                clearInterval(pollInterval);
                setTimeout(closeMenu, 150);
                return;
            }
            if (attempts >= maxAttempts) {
                clearInterval(pollInterval);
                console.warn('[YT Tools] Could not find cinematic/ambient toggle after', maxAttempts, 'attempts');
                closeMenu();
            }
        }, 200);
    }

    // Function to apply settings
    function applySettings() {
        const formulariodescarga = $e('.formulariodescarga');
        const formulariodescargaaudio = $e('.formulariodescargaaudio');
        if (formulariodescarga != undefined) {
            formulariodescarga.classList.add('ocultarframe');
            formulariodescargaaudio.classList.add('ocultarframe');
        }
        const settings = {
            theme: $e('input[name="theme"]:checked').value,
            bgColorPicker: $id('bg-color-picker').value,
            progressbarColorPicker: $id('progressbar-color-picker').value,
            primaryColorPicker: $id('primary-color-picker').value,
            secondaryColorPicker: $id('secondary-color-picker').value,
            headerColorPicker: $id('header-color-picker').value,
            iconsColorPicker: $id('icons-color-picker').value,
            menuColorPicker: $id('menu-color-picker').value,
            lineColorPicker: $id('line-color-picker').value,
            timeColorPicker: $id('time-color-picker').value,
            dislikes: $id('dislikes-toggle').checked,
            likeDislikeBar: $id('like-dislike-bar-toggle').checked,
            bookmarks: $id('bookmarks-toggle').checked,
            continueWatching: $id('continue-watching-toggle').checked,
            shortsChannelName: $id('shorts-channel-name-toggle').checked,
            nonstopPlayback: $id('nonstop-playback-toggle') ? $id('nonstop-playback-toggle').checked : true,
            audioOnly: $id('audio-only-toggle') ? $id('audio-only-toggle').checked : false,
            themes: $id('themes-toggle').checked,
            translation: $id('translation-toggle').checked,
            avatars: $id('avatars-toggle').checked,
            reverseMode: $id('reverse-mode-toggle').checked,
            waveVisualizer: $id('wave-visualizer-toggle').checked,
            waveVisualizerSelected: $id('select-wave-visualizer-select').value,
            hideComments: $id('hide-comments-toggle').checked,
            hideSidebar: $id('hide-sidebar-toggle').checked,
            disableAutoplay: $id('autoplay-toggle').checked,
            cinematicLighting: $id('cinematic-lighting-toggle') ? $id('cinematic-lighting-toggle').checked : false,
            syncCinematic: $id('sync-cinematic-toggle') ? $id('sync-cinematic-toggle').checked : false, // NUEVO SETTING
            sidePanelStyle: $id('side-panel-style-select') ? $id('side-panel-style-select').value : 'blur',
            customTimelineColor: $id('custom-timeline-color-toggle') ? $id('custom-timeline-color-toggle').checked : false,
            disableSubtitles: $id('subtitles-toggle') ? $id('subtitles-toggle').checked : false,
            // fontSize: $id('font-size-slider').value,
            playerSize: $id('player-size-slider').value,
            selectVideoQuality: $id('select-video-qualitys-select').value,
            languagesComments: $id('select-languages-comments-select').value,
            // menuBgColor: $id('menu-bg-color-picker').value,
            // menuTextColor: $id('menu-text-color-picker').value,
            menu_developermdcm: {
                bg: selectedBgColor,
                color: selectedTextColor,
                accent: selectedBgAccentColor
            }
            // menuFontSize: $id('menu-font-size-slider').value,
        };
        $sp('--yt-enhance-menu-bg', settings.menu_developermdcm.bg);
        $sp('--yt-enhance-menu-text', settings.menu_developermdcm.color);
        $sp('--yt-enhance-menu-accent', settings.menu_developermdcm.accent);

        renderizarButtons();
        applyNonstopPlayback(settings.nonstopPlayback);
        syncAudioOnlyTabCheckbox(settings);
        applyAudioOnlyMode(getEffectiveAudioOnly(settings));

        // Handle Side Panel Style classes
        document.body.classList.remove('ytm-style-blur', 'ytm-style-liquid', 'ytm-style-transparent');
        if (settings.sidePanelStyle === 'liquid') {
            document.body.classList.add('ytm-style-liquid');
        } else if (settings.sidePanelStyle === 'transparent') {
            document.body.classList.add('ytm-style-transparent');
        } else {
            document.body.classList.add('ytm-style-blur');
        }


        // Initialize header buttons
        initializeHeaderButtons();



        // Hide comments (YT only)
        if (!isYTMusic) {
            const commentsSection = $id('comments');
            if (commentsSection) {
                commentsSection.style.display = settings.hideComments ? 'none' : 'block';
            }

            // Like vs Dislike Bar (YT only)
            if (typeof applyLikeDislikeBarIfEnabled === 'function') {
                applyLikeDislikeBarIfEnabled(settings);
            }

            // Show Dislikes count (YT only)
            if (typeof videoDislike === 'function') videoDislike();
            if (typeof shortDislike === 'function') shortDislike();
            showDislikes = !!settings.dislikes;
        }

        // Active inactive Themes
        const themesMenuSection = $e('.themes-hidden');
        if (themesMenuSection) {
            themesMenuSection.style.display = settings.themes ? 'block' : 'none';
        }

        // Hide sidebar (YT only)
        if (!isYTMusic) {
            const sidebarSection = $e('#secondary > #secondary-inner');
            if (sidebarSection) {
                sidebarSection.classList.add('side-moi');
                const sidebarSection2 = $e('.side-moi');
                sidebarSection2.style.display = settings.hideSidebar ? 'none' : 'block';
            }
        }

        // Disable autoplay (YT only - uses .ytp-autonav-toggle-button)
        if (!isYTMusic) {
            const autoplayToggle = $e('.ytp-autonav-toggle-button');
            if (autoplayToggle) {
                const isCurrentlyOn =
                    autoplayToggle.getAttribute('aria-checked') === 'true';
                if (settings.disableAutoplay && isCurrentlyOn) {
                    autoplayToggle.click();
                } else if (!settings.disableAutoplay && !isCurrentlyOn) {
                    autoplayToggle.click();
                }
            }
        }
        // Disable subtitles (YT only - uses .ytp-subtitles-button)
        if (!isYTMusic) {
            const subtitleToggle = $e('.ytp-subtitles-button');
            if (subtitleToggle) {
                const isCurrentlyOn =
                    subtitleToggle.getAttribute('aria-pressed') === 'true';
                if (settings.disableSubtitles && isCurrentlyOn) {
                    subtitleToggle.click();
                } else if (!settings.disableSubtitles && !isCurrentlyOn) {
                    subtitleToggle.click();
                }
            }
        }
        // Apply cinematic/ambient lighting setting
        if (isYTMusic) {
            // YTM: custom ambient mode
            if (settings.cinematicLighting && isWatchPage()) {
                setTimeout(() => {
                    ytmAmbientMode.setup();
                }, 800);
            } else {
                ytmAmbientMode.cleanup();
            }
        } else if (isWatchPage()) {
            setTimeout(() => {
                const isCurrentlyActive = isCinematicActive();
                if (settings.syncCinematic) {
                    if (settings.cinematicLighting && !isCurrentlyActive) {
                        toggleCinematicLighting();
                    } else if (!settings.cinematicLighting && isCurrentlyActive) {
                        toggleCinematicLighting();
                    }
                } else {
                    const cinematicDiv = $id('cinematics');
                    if (cinematicDiv) {
                        cinematicDiv.style.display = settings.cinematicLighting ? 'block' : 'none';
                    }
                }
            }, 1000);
        }

        // Adjust font size
        // $e('body').style.fontSize = `${settings.fontSize}px`;

        // Adjust player size
        const player = $e('video');
        if (player) {
            player.style.transform = `scale(${settings.playerSize / 100})`;
        }

        // selected video quality (YT only - uses div#movie_player)
        if (!isYTMusic) {
            const video = $e('div#movie_player');
            let ytPlayerQuality = localStorage.getItem('yt-player-quality');

            if (video != undefined && settings.selectVideoQuality !== "user") {
                if (ytPlayerQuality) {
                    let qualitySettings = JSON.parse(ytPlayerQuality);
                    qualitySettings.data = JSON.stringify({
                        quality: settings.selectVideoQuality,
                        previousQuality: 240
                    });
                    localStorage.setItem('yt-player-quality', JSON.stringify(qualitySettings));
                } else {
                    let defaultQualitySettings = {
                        data: JSON.stringify({
                            quality: 720,
                            previousQuality: 240
                        }),
                        expiration: Date.now() + (365 * 24 * 60 * 60 * 1000),
                        creation: Date.now()
                    };
                    localStorage.setItem('yt-player-quality', JSON.stringify(defaultQualitySettings));
                }
            }
        }

        // Apply menu appearance settings
        // $sp('--yt-enhance-menu-bg', settings.menuBgColor);
        // $sp('--yt-enhance-menu-text', settings.menuTextColor);
        // $sp('--yt-enhance-menu-font-size', `${settings.menuFontSize}px`);

        // Apply theme
        const selectedTheme = themes[settings.theme] || themes[0] || {};
        const isThemeCustom = $e(`input[name="theme"][value="custom"]`).checked;
        const isThemeNormal = $e(`input[name="theme"][value="normal"]`).checked;
        const themeCustomOptions = $e('.theme-custom-options');
        const themeNormal = $e('.theme-selected-normal');
        // Tối ưu: Dùng mảng để gom CSS, chỉ tiêm vào trang 1 lần duy nhất ở cuối
        let dynamicCssArray = [];
        const addDynamicCss = (css) => {
            if (css) dynamicCssArray.push(css);
        };

        // CHANGE DEFAULT TIMELINE TO ROYAL PURPLE AESTHETIC
        if (settings.customTimelineColor) {
            addDynamicCss(`
      .ytp-swatch-background-color {
        background: linear-gradient(135deg, #4c1d95, #8b5cf6) !important;
      }
    `);
            if (isYTMusic) {
                addDynamicCss(`
         #progress-bar {
           --paper-slider-active-color: #8b5cf6 !important;
           --paper-slider-knob-color: #8b5cf6 !important;
           --paper-slider-secondary-color: #8b5cf680 !important;
         }
       `);
            }
        }
        if (isThemeCustom) {
            themeNormal.style.display = "flex"
            themeCustomOptions.style.display = "flex";
            $e('.themes-options').style.display = "none";
        }
        if (isThemeNormal) {
            $e(`input[name="theme"][value="custom"]`).checked = false;
        }



        // Helper: apply YTM-specific CSS variables for theming
        function applyYTMThemeVars(bgColor, textColor, secondaryText, menuBg, iconColor, raisedBg, progressColor, progressSecondary) {
            // YTM-specific variables
            $sp('--ytmusic-general-background', bgColor);
            $sp('--ytmusic-background', bgColor);
            $sp('--ytmusic-color-white1', textColor);
            $sp('--ytmusic-color-white2', secondaryText || textColor);
            $sp('--ytmusic-color-white3', secondaryText || textColor);
            $sp('--ytmusic-color-white4', secondaryText || textColor);
            $sp('--ytmusic-player-bar-background', raisedBg || bgColor);
            $sp('--ytmusic-nav-bar-background', bgColor);
            $sp('--ytmusic-nav-bar', bgColor);
            $sp('--ytmusic-search-background', menuBg || bgColor);
            // Shared YT/YTM variables
            $sp('--yt-spec-general-background-a', bgColor);
            $sp('--yt-spec-general-background-b', bgColor);
            $sp('--yt-spec-general-background-c', bgColor);

            // YTM Slider Progress bar
            if (progressColor) {
                $sp('--paper-slider-active-color', progressColor);
                $sp('--paper-slider-knob-color', progressColor);
                $sp('--paper-progress-active-color', progressColor);
            }
            if (progressSecondary) {
                $sp('--paper-slider-secondary-color', progressSecondary);
                $sp('--paper-progress-secondary-color', progressSecondary);
            }

            // Force colors via CSS to prevent YTM's native ambient mode from overriding the variables
            // Only add this if not cleared (bgColor is truthy)
            if (bgColor) {
                addDynamicCss(`
                    #nav-bar-background.ytmusic-app-layout {
                        background: ${bgColor} !important;
                        background-image: ${bgColor.includes('gradient') ? bgColor : 'none'} !important;
                    }
                    ytmusic-app-layout.content-scrolled #nav-bar-background.ytmusic-app-layout {
                        background: ${bgColor} !important;
                    }
                    #player-bar-background.ytmusic-app-layout {
                        background: ${raisedBg || bgColor} !important;
                        background-image: ${(raisedBg || bgColor).includes('gradient') ? (raisedBg || bgColor) : 'none'} !important;
                    }
                `);
            }
        }

        if (isYTMusic) {
            initYTMHeaderScroll();
        }

        function checkDarkMode() {

            if (settings.themes) {

                if (isDarkModeActive === 'dark' && !isThemeCustom) {
                    // Apply theme
                    const themesOpts = $e('.themes-options');
                    if (themesOpts) themesOpts.style.display = "block";
                    if (themeNormal) themeNormal.style.display = "none";
                    if (themeCustomOptions) themeCustomOptions.style.display = "none";

                    if (settings.theme === '0') {
                        // Clean up CSS vars from previous theme
                        const props = [
                            '--ytmusic-general-background', '--ytmusic-background', '--ytmusic-color-white1', '--ytmusic-color-white2',
                            '--ytmusic-color-white3', '--ytmusic-color-white4', '--ytmusic-player-bar-background', '--ytmusic-nav-bar-background',
                            '--ytmusic-search-background', '--yt-spec-general-background-a', '--yt-spec-general-background-b', '--yt-spec-general-background-c',
                            '--yt-spec-base-background', '--yt-spec-text-primary', '--yt-spec-text-secondary', '--yt-spec-menu-background',
                            '--yt-spec-icon-inactive', '--yt-spec-brand-icon-inactive', '--yt-spec-brand-icon-active', '--yt-spec-static-brand-red',
                            '--yt-spec-raised-background', '--yt-spec-static-brand-white', '--ytd-searchbox-background', '--ytd-searchbox-text-color',
                            '--ytcp-text-primary', '--ytmusic-nav-bar', '--paper-slider-active-color', '--paper-slider-knob-color',
                            '--paper-progress-active-color', '--paper-slider-secondary-color', '--paper-progress-secondary-color'
                        ];
                        props.forEach(p => document.documentElement.style.removeProperty(p));
                        addDynamicCss(`
              .botones_div {
               background-color: transparent;
               border: none;
               color: #ccc !important;
               user-select: none;
             }
               `);
                        if (localStorage.getItem('backgroundImage')) {
                            applyPageBackground(localStorage.getItem('backgroundImage'), null);
                        } else {
                            applyPageBackground(null);
                        }
                        return;
                    }

                    // Standard YT CSS variables
                    $sp('--yt-spec-base-background', selectedTheme.gradient);
                    $sp('--yt-spec-text-primary', selectedTheme.textColor);
                    $sp('--yt-spec-text-secondary', selectedTheme.textColor);
                    $sp('--yt-spec-menu-background', selectedTheme.gradient);
                    $sp('--yt-spec-icon-inactive', selectedTheme.textColor);
                    $sp('--yt-spec-brand-icon-inactive', selectedTheme.textColor);
                    $sp('--yt-spec-brand-icon-active', selectedTheme.gradient);
                    $sp('--yt-spec-static-brand-red', selectedTheme.gradient); // line current time
                    $sp('--yt-spec-raised-background', selectedTheme.raised);
                    $sp('--yt-spec-static-brand-red', selectedTheme.CurrentProgressVideo);
                    $sp('--yt-spec-static-brand-white', selectedTheme.textColor);
                    $sp('--ytd-searchbox-background', selectedTheme.gradient);
                    $sp('--ytd-searchbox-text-color', selectedTheme.textColor);
                    $sp('--ytcp-text-primary', selectedTheme.textColor);

                    // YTM-specific CSS variables
                    let ytmSliderSolidColor = selectedTheme.CurrentProgressVideo;
                    if (selectedTheme.gradient) {
                        let colors = selectedTheme.gradient.match(/#[0-9a-fA-F]{3,6}/g);
                        if (colors && colors.length > 0) {
                            ytmSliderSolidColor = colors[colors.length - 1]; // Use the most vibrant gradient color
                        }
                    }

                    if (isYTMusic) {
                        applyYTMThemeVars(
                            selectedTheme.gradient,
                            selectedTheme.textColor,
                            selectedTheme.textColor,
                            selectedTheme.gradient,
                            selectedTheme.colorIcons || selectedTheme.textColor,
                            selectedTheme.raised === '#303131' ? selectedTheme.gradient : selectedTheme.raised,
                            ytmSliderSolidColor,
                            ytmSliderSolidColor + '80' // Add 50% opacity in hex for secondary 'buffer' slider
                        );
                    }

                    addDynamicCss(`
              .botones_div {
              background-color: transparent;
              border: none;
              color: #999999;
              user-select: none;
            }
              .ytp-menuitem[aria-checked=true] .ytp-menuitem-toggle-checkbox {
              background:  ${selectedTheme.gradient} !important;
              }
            #background.ytd-masthead { background: ${selectedTheme.gradient}  !important; }
            .ytp-swatch-background-color {
            background: ${selectedTheme.gradient} !important;
          }
          html, body {
            background-color: #0f0f0f !important;
          }
          `);

                    /* Apply background image with theme overlay if exists */
                    if (localStorage.getItem('backgroundImage')) {
                        applyPageBackground(localStorage.getItem('backgroundImage'), selectedTheme.gradient);
                    } else {
                        // Apply only theme gradient
                        addDynamicCss(`
              html, body {
                background-image: ${selectedTheme.gradient} !important;
                background-size: cover !important;
                background-position: center !important;
                background-attachment: fixed !important;
              }
            `);
                    }

                    /* Minimal transparency to allow background to show */
                    addDynamicCss(`
          ytd-app,
          #content.ytd-app,
          #page-manager.ytd-app,
          ytd-browse,
          ytd-watch-flexy,
          ytd-two-column-browse-results-renderer,
          #primary.ytd-two-column-browse-results-renderer,
          #secondary.ytd-two-column-browse-results-renderer,
          ytd-rich-grid-renderer,
          #contents.ytd-rich-grid-renderer,
          ytd-item-section-renderer,
          ytd-comments-header-renderer,
          ytd-comment-simplebox-renderer,
          ytd-comment-thread-renderer,
          ytd-comment-renderer,
          #header.ytd-item-section-renderer,
          #body.ytd-comment-renderer,
          #author-thumbnail.ytd-comment-simplebox-renderer,
          #cinematic-shorts-scrim.ytd-shorts,
          ytd-comment-view-model,
          ytd-comment-engagement-bar,
          ytd-comment-replies-renderer,
          #anchored-panel.ytd-shorts,
          #cinematic-container.ytd-reel-video-renderer,
          #shorts-cinematic-container,
          .short-video-container.ytd-reel-video-renderer,
          ytd-reel-video-renderer,
          .navigation-container.ytd-shorts,
          .navigation-button.ytd-shorts {
            background: transparent !important;
          }
          /* Completely hide the cinematic glow in shorts if it's causing black blocks */
          #cinematic-container.ytd-reel-video-renderer,
          #shorts-cinematic-container,
          #cinematic-shorts-scrim.ytd-shorts {
            display: none !important;
            opacity: 0 !important;
            visibility: hidden !important;
          }

          /* Use theme colors on major components without breaking layout */
          #masthead-container.ytd-app,
          #background.ytd-masthead {
            background: ${selectedTheme.gradient} !important;
          }

          /* Revert chip bar to near-native but themed */
          #header.ytd-rich-grid-renderer,
          ytd-feed-filter-chip-bar-renderer,
          #chips-wrapper.ytd-feed-filter-chip-bar-renderer {
            background: transparent !important;
          }


          /* Improve Shorts Navigation: Center 'Next' button if it's the first Short */
          ytd-shorts[is-watch-while-mode] .navigation-container.ytd-shorts,
          .navigation-container.ytd-shorts {
            display: flex !important;
            flex-direction: column !important;
            justify-content: center !important;
            gap: 12px !important;
            height: 100% !important;
            top: 0 !important;
            bottom: 0 !important;
            margin: 0 !important;
            background: transparent !important;
            background-color: transparent !important;
          }
          .navigation-button.ytd-shorts {
            margin: 0 !important;
          }
          /* Ensure hidden buttons don't take up space in the flex container */
          #navigation-button-up[aria-hidden="true"],
          #navigation-button-up[aria-hidden=""],
          #navigation-button-up[hidden],
          #navigation-button-down[aria-hidden="true"],
          #navigation-button-down[aria-hidden=""],
          #navigation-button-down[hidden] {
            display: none !important;
          }

          /* Restore the 'frosted-glass' look but with the theme gradient */
          #frosted-glass.ytd-app {
            background: ${selectedTheme.gradient} !important;
            opacity: 0.8 !important;
          }

          ytd-engagement-panel-section-list-renderer { background: ${selectedTheme.gradient} !important; backdrop-filter: blur(12px) !important; }
            ytd-engagement-panel-title-header-renderer[shorts-panel] #header.ytd-engagement-panel-title-header-renderer {
            background: ${selectedTheme.gradient}  !important;}
            .buttons-tranlate {
            background: ${selectedTheme.btnTranslate} !important;
            }
            .badge-shape-wiz--thumbnail-default {
            color: ${selectedTheme.videoDuration} !important;
            background: ${selectedTheme.gradient} !important;
            }
            #logo-icon {
            color:  ${selectedTheme.textLogo} !important;
          }
          .yt-spec-button-shape-next--overlay.yt-spec-button-shape-next--text {
            color:  ${selectedTheme.colorIcons} !important;
          }
          .ytd-topbar-menu-button-renderer #button.ytd-topbar-menu-button-renderer {
            color:  ${selectedTheme.colorIcons} !important;
          }
          .yt-spec-icon-badge-shape--style-overlay .yt-spec-icon-badge-shape__icon {
            color:  ${selectedTheme.colorIcons} !important;
          }
          .ytp-svg-fill {
            fill:  ${selectedTheme.colorIcons} !important;
          }
          #ytp-id-30,#ytp-id-17,#ytp-id-19,#ytp-id-20{
            fill:  ${selectedTheme.colorIcons} !important;
          }
            `);

                    // YTM-specific element selectors
                    if (isYTMusic) {
                        addDynamicCss(`
              html, body, ytmusic-app {
                background-color: ${localStorage.getItem('backgroundImage') ? 'transparent' : '#030303'} !important;
                background-image: ${localStorage.getItem('backgroundImage') ? 'none' : selectedTheme.gradient} !important;
                background-size: cover !important;
                background-position: center !important;
                background-attachment: fixed !important;
              }
              ytmusic-player-bar {
                background: ${localStorage.getItem('backgroundImage') ? 'transparent' : selectedTheme.gradient} !important;
                ${localStorage.getItem('backgroundImage') ? 'backdrop-filter: blur(20px) !important; -webkit-backdrop-filter: blur(20px) !important;' : ''}
              }
              ytmusic-nav-bar {
                background: transparent !important;
                transition: background 0.4s ease-in-out !important;
              }
              ytmusic-nav-bar.scrolled,
              ytmusic-nav-bar[opened],
              body[player-page-open] ytmusic-nav-bar {
                background: ${selectedTheme.gradient} !important;
                ${localStorage.getItem('backgroundImage') ? 'backdrop-filter: blur(20px) !important; -webkit-backdrop-filter: blur(20px) !important;' : ''}
              }
              ytmusic-search-box #input-box { background: ${selectedTheme.gradient} !important; }
              ytmusic-browse-response,
              ytmusic-header-renderer,
              ytmusic-tabbed-browse-renderer,
              ytmusic-detail-header-renderer,
              ytmusic-section-list-renderer,
              ytmusic-carousel-shelf-renderer,
              ytmusic-grid-renderer,
              ytmusic-item-section-renderer,
              #content.ytmusic-app,
              #shorts-container, ytd-shorts, #shorts-inner-container, ytd-reel-player-overlay, #overlay.ytd-reel-video-renderer, ytmusic-app-layout, #mini-guide-background, #guide-wrapper.ytmusic-app-layout, ytmusic-browse-response #background, ytmusic-browse-response .background, ytmusic-app-layout #background, ytmusic-immersive-header-renderer, ytmusic-card-shelf-renderer, ytmusic-chip-cloud-chip-renderer, ytmusic-chip-cloud-renderer, ytmusic-player-page, ytmusic-player-page #background { background: transparent !important; }

              /* Neutralize default YTM gradients */
              ytmusic-browse-response #background,
              ytmusic-header-renderer #background,
              ytmusic-tabbed-browse-renderer #background,
              ytmusic-player-page #background,
              ytmusic-player-page .background,
              .background-gradient.ytmusic-browse-response,
              #background.style-scope.ytmusic-browse-response,
              #header.style-scope.ytmusic-browse-response,

              ytmusic-browse-response [id="background"],
              ytmusic-header-renderer [id="background"], #mini-guide-background, #guide-spacer, .immersive-background, ytmusic-fullbleed-thumbnail-renderer[is-background] {
                background: transparent !important;
                background-image: none !important;
                }
              .immersive-background, ytmusic-fullbleed-thumbnail-renderer[is-background] {
                display: none !important;
              }

              #layout { background: transparent !important; }
              .content.ytmusic-player-page { background: transparent !important; }

              ytmusic-player-bar .title, ytmusic-player-bar .byline {
                color: ${selectedTheme.textColor} !important;
              }
              .ytmusic-player-bar .yt-spec-icon-shape, .ytmusic-player-bar svg {
                color: ${selectedTheme.colorIcons || selectedTheme.textColor} !important;
                fill: ${selectedTheme.colorIcons || selectedTheme.textColor} !important;
              }
              #progress-bar {
                --paper-slider-active-color: ${ytmSliderSolidColor} !important;
                --paper-slider-knob-color: ${ytmSliderSolidColor} !important;
                --paper-slider-secondary-color: ${ytmSliderSolidColor}80 !important;
              }
            `);
                        initYTMHeaderScroll();
                    }

                } else if (isDarkModeActive === 'dark' && isThemeCustom) {
                    $sp('--yt-spec-base-background', settings.bgColorPicker);
                    $sp('--yt-spec-text-primary', settings.primaryColorPicker);
                    $sp('--yt-spec-text-secondary', settings.secondaryColorPicker);
                    $sp('--yt-spec-menu-background', settings.menuColorPicker);
                    $sp('--yt-spec-icon-inactive', settings.iconsColorPicker);
                    $sp('--yt-spec-brand-icon-inactive', settings.primaryColorPicker);
                    $sp('--yt-spec-brand-icon-active', settings.primaryColorPicker);
                    $sp('--yt-spec-raised-background', settings.headerColorPicker);
                    $sp('--yt-spec-static-brand-red', settings.lineColorPicker);
                    $sp('--yt-spec-static-brand-white', settings.timeColorPicker);
                    $sp('--ytd-searchbox-background', settings.primaryColorPicker);
                    $sp('--ytd-searchbox-text-color', settings.secondaryColorPicker);
                    $sp('--ytcp-text-primary', settings.primaryColorPicker);

                    // YTM-specific CSS variables for custom theme
                    if (isYTMusic) {
                        applyYTMThemeVars(
                            settings.bgColorPicker,
                            settings.primaryColorPicker,
                            settings.secondaryColorPicker,
                            settings.menuColorPicker,
                            settings.iconsColorPicker,
                            settings.headerColorPicker,
                            settings.progressbarColorPicker,
                            settings.progressbarColorPicker + '80' // Add 50% opacity in hex
                        );

                        addDynamicCss(`
            #progress-bar {
              --paper-slider-active-color: ${settings.progressbarColorPicker} !important;
              --paper-slider-knob-color: ${settings.progressbarColorPicker} !important;
              --paper-slider-secondary-color: ${settings.progressbarColorPicker}80 !important;
            }
          `);
                    }

                    addDynamicCss(`
            .html5-video-player {
                color: ${settings.primaryColorPicker} !important;
              }
                .ytProgressBarLineProgressBarPlayed {
                background: linear-gradient(to right, ${settings.progressbarColorPicker} 80%, ${settings.progressbarColorPicker} 100%);

                }
              .ytp-menuitem .ytp-menuitem-icon svg path{
                fill: ${settings.iconsColorPicker} !important;
                }
                .ytThumbnailOverlayProgressBarHostWatchedProgressBarSegment {
                  background: linear-gradient(to right, ${settings.lineColorPicker} 80%, ${settings.lineColorPicker} 100%) !important;
                }
                .yt-badge-shape--thumbnail-default {
                  color: ${settings.timeColorPicker} !important;
                }
                a svg > path, .ytp-button svg path  {
                  fill: ${settings.iconsColorPicker} !important;
              }
                svg.path{
                 fill: ${settings.iconsColorPicker} !important;
                }

              svg {
                color: ${settings.iconsColorPicker} !important;
                }
              .ytp-volume-slider-handle:before, .ytp-volume-slider-handle, .ytp-tooltip.ytp-preview:not(.ytp-text-detail) {
                background-color: ${settings.iconsColorPicker} !important;
              }
                .ytp-autonav-toggle-button[aria-checked=true] {
                  background-color: ${settings.iconsColorPicker} !important;
                }
                  .tp-yt-iron-icon {
                   fill: ${settings.iconsColorPicker} !important;
                  }

             .botones_div {
            background-color: transparent;
            border: none;
            color: ${settings.iconsColorPicker} !important;
            user-select: none;
          }
              #container.ytd-searchbox {
              color: red !important;
              }
            .ytp-menuitem[aria-checked=true] .ytp-menuitem-toggle-checkbox {
            background:  ${settings.primaryColorPicker} !important;
            }
            .yt-spec-icon-shape {
              display: flex;
              align-items: center;
              justify-content: center;
              width: 100%;
              height: 100%;
              color: ${settings.iconsColorPicker} !important;
          }
            .ytp-time-current, .ytp-time-separator, .ytp-time-duration {
              color: ${settings.iconsColorPicker} !important;
            }
            #background.ytd-masthead { background: ${settings.headerColorPicker}  !important; }
            .ytp-swatch-background-color {
            background: ${settings.progressbarColorPicker
                        } !important;
          }
        #shorts-container,
        ytd-shorts,
        #shorts-inner-container,
        #page-manager.ytd-app,
        #cinematic-container.ytd-reel-video-renderer,
        #shorts-cinematic-container,
        .short-video-container.ytd-reel-video-renderer,
        ytd-reel-video-renderer,
        ytd-reel-player-overlay,
        #overlay.ytd-reel-video-renderer {
            background: transparent !important;
        }
        #cinematic-container.ytd-reel-video-renderer,
        #shorts-cinematic-container,
        #cinematic-shorts-scrim.ytd-shorts {
            display: none !important;
            opacity: 0 !important;
            visibility: hidden !important;
        }
            ytd-engagement-panel-title-header-renderer[shorts-panel] #header.ytd-engagement-panel-title-header-renderer {
            background: ${settings.bgColorPicker}  !important;}

            .badge-shape-wiz--thumbnail-default {
            color: ${settings.timeColorPicker} !important;
             background: ${settings.secondaryColorPicker} !important;
            }
             #logo-icon {
             color:  ${settings.primaryColorPicker} !important;
          }
          .yt-spec-button-shape-next--overlay.yt-spec-button-shape-next--text {
            color:  ${settings.iconsColorPicker} !important;
          }
          .ytd-topbar-menu-button-renderer #button.ytd-topbar-menu-button-renderer {
            color:  ${settings.iconsColorPicker} !important;
          }
          .yt-spec-icon-badge-shape--style-overlay .yt-spec-icon-badge-shape__icon {
            color:  ${settings.iconsColorPicker} !important;
          }
          .ytp-svg-fill {
            fill:  ${settings.iconsColorPicker} !important;
          }
          #ytp-id-30,#ytp-id-17,#ytp-id-19,#ytp-id-20{
            fill:  ${settings.iconsColorPicker} !important;
          }
            `);

                    // YTM-specific element selectors for custom theme
                    if (isYTMusic) {
                        addDynamicCss(`
              html, body, ytmusic-app {
                background-image: none !important;
                background-color: ${localStorage.getItem('backgroundImage') ? 'transparent' : settings.bgColorPicker} !important;
                background-size: cover !important;
                background-position: center !important;
                background-attachment: fixed !important;
              }
              ytmusic-player-bar {
                background: ${localStorage.getItem('backgroundImage') ? 'transparent' : (settings.headerColorPicker || settings.bgColorPicker)} !important;
                ${localStorage.getItem('backgroundImage') ? 'backdrop-filter: blur(20px) !important; -webkit-backdrop-filter: blur(20px) !important;' : ''}
              }
              ytmusic-nav-bar {
                background: transparent !important;
                transition: background 0.4s ease-in-out !important;
              }
              ytmusic-nav-bar.scrolled,
              ytmusic-nav-bar[opened],
              body[player-page-open] ytmusic-nav-bar {
                background: ${(settings.headerColorPicker || settings.bgColorPicker)} !important;
                ${localStorage.getItem('backgroundImage') ? 'backdrop-filter: blur(20px) !important; -webkit-backdrop-filter: blur(20px) !important;' : ''}
              }
              ytmusic-search-box #input-box { background: ${settings.menuColorPicker || settings.bgColorPicker} !important; }
              ytmusic-browse-response,
              ytmusic-header-renderer,
              ytmusic-tabbed-browse-renderer,
              ytmusic-detail-header-renderer,
              ytmusic-section-list-renderer,
              ytmusic-carousel-shelf-renderer,
              ytmusic-grid-renderer,
              ytmusic-item-section-renderer,
              #content.ytmusic-app,
              #shorts-container, ytd-shorts, #shorts-inner-container, ytd-reel-player-overlay, #overlay.ytd-reel-video-renderer,
              ytmusic-app-layout, ytmusic-app-layout.content-scrolled,
              #mini-guide-background, #guide-wrapper.ytmusic-app-layout,
              ytmusic-browse-response #background, ytmusic-browse-response .background,
              ytmusic-app-layout #background, ytmusic-app-layout #guide-background, ytmusic-app-layout #nav-bar-background, ytmusic-app-layout #player-bar-background,
              tp-yt-app-drawer, tp-yt-app-drawer #contentContainer,
              #mini-guide, #mini-guide-renderer,
              ytmusic-guide-renderer, #guide-wrapper, #guide-content, #guide-spacer,
              ytmusic-guide-section-renderer, ytmusic-guide-entry-renderer, tp-yt-paper-item.ytmusic-guide-entry-renderer,
              ytmusic-immersive-header-renderer, ytmusic-card-shelf-renderer, ytmusic-chip-cloud-chip-renderer, ytmusic-chip-cloud-renderer, ytmusic-player-page, ytmusic-player-page #background {
                background: transparent !important;
                --ytmusic-guide-background: transparent !important;
                --iron-drawer-background-color: transparent !important;
              }

              /* Neutralize default YTM gradients */
              ytmusic-browse-response #background,
              ytmusic-header-renderer #background,
              ytmusic-tabbed-browse-renderer #background,
              ytmusic-player-page #background,
              ytmusic-player-page .background,
              .background-gradient.ytmusic-browse-response,
              #background.style-scope.ytmusic-browse-response,
              #header.style-scope.ytmusic-browse-response,

              ytmusic-browse-response [id="background"],
              ytmusic-header-renderer [id="background"], #mini-guide-background, #guide-spacer, .immersive-background, ytmusic-fullbleed-thumbnail-renderer[is-background] {
                background: transparent !important;
                background-image: none !important;
                }
              body:not(.ytm-ambient-active) #mini-guide-background,
              .immersive-background, ytmusic-fullbleed-thumbnail-renderer[is-background] {
                opacity: 0 !important;
                pointer-events: none !important;
              }

              #layout { background: transparent !important; }
              .content.ytmusic-player-page { background: transparent !important; }

              ytmusic-player-bar .title, ytmusic-player-bar .byline {
                color: ${settings.primaryColorPicker} !important;
              }
              .ytmusic-player-bar .yt-spec-icon-shape, .ytmusic-player-bar svg {
                color: ${settings.iconsColorPicker} !important;
                fill: ${settings.iconsColorPicker} !important;
              }
            `);
                        initYTMHeaderScroll();
                    }
                } else {
                    addDynamicCss(`
            .botones_div {
             background-color: transparent;
             border: none;
             color: #000 !important;
             user-select: none;
           }
             `);
                }

            } else {
                if (localStorage.getItem('backgroundImage')) {
                    applyPageBackground(localStorage.getItem('backgroundImage'), null);
                } else {
                    applyPageBackground(null);
                }
                // Cleanup theme vars when toggled off to fix stuck colors on side-panel
                const props = [
                    '--ytmusic-general-background', '--ytmusic-background', '--ytmusic-color-white1', '--ytmusic-color-white2',
                    '--ytmusic-color-white3', '--ytmusic-color-white4', '--ytmusic-player-bar-background',
                    '--ytmusic-search-background', '--yt-spec-general-background-a', '--yt-spec-general-background-b', '--yt-spec-general-background-c',
                    '--yt-spec-base-background', '--yt-spec-text-primary', '--yt-spec-text-secondary', '--yt-spec-menu-background',
                    '--yt-spec-icon-inactive', '--yt-spec-brand-icon-inactive', '--yt-spec-brand-icon-active', '--yt-spec-static-brand-red',
                    '--yt-spec-raised-background', '--yt-spec-static-brand-white', '--ytd-searchbox-background', '--ytd-searchbox-text-color',
                    '--ytcp-text-primary', '--ytmusic-nav-bar', '--ytmusic-nav-bar-background', '--paper-slider-active-color',
                    '--paper-slider-knob-color', '--paper-progress-active-color', '--paper-slider-secondary-color', '--paper-progress-secondary-color'
                ];
                props.forEach(p => document.documentElement.style.removeProperty(p));

                // Restore YTM native defaults instead of leaving vars undefined
                if (isYTMusic) {
                    const hasBgImage = !!localStorage.getItem('backgroundImage');
                    if (hasBgImage) {
                        // When bgImage is active, force transparent vars so YTM CSS doesn't override our blur
                        document.documentElement.style.setProperty('--ytmusic-nav-bar-background', 'transparent');
                        document.documentElement.style.setProperty('--ytmusic-player-bar-background', 'transparent');
                    } else {
                        // No bgImage → restore YTM native defaults completely
                        document.documentElement.style.removeProperty('--ytmusic-nav-bar-background');
                        document.documentElement.style.removeProperty('--ytmusic-player-bar-background');
                        document.documentElement.style.removeProperty('--ytmusic-nav-bar');
                    }
                    // Cleanup carousel/container backgrounds that were made transparent by theme
                    // But DON'T reset nav-bar/player-bar when backgroundImage is active (applyPageBackground handles those)
                    addDynamicCss(`
          ytmusic-carousel-shelf-renderer,
          ytmusic-section-list-renderer,
          ytmusic-grid-renderer,
          ytmusic-card-shelf-renderer,
          ytmusic-chip-cloud-renderer,
          ytmusic-chip-cloud-chip-renderer,
          ytmusic-header-renderer,
          ytmusic-tabbed-browse-renderer,
          ytmusic-detail-header-renderer,
          ytmusic-item-section-renderer,
          ytmusic-immersive-header-renderer {
            background: ${hasBgImage ? 'transparent' : 'initial'} !important;
          }
          .immersive-background, ytmusic-fullbleed-thumbnail-renderer[is-background] {
            display: initial !important;
          }
          ${hasBgImage ? `
          /* Theme OFF + bgImage: nav-bar/player-bar need blur background */
          #nav-bar-background.ytmusic-app-layout {
            background: transparent !important;
            transition: background 0.3s ease, backdrop-filter 0.3s ease !important;
          }
          /* High specificity transparency for YTM Guide/Sidebar */
          tp-yt-app-drawer,
          tp-yt-app-drawer #contentContainer,
          tp-yt-app-drawer #contentContainer.tp-yt-app-drawer,
          #guide-wrapper.ytmusic-app,
          #guide-content.ytmusic-app,
          #guide-spacer.ytmusic-app,
          #guide-renderer.ytmusic-app,
          ytmusic-guide-renderer,
          #sections.ytmusic-guide-renderer,
          ytmusic-guide-section-renderer,
          #items.ytmusic-guide-section-renderer,
          #divider.ytmusic-guide-section-renderer,
          ytmusic-app-layout.content-scrolled,
          ytmusic-app-layout #background,
          ytmusic-app-layout #guide-background,
          ytmusic-app-layout #player-bar-background,
          ytmusic-app-layout #nav-bar-background:not(.scrolled) {
            background: transparent !important;
            background-color: transparent !important;
            --ytmusic-guide-background: transparent !important;
            --iron-drawer-background-color: transparent !important;
          }
          ytmusic-nav-bar, #nav-bar-divider {
            background: transparent !important;
            border: none !important;
          }
          /* High specificity rules for scrolled state - targeting both to ensure coverage */
          ytmusic-nav-bar.scrolled,
          #nav-bar-background.scrolled,
          ytmusic-nav-bar[opened],
          body[player-page-open] ytmusic-nav-bar,
          body[player-page-open] #nav-bar-background {
            background: rgba(10, 10, 10, 0.4) !important;
            backdrop-filter: blur(25px) !important;
            -webkit-backdrop-filter: blur(25px) !important;
          }
          ytmusic-player-bar {
            background: rgba(0, 0, 0, 0.2) !important;
            backdrop-filter: blur(30px) !important;
            -webkit-backdrop-filter: blur(30px) !important;
            border-top: 1px solid rgba(255, 255, 255, 0.05) !important;
          }
          /* Standardized YTM Glass Buttons (Edit, Menu, Play, etc.) */
          button.ytSpecButtonShapeNextHost,
          yt-button-shape button,
          yt-icon-button#guide-button #button,
          .history-button #button {
            background: rgba(255, 255, 255, 0.15) !important;
            backdrop-filter: blur(12px) !important;
            -webkit-backdrop-filter: blur(12px) !important;
            color: #fff !important;
          }
          /* Play button specific fixes */
          ytmusic-play-button-renderer {
            background: transparent !important;
            --ytmusic-play-button-background-color: transparent !important;
            --ytmusic-play-button-active-background-color: rgba(255, 255, 255, 0.25) !important;
          }
          ytmusic-play-button-renderer .content-wrapper {
            background: rgba(255, 255, 255, 0.15) !important;
            backdrop-filter: blur(12px) !important;
            -webkit-backdrop-filter: blur(12px) !important;
            border-radius: 50% !important;
          }
          ytmusic-play-button-renderer yt-icon,
          ytmusic-play-button-renderer #icon,
          ytmusic-play-button-renderer .icon {
            background: transparent !important;
            background-color: transparent !important;
            color: #fff !important;
            --ytmusic-play-button-icon-color: #fff !important;
          }
          /* Ensure SVGs inside are visible */
          ytmusic-play-button-renderer svg {
            fill: #fff !important;
          }
          ` : ''}
        `);
                } else {
                    // Remove nav-bar var only on YT (not relevant there anyway)
                    document.documentElement.style.removeProperty('--ytmusic-nav-bar-background');
                }

                addDynamicCss(`
          .botones_div {
           background-color: transparent;
           border: none;
           color: #ccc !important;
           user-select: none;
         }
           `);
            }

        }


        // Reverse mode and sidebar CSS (YT only selectors)
        if (!isYTMusic) {
            addDynamicCss(`
        #columns.style-scope.ytd-watch-flexy {
          flex-direction: ${settings.reverseMode ? 'row-reverse' : 'row'} !important;
          padding-left: ${settings.reverseMode ? '20px' : '0'} !important;
          }
          #secondary.style-scope.ytd-watch-flexy {display: ${settings.hideSidebar ? 'none' : 'block'} !important;}
        `);
        }
        addDynamicCss(`
        #icon-menu-settings {
         color: ${settings.iconsColorPicker} !important;
        }
      `);

        checkDarkMode();
        // Apply dynamic CSS once per settings update
        setDynamicCss(dynamicCssArray.join('\n')); // Gộp tất cả CSS trong mảng và tiêm vào trang

        // Apply new features (safe, no heavy loops)
        applyBookmarksIfEnabled(settings);
        setupContinueWatchingFeature(settings.continueWatching);
        if (!isYTMusic) {
            scheduleLikeBarUpdate(settings, 5);
            setupShortsChannelNameFeature(settings.shortsChannelName);
            setupLockupCachedStats();
        }
        checkForVideo();
        downloadDescriptionVideo();
        traductor();

        function checkForVideo() {
            if (!settings.waveVisualizer) {
                cleanup(true); // Limpieza completa
                return;
            }
            const video = $e('video');
            const miniPlayer = $e('.ytp-miniplayer-ui');
            if ((video && document.location.href.includes('watch')) || miniPlayer) {

                // Solo si el video cambió o no está configurado
                if (video !== currentVideo || !isSetup) {
                    cleanup(true); // Limpieza completa antes de crear uno nuevo
                    setupAudioAnalyzer(video);
                } else if (controlPanel && video.paused === false) {
                    showCanvas();
                }
            }
        }



        function downloadDescriptionVideo() {
            if (isYTMusic) return; // YTM has no description row
            if (!window.location.href.includes('youtube.com/watch')) return;
            if ($e('#button_copy_description')) return;

            const containerDescription = $e('#bottom-row.style-scope.ytd-watch-metadata');
            if (!containerDescription) return;

            const buttomHTML = `
        <div id="button_copy_description" style="display: flex; justify-content: end; align-items: center;margin-top: 10px;" >
          <button id="copy-description" title="Copy description" class="botones_div" type="button" style="cursor: pointer;">
            <i style="font-size: 20px;" class="fa-solid fa-copy"></i>
          </button>
        </div>
      `;

            containerDescription.insertAdjacentHTML('beforebegin', safeHTML(buttomHTML));

            $id('copy-description').addEventListener('click', () => {
                const ldJson = [...$m('script[type="application/ld+json"]')];
                for (let script of ldJson) {
                    try {
                        const data = JSON.parse(script.innerText);
                        if (data['@type'] === 'VideoObject') {
                            const description =
                                `📅 Date published: ${data.uploadDate || 'No disponible'}\n` +
                                `Author: ${data.author || 'No disponible'}\n` +
                                `🎬 Name video: ${data.name || 'No disponible'}\n` +
                                `🖼️ Thumbnail: ${Array.isArray(data.thumbnailUrl) ? data.thumbnailUrl.join(', ') : data.thumbnailUrl || 'No disponible'}\n` +
                                `📝 Description: ${data.description || 'No disponible'}\n\n\n` +
                                `🎭 Category: ${data.genre || 'No disponible'}\n`;

                            navigator.clipboard.writeText(description);
                            Notify('success', 'Description copied');
                        }
                    } catch (e) {
                        Notify('error', 'Error parsing JSON-LD');
                    }
                }
            });
        }



        // Biến cờ phải nằm ngoài hàm để không bị reset
        let translatorEventBound = false;

        function traductor() {
            // Chỉ quét những comment chưa có nút dịch (dùng thuộc tính data-translated)
            const texts = document.querySelectorAll('#content-text:not([data-translated])');
            if (texts.length === 0) return;

            const languages = languagesTranslate;
            const idiomaDestino = $id('select-languages-comments-select').value;

            // Tạo sẵn HTML cho dropdown ngôn ngữ để dùng chung
            const optionsHTML = Object.entries(languages)
                .map(([code, name]) => `<option value="${code}" ${code === idiomaDestino ? 'selected' : ''}>${name}</option>`)
                .join('');

            // Gắn nút dịch vào các comment mới
            texts.forEach((texto) => {
                texto.setAttribute('data-translated', 'true'); // Đánh dấu là đã gắn nút
                const controlsHTML = `
				<div class="traductor-container">
					<button class="buttons-tranlate" data-action="translate-comment"> Translate <i class="fa-solid fa-language"></i></button>
					<select class="select-traductor">
					${optionsHTML}
					</select>
				</div>
				`;
                texto.insertAdjacentHTML('afterend', safeHTML(controlsHTML));
            });

            // Áp dụng Event Delegation: Chỉ gắn sự kiện click 1 lần duy nhất lên document
            if (!translatorEventBound) {
                translatorEventBound = true;

                document.addEventListener('click', (e) => {
                    const btn = e.target.closest('.buttons-tranlate[data-action="translate-comment"]');
                    if (!btn) return;

                    const container = btn.closest('.traductor-container');
                    const selectLang = container.querySelector('.select-traductor');
                    const textNode = container.previousElementSibling; // Thẻ #content-text

                    if (!textNode || !selectLang) return;

                    const urlLista = `?client=dict-chrome-ex&sl=auto&tl=${selectLang.value}&q=` + encodeURIComponent(textNode.textContent);

                    btn.innerHTML = safeHTML('Translating... <i class="fa-solid fa-spinner fa-spin"></i>');

                    fetch(apiGoogleTranslate + urlLista)
                        .then((response) => response.json())
                        .then((datos) => {
                            textNode.textContent = datos[0][0];
                            btn.textContent = 'Translated';
                        })
                        .catch((err) => {
                            console.error('Error en la traducción:', err);
                            btn.textContent = 'Error';
                        });
                });
            }
        }


        function limpiarHTML(selector) {
            $m(selector).forEach((button) => button.remove());
        }

        // === CODE TỐI ƯU MỚI THAY THẾ CHO SCROLL EVENT === (YT only)
        if (!isYTMusic) {
            let _commentIO = null;
            let _commentMO = null;
            function initSmartCommentObserver() {
                const commentsContainer = document.querySelector('#comments');
                if (!commentsContainer) return;

                // Disconnect previous observers to avoid duplicates
                if (_commentIO) { try { _commentIO.disconnect(); } catch (e) { } _commentIO = null; }
                if (_commentMO) { try { _commentMO.disconnect(); } catch (e) { } _commentMO = null; }

                _commentIO = new IntersectionObserver((entries) => {
                    if (entries[0].isIntersecting) {

                        _commentMO = new MutationObserver((mutations) => {
                            let shouldUpdate = false;
                            for (let m of mutations) {
                                if (m.addedNodes.length > 0) {
                                    shouldUpdate = true;
                                    break;
                                }
                            }

                            if (shouldUpdate) {
                                window.requestAnimationFrame(() => {
                                    if (settings.avatars) agregarBotonesDescarga();
                                    if (settings.translation) traductor();
                                });
                            }
                        });

                        const commentContents = document.querySelector('ytd-comments #contents');
                        if (commentContents) {
                            _commentMO.observe(commentContents, {
                                childList: true,
                                subtree: true
                            });
                        }

                        _commentIO.disconnect();
                    }
                });

                _commentIO.observe(commentsContainer);
            }

            if (!window.__ytToolsCommentNavBound) {
                window.__ytToolsCommentNavBound = true;
                document.addEventListener('yt-navigate-finish', () => {
                    setTimeout(initSmartCommentObserver, 1500);
                });
            }

            initSmartCommentObserver();
        } // end if (!isYTMusic)
        // === KẾT THÚC CODE TỐI ƯU ===


        // Shorts DOM observer (YT only) – guarded via __ytToolsRuntime.shortsObserver
        if (!isYTMusic) {
            const contentScrollable = $e('.anchored-panel.style-scope.ytd-shorts #contents.style-scope.ytd-item-section-renderer.style-scope.ytd-item-section-renderer');
            if (contentScrollable) {
                // Disconnect previous Shorts observer if it exists
                if (__ytToolsRuntime.shortsObserver) {
                    try { __ytToolsRuntime.shortsObserver.disconnect(); } catch (e) { }
                    __ytToolsRuntime.shortsObserver = null;
                }
                let domTimeout;
                __ytToolsRuntime.shortsObserver = new MutationObserver(() => {
                    if (domTimeout) clearTimeout(domTimeout);
                    domTimeout = setTimeout(() => {
                        insertButtons();
                        addIcon();
                    }, 300);
                });

                __ytToolsRuntime.shortsObserver.observe(contentScrollable, { childList: true, subtree: true });
            }
        } // end if (!isYTMusic) shorts observer

        function agregarBotonesDescarga() {
            const avatars = $m('#author-thumbnail-button #img.style-scope.yt-img-shadow');


            avatars.forEach((img) => {

                if (img.parentElement.querySelector('.yt-image-avatar-download')) return;

                const button = $cl('button');
                button.innerHTML = safeHTML('<i class="fa fa-download"></i>');
                button.classList.add('yt-image-avatar-download');

                button.onclick = async function () {
                    try {
                        const imageUrl = img.src.split('=')[0];
                        const response = await fetch(imageUrl);
                        const blob = await response.blob();
                        const blobUrl = URL.createObjectURL(blob);

                        const parentComment = img.closest('ytd-comment-thread-renderer, ytd-comment-renderer');
                        const nameElement = parentComment?.querySelector('#author-text');
                        let authorName = nameElement ? nameElement.textContent.trim() : 'avatar';
                        authorName = authorName.replace(/[\/\\:*?"<>|]/g, '');

                        const link = $cl('a');
                        link.href = blobUrl;
                        link.download = `${authorName}_avatar.jpg` || 'avatar.jpg';
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);
                        setTimeout(() => URL.revokeObjectURL(blobUrl), 1000); // Đợi 1s cho trình duyệt bắt đầu tải
                    } catch (error) {
                        console.error('Error al descargar la imagen:', error);
                    }
                };

                img.parentElement.style.position = 'relative';
                img.parentElement.appendChild(button);
            });
        }

        const redirectToClassic = () => {
            const videoId = window.location.pathname.split('/').pop();
            const classicUrl = `https://www.youtube.com/watch?v=${videoId}`;
            window.open(classicUrl, '_blank');
            $e('video.video-stream.html5-main-video').pause();
        };

        // Update the Shorts "views" button label (same bar as Classic). Call with viewCount from API/cache.
        function updateShortsViewsButton(videoId, viewCount) {
            const bar = $e('reel-action-bar-view-model');
            if (!bar) return;
            const viewsWrap = bar.querySelector('[data-yt-tools-shorts-views]');
            if (!viewsWrap) return;
            const labelSpan = viewsWrap.querySelector('.yt-spec-button-shape-with-label__label span, [role="text"]');
            if (!labelSpan) return;
            labelSpan.textContent = Number.isFinite(viewCount) && viewCount >= 0 ? FormatterNumber(viewCount, 0) : '—';
        }

        // Update the Shorts "rating" button label (rating 0–5 from API/cache, shown as e.g. "4.9").
        function updateShortsRatingButton(videoId, rating) {
            const bar = $e('reel-action-bar-view-model');
            if (!bar) return;
            const ratingWrap = bar.querySelector('[data-yt-tools-shorts-rating]');
            if (!ratingWrap) return;
            const labelSpan = ratingWrap.querySelector('.yt-spec-button-shape-with-label__label span, [role="text"]');
            if (!labelSpan) return;
            labelSpan.textContent = (Number.isFinite(rating) && rating >= 0 && rating <= 5) ? rating.toFixed(1) : '—';
        }

        // Build one YT-style button for the reel action bar using pure DOM API (Trusted Types safe).
        function createReelBarButton(opts) {
            const wrap = document.createElement('div');
            wrap.className = 'button-view-model ytSpecButtonViewModelHost';
            if (opts.dataAttr) wrap.setAttribute(opts.dataAttr, '1');

            const label = document.createElement('label');
            label.className = 'yt-spec-button-shape-with-label ytSpecButtonShapeWithLabelHost';

            const button = document.createElement('button');
            button.type = 'button';
            button.className = 'yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-l yt-spec-button-shape-next--icon-button ytSpecButtonShapeNextHost ytSpecButtonShapeNextTonal ytSpecButtonShapeNextMono ytSpecButtonShapeNextSizeL ytSpecButtonShapeNextIconButton';
            button.title = opts.title || '';
            button.setAttribute('aria-label', opts.ariaLabel || '');

            const iconDiv = document.createElement('div');
            iconDiv.className = 'yt-spec-button-shape-next__icon';
            iconDiv.setAttribute('aria-hidden', 'true');

            const iconSpan = document.createElement('span');
            iconSpan.className = 'yt-icon-shape ytSpecIconShapeHost';
            // Use safeHTML + temp div to parse SVG (works with Trusted Types)
            if (opts.iconSvg) {
                try {
                    const tempDiv = document.createElement('div');
                    tempDiv.innerHTML = safeHTML(opts.iconSvg);
                    while (tempDiv.firstChild) {
                        iconSpan.appendChild(tempDiv.firstChild);
                    }
                } catch (e) {
                    console.warn('[YT Tools] SVG parse error:', e);
                }
            }
            iconDiv.appendChild(iconSpan);
            button.appendChild(iconDiv);

            const labelDiv = document.createElement('div');
            labelDiv.className = 'yt-spec-button-shape-with-label__label';
            labelDiv.setAttribute('aria-hidden', 'false');

            const labelSpan = document.createElement('span');
            labelSpan.className = 'yt-core-attributed-string yt-core-attributed-string--white-space-pre-wrap yt-core-attributed-string--text-alignment-center yt-core-attributed-string--word-wrapping';
            labelSpan.setAttribute('role', 'text');
            labelSpan.textContent = opts.labelText || '';

            labelDiv.appendChild(labelSpan);
            label.appendChild(button);
            label.appendChild(labelDiv);
            wrap.appendChild(label);

            if (opts.onclick) button.addEventListener('click', opts.onclick);
            return wrap;
        }

        const eyeIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-eye"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" /><path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" /></svg>';
        const classicIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-device-tv"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 9a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v9a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2l0 -9" /><path d="M16 3l-4 4l-4 -4" /></svg>';
        const starIconSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>';

        function insertReelBarButtons() {
            const isShortsPage = document.location.pathname.startsWith('/shorts');
            const bar = $e('reel-action-bar-view-model');
            if (!isShortsPage || !bar) {
                document.querySelectorAll('[data-yt-tools-shorts-classic], [data-yt-tools-shorts-views], [data-yt-tools-shorts-rating]').forEach(el => el.remove());
                return;
            }
            if (bar.querySelector('[data-yt-tools-shorts-classic]')) return;

            const classicBtn = createReelBarButton({
                dataAttr: 'data-yt-tools-shorts-classic',
                title: 'Classic mode',
                ariaLabel: 'Chế độ cổ điển',
                iconSvg: classicIconSvg,
                labelText: '',
                onclick: redirectToClassic,
            });
            const viewsBtn = createReelBarButton({
                dataAttr: 'data-yt-tools-shorts-views',
                title: 'Vistas',
                ariaLabel: 'Vistas',
                iconSvg: eyeIconSvg,
                labelText: '—',
                onclick: function () { },
            });
            const ratingBtn = createReelBarButton({
                dataAttr: 'data-yt-tools-shorts-rating',
                title: 'Rating (likes/dislikes)',
                ariaLabel: 'Rating',
                iconSvg: starIconSvg,
                labelText: '—',
                onclick: function () { },
            });

            bar.insertBefore(ratingBtn, bar.firstChild);
            bar.insertBefore(viewsBtn, bar.firstChild);
            bar.insertBefore(classicBtn, bar.firstChild);

            const videoId = (document.location.pathname.split('/').filter(Boolean))[1];
            if (videoId) {
                const persisted = getLikesDislikesFromPersistedCache(videoId);
                if (persisted && persisted.viewCount != null) updateShortsViewsButton(videoId, persisted.viewCount);
                if (persisted && persisted.rating != null) updateShortsRatingButton(videoId, persisted.rating);
            }
            __ytToolsRuntime.updateShortsViewsButton = updateShortsViewsButton;
            __ytToolsRuntime.updateShortsRatingButton = updateShortsRatingButton;
        }

        const insertButtons = () => {
            insertReelBarButtons();
        };

        const targetNode = $e('body');

        if (targetNode != undefined && !isYTMusic) {
            const element = $e('ytd-item-section-renderer[static-comments-header] #contents');
            if (element != undefined && settings.theme !== 'custom') {
                const observerElementDom = (elem) => {
                    const observer = new IntersectionObserver(entries => {

                        if (entries[0].isIntersecting) {

                            element.style.background = `${selectedTheme.gradient ?? ''}`;
                        } else {
                            return
                        }
                    })

                    return observer.observe($e(`${elem}`))

                }
                observerElementDom('ytd-item-section-renderer[static-comments-header] #contents')
            }
        }

        // Stats

        function formatTime(seconds) {
            if (isNaN(seconds)) return '0h 0m 0s';
            seconds = Math.floor(seconds);
            const h = Math.floor(seconds / 3600);
            const m = Math.floor((seconds % 3600) / 60);
            const s = seconds % 60;
            return `${h}h ${m}m ${s}s`;
        }

        function updateUI() {
            $id('total-time').textContent = formatTime(usageTime);
            $id('video-time').textContent = formatTime(videoTime);
            $id('shorts-time').textContent = formatTime(shortsTime);

            const maxTime = 86400; // 24 hours
            $id('usage-bar').style.width =
                `${(usageTime / maxTime) * 100}%`;
            $id('video-bar').style.width =
                `${(videoTime / maxTime) * 100}%`;
            $id('shorts-bar').style.width =
                `${(shortsTime / maxTime) * 100}%`;
        }

        function detectContentType(videoElement) {
            if (/\/shorts\//.test(window.location.pathname)) return 'shorts';

            let parent = videoElement;
            while ((parent = parent.parentElement) !== null) {
                if (parent.classList.contains('shorts-container') ||
                    parent.classList.contains('reel-video') ||
                    parent.tagName === 'YTD-REEL-VIDEO-RENDERER') {
                    return 'shorts';
                }
            }


            if (videoElement.closest('ytd-watch-flexy') ||
                videoElement.closest('#primary-inner')) {
                return 'video';
            }
            if (videoElement.closest('ytd-thumbnail') ||
                videoElement.closest('ytd-rich-item-renderer')) {
                return 'video';
            }

            return null;
        }

        function findActiveVideo() {
            const videos = $m('video');
            for (const video of videos) {
                if (!video.paused && !video.ended && video.readyState > 2) {
                    return video;
                }
            }
            return null;
        }

        function updateCanvasSize() {
            if (canvas) {
                canvas.width = window.innerWidth;
                canvas.height = canvasHeight;
            }
        }

        function onWaveStyleChange(e) {
            waveStyle = e.target.value;
            const selectAppend = $id('select-wave-visualizer-select');
            if (selectAppend) selectAppend.value = e.target.value;
            saveSettings();
        }

        function cleanup(fullCleanup = false) {
            if (fullCleanup && animationId) {
                cancelAnimationFrame(animationId);
                animationId = null;
            }
            if (currentVideo) {
                currentVideo.removeEventListener('play', showCanvas);
                currentVideo.removeEventListener('pause', hideCanvas);
                currentVideo.removeEventListener('ended', hideCanvas);
            }
            if (fullCleanup) {
                if (canvas && canvas.parentNode) {
                    canvas.parentNode.removeChild(canvas);
                    canvas = null;
                    ctx = null;
                }
                if (controlPanel && controlPanel.parentNode) {
                    controlPanel.parentNode.removeChild(controlPanel);
                    controlPanel = null;
                }
                if (source) {
                    try {
                        source.disconnect();
                        // Reconnect source directly to destination to keep audio playing
                        // (createMediaElementSource routes ALL audio through Web Audio API)
                        if (audioCtx && audioCtx.state !== 'closed') {
                            source.connect(audioCtx.destination);
                        }
                    } catch (err) { }
                    // Don't null source — cached on video.__ytToolsAudioSource for reuse
                }
                // Keep audioCtx running — source is connected to destination for audio passthrough
                if (currentVideo && currentVideo[PROCESSED_FLAG]) {
                    delete currentVideo[PROCESSED_FLAG];
                }
                currentVideo = null;
                isSetup = false;

                window.removeEventListener('resize', updateCanvasSize);
                const selectAppend = $id('select-wave-visualizer-select');
                if (selectAppend) selectAppend.removeEventListener('change', onWaveStyleChange);
            } else {
                if (canvas) canvas.style.opacity = '0';
                if (controlPanel) controlPanel.style.opacity = '0';
            }
        }



        function createCanvasOverlay() {
            if (canvas) return;
            const parent = document.body;
            canvas = document.createElement('canvas');
            canvas.id = 'wave-visualizer-canvas';
            canvas.width = window.innerWidth;
            canvas.height = canvasHeight;
            canvas.style.position = 'fixed';
            canvas.style.left = '0';
            canvas.style.top = '0';
            canvas.style.width = '100%';
            canvas.style.pointerEvents = 'none';
            canvas.style.backgroundColor = 'transparent';
            canvas.style.zIndex = '10000';
            canvas.style.opacity = '0';
            canvas.style.transition = 'opacity 0.3s';

            parent.appendChild(canvas);
            ctx = canvas.getContext('2d');
        }


        function createControlPanelWave() {
            if (controlPanel) return;

            controlPanel = $cl('div');
            controlPanel.id = 'wave-visualizer-control';
            const selectAppend = $id('select-wave-visualizer-select');
            waveStyle = settings.waveVisualizerSelected;

            if (selectAppend) {
                selectAppend.removeEventListener('change', onWaveStyleChange);
                selectAppend.addEventListener('change', onWaveStyleChange);
            }
        }



        // setting Audio y Analyser
        function setupAudioAnalyzer(video) {
            if (!video || video[PROCESSED_FLAG]) return;
            video[PROCESSED_FLAG] = true;
            cleanup(false);
            currentVideo = video;
            createCanvasOverlay();
            createControlPanelWave();

            // Reuse existing AudioContext if possible (suspend/resume pattern)
            if (!audioCtx || audioCtx.state === 'closed') {
                const AudioContext = window.AudioContext || window.webkitAudioContext;
                audioCtx = new AudioContext();
            } else if (audioCtx.state === 'suspended') {
                audioCtx.resume();
            }

            analyser = audioCtx.createAnalyser();
            analyser.fftSize = 2048;
            analyser.smoothingTimeConstant = 0.85;
            bufferLength = analyser.fftSize;
            dataArray = new Uint8Array(bufferLength);
            smoothedData = new Array(bufferLength).fill(128);

            try {
                // Reuse cached source if video already has one (createMediaElementSource is one-shot per element)
                if (video.__ytToolsAudioSource) {
                    source = video.__ytToolsAudioSource;
                    try { source.disconnect(); } catch (e) { }
                } else {
                    source = audioCtx.createMediaElementSource(video);
                    video.__ytToolsAudioSource = source;
                }
                source.connect(analyser);
                analyser.connect(audioCtx.destination);
            } catch (e) {
                Notify('error', "MediaElementSource or error:", e);
                cleanup(true);
                return;
            }

            video.removeEventListener('play', showCanvas);
            video.removeEventListener('pause', hideCanvas);
            video.removeEventListener('ended', hideCanvas);

            video.addEventListener('play', showCanvas);
            video.addEventListener('pause', hideCanvas);
            video.addEventListener('ended', hideCanvas);

            window.removeEventListener('resize', updateCanvasSize);
            window.addEventListener('resize', updateCanvasSize);

            draw();
            isSetup = true;
        }

        function draw() {
            animationId = requestAnimationFrame(draw);

            if (parseFloat(canvas.style.opacity) <= 0) return;

            analyser.getByteTimeDomainData(dataArray);
            for (let i = 0; i < bufferLength; i++) {
                smoothedData[i] += smoothingFactor * (dataArray[i] - smoothedData[i]);
            }
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            let sliceWidth = canvas.width / bufferLength;

            switch (waveStyle) {

                case 'linea': {
                    ctx.lineWidth = 2;
                    ctx.strokeStyle = 'lime';
                    ctx.beginPath();
                    let x = 0;
                    for (let i = 0; i < bufferLength; i++) {
                        let amplitude = Math.max(0, smoothedData[i] - 128) * scale;
                        if (i === 0) ctx.moveTo(x, amplitude);
                        else ctx.lineTo(x, amplitude);
                        x += sliceWidth;
                    }
                    ctx.stroke();
                    break;
                }
                case 'barras': {
                    let x = 0;
                    for (let i = 0; i < bufferLength; i += 5) {
                        let amplitude = Math.max(0, smoothedData[i] - 128) * scale;
                        ctx.fillStyle = 'cyan';
                        ctx.fillRect(x, 0, sliceWidth * 4, amplitude);
                        x += sliceWidth * 5;
                    }
                    break;
                }
                case 'curva': {
                    ctx.lineWidth = 2;
                    ctx.strokeStyle = 'yellow';
                    ctx.beginPath();
                    ctx.moveTo(0, Math.max(0, smoothedData[0] - 128) * scale);
                    for (let i = 0; i < bufferLength - 1; i++) {
                        let x0 = i * sliceWidth;
                        let x1 = (i + 1) * sliceWidth;
                        let y0 = Math.max(0, smoothedData[i] - 128) * scale;
                        let y1 = Math.max(0, smoothedData[i + 1] - 128) * scale;
                        let cp1x = x0 + sliceWidth / 3;
                        let cp1y = y0;
                        let cp2x = x1 - sliceWidth / 3;
                        let cp2y = y1;
                        ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x1, y1);
                    }
                    ctx.stroke();
                    break;
                }
                case 'picos': {
                    ctx.fillStyle = 'magenta';
                    let x = 0;
                    for (let i = 0; i < bufferLength; i += 5) {
                        let amplitude = Math.max(0, smoothedData[i] - 128) * scale;
                        ctx.beginPath();
                        ctx.arc(x, amplitude, 2, 0, Math.PI * 2);
                        ctx.fill();
                        x += sliceWidth * 5;
                    }
                    break;
                }
                case 'solida': {
                    ctx.beginPath();
                    let x = 0;
                    ctx.moveTo(0, 0);
                    for (let i = 0; i < bufferLength; i++) {
                        let amplitude = Math.max(0, smoothedData[i] - 128) * scale;
                        ctx.lineTo(x, amplitude);
                        x += sliceWidth;
                    }
                    ctx.lineTo(canvas.width, 0);
                    ctx.closePath();
                    ctx.fillStyle = 'rgba(0,255,0,0.3)';
                    ctx.fill();
                    break;
                }
                case 'dinamica': {
                    let gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
                    gradient.addColorStop(0, 'red');
                    gradient.addColorStop(0.5, 'purple');
                    gradient.addColorStop(1, 'blue');
                    ctx.lineWidth = 3;
                    ctx.strokeStyle = gradient;
                    ctx.beginPath();
                    let x = 0;
                    for (let i = 0; i < bufferLength; i++) {
                        let amplitude = Math.max(0, smoothedData[i] - 128) * scale;
                        if (i === 0) ctx.moveTo(x, amplitude);
                        else ctx.lineTo(x, amplitude);
                        x += sliceWidth;
                    }
                    ctx.stroke();
                    break;
                }
                case 'montana': {
                    ctx.beginPath();
                    let x = 0;
                    ctx.moveTo(0, 0);
                    for (let i = 0; i < bufferLength; i++) {
                        let amp = (smoothedData[i] - 128) * scale * 0.8;
                        ctx.lineTo(x, amp);
                        x += sliceWidth;
                    }
                    ctx.lineTo(canvas.width, 0);
                    ctx.closePath();
                    ctx.fillStyle = 'rgba(128,128,255,0.4)';
                    ctx.fill();
                    break;
                }

                default:
                    break;
            }
        }

        // Sử dụng các API sự kiện có sẵn của YouTube để tránh dùng MutationObserver
        // (chỉ gắn 1 lần, tránh leak khi applySettings chạy lại)
        if (!window.__ytToolsPageDataBound && !isYTMusic) {
            window.__ytToolsPageDataBound = true;
            document.addEventListener('yt-page-data-updated', () => {
                requestAnimationFrame(() => {
                    if (window.location.pathname.startsWith('/shorts')) {
                        insertButtons();
                    }
                    addIcon();
                });
            });
        }

        // Cập nhật thống kê thời gian xem định kỳ mà không cần MutationObserver
        // GM_setValue chỉ gọi mỗi 30 giây để giảm I/O, UI vẫn cập nhật mỗi 1 giây
        if (!__ytToolsRuntime.statsIntervalId) {
            let __lastStatsSave = 0;
            __ytToolsRuntime.statsIntervalId = setInterval(() => {
                const now = Date.now();
                const delta = (now - lastUpdate) / 1000;

                const isVisible = document.visibilityState === 'visible';
                if (isVisible) {
                    usageTime += delta;
                }

                // Only do DOM query when tab is visible
                if (isVisible) {
                    const activeVideoEl = document.querySelector('video.video-stream');
                    if (activeVideoEl && !activeVideoEl.paused && !activeVideoEl.ended) {
                        const type = window.location.pathname.startsWith('/shorts') ? 'shorts' : 'video';
                        if (type === 'video') videoTime += delta;
                        else shortsTime += delta;
                    }
                }

                lastUpdate = now;
                // Chỉ lưu vào GM storage mỗi 30 giây để giảm I/O
                if (now - __lastStatsSave >= 30000) {
                    __lastStatsSave = now;
                    GM_setValue(STORAGE.USAGE, usageTime);
                    GM_setValue(STORAGE.VIDEO, videoTime);
                    GM_setValue(STORAGE.SHORTS, shortsTime);
                }
                if (isVisible && $id('stats')?.classList?.contains('active')) updateUI();
            }, 2000); // Reduced from 1s to 2s — UI still feels responsive
            // Lưu ngay khi user rời trang
            window.addEventListener('pagehide', () => {
                GM_setValue(STORAGE.USAGE, usageTime);
                GM_setValue(STORAGE.VIDEO, videoTime);
                GM_setValue(STORAGE.SHORTS, shortsTime);
            }, { capture: true });
        }

        // Chạy lần đầu tiên cho Shorts nếu đang ở trang Shorts
        if (!isYTMusic && window.location.pathname.startsWith('/shorts')) {
            insertButtons();
        }
        // --- KẾT THÚC GLOBAL OBSERVER ---

        checkForVideo(); // retry: video element may not exist at first call (line ~5228)

        // [REMOVED] Duplicate stats interval was here — already handled above (line ~5924).



        updateUI();

        // end stats
        if (__ytToolsRuntime.settingsLoaded) {
            saveSettings();
        }

    }


    // Build YTM toolbar using pure DOM API (bypasses Trusted Types)

    const UPDATE_INTERVAL = 1000;
    const STORAGE = {
        USAGE: 'YT_TOTAL_USAGE',
        VIDEO: 'YT_VIDEO_TIME',
        SHORTS: 'YT_SHORTS_TIME'
    };

    let usageTime = GM_getValue(STORAGE.USAGE, 0);
    let videoTime = GM_getValue(STORAGE.VIDEO, 0);
    let shortsTime = GM_getValue(STORAGE.SHORTS, 0);
    let lastUpdate = Date.now();
    let activeVideo = null;
    let activeType = null;

    // Inicializar almacenamiento
    GM_setValue(STORAGE.USAGE, usageTime);
    GM_setValue(STORAGE.VIDEO, videoTime);
    GM_setValue(STORAGE.SHORTS, shortsTime);


    console.log('Script en ejecución by: Akari');
    const HEADER_STYLE = 'color: #F00; font-size: 24px; font-family: sans-serif;';
    const MESSAGE_STYLE = 'color: #00aaff; font-size: 16px; font-family: sans-serif;';
    const CODE_STYLE = 'font-size: 14px; font-family: monospace;';

    console.log(
        `%cYoutube Ultimate Tools (v${GM_info.script.version})\n` +
        '%cDeveloped by Akari\n' +
        '%c(Based on MDCM & nvbangg)',
        HEADER_STYLE,
        CODE_STYLE,
        MESSAGE_STYLE
    );

    const currentVersion = GM_info.script.version;
    if (!localStorage.getItem('notification-Akari-' + currentVersion)) {
        Notify('info', 'Youtube Ultimate Tools by: Akari (v' + currentVersion + ')');
        localStorage.setItem('notification-Akari-' + currentVersion, true);
    }



    // Add event listeners to all inputs
    const inputs = panel.querySelectorAll('input');
    inputs.forEach((input) => {
        input.addEventListener('change', () => {
            try {
                saveSettings();
            } catch (e) {
                console.error('saveSettings error:', e);
            }
            scheduleApplySettings();
        });
        if (input.type === 'range') {
            input.addEventListener('input', () => {
                updateSliderValues();
            });
        }
    });

    // Some settings are controlled by <select> elements; ensure they persist and apply without duplicating listeners.
    function bindSelectOnce(id) {
        const el = $id(id);
        if (!el) return;
        if (el.dataset.ytToolsBound === '1') return;
        el.dataset.ytToolsBound = '1';
        el.addEventListener('change', () => {
            // Persist immediately
            try {
                saveSettings();
            } catch (e) {
                console.error('saveSettings error:', e);
            }
            // Apply with debounce
            scheduleApplySettings();
        });
    }

    bindSelectOnce('select-video-qualitys-select');
    bindSelectOnce('select-languages-comments-select');
    bindSelectOnce('select-wave-visualizer-select');

    // Export configuration

    //   Settings saved
    //   const settings = GM_getValue(SETTINGS_KEY, '{}');
    //   $id('config-data').value = settings;

    $id('export-config').addEventListener('click', () => {
        const settings = GM_getValue(SETTINGS_KEY, '{}');
        $id('config-data').value = settings;
        const configData = settings;
        try {
            JSON.parse(configData); // Validate JSON
            GM_setValue(SETTINGS_KEY, configData);
            setTimeout(() => {
                Notify('success', 'Configuration export successfully!');
            }, 1000);
        } catch (e) {
            Notify('error', 'Invalid configuration data. Please check and try again.');
        }
    });
    // Import configuration
    $id('import-config').addEventListener('click', () => {
        const configData = $id('config-data').value;
        try {
            JSON.parse(configData); // Validate JSON
            GM_setValue(SETTINGS_KEY, configData);
            setTimeout(() => {
                Notify('success', 'Configuration imported successfully!');
                window.location.reload();
            }, 1000);
            // window.location.reload(); // removed: duplicate (setTimeout above already reloads)
        } catch (e) {
            Notify('error', 'Invalid configuration data. Please check and try again.');
        }
    });
    panel.style.display = 'none';

    // var for wave

    // Load saved settings
    // Visible element DOM
    function checkElement(selector, callback, maxAttempts = 100) {
        let attempts = 0;
        const interval = setInterval(() => {
            if ($e(selector)) {
                clearInterval(interval);
                callback();
            } else {
                attempts++;
                if (attempts >= maxAttempts) {
                    clearInterval(interval);
                    console.warn(`[Youtube Tools] Không tìm thấy element: ${selector}`);
                }
            }
        }, 100);
    }

    const checkActiveWave = $id('wave-visualizer-toggle');
    if (checkActiveWave) {
        checkActiveWave.addEventListener('change', () => {
            const waveVisualizer = $e('#wave-visualizer-toggle');
            if (waveVisualizer.checked) {
                Notify('success', 'Wave visualizer enabled');
                saveSettings();
                scheduleApplySettings();
            } else {
                // Soft cleanup: hide canvas + stop animation, but keep AudioContext alive
                // (createMediaElementSource can only bind once per video element)
                if (animationId) {
                    cancelAnimationFrame(animationId);
                    animationId = null;
                }
                hideCanvas();
                saveSettings();
                Notify('success', 'Wave visualizer disabled');
            }
        });
    }

    const checkAudioOnlyTabToggle = $id('audio-only-tab-toggle');
    if (checkAudioOnlyTabToggle) {
        checkAudioOnlyTabToggle.addEventListener('change', () => {
            const defaultEnabled = $id('audio-only-toggle') ? $id('audio-only-toggle').checked : false;
            setAudioOnlyTabOverride(checkAudioOnlyTabToggle.checked, defaultEnabled);
            const settings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
            syncAudioOnlyTabCheckbox({
                ...settings,
                audioOnly: defaultEnabled
            });
            Notify('success', checkAudioOnlyTabToggle.checked ? 'Audio-only enabled for this tab' : 'Audio-only disabled for this tab');
            scheduleApplySettings();
        });
    }

    const checkAudioOnlyToggle = $id('audio-only-toggle');
    if (checkAudioOnlyToggle) {
        checkAudioOnlyToggle.addEventListener('change', () => {
            const settings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
            syncAudioOnlyTabCheckbox({
                ...settings,
                audioOnly: checkAudioOnlyToggle.checked
            });
            Notify('success', checkAudioOnlyToggle.checked ? 'Audio-only mode enabled' : 'Audio-only mode disabled');
        });
    }

    const checkNonstopPlaybackToggle = $id('nonstop-playback-toggle');
    if (checkNonstopPlaybackToggle) {
        checkNonstopPlaybackToggle.addEventListener('change', () => {
            Notify('success', checkNonstopPlaybackToggle.checked ? 'Nonstop playback enabled' : 'Nonstop playback disabled');
        });
    }

    // Themes toggle event listener (auto-disable ambient in YTM if themes are turned on)
    const checkThemesToggle = $id('themes-toggle');
    if (checkThemesToggle) {
        checkThemesToggle.addEventListener('change', () => {
            if (isYTMusic && checkThemesToggle.checked) {
                const cinematicToggle = $id('cinematic-lighting-toggle');
                if (cinematicToggle && cinematicToggle.checked) {
                    cinematicToggle.checked = false;
                    try { saveSettings(); } catch (e) { }
                    scheduleApplySettings();
                }
            }
        });
    }

    // Cinematic/Ambient lighting toggle event listener
    const checkCinematicLighting = $id('cinematic-lighting-toggle');
    if (checkCinematicLighting) {
        checkCinematicLighting.addEventListener('change', () => {
            const cinematicToggle = $e('#cinematic-lighting-toggle');
            const syncToggle = $e('#sync-cinematic-toggle');
            const cinematicDiv = $id('cinematics');

            if (cinematicToggle.checked) {
                Notify('success', isYTMusic ? 'Ambient mode enabled' : 'Cinematic mode enabled');
            } else {
                Notify('success', isYTMusic ? 'Ambient mode disabled' : 'Cinematic mode disabled');
            }

            if (isYTMusic) {
                // YTM: use custom ambient mode
                if (cinematicToggle.checked) {
                    // Auto-disable theme when ambient is ON (they conflict)
                    const themesToggle = $id('themes-toggle');
                    if (themesToggle && themesToggle.checked) {
                        themesToggle.checked = false;
                        try { saveSettings(); } catch (e) { }
                        scheduleApplySettings();
                    }
                    ytmAmbientMode.show();
                } else {
                    ytmAmbientMode.destroy();
                }
            } else {
                // YT: use cinematic lighting
                if (syncToggle.checked) {
                    setTimeout(() => {
                        toggleCinematicLighting();
                    }, 300);
                } else {
                    if (cinematicDiv) {
                        cinematicDiv.style.display = cinematicToggle.checked ? 'block' : 'none';
                    }
                }
            }
        });
    }

    // Sync cinematic toggle event listener
    const checkSyncCinematic = $id('sync-cinematic-toggle');
    if (checkSyncCinematic) {
        checkSyncCinematic.addEventListener('change', () => {
            const syncToggle = $e('#sync-cinematic-toggle');
            const cinematicToggle = $e('#cinematic-lighting-toggle');
            const cinematicDiv = $id('cinematics');

            if (syncToggle.checked) {
                Notify('success', 'Sync with YouTube enabled');
                // Si se activa la sincronización y el modo cinematic está activado, sincronizar con YouTube
                if (cinematicToggle.checked) {
                    setTimeout(() => {
                        toggleCinematicLighting();
                    }, 500);
                }
            } else {
                Notify('success', 'Sync with YouTube disabled');
                // Si se desactiva la sincronización, aplicar inmediatamente el estado del toggle
                if (cinematicDiv) {
                    cinematicDiv.style.display = cinematicToggle.checked ? 'block' : 'none';
                }
            }
        });
    }

    // Side Panel Style listener
    const checkSidePanelStyle = $id('side-panel-style-select');
    if (checkSidePanelStyle) {
        checkSidePanelStyle.addEventListener('change', () => {
            saveSettings();
            scheduleApplySettings();
        });
    }

    // Custom Timeline Color listener
    const checkCustomTimeline = $id('custom-timeline-color-toggle');
    if (checkCustomTimeline) {
        checkCustomTimeline.addEventListener('change', () => {
            saveSettings();
            scheduleApplySettings();
        });
    }

    // Use the correct selector depending on YouTube vs YouTube Music
    const topBarSelector = isYTMusic ? '#right-content' : 'ytd-topbar-menu-button-renderer';
    checkElement(topBarSelector, () => {
        addIcon(); // ensure gear icon is created now that topbar exists
        loadSettings();
        initializeHeaderButtons();
        setTimeout(checkNewVersion, 3000);
    });
    // validate change url SPA youtube

    document.addEventListener('fullscreenchange', () => {
        if (document.fullscreenElement !== null) {
            hideCanvas();
        } else {
            showCanvas();
        }
    });

    // Wave retry: poll for <video> element after SPA navigation to a watch page
    function retryWaveSetupAfterNav() {
        const settings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
        if (!settings.waveVisualizer) return;
        if (!document.location.href.includes('watch')) return;

        let waveRetries = 0;
        const maxWaveRetries = 20; // up to 10 seconds
        const waveRetryInterval = setInterval(() => {
            waveRetries++;
            const video = $e('video');
            if (video && !video.paused) {
                clearInterval(waveRetryInterval);
                // Only set up if not already set up for this video
                if (video !== currentVideo || !isSetup) {
                    if (typeof cleanup === 'function') {
                        // cleanup is scoped inside applySettings, so call scheduleApplySettings
                        // which will trigger checkForVideo
                        scheduleApplySettings();
                    }
                }
                return;
            }
            if (video && video.paused) {
                // Wait for play event
                const onPlay = () => {
                    video.removeEventListener('play', onPlay);
                    clearInterval(waveRetryInterval);
                    if (video !== currentVideo || !isSetup) {
                        scheduleApplySettings();
                    }
                };
                video.addEventListener('play', onPlay, { once: true });
                clearInterval(waveRetryInterval);
                return;
            }
            if (waveRetries >= maxWaveRetries) {
                clearInterval(waveRetryInterval);
            }
        }, 500);
    }

    document.addEventListener('yt-navigate-finish', () => {
        // Re-inject gear icon if it was lost during navigation
        if (typeof addIcon === 'function') {
            addIcon();
        }

        if (!document.location.href.includes('watch')) {
            hideCanvas();
        }
        scheduleApplySettings();

        // Retry wave setup after SPA navigation (video may not be ready yet)
        retryWaveSetupAfterNav();

        const isYTSite = document.location.href.includes('youtube.com');
        if (!isYTSite) return;

        if (isYTMusic) {
            // On YTM, re-enable button injection when navigating to a new song
            if (document.location.href.includes('watch')) {
                const existingContainer = $e('.yt-tools-container');
                if (existingContainer) existingContainer.remove();
                validoBotones = true;
                setTimeout(() => renderizarButtons(), 500);

                // Re-initialize ambient mode for the new video (if enabled)
                const savedSettings = JSON.parse(GM_getValue(SETTINGS_KEY, '{}'));
                if (savedSettings.cinematicLighting) {
                    ytmAmbientMode.cleanup();
                    setTimeout(() => ytmAmbientMode.setup(), 1000);
                }
            } else {
                // Not on a watch page, cleanup ambient mode
                ytmAmbientMode.cleanup();
            }
        } else {
            // Re-inject lockup stats (reduced passes to save CPU)
            if (document.location.href.includes('youtube.com/watch')) {
                [400, 1500].forEach((ms) => setTimeout(() => {
                    injectLockupCachedStats();
                    injectShortsLockupCachedStats();
                    retargetLockupStatsObserverIfNeeded();
                }, ms));
            } else {
                // Re-inject when landing on home
                [400, 1800].forEach((ms) => setTimeout(() => {
                    injectLockupCachedStats();
                    injectShortsLockupCachedStats();
                }, ms));
            }
        }
    });
    GM_registerMenuCommand('Update Script by: Akari', function () {
        window.open('https://update.greasyfork.org/scripts/576162/YouTube%20Ultimate%20Tools.user.js', '_blank');
    });

    // apis for download
    // https://video-download-api.com
    // 4kdownload


    let ytmScrollListenerInited = false;
    let ytmScrollInitAttempts = 0;
    function initYTMHeaderScroll() {
        if (!isYTMusic || ytmScrollListenerInited) return;
        const navBar = document.querySelector('ytmusic-nav-bar');

        if (!navBar) {
            if (ytmScrollInitAttempts < 10) {
                ytmScrollInitAttempts++;
                setTimeout(initYTMHeaderScroll, 500);
            }
            return;
        }
        ytmScrollListenerInited = true;

        const updateHeader = () => {
            const isScrolled = window.scrollY > 10;
            const isWatchPage = window.location.pathname.startsWith('/watch');
            const isPlayerOpen = document.body.hasAttribute('player-page-open') ||
                navBar.hasAttribute('opened') ||
                isWatchPage;

            const navBarBg = document.querySelector('#nav-bar-background');
            if (isScrolled || isPlayerOpen) {
                navBar.classList.add('scrolled');
                if (navBarBg) navBarBg.classList.add('scrolled');
            } else {
                navBar.classList.remove('scrolled');
                if (navBarBg) navBarBg.classList.remove('scrolled');
            }
        };

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

        // Initial checks to ensure it catches the state on load/refresh
        updateHeader();
        setTimeout(updateHeader, 500);
        setTimeout(updateHeader, 2000);

        // Observe state changes
        const observer = new MutationObserver(updateHeader);
        observer.observe(document.body, { attributes: true, attributeFilter: ['player-page-open'] });
        observer.observe(navBar, { attributes: true, attributeFilter: ['opened'] });
    }

    function applyPageBackground(url, themeColor = null) {
        const isYTMusic = window.location.hostname === 'music.youtube.com';
        const selector = isYTMusic ? 'body, ytmusic-app' : 'ytd-app, body';
        const styleId = 'yt-tools-page-background';
        let styleEl = $id(styleId);

        if (!styleEl) {
            styleEl = document.createElement('style');
            styleEl.id = styleId;
            document.head.appendChild(styleEl);
        }

        if (url) {
            const overlayColor = themeColor || 'rgba(0,0,0,0.5)';
            styleEl.textContent = `
      ${selector} {
        background: transparent !important;
        background-color: transparent !important;
      }
      /* Layer 1: Blurred Background Image */
      body::before {
        content: "" !important;
        position: fixed !important;
        top: -10px !important;
        left: -10px !important;
        width: calc(100% + 20px) !important;
        height: calc(100% + 20px) !important;
        background-image: url("${url}") !important;
        background-size: cover !important;
        background-position: center !important;
        background-attachment: fixed !important;
        background-repeat: no-repeat !important;
        filter: blur(8px) brightness(0.8) !important;
        z-index: -3 !important;
        pointer-events: none !important;
      }
      /* Layer 2: Theme Overlay (Semi-transparent) */
      body::after {
        content: "" !important;
        position: fixed !important;
        top: 0 !important;
        left: 0 !important;
        width: 100% !important;
        height: 100% !important;
        background: ${themeColor ? themeColor : 'rgba(0,0,0,0.5)'} !important;
        opacity: ${themeColor ? '0.6' : '1'} !important;
        z-index: -2 !important;
        pointer-events: none !important;
      }
      ${isYTMusic ? `
      /* YTM: Elevate content above blur layers */
      ytmusic-app {
        position: relative !important;
        z-index: 3 !important;
      }
      ` : ''}
      #content.ytmusic-app,
      #page-manager.ytd-app,
      #columns.ytd-watch-flexy,
      ytd-browse,
      ytmusic-browse-response,
      ytmusic-section-list-renderer,
      ytmusic-shelf-renderer,
      ytmusic-grid-renderer,
      ytmusic-player-page,
      ytmusic-app-layout,
      ytmusic-guide-renderer,
      tp-yt-app-drawer,
      tp-yt-app-drawer #contentContainer,
      tp-yt-app-drawer #contentContainer.tp-yt-app-drawer,
      #mini-guide,
      #mini-guide-renderer,
      #guide-wrapper,
      #guide-content,
      #guide-spacer,
      #guide-renderer,
      #sections.ytmusic-guide-renderer,
      ytmusic-guide-section-renderer,
      ytmusic-guide-entry-renderer,
      tp-yt-paper-item.ytmusic-guide-entry-renderer,
      #items.ytmusic-guide-section-renderer,
      #divider.ytmusic-guide-section-renderer,
      ytmusic-app-layout.content-scrolled,
      ytmusic-app-layout #background,
      ytmusic-app-layout #guide-background,
      ytmusic-app-layout #player-bar-background,
      ytmusic-app-layout #nav-bar-background,
      #contents.ytmusic-section-list-renderer,
      #header.ytmusic-browse-response,
      #guide-wrapper.ytmusic-guide-renderer,
      ytmusic-responsive-header-renderer,
      .background-gradient.ytmusic-browse-response,
      #content-wrapper.ytmusic-browse-response,
      ytmusic-carousel-shelf-renderer,
      .ytmusic-shelf,
      ytmusic-chip-cloud-renderer,
      ytmusic-carousel-shelf-basic-header-renderer,
      ytmusic-header-renderer,
      ytmusic-tabbed-browse-renderer,
      ytmusic-detail-header-renderer,
      ytmusic-item-section-renderer,
      ytmusic-immersive-header-renderer,
      ytmusic-card-shelf-renderer {
        background: transparent !important;
        background-color: transparent !important;
        background-image: none !important;
        --ytmusic-background: transparent !important;
        --ytmusic-general-background: transparent !important;
        --ytmusic-guide-background: transparent !important;
        --iron-drawer-background-color: transparent !important;
        --yt-spec-general-background-a: transparent !important;
        --yt-spec-general-background-b: transparent !important;
        --yt-spec-general-background-c: transparent !important;
        --yt-spec-menu-background: transparent !important;
      }
      ${isYTMusic ? `
      /* YTM Nav Bar: transparent at top, dark blurred when scrolled */
      body.ytm-style-transparent #nav-bar-background.ytmusic-app-layout,
      body.ytm-ambient-active #nav-bar-background.ytmusic-app-layout {
        background: transparent !important;
        transition: background 0.3s ease, backdrop-filter 0.3s ease !important;
      }
      body.ytm-style-transparent ytmusic-nav-bar,
      body.ytm-ambient-active ytmusic-nav-bar,
      body.ytm-style-transparent #nav-bar-divider,
      body.ytm-ambient-active #nav-bar-divider {
        background: transparent !important;
        border: none !important;
        transition: background 0.3s ease !important;
      }
      body.ytm-style-transparent ytmusic-nav-bar.scrolled,
      body.ytm-ambient-active ytmusic-nav-bar.scrolled,
      body.ytm-style-transparent #nav-bar-background.scrolled,
      body.ytm-ambient-active #nav-bar-background.scrolled,
      body.ytm-style-transparent ytmusic-nav-bar[opened],
      body.ytm-ambient-active ytmusic-nav-bar[opened],
      body.ytm-style-transparent[player-page-open] ytmusic-nav-bar,
      body.ytm-ambient-active[player-page-open] ytmusic-nav-bar,
      body.ytm-style-transparent[player-page-open] #nav-bar-background,
      body.ytm-ambient-active[player-page-open] #nav-bar-background {
        background: rgba(10, 10, 10, 0.4) !important;
        backdrop-filter: blur(25px) !important;
        -webkit-backdrop-filter: blur(25px) !important;
      }
      body.ytm-ambient-active[player-page-open] ytmusic-nav-bar,
      body.ytm-ambient-active[player-page-open] #nav-bar-background {
        background: transparent !important;
      }
      /* YTM Player Bar: semi-transparent with blur - respect ambient */
      body.ytm-style-transparent ytmusic-player-bar,
      body.ytm-ambient-active ytmusic-player-bar {
        background: rgba(0, 0, 0, 0.2) !important;
        backdrop-filter: blur(30px) !important;
        -webkit-backdrop-filter: blur(30px) !important;
        border-top: 1px solid rgba(255, 255, 255, 0.05) !important;
      }
      body.ytm-ambient-active ytmusic-player-bar {
        background: transparent !important;
        border-top: 1px solid rgba(255, 255, 255, 0.1) !important;
      }
      /* YTM Sidebar (Expanded & Collapsed): Glass with separator line - respect ambient */
      body.ytm-style-transparent tp-yt-app-drawer #contentContainer,
      body.ytm-style-transparent #mini-guide,
      body.ytm-style-transparent #mini-guide-renderer,
      body.ytm-ambient-active tp-yt-app-drawer #contentContainer,
      body.ytm-ambient-active #mini-guide,
      body.ytm-ambient-active #mini-guide-renderer {
        background: rgba(0, 0, 0, 0.1) !important;
        backdrop-filter: blur(25px) !important;
        -webkit-backdrop-filter: blur(25px) !important;
        border-right: 1px solid rgba(255, 255, 255, 0.1) !important;
      }
      body.ytm-ambient-active tp-yt-app-drawer #contentContainer,
      body.ytm-ambient-active #mini-guide,
      body.ytm-ambient-active #mini-guide-renderer {
        background: transparent !important;
      }
      /* Standardized YTM Glass Buttons (Edit, Menu, Play, etc.) */
      body.ytm-style-transparent button.ytSpecButtonShapeNextHost,
      body.ytm-style-transparent yt-button-shape button,
      body.ytm-style-transparent .history-button #button,
      body.ytm-ambient-active button.ytSpecButtonShapeNextHost,
      body.ytm-ambient-active yt-button-shape button,
      body.ytm-ambient-active .history-button #button {
        background: rgba(255, 255, 255, 0.15) !important;
        backdrop-filter: blur(12px) !important;
        -webkit-backdrop-filter: blur(12px) !important;
        color: #fff !important;
      }
      /* Clean Guide Button */
      yt-icon-button#guide-button,
      yt-icon-button#guide-button *,
      #guide-button,
      #guide-button #button,
      #guide-button #interaction,
      #guide-button yt-icon,
      #guide-button .yt-interaction,
      #guide-button .stroke.yt-interaction,
      #guide-button .fill.yt-interaction {
        background: transparent !important;
        background-color: transparent !important;
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        border: none !important;
        box-shadow: none !important;
        --yt-spec-touch-response: transparent !important;
        --yt-spec-touch-response-inverse: transparent !important;
        --yt-sys-color-baseline--touch-response-inverse: transparent !important;
      }
      /* Play button specific fixes */
      ytmusic-play-button-renderer {
        background: transparent !important;
        --ytmusic-play-button-background-color: transparent !important;
        --ytmusic-play-button-active-background-color: rgba(255, 255, 255, 0.25) !important;
      }
      ytmusic-play-button-renderer .content-wrapper {
        background: rgba(255, 255, 255, 0.2) !important;
        backdrop-filter: blur(15px) !important;
        -webkit-backdrop-filter: blur(15px) !important;
        border-radius: 50% !important;
        box-shadow: 0 0 10px rgba(0,0,0,0.3) !important;
      }
      ytmusic-play-button-renderer:hover .content-wrapper {
        background: rgba(255, 255, 255, 0.3) !important;
      }
      ytmusic-play-button-renderer yt-icon,
      ytmusic-play-button-renderer #icon,
      ytmusic-play-button-renderer .icon,
      ytmusic-play-button-renderer .icon.ytmusic-play-button-renderer,
      ytmusic-play-button-renderer yt-icon.ytmusic-play-button-renderer {
        background: transparent !important;
        background-color: transparent !important;
        color: #fff !important;
        --ytmusic-play-button-icon-color: #fff !important;
        opacity: 1 !important;
        visibility: visible !important;
      }
      /* Ensure SVGs inside are visible */
      ytmusic-play-button-renderer svg {
        fill: #fff !important;
      }
      ` : ''}
      /* Engagement panels: Solid on regular YT, but NOT on Shorts */
      ytd-watch-flexy ytd-engagement-panel-section-list-renderer,
      ytd-watch-flexy ytd-engagement-panel-section-list-renderer #content,
      ytd-watch-flexy ytd-engagement-panel-section-list-renderer #header,
      ytd-watch-flexy ytd-engagement-panel-title-header-renderer,
      ytd-watch-flexy ytd-engagement-panel-title-header-renderer #header,
      ytd-watch-flexy ytd-section-list-renderer[engagement-panel] {
        background: #212121 !important;
        background-color: #212121 !important;
      }
      /* Nuclear transparency for Shorts engagement panels to reveal theme background */
      ytd-shorts #shorts-panel-container,
      ytd-shorts #anchored-panel,
      ytd-shorts ytd-engagement-panel-section-list-renderer,
      ytd-shorts ytd-engagement-panel-section-list-renderer #content,
      ytd-shorts ytd-engagement-panel-section-list-renderer #header,
      /* Highly specific YouTube selectors identified during debugging */
      ytd-shorts ytd-engagement-panel-section-list-renderer[match-content-theme] #content,
      ytd-shorts ytd-engagement-panel-section-list-renderer[match-content-theme] #content.ytd-engagement-panel-section-list-renderer,
      ytd-shorts ytd-engagement-panel-section-list-renderer[target-id="engagement-panel-comments-section"] #content,
      ytd-shorts ytd-engagement-panel-section-list-renderer[target-id="engagement-panel-comments-section"] #header,
      ytd-shorts ytd-engagement-panel-title-header-renderer,
      ytd-shorts ytd-engagement-panel-title-header-renderer #header,
      ytd-shorts ytd-comments-header-renderer,
      ytd-shorts ytd-comment-thread-renderer,
      ytd-shorts ytd-comment-view-model,
      ytd-shorts ytd-item-section-renderer,
      ytd-shorts #sections.ytd-item-section-renderer,
      ytd-shorts #contents.ytd-item-section-renderer,
      ytd-shorts ytd-comment-simplebox-renderer {
        background: transparent !important;
        background-color: transparent !important;
      }
      /* Search button - restore default YT gray */
      ytd-searchbox #search-icon-legacy,
      button.ytSearchboxComponentSearchButton,
      button.ytSearchboxComponentSearchButtonDark {
        background-color: #222222 !important;
        border: none !important;
      }
      /* Voice search button - add blur backdrop for visibility */
      #voice-search-button .ytSpecButtonShapeNextHost,
      #voice-search-button button {
        background: rgba(255, 255, 255, 0.15) !important;
        backdrop-filter: blur(12px) !important;
        -webkit-backdrop-filter: blur(12px) !important;
        border-radius: 50% !important;
      }
      /* Hide YTM native background elements when custom background is set */
      body:not(.ytm-ambient-active) #mini-guide-background,
      ytmusic-browse-response #background.immersive-background,
      ytmusic-fullbleed-thumbnail-renderer[is-background],
      ytmusic-player-page #background.immersive-background,
      #background.ytmusic-browse-response {
        opacity: 0 !important;
        pointer-events: none !important;
        visibility: hidden !important;
      }
      /* Hide Shorts cinematic black blocks */
      #cinematic-container.ytd-reel-video-renderer,
      #shorts-cinematic-container,
      #cinematic-shorts-scrim.ytd-shorts {
        display: none !important;
        opacity: 0 !important;
        visibility: hidden !important;
      }
      /* Remove dark gradient overlays from Shorts */
      .overlay.ytd-reel-video-renderer,
      ytd-reel-player-overlay-renderer,
      ytd-reel-player-overlay-renderer #overlay,
      .overlay-container.ytd-reel-player-overlay-renderer {
        background: transparent !important;
        background-image: none !important;
      }
    `;
        } else {
            styleEl.textContent = '';
        }
    }

    // --- Background Image Customization ---
    const inputFile = $id('background_image');
    const preview = $id('background-image-preview');
    const removeBtn = $id('remove-background-image');

    if (inputFile && preview) {
        // show preview
        const storedImage = localStorage.getItem('backgroundImage');
        if (storedImage) {
            preview.style.backgroundImage = `url(${storedImage})`;
            preview.classList.add('has-image');
            if (removeBtn) removeBtn.style.display = 'flex';
            applyPageBackground(storedImage);
        } else {
            preview.style.backgroundImage = '';
            preview.classList.remove('has-image');
            if (removeBtn) removeBtn.style.display = 'none';
            applyPageBackground(null);
        }


        preview.addEventListener('click', (e) => {
            if (e.target === removeBtn) return;
            inputFile.click();
        });

        // add background image (bind once)
        inputFile.addEventListener('change', (e) => {
            const file = e.target.files[0];
            if (!file) return;
            const reader = new FileReader();
            reader.onload = function (ev) {
                const dataUrl = ev.target.result;
                preview.style.backgroundImage = `url(${dataUrl})`;
                preview.classList.add('has-image');
                localStorage.setItem('backgroundImage', dataUrl);
                if (removeBtn) removeBtn.style.display = 'flex';
                applyPageBackground(dataUrl);
            };
            reader.readAsDataURL(file);
        });

        // Remove background image (bind once)
        if (removeBtn && removeBtn.dataset.ytToolsBound !== '1') {
            removeBtn.dataset.ytToolsBound = '1';
            removeBtn.addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();
                // Only allow real user click to remove stored background
                if (e.isTrusted === false) return;
                preview.style.backgroundImage = '';
                preview.classList.remove('has-image');
                localStorage.removeItem('backgroundImage');
                removeBtn.style.display = 'none';
                applyPageBackground(null);
                // Force theme refresh to remove image from dynamic CSS
                if (typeof scheduleApplySettings === 'function') {
                    scheduleApplySettings();
                }
            });
        }
    }

    // Nuclear fix for persistent black cinematic blocks in Shorts
    function nukeShortsCinematic() {
        if (isYTMusic) return;
        // 1. Remove from regular DOM
        const selector = '#cinematic-container.ytd-reel-video-renderer, #shorts-cinematic-container, #cinematic-shorts-scrim';
        document.querySelectorAll(selector).forEach(el => el.remove());

        // 2. Remove from Shadow DOMs of all reel renderers
        document.querySelectorAll('ytd-reel-video-renderer').forEach(reel => {
            if (reel.shadowRoot) {
                const cinematic = reel.shadowRoot.querySelector('#cinematic-container');
                if (cinematic) cinematic.remove();
            }
        });

        // 3. Force transparency on engagement panels in Shorts
        document.querySelectorAll('ytd-engagement-panel-section-list-renderer[shorts-panel], ytd-shorts ytd-engagement-panel-section-list-renderer').forEach(panel => {
            const content = panel.querySelector('#content');
            const header = panel.querySelector('#header');
            if (content) {
                content.style.setProperty('background', 'transparent', 'important');
                content.style.setProperty('background-color', 'transparent', 'important');
            }
            if (header) {
                header.style.setProperty('background', 'transparent', 'important');
                header.style.setProperty('background-color', 'transparent', 'important');
            }
            panel.style.setProperty('background', 'transparent', 'important');
            panel.style.setProperty('background-color', 'transparent', 'important');
        });

        // 4. Force transparency on navigation container in Shorts
        document.querySelectorAll('.navigation-container.ytd-shorts').forEach(nav => {
            nav.style.setProperty('background', 'transparent', 'important');
            nav.style.setProperty('background-color', 'transparent', 'important');
        });
    }


    // Run periodically during Shorts browsing - only once
    if (!window.__ytToolsShortsNukeInterval) {
        window.__ytToolsShortsNukeInterval = setInterval(() => {
            if (window.location.pathname.startsWith('/shorts/')) {
                nukeShortsCinematic();
            }
        }, 1500);
    }

})();