YouTube Video Hider with 🚫 Icon and Shorts Toggle

Adds a 🚫 symbol without background in the top-left corner of the thumbnail for natively hiding videos and a button in the topbar to toggle the Shorts section on YouTube

安裝腳本?
作者推薦腳本

您可能也會喜歡 Twitter/X Timeline Sync

安裝腳本
// ==UserScript==
// @name         YouTube Video Hider with 🚫 Icon and Shorts Toggle
// @name:de      YouTube Video Ausblender mit 🚫 Symbol und Shorts Umschalter
// @name:es      Ocultador de Videos de YouTube con Icono 🚫 y Alternador de Shorts
// @name:fr      Masqueur de Vidéos YouTube avec Icône 🚫 et Basculeur de Shorts
// @name:it      Nascondi Video YouTube con Icona 🚫 e Interruttore Shorts
// @namespace    http://tampermonkey.net/
// @version      2025.6.15
// @description  Adds a 🚫 symbol without background in the top-left corner of the thumbnail for natively hiding videos and a button in the topbar to toggle the Shorts section on YouTube
// @description:de Fügt ein 🚫 Symbol ohne Hintergrund in der oberen linken Ecke des Thumbnails hinzu, um Videos nativ auszublenden, und einen Button in der oberen Leiste, um den Shorts-Abschnitt auf YouTube ein-/auszublenden
// @description:es Agrega un símbolo 🚫 sin fondo en la esquina superior izquierda de la miniatura para ocultar videos de forma nativa y un botón en la barra superior para alternar la sección de Shorts en YouTube
// @description:fr Ajoute un symbole 🚫 sans fond dans le coin supérieur gauche de la miniature pour masquer nativement les vidéos et un bouton dans la barre supérieure pour activer/désactiver la section Shorts sur YouTube
// @description:it Aggiunge un simbolo 🚫 senza sfondo nell'angolo superiore sinistro della miniatura per nascondere nativamente i video e un pulsante nella barra superiore per attivare/disattivare la sezione Shorts su YouTube
// @icon         https://youtube.com/favicon.ico
// @author       Copiis
// @license      MIT
// @match        https://www.youtube.com/*
// @grant        none
// ==/UserScript==
//                    If you find this script useful and would like to support my work, consider making a small donation!
//                    Bitcoin (BTC): bc1quc5mkudlwwkktzhvzw5u2nruxyepef957p68r7
//                    PayPal: https://www.paypal.com/paypalme/Coopiis?country.x=DE&locale.x=de_DE

(function () {
    'use strict';

    // Spracherkennung
    const userLang = (navigator.language || navigator.languages[0] || 'en').substring(0, 2);
    console.log(`[Initializer] Erkannte Sprache: ${userLang}`);

    // Übersetzungsobjekt
    const translations = {
        en: {
            hideVideosFound: 'Found videos: ${count}',
            hideNoThumbnail: 'Video ${index}: No thumbnail or image found',
            hideButtonAdded: 'Video ${index}: Button added',
            hideNoMenuButton: 'Video ${index}: No menu button found',
            hideMenuOpened: 'Video ${index}: Menu opened',
            hideOptionClicked: 'Video ${index}: Hide option clicked',
            hideOptionNotFound: 'Video ${index}: Hide option not found',
            hideError: 'Video ${index}: Error while hiding: ${error}',
            shortsNoTopbar: 'Topbar or YouTube logo not found',
            shortsButtonExists: 'Toggle button already exists, skipping',
            shortsButtonAdded: 'Toggle button added to topbar',
            shortsNotFound: 'Shorts section not found',
            shortsFound: 'Shorts section found: ${details}',
            shortsSectionHidden: 'Shorts section: hidden',
            shortsSectionShown: 'Shorts section: shown',
            shortsButtonTextHide: 'Hide Shorts',
            shortsButtonTextShow: 'Show Shorts',
            shortsButtonTextUnavailable: 'Shorts unavailable',
            shortsDebugPrimary: 'Primary selector ytd-rich-shelf-renderer[is-shorts]: ${result}',
            shortsDebugSection: 'Checking section: ${details}',
            shortsNoUpdate: 'No Shorts section found, button remains disabled',
            initStarted: 'Script initialized',
            initAttempt: 'Attempt ${current} of ${max} for Shorts section',
            initMaxAttempts: 'Maximum attempts reached, no Shorts section found',
            initError: 'Error during initialization: ${error}',
            observerError: 'Error in MutationObserver: ${error}',
            shortsTitles: ['shorts', 'short videos']
        },
        de: {
            hideVideosFound: 'Gefundene Videos: ${count}',
            hideNoThumbnail: 'Video ${index}: Kein Thumbnail oder Bild gefunden',
            hideButtonAdded: 'Video ${index}: Button hinzugefügt',
            hideNoMenuButton: 'Video ${index}: Kein Menü-Button gefunden',
            hideMenuOpened: 'Video ${index}: Menü geöffnet',
            hideOptionClicked: 'Video ${index}: Ausblenden geklickt',
            hideOptionNotFound: 'Video ${index}: Ausblenden-Option nicht gefunden',
            hideError: 'Video ${index}: Fehler beim Ausblenden: ${error}',
            shortsNoTopbar: 'Obere Leiste oder YouTube-Logo nicht gefunden',
            shortsButtonExists: 'Toggle-Button bereits vorhanden, überspringe',
            shortsButtonAdded: 'Toggle-Button in oberer Leiste hinzugefügt',
            shortsNotFound: 'Shorts-Abschnitt nicht gefunden',
            shortsFound: 'Shorts-Abschnitt gefunden: ${details}',
            shortsSectionHidden: 'Shorts-Abschnitt: ausgeblendet',
            shortsSectionShown: 'Shorts-Abschnitt: eingeblendet',
            shortsButtonTextHide: 'Shorts ausblenden',
            shortsButtonTextShow: 'Shorts einblenden',
            shortsButtonTextUnavailable: 'Shorts nicht verfügbar',
            shortsDebugPrimary: 'Primärer Selektor ytd-rich-shelf-renderer[is-shorts]: ${result}',
            shortsDebugSection: 'Prüfe Abschnitt: ${details}',
            shortsNoUpdate: 'Kein Shorts-Abschnitt gefunden, Button bleibt deaktiviert',
            initStarted: 'Skript initialisiert',
            initAttempt: 'Versuch ${current} von ${max} für Shorts-Abschnitt',
            initMaxAttempts: 'Maximale Versuche erreicht, kein Shorts-Abschnitt gefunden',
            initError: 'Fehler bei der Initialisierung: ${error}',
            observerError: 'Fehler im MutationObserver: ${error}',
            shortsTitles: ['shorts', 'kurzvideos']
        },
        es: {
            hideVideosFound: 'Videos encontrados: ${count}',
            hideNoThumbnail: 'Video ${index}: No se encontró miniatura o imagen',
            hideButtonAdded: 'Video ${index}: Botón añadido',
            hideNoMenuButton: 'Video ${index}: No se encontró botón de menú',
            hideMenuOpened: 'Video ${index}: Menú abierto',
            hideOptionClicked: 'Video ${index}: Opción de ocultar clicada',
            hideOptionNotFound: 'Video ${index}: Opción de ocultar no encontrada',
            hideError: 'Video ${index}: Error al ocultar: ${error}',
            shortsNoTopbar: 'Barra superior o logo de YouTube no encontrados',
            shortsButtonExists: 'Botón de alternancia ya existe, omitiendo',
            shortsButtonAdded: 'Botón de alternancia añadido a la barra superior',
            shortsNotFound: 'Sección de Shorts no encontrada',
            shortsFound: 'Sección de Shorts encontrada: ${details}',
            shortsSectionHidden: 'Sección de Shorts: oculta',
            shortsSectionShown: 'Sección de Shorts: mostrada',
            shortsButtonTextHide: 'Ocultar Shorts',
            shortsButtonTextShow: 'Mostrar Shorts',
            shortsButtonTextUnavailable: 'Shorts no disponibles',
            shortsDebugPrimary: 'Selector primario ytd-rich-shelf-renderer[is-shorts]: ${result}',
            shortsDebugSection: 'Verificando sección: ${details}',
            shortsNoUpdate: 'No se encontró sección de Shorts, el botón permanece deshabilitado',
            initStarted: 'Script inicializado',
            initAttempt: 'Intento ${current} de ${max} para la sección de Shorts',
            initMaxAttempts: 'Máximo de intentos alcanzado, no se encontró sección de Shorts',
            initError: 'Error durante la inicialización: ${error}',
            observerError: 'Error en MutationObserver: ${error}',
            shortsTitles: ['shorts', 'cortos', 'videos cortos']
        },
        fr: {
            hideVideosFound: 'Vidéos trouvées : ${count}',
            hideNoThumbnail: 'Vidéo ${index} : Aucune vignette ou image trouvée',
            hideButtonAdded: 'Vidéo ${index} : Bouton ajouté',
            hideNoMenuButton: 'Vidéo ${index} : Aucun bouton de menu trouvé',
            hideMenuOpened: 'Vidéo ${index} : Menu ouvert',
            hideOptionClicked: 'Vidéo ${index} : Option de masquer cliquée',
            hideOptionNotFound: 'Vidéo ${index} : Option de masquer non trouvée',
            hideError: 'Vidéo ${index} : Erreur lors du masquage : ${error}',
            shortsNoTopbar: 'Barre supérieure ou logo YouTube non trouvés',
            shortsButtonExists: 'Bouton de bascule déjà présent, ignoré',
            shortsButtonAdded: 'Bouton de bascule ajouté à la barre supérieure',
            shortsNotFound: 'Section Shorts non trouvée',
            shortsFound: 'Section Shorts trouvée : ${details}',
            shortsSectionHidden: 'Section Shorts : masquée',
            shortsSectionShown: 'Section Shorts : affichée',
            shortsButtonTextHide: 'Masquer les Shorts',
            shortsButtonTextShow: 'Afficher les Shorts',
            shortsButtonTextUnavailable: 'Shorts indisponibles',
            shortsDebugPrimary: 'Sélecteur principal ytd-rich-shelf-renderer[is-shorts] : ${result}',
            shortsDebugSection: 'Vérification de la section : ${details}',
            shortsNoUpdate: 'Aucune section Shorts trouvée, le bouton reste désactivé',
            initStarted: 'Script initialisé',
            initAttempt: 'Tentative ${current} sur ${max} pour la section Shorts',
            initMaxAttempts: 'Nombre maximum de tentatives atteint, aucune section Shorts trouvée',
            initError: 'Erreur lors de l’initialisation : ${error}',
            observerError: 'Erreur dans MutationObserver : ${error}',
            shortsTitles: ['shorts', 'vidéos courtes']
        },
        it: {
            hideVideosFound: 'Video trovati: ${count}',
            hideNoThumbnail: 'Video ${index}: Nessuna miniatura o immagine trovata',
            hideButtonAdded: 'Video ${index}: Pulsante aggiunto',
            hideNoMenuButton: 'Video ${index}: Nessun pulsante di menu trovato',
            hideMenuOpened: 'Video ${index}: Menu aperto',
            hideOptionClicked: 'Video ${index}: Opzione nascondi cliccata',
            hideOptionNotFound: 'Video ${index}: Opzione nascondi non trovata',
            hideError: 'Video ${index}: Errore durante la nascondazione: ${error}',
            shortsNoTopbar: 'Barra superiore o logo YouTube non trovati',
            shortsButtonExists: 'Pulsante di attivazione già presente, salto',
            shortsButtonAdded: 'Pulsante di attivazione aggiunto alla barra superiore',
            shortsNotFound: 'Sezione Shorts non trovata',
            shortsFound: 'Sezione Shorts trovata: ${details}',
            shortsSectionHidden: 'Sezione Shorts: nascosta',
            shortsSectionShown: 'Sezione Shorts: mostrata',
            shortsButtonTextHide: 'Nascondi Shorts',
            shortsButtonTextShow: 'Mostra Shorts',
            shortsButtonTextUnavailable: 'Shorts non disponibili',
            shortsDebugPrimary: 'Selettore primario ytd-rich-shelf-renderer[is-shorts]: ${result}',
            shortsDebugSection: 'Controllo sezione: ${details}',
            shortsNoUpdate: 'Nessuna sezione Shorts trovata, il pulsante rimane disabilitato',
            initStarted: 'Script inizializzato',
            initAttempt: 'Tentativo ${current} di ${max} per la sezione Shorts',
            initMaxAttempts: 'Massimo numero di tentativi raggiunto, nessuna sezione Shorts trovata',
            initError: 'Errore durante l’inizializzazione: ${error}',
            observerError: 'Errore in MutationObserver: ${error}',
            shortsTitles: ['shorts', 'video brevi']
        }
    };

    // Wähle Übersetzungen basierend auf der Sprache (Fallback: Englisch)
    const t = translations[userLang] || translations.en;

    // Funktion zum Formatieren von Übersetzungen mit Platzhaltern
    function formatTranslation(key, params = {}) {
        let str = t[key] || translations.en[key] || key;
        Object.keys(params).forEach(param => {
            str = str.replace(`\${${param}}`, params[param]);
        });
        return str;
    }

    // Funktion zum Hinzufügen des Ausblende-Buttons für Videos
function addHideButton() {
    const videoElements = document.querySelectorAll('ytd-rich-grid-media:not([data-hide-button-added])');

    if (videoElements.length > 0) {
        console.log(formatTranslation('hideVideosFound', { count: videoElements.length }));
    }

    videoElements.forEach((video, index) => {
        const thumbnailContainer = video.querySelector('#thumbnail');
        const thumbnailImage = thumbnailContainer?.querySelector('img.yt-core-image');
        if (!thumbnailContainer || !thumbnailImage) {
            console.log(formatTranslation('hideNoThumbnail', { index }));
            return;
        }

        const hideButton = document.createElement('div');
        hideButton.className = 'hide-video-btn';
        hideButton.textContent = '🚫';
        Object.assign(hideButton.style, {
            position: 'absolute',
            top: '8px',
            left: '8px',
            cursor: 'pointer',
            zIndex: '9999',
            borderRadius: '50%',
            width: '32px',
            height: '32px',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            fontSize: '18px',
            color: 'white',
            backgroundColor: 'transparent',
            pointerEvents: 'auto'
        });

        thumbnailContainer.style.position = 'relative';
        thumbnailContainer.appendChild(hideButton);
        video.setAttribute('data-hide-button-added', 'true');
        console.log(formatTranslation('hideButtonAdded', { index }));

        hideButton.addEventListener('click', async () => {
            try {
                const menuButton = video.querySelector('yt-icon-button#button.dropdown-trigger');
                if (!menuButton) {
                    console.log(formatTranslation('hideNoMenuButton', { index }));
                    return;
                }

                menuButton.querySelector('button')?.dispatchEvent(new MouseEvent('click', { bubbles: true }));
                console.log(formatTranslation('hideMenuOpened', { index }));
                await new Promise(resolve => requestAnimationFrame(() => setTimeout(resolve, 1500))); // Verzögerung auf 1500 ms erhöht

                const menu = document.querySelector('ytd-menu-popup-renderer');
                if (!menu) {
                    console.log(formatTranslation('hideOptionNotFound', { index }) + ' - No menu popup found');
                    return;
                }

                const menuItems = menu.querySelectorAll('ytd-menu-service-item-renderer, ytd-menu-navigation-item-renderer, tp-yt-paper-item');
                const hideOption = Array.from(menuItems).find(item => {
                    const textElement = item.querySelector('yt-formatted-string, span, div');
                    const text = textElement?.textContent?.trim().toLowerCase();
                    const ariaLabel = item.getAttribute('aria-label')?.toLowerCase();
                    const hasHideIcon = item.querySelector('yt-icon path[d="M12 2c5.52 0 10 4.48 10 10s-4.48 10-10 10S2 17.52 2 12 6.48 2 12 2zM3 12c0 2.31.87 4.41 2.29 6L18 5.29C16.41 3.87 14.31 3 12 3c-4.97 0-9 4.03-9 9zm15.71-6L6 18.71C7.59 20.13 9.69 21 12 21c4.97 0 9-4.03 9-9 0-2.31-.87-4.41-2.29-6z"]') !== null;
                    console.log(`[Hide Debug] Checking menu item: text="${text || 'No text'}" aria-label="${ariaLabel || 'No aria-label'}" hasHideIcon=${hasHideIcon}`);
                    return text === 'hide' ||
                           text === 'ausblenden' ||
                           text === 'video ausblenden' ||
                           text === 'ocultar' ||
                           text === 'masquer' ||
                           text === 'nascondi' ||
                           ariaLabel?.includes('ausblenden') ||
                           ariaLabel?.includes('hide') ||
                           ariaLabel?.includes('ocultar') ||
                           ariaLabel?.includes('masquer') ||
                           ariaLabel?.includes('nascondi') ||
                           hasHideIcon;
                });

                if (hideOption) {
                    console.log(`[Hide Debug] Found hide option: ${hideOption.outerHTML}`);
                    hideOption.closest('ytd-menu-service-item-renderer')?.dispatchEvent(new MouseEvent('click', { bubbles: true })) || hideOption.dispatchEvent(new MouseEvent('click', { bubbles: true }));
                    console.log(formatTranslation('hideOptionClicked', { index }));
                    await new Promise(resolve => requestAnimationFrame(() => setTimeout(resolve, 500)));

                    // Suche nach Bestätigungs-Popup
                    const confirmButton = document.querySelector('yt-button-renderer#confirm-button, yt-button-renderer a[aria-label*="bestätigen" i], yt-button-renderer a[aria-label*="confirm" i], tp-yt-paper-button');
                    if (confirmButton) {
                        console.log(`[Hide Debug] Found confirm button: ${confirmButton.outerHTML}`);
                        confirmButton.querySelector('a, tp-yt-paper-button')?.dispatchEvent(new MouseEvent('click', { bubbles: true })) || confirmButton.dispatchEvent(new MouseEvent('click', { bubbles: true }));
                        console.log(formatTranslation('hideConfirmClicked', { index }));
                    } else {
                        console.log(formatTranslation('hideConfirmNotFound', { index }));
                    }

                    await new Promise(resolve => requestAnimationFrame(() => setTimeout(resolve, 500)));
                    document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
                } else {
                    console.log(formatTranslation('hideOptionNotFound', { index }));
                    console.log(`[Hide Debug] Full menu structure: ${menu.outerHTML}`);
                    Array.from(menuItems).forEach(item => {
                        const text = item.querySelector('yt-formatted-string, span, div')?.textContent?.trim() || 'No text';
                        const ariaLabel = item.getAttribute('aria-label') || 'No aria-label';
                        const hasHideIcon = item.querySelector('yt-icon path[d="M12 2c5.52 0 10 4.48 10 10s-4.48 10-10 10S2 17.52 2 12 6.48 2 12 2zM3 12c0 2.31.87 4.41 2.29 6L18 5.29C16.41 3.87 14.31 3 12 3c-4.97 0-9 4.03-9 9zm15.71-6L6 18.71C7.59 20.13 9.69 21 12 21c4.97 0 9-4.03 9-9 0-2.31-.87-4.41-2.29-6z"]') !== null;
                        console.log(`[Hide Debug] Menu item: text="${text}" aria-label="${ariaLabel}" hasHideIcon=${hasHideIcon}`);
                    });
                }
            } catch (err) {
                console.error(formatTranslation('hideError', { index, error: err.message }));
            }
        });
    });
}

    // Funktion zum Hinzufügen des Shorts-Toggle-Buttons in der oberen Leiste
    function addShortsToggleButton() {
        // Finde die obere Leiste und das YouTube-Logo
        const topbar = document.querySelector('ytd-masthead #start');
        const logo = document.querySelector('ytd-topbar-logo-renderer');

        if (!topbar || !logo) {
            console.log(formatTranslation('shortsNoTopbar'));
            return;
        }

        // Prüfe, ob der Button bereits hinzugefügt wurde
        let wrapper = topbar.querySelector('.shorts-toggle-wrapper');
        let toggleButton = wrapper?.querySelector('.shorts-toggle-btn');

        // Finde den Shorts-Abschnitt
        let shortsSection = document.querySelector('ytd-rich-shelf-renderer[is-shorts]');
        console.log(formatTranslation('shortsDebugPrimary', { result: shortsSection ? 'found' : 'not found' }));

        // Fallback: Suche nach Titel in verschiedenen Sprachen
        if (!shortsSection) {
            const sections = document.querySelectorAll('ytd-rich-section-renderer, ytd-rich-shelf-renderer');
            shortsSection = Array.from(sections).find(section => {
                const title = section.querySelector('span[id="title"]');
                const titleText = title?.textContent.trim().toLowerCase();
                const isShortsTitle = t.shortsTitles.some(shortsTitle => titleText === shortsTitle.toLowerCase());
                console.log(formatTranslation('shortsDebugSection', {
                    details: JSON.stringify({
                        tag: section.tagName,
                        title: titleText || 'No title',
                        isShorts: section.hasAttribute('is-shorts')
                    })
                }));
                return isShortsTitle;
            });
        }

        // Wenn immer noch nicht gefunden, aber Button existiert, aktualisiere ihn nicht
        if (!shortsSection && toggleButton) {
            console.log(formatTranslation('shortsNoUpdate'));
            return;
        }

        // Erstelle oder aktualisiere den Toggle-Button
        if (!wrapper) {
            toggleButton = document.createElement('button');
            toggleButton.className = 'shorts-toggle-btn';
            wrapper = document.createElement('div');
            wrapper.className = 'shorts-toggle-wrapper';
            wrapper.style.cssText = `
                display: inline-flex !important;
                align-items: center !important;
                margin-left: 8px !important;
                z-index: 10001 !important;
            `;
            wrapper.appendChild(toggleButton);
            logo.parentNode.insertBefore(wrapper, logo.nextSibling);
            topbar.setAttribute('data-shorts-button-added', 'true');
            console.log(formatTranslation('shortsButtonAdded'));
        }

        // Button-Styling und Status
        toggleButton.textContent = shortsSection ? t.shortsButtonTextHide : t.shortsButtonTextUnavailable;
        Object.assign(toggleButton.style, {
            padding: '6px 12px',
            margin: '0 8px',
            backgroundColor: shortsSection ? '#ff4444' : '#cccccc',
            border: 'none',
            borderRadius: '4px',
            cursor: shortsSection ? 'pointer' : 'not-allowed',
            fontSize: '12px',
            fontWeight: '500',
            color: '#ffffff',
            zIndex: '10001',
            display: 'inline-flex',
            alignItems: 'center',
            height: '32px',
            verticalAlign: 'middle'
        });
        toggleButton.disabled = !shortsSection;

        // Toggle-Logik
        if (shortsSection && !toggleButton.hasListener) {
            let isShortsHidden = false;
            toggleButton.addEventListener('click', () => {
                isShortsHidden = !isShortsHidden;
                shortsSection.style.display = isShortsHidden ? 'none' : '';
                toggleButton.textContent = isShortsHidden ? t.shortsButtonTextShow : t.shortsButtonTextHide;
                console.log(formatTranslation(isShortsHidden ? 'shortsSectionHidden' : 'shortsSectionShown'));
            });
            toggleButton.hasListener = true;
        }

        // Debugging
        if (!shortsSection) {
            console.log(formatTranslation('shortsNotFound'));
            const sections = document.querySelectorAll('ytd-rich-section-renderer, ytd-rich-shelf-renderer');
            sections.forEach((section, index) => {
                const title = section.querySelector('span[id="title"]');
                const attributes = Array.from(section.attributes).map(attr => `${attr.name}="${attr.value}"`).join(', ');
                console.log(formatTranslation('shortsDebugSection', {
                    details: JSON.stringify({
                        index,
                        title: title ? title.textContent.trim() : 'No title found',
                        tag: section.tagName,
                        attributes: attributes || 'No attributes',
                        isShorts: section.hasAttribute('is-shorts') ? 'true' : 'false'
                    })
                }));
            });
        } else {
            const title = shortsSection.querySelector('span[id="title"]');
            const attributes = Array.from(shortsSection.attributes).map(attr => `${attr.name}="${attr.value}"`).join(', ');
            console.log(formatTranslation('shortsFound', {
                details: JSON.stringify({
                    tag: shortsSection.tagName,
                    attributes: attributes || 'No attributes',
                    title: title ? title.textContent.trim() : 'No title found',
                    isShorts: shortsSection.hasAttribute('is-shorts') ? 'true' : 'false'
                })
            }));
        }
    }

    // CSS hinzufügen
    const style = document.createElement('style');
    style.textContent = `
        .hide-video-btn {
            color: white !important;
            background-color: transparent !important;
            border-radius: 50% !important;
            font-size: 18px !important;
            width: 32px !important;
            height: 32px !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            position: absolute !important;
            top: 8px !important;
            left: 8px !important;
            cursor: pointer !important;
            pointer-events: auto !important;
            z-index: 9999 !important;
            visibility: visible !important;
            opacity: 1 !important;
        }

        .hide-video-btn:hover {
            background-color: transparent !important;
            box-shadow: 0 0 10px 2px rgba(255, 215, 0, 0.8) !important;
        }

        .shorts-toggle-btn {
            transition: background-color 0.2s !important;
        }

        .shorts-toggle-btn:not(:disabled):hover {
            background-color: #cc0000 !important;
        }

        .shorts-toggle-wrapper {
            display: inline-flex !important;
            align-items: center !important;
            margin-left: 8px !important;
            z-index: 10001 !important;
        }
    `;
    document.head.appendChild(style);

    // Initiale Ausführung mit Verzögerung
    function initialize() {
        try {
            addHideButton();
            addShortsToggleButton();
            console.log(formatTranslation('initStarted'));
            // Wiederholte Prüfung für Shorts-Abschnitt
            let attempts = 0;
            const maxAttempts = 10;
            const interval = setInterval(() => {
                console.log(formatTranslation('initAttempt', { current: attempts + 1, max: maxAttempts }));
                const shortsSection = document.querySelector('ytd-rich-shelf-renderer[is-shorts]');
                if (shortsSection || document.querySelector('span[id="title"][textContent*="Shorts" i]')) {
                    addShortsToggleButton();
                    clearInterval(interval);
                } else if (attempts >= maxAttempts) {
                    console.log(formatTranslation('initMaxAttempts'));
                    clearInterval(interval);
                }
                attempts++;
            }, 1000);
        } catch (err) {
            console.error(formatTranslation('initError', { error: err.message }));
        }
    }

    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        setTimeout(initialize, 1000);
    } else {
        document.addEventListener('DOMContentLoaded', () => setTimeout(initialize, 1000));
    }

    // Begrenzter MutationObserver
    const observer = new MutationObserver((mutations, obs) => {
        try {
            const hasRelevantChanges = mutations.some(mutation =>
                mutation.addedNodes.length > 0 &&
                mutation.addedNodes[0]?.nodeType === Node.ELEMENT_NODE &&
                (mutation.target.matches('ytd-rich-grid-media, ytd-rich-shelf-renderer, ytd-rich-section-renderer, ytd-masthead, ytd-rich-shelf-renderer[is-shorts]') ||
                 mutation.target.querySelector('ytd-rich-grid-media, ytd-rich-shelf-renderer, ytd-rich-section-renderer, ytd-topbar-logo-renderer, ytd-rich-shelf-renderer[is-shorts]')) &&
                !mutation.target.classList?.contains('shorts-toggle-wrapper')
            );

            if (hasRelevantChanges) {
                addHideButton();
                addShortsToggleButton();
            }
        } catch (err) {
            console.error(formatTranslation('observerError', { error: err.message }));
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true,
        attributes: false
    });

})();