YouTube Fix for Yandex

Оптимизация YouTube специально для Яндекс Браузера: исправление сетки видео, производительности и интерфейса

// ==UserScript==
// @name         YouTube Fix for Yandex
// @namespace    https://github.com/Xanixsl
// @version      4.2.1
// @description  Оптимизация YouTube специально для Яндекс Браузера: исправление сетки видео, производительности и интерфейса
// @author       Xanix
// @match        https://www.youtube.com/*
// @match        https://m.youtube.com/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- Trusted Types Policy ---
    window.ytEnhancerTrustedTypesPolicy = window.trustedTypes
        ? window.trustedTypes.createPolicy('yt-enhancer', {
            createHTML: (input) => input
        })
        : null;

    function setInnerHTML(element, htmlString) {
        element.innerHTML = window.ytEnhancerTrustedTypesPolicy
            ? window.ytEnhancerTrustedTypesPolicy.createHTML(htmlString)
            : htmlString;
    }

    // --- Расширенное определение Яндекс.Браузера ---
    function isYandexBrowser() {
        const ua = navigator.userAgent;
        if (/YaBrowser/i.test(ua)) return true;
        if (window.yandex) return true;
        if (navigator.vendor && navigator.vendor.toLowerCase().includes('yandex')) return true;
        if (window.chrome && chrome.runtime && chrome.runtime.id && chrome.runtime.id.startsWith('bhchdcejhohfmigjafbampogmaanbfkg')) return true;
        return false;
    }

    // --- Проверка ОС ---
    function getOS() {
        const userAgent = window.navigator.userAgent;
        const platform = window.navigator.platform;

        if (/Windows/.test(userAgent)) return 'Windows';
        if (/Mac/.test(platform)) return 'MacOS';
        if (/Linux/.test(platform)) return 'Linux';
        if (/Android/.test(userAgent)) return 'Android';
        if (/iOS|iPhone|iPad|iPod/.test(userAgent)) return 'iOS';

        return 'Unknown';
    }

    // --- Конфигурация по умолчанию ---
    const defaultConfig = {
        // Основные функции
        hideChips: false,
        compactMode: false,
        hideShorts: true,
        hideRFSlowWarning: true,

        // Яндекс-специфичные настройки
        yandexBrowserFix: true,
        yandexGridFix: true,
        yandexVideoCount: 4,
        yandexChipbarMargin: -70,
        yandexVideoMargin: 100,
        yandexLanguage: 'auto',
        yandexPerformanceMode: true,
        yandexExperimentalFix: false,
        yandexSiteShift: 0,

        // Внешний вид
        darkModeSupport: true,
        customThumbnailSize: 'default',
        enhancerTheme: 'auto',
        enhancerFontSize: 14
    };

    // --- Безопасное хранилище для настроек ---
    const storage = {
        get: (key) => {
            try {
                if (typeof localStorage !== 'undefined') {
                    const value = localStorage.getItem(`ytEnhancer_${key}`);
                    return value ? JSON.parse(value) : null;
                }
                return null;
            } catch (e) {
                return null;
            }
        },
        set: (key, value) => {
            try {
                if (typeof localStorage !== 'undefined') {
                    localStorage.setItem(`ytEnhancer_${key}`, JSON.stringify(value));
                    return true;
                }
                return false;
            } catch (e) {
                return false;
            }
        }
    };

    // --- Загрузка конфигурации ---
    let config = (function() {
        try {
            const saved = storage.get('ytEnhancerConfig');
            return saved ? {...defaultConfig, ...saved} : {...defaultConfig};
        } catch (e) {
            return {...defaultConfig};
        }
    })();

    // --- Фиксы для Яндекс Браузера ---
    function applyYandexFixes() {
        if (!isYandexBrowser() || !config.yandexBrowserFix) return;

        // Настройки языка интерфейса
        if (config.yandexLanguage === 'en') {
            document.cookie = 'PREF=hl=en; domain=.youtube.com; path=/; secure';
            document.cookie = 'CONSENT=YES+; domain=.youtube.com; path=/; secure';
        } else if (config.yandexLanguage === 'ru') {
            document.cookie = 'PREF=hl=ru; domain=.youtube.com; path=/; secure';
            document.cookie = 'CONSENT=YES+; domain=.youtube.com; path=/; secure';
        }

        // Исправление сетки видео
        if (config.yandexGridFix) {
            const fixGrid = () => {
                const grids = document.querySelectorAll('ytd-rich-grid-renderer');
                grids.forEach(grid => {
                    grid.style.setProperty('--ytd-rich-grid-items-per-row', config.yandexVideoCount, 'important');
                    grid.style.setProperty('--ytd-rich-grid-posts-per-row', config.yandexVideoCount, 'important');
                });
            };

            fixGrid();
            setInterval(fixGrid, 3000);
        }

        // Оптимизация производительности
        if (config.yandexPerformanceMode) {
            addStyles(`
                ytd-rich-grid-renderer, ytd-rich-item-renderer {
                    will-change: unset !important;
                    contain: unset !important;
                }

                #items.ytd-grid-renderer {
                    contain: strict !important;
                }

                ytd-video-renderer, ytd-grid-video-renderer {
                    transform: translateZ(0);
                }
            `);
        }

        // Экспериментальный фикс - сдвиг сайта
        if (config.yandexExperimentalFix) {
            addStyles(`
                ytd-page-manager, ytd-browse {
                    transform: translateY(${config.yandexSiteShift}px) !important;
                }

                ytd-masthead, #header.ytd-rich-grid-renderer, ytd-feed-filter-chip-bar-renderer {
                    transform: none !important;
                }
            `);
        }
    }

    // --- Скрытие уведомления о замедлении YouTube в РФ ---
    function hideRFSlowWarning() {
        if (!config.hideRFSlowWarning) return;

        const style = document.createElement('style');
        style.textContent = `
            .sf-notification-btn { display: none !important; }
            ytd-mealbar-promo-renderer { display: none !important; }
            #clarify-box { display: none !important; }
        `;
        document.head.appendChild(style);
    }

    // --- Основные функции ---
    function applyMainFeatures() {
        // Скрытие Shorts
        if (config.hideShorts) {
            addStyles(`
                ytd-rich-section-renderer[section-identifier="shorts-shelf"],
                ytd-reel-shelf-renderer,
                ytd-guide-entry-renderer[title="Shorts"],
                a[title="Shorts"],
                ytd-mini-guide-entry-renderer[title="Shorts"],
                ytd-rich-shelf-renderer[is-shorts],
                ytd-rich-section-renderer[section-identifier="shorts-shelf"] {
                    display: none !important;
                }
            `);
        }

        // Скрытие чипсов
        if (config.hideChips) {
            addStyles(`
                ytd-feed-filter-chip-bar-renderer,
                yt-chip-cloud-renderer,
                yt-related-chip-cloud-renderer,
                #chips-wrapper.ytd-rich-grid-renderer {
                    display: none !important;
                }
            `);
        }

        // Компактный режим
        if (config.compactMode) {
            addStyles(`
                ytd-rich-item-renderer {
                    margin-bottom: 8px !important;
                }
            `);
        }
    }

    // --- Добавление стилей в DOM ---
    function addStyles(css) {
        const style = document.createElement('style');
        style.type = 'text/css';
        style.textContent = css;
        const target = document.head || document.documentElement;
        if (target) {
            target.appendChild(style);
        } else {
            setTimeout(() => addStyles(css), 100);
        }
    }

    // --- Применение стилей ---
    function applyStyles() {
        const styles = generateStyles();
        addStyles(styles);
        cleanupSpacing();
    }

    // --- Очистка пробелов ---
    function cleanupSpacing() {
        if (!isYandexBrowser()) return;

        const selectors = [
            '#contents.ytd-rich-grid-renderer',
            'ytd-rich-grid-renderer',
            '#contentContainer.ytd-rich-grid-renderer'
        ];

        selectors.forEach(selector => {
            try {
                document.querySelectorAll(selector).forEach(el => {
                    if (el && el.style) {
                        el.style.marginTop = '0';
                        el.style.paddingTop = '0';
                    }
                });
            } catch (e) {
                console.error(`Error cleaning up selector ${selector}:`, e);
            }
        });

        // Исправление количества видео для Яндекс Браузера
        if (config.yandexGridFix) {
            try {
                const grid = document.querySelector('ytd-rich-grid-renderer');
                if (grid) {
                    grid.style.setProperty('--ytd-rich-grid-items-per-row', config.yandexVideoCount, 'important');
                }
            } catch (e) {
                console.error('Error fixing Yandex grid:', e);
            }
        }
    }

    // --- Генерация CSS ---
    function generateStyles() {
        let css = `
            :root {
                --chips-animation-duration: 0.3s;
                --ytd-rich-grid-items-per-row: ${isYandexBrowser() ? config.yandexVideoCount : 4};
            }
        `;

        if (isYandexBrowser()) {
            css += `
                #frosted-glass.with-chipbar {
                    margin-top: ${config.yandexChipbarMargin}px !important;
                }
                ytd-rich-grid-renderer,
                #contents.ytd-rich-grid-renderer {
                    margin-top: ${config.yandexExperimentalFix ? 0 : config.yandexVideoMargin}px !important;
                }
                ytd-rich-grid-renderer {
                    --ytd-rich-grid-items-per-row: ${config.yandexVideoCount} !important;
                }
            `;
        } else {
            // Минимальные стили для других браузеров
            css += `
                ytd-rich-grid-renderer {
                    --ytd-rich-grid-items-per-row: 4 !important;
                }
            `;
        }

        // Размеры миниатюр
        if (config.customThumbnailSize !== 'default') {
            css += `
                ytd-rich-grid-media {
                    aspect-ratio: ${getThumbnailAspectRatio()} !important;
                }
                ytd-rich-item-renderer {
                    width: ${getThumbnailWidth()} !important;
                }
            `;
        }

        // Темы окна
        css += `
            #yt-enhancer-settings {
                font-size: ${config.enhancerFontSize}px !important;
                line-height: 1.6 !important;
                font-family: 'Segoe UI', 'Roboto', Arial, sans-serif !important;
                box-shadow: 0 8px 32px rgba(0,0,0,0.25) !important;
                transition: background 0.2s, color 0.2s;
                min-width: ${Math.min(540, Math.max(320, config.enhancerFontSize * 20))}px;
            }
        `;

        if (config.enhancerTheme === 'dark') {
            css += `
                #yt-enhancer-settings {
                    background: #181a1b !important;
                    color: #fff !important;
                    border-color: #222 !important;
                }
                #yt-enhancer-settings input, #yt-enhancer-settings select {
                    background: #23272a !important;
                    color: #fff !important;
                    border-color: #333 !important;
                }
            `;
        } else if (config.enhancerTheme === 'blue') {
            css += `
                #yt-enhancer-settings {
                    background: #eaf3fb !important;
                    color: #065fd4 !important;
                    border-color: #065fd4 !important;
                }
                #yt-enhancer-settings input, #yt-enhancer-settings select {
                    background: #f5faff !important;
                    color: #065fd4 !important;
                    border-color: #b3d4fc !important;
                }
            `;
        } else if (config.enhancerTheme === 'glass') {
            css += `
                #yt-enhancer-settings {
                    background: rgba(255,255,255,0.92) !important;
                    backdrop-filter: blur(16px) !important;
                    color: #222 !important;
                    border-color: #e0e0e0 !important;
                }
                #yt-enhancer-settings input, #yt-enhancer-settings select {
                    background: rgba(255,255,255,0.7) !important;
                    color: #222 !important;
                    border-color: #ccc !important;
                }
            `;
        } else if (config.enhancerTheme === 'auto') {
            css += `
                @media (prefers-color-scheme: dark) {
                    #yt-enhancer-settings {
                        background: #181a1b !important;
                        color: #fff !important;
                        border-color: #222 !important;
                    }
                    #yt-enhancer-settings input, #yt-enhancer-settings select {
                        background: #23272a !important;
                        color: #fff !important;
                        border-color: #333 !important;
                    }
                }
            `;
        }

        // Темный режим YouTube
        if (config.darkModeSupport) {
            css += `
                @media (prefers-color-scheme: dark) {
                    :root {
                        --yt-spec-base-background: #0f0f0f !important;
                    }
                }
            `;
        }

        return css;
    }

    // --- Вспомогательные функции ---
    function getThumbnailAspectRatio() {
        switch(config.customThumbnailSize) {
            case 'small': return '16/9';
            case 'medium': return '4/3';
            case 'large': return '1/1';
            default: return '16/9';
        }
    }

    function getThumbnailWidth() {
        switch(config.customThumbnailSize) {
            case 'small': return '240px';
            case 'medium': return '320px';
            case 'large': return '360px';
            default: return '100%';
        }
    }

    // --- UI настроек ---
    function createSettingsUI() {
        if (document.getElementById('yt-enhancer-settings')) return;

        const dialog = document.createElement('div');
        dialog.id = 'yt-enhancer-settings';
        dialog.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: var(--yt-spec-base-background, #fff);
            color: var(--yt-spec-text-primary, #030303);
            padding: 24px;
            border-radius: 12px;
            box-shadow: 0 8px 32px rgba(0,0,0,0.2);
            z-index: 999999;
            width: ${isYandexBrowser() ? '540px' : '400px'};
            max-width: 98vw;
            max-height: 96vh;
            overflow-y: auto;
            font-family: 'Segoe UI', 'Roboto', Arial, sans-serif;
            border: 1.5px solid var(--yt-spec-10-percent-layer, #ddd);
        `;

        const header = document.createElement('div');
        header.style.display = 'flex';
        header.style.justifyContent = 'space-between';
        header.style.alignItems = 'center';
        header.style.marginBottom = '20px';

        const title = document.createElement('h2');
        title.textContent = isYandexBrowser() ? 'YouTube Yandex Optimizer' : 'YouTube Basic Enhancer';
        title.style.margin = '0';
        title.style.fontSize = '1.5em';
        title.style.color = 'var(--yt-spec-text-primary, #030303)';
        title.style.fontWeight = 'bold';

        const closeBtn = document.createElement('button');
        setInnerHTML(closeBtn, '×');
        closeBtn.style.cssText = `
            background: none;
            border: none;
            font-size: 2em;
            cursor: pointer;
            color: var(--yt-spec-text-secondary, #606060);
            padding: 0 8px;
            line-height: 1;
        `;

        header.appendChild(title);
        header.appendChild(closeBtn);
        dialog.appendChild(header);

        if (!isYandexBrowser()) {
            const warning = document.createElement('div');
            warning.style.padding = '12px';
            warning.style.marginBottom = '20px';
            warning.style.backgroundColor = 'var(--yt-spec-badge-chip-background, #f8f9fa)';
            warning.style.borderRadius = '8px';
            warning.style.textAlign = 'center';
            setInnerHTML(warning, `Полная версия расширения доступна только в <a href="https://browser.yandex.com/?lang=ru" target="_blank" style="color: var(--yt-spec-brand-button-background, #065fd4); text-decoration: none; font-weight: bold;">Яндекс Браузере</a>.`);
            dialog.appendChild(warning);
        }

        // Создание вкладок
        const tabs = document.createElement('div');
        tabs.style.display = 'flex';
        tabs.style.marginBottom = '20px';
        tabs.style.borderBottom = '1px solid var(--yt-spec-10-percent-layer, #ddd)';

        const tabNames = isYandexBrowser()
            ? ['Основные', 'Яндекс-фиксы', 'Внешний вид']
            : ['Основные', 'Внешний вид'];

        const tabContents = [];

        tabNames.forEach((name, i) => {
            const tab = document.createElement('button');
            tab.textContent = name;
            tab.dataset.tab = i;
            tab.style.cssText = `
                padding: 10px 18px;
                background: none;
                border: none;
                border-bottom: 2.5px solid transparent;
                cursor: pointer;
                font-weight: 600;
                color: var(--yt-spec-text-secondary, #606060);
                margin-right: 8px;
                font-size: 1em;
                transition: color 0.15s, border-bottom-color 0.15s;
            `;

            if (i === 0) {
                tab.style.color = 'var(--yt-spec-text-primary, #030303)';
                tab.style.borderBottomColor = 'var(--yt-spec-brand-button-background, #065fd4)';
            }

            tab.addEventListener('click', () => {
                tabs.querySelectorAll('button').forEach(t => {
                    t.style.color = 'var(--yt-spec-text-secondary, #606060)';
                    t.style.borderBottomColor = 'transparent';
                });
                tab.style.color = 'var(--yt-spec-text-primary, #030303)';
                tab.style.borderBottomColor = 'var(--yt-spec-brand-button-background, #065fd4)';

                tabContents.forEach((content, j) => {
                    content.style.display = i === j ? 'block' : 'none';
                });
            });

            tabs.appendChild(tab);

            // Содержимое вкладки
            const content = document.createElement('div');
            content.style.display = i === 0 ? 'block' : 'none';
            content.style.marginBottom = '20px';
            tabContents.push(content);
        });

        dialog.appendChild(tabs);

        // Содержимое вкладок
        if (isYandexBrowser()) {
            createMainTab(tabContents[0]);
            createYandexTab(tabContents[1]);
            createAppearanceTab(tabContents[2]);
        } else {
            createMainTab(tabContents[0]);
            createAppearanceTab(tabContents[1]);
        }

        tabContents.forEach(content => dialog.appendChild(content));

        // Кнопки сохранения/сброса
        const buttons = document.createElement('div');
        buttons.style.display = 'flex';
        buttons.style.justifyContent = 'space-between';
        buttons.style.marginTop = '20px';

        const saveBtn = document.createElement('button');
        saveBtn.textContent = 'Сохранить настройки';
        saveBtn.style.cssText = `
            padding: 12px 24px;
            background: var(--yt-spec-brand-button-background, #065fd4);
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-weight: 600;
            flex: 1;
            margin-right: 10px;
        `;

        const resetBtn = document.createElement('button');
        resetBtn.textContent = 'Сбросить настройки';
        resetBtn.style.cssText = `
            padding: 12px 24px;
            background: var(--yt-spec-10-percent-layer, #f1f1f1);
            color: var(--yt-spec-text-primary, #030303);
            border: none;
            border-radius: 5px;
            cursor: pointer;
            flex: 1;
            font-weight: 600;
        `;

        buttons.appendChild(saveBtn);
        buttons.appendChild(resetBtn);
        dialog.appendChild(buttons);

        document.body.appendChild(dialog);

        // Обработчики событий
        closeBtn.addEventListener('click', () => dialog.remove());

        saveBtn.addEventListener('click', () => {
            const inputs = dialog.querySelectorAll('input, select');
            inputs.forEach(input => {
                if (input.type === 'checkbox') {
                    config[input.id] = input.checked;
                } else if (input.type === 'number') {
                    config[input.id] = parseInt(input.value) || 0;
                } else {
                    config[input.id] = input.value;
                }
            });

            storage.set('ytEnhancerConfig', config);
            applyStyles();
            applyMainFeatures();
            applyYandexFixes();
            hideRFSlowWarning();
            dialog.remove();
            showNotification('Настройки сохранены! Страница будет перезагружена...');
            setTimeout(() => location.reload(), 1000);
        });

        resetBtn.addEventListener('click', () => {
            if (confirm('Вы уверены, что хотите сбросить все настройки к значениям по умолчанию?')) {
                config = {...defaultConfig};
                storage.set('ytEnhancerConfig', config);
                applyStyles();
                applyMainFeatures();
                applyYandexFixes();
                hideRFSlowWarning();
                dialog.remove();
                showNotification('Настройки сброшены! Страница будет перезагружена...');
                setTimeout(() => location.reload(), 1000);
            }
        });

        // Закрытие при клике вне диалога
        const handleOutsideClick = (e) => {
            if (!dialog.contains(e.target)) {
                dialog.remove();
                document.removeEventListener('click', handleOutsideClick);
            }
        };

        setTimeout(() => document.addEventListener('click', handleOutsideClick), 100);
        dialog.addEventListener('click', e => e.stopPropagation());
    }

    // --- Основная вкладка ---
    function createMainTab(container) {
        const section = (title, description = '') => {
            const sectionDiv = document.createElement('div');
            sectionDiv.style.marginBottom = '16px';

            const h3 = document.createElement('h3');
            h3.textContent = title;
            h3.style.margin = '16px 0 8px 0';
            h3.style.fontSize = '1.1em';
            h3.style.color = 'var(--yt-spec-text-primary, #030303)';
            h3.style.fontWeight = 'bold';

            sectionDiv.appendChild(h3);

            if (description) {
                const desc = document.createElement('p');
                desc.textContent = description;
                desc.style.margin = '4px 0 8px 0';
                desc.style.fontSize = '0.9em';
                desc.style.color = 'var(--yt-spec-text-secondary, #606060)';
                sectionDiv.appendChild(desc);
            }

            return sectionDiv;
        };

        // Настройки языка (только для Яндекс)
        if (isYandexBrowser()) {
            const langSection = section('Язык интерфейса', 'Выберите предпочитаемый язык интерфейса YouTube');

            const langDiv = document.createElement('div');
            langDiv.style.marginBottom = '16px';

            const langSelect = document.createElement('select');
            langSelect.id = 'yandexLanguage';
            langSelect.style.width = '100%';
            langSelect.style.padding = '8px';
            langSelect.style.borderRadius = '4px';
            langSelect.style.border = '1px solid var(--yt-spec-10-percent-layer, #ddd)';

            [
                {value: 'auto', label: 'Автоматически (по браузеру)'},
                {value: 'ru', label: 'Русский'},
                {value: 'en', label: 'Английский'}
            ].forEach(option => {
                const optEl = document.createElement('option');
                optEl.value = option.value;
                optEl.textContent = option.label;
                if (option.value === config.yandexLanguage) optEl.selected = true;
                langSelect.appendChild(optEl);
            });

            langDiv.appendChild(langSelect);
            langSection.appendChild(langDiv);
            container.appendChild(langSection);
        }

        // Основные настройки
        const mainSection = section('Основные настройки', 'Общие параметры для всех браузеров');

        const createCheckbox = (id, label, checked, description = '') => {
            const div = document.createElement('div');
            div.style.display = 'flex';
            div.style.alignItems = 'flex-start';
            div.style.marginBottom = '12px';

            const input = document.createElement('input');
            input.type = 'checkbox';
            input.id = id;
            input.checked = checked;
            input.style.marginRight = '10px';
            input.style.marginTop = '3px';

            const labelDiv = document.createElement('div');

            const labelEl = document.createElement('label');
            labelEl.htmlFor = id;
            labelEl.textContent = label;
            labelEl.style.userSelect = 'none';
            labelEl.style.fontWeight = '500';

            labelDiv.appendChild(labelEl);

            if (description) {
                const desc = document.createElement('div');
                desc.textContent = description;
                desc.style.fontSize = '0.85em';
                desc.style.color = 'var(--yt-spec-text-secondary, #606060)';
                desc.style.marginTop = '4px';
                labelDiv.appendChild(desc);
            }

            div.appendChild(input);
            div.appendChild(labelDiv);
            return div;
        };

        mainSection.appendChild(createCheckbox(
            'hideChips',
            'Скрыть чипсы (фильтры)',
            config.hideChips,
            'Скрывает полосу с фильтрами на главной странице и в разделах'
        ));

        mainSection.appendChild(createCheckbox(
            'compactMode',
            'Компактный режим',
            config.compactMode,
            'Уменьшает отступы между видео для более плотного расположения'
        ));

        mainSection.appendChild(createCheckbox(
            'hideShorts',
            'Скрыть Shorts',
            config.hideShorts,
            'Убирает раздел Shorts и рекомендации коротких видео'
        ));

        mainSection.appendChild(createCheckbox(
            'hideRFSlowWarning',
            'Скрыть предупреждение о замедлении',
            config.hideRFSlowWarning,
            'Убирает уведомление о возможных замедлениях работы YouTube в РФ'
        ));

        container.appendChild(mainSection);
    }

    // --- Яндекс вкладка ---
    function createYandexTab(container) {
        const section = (title, description = '') => {
            const sectionDiv = document.createElement('div');
            sectionDiv.style.marginBottom = '16px';

            const h3 = document.createElement('h3');
            h3.textContent = title;
            h3.style.margin = '16px 0 8px 0';
            h3.style.fontSize = '1.1em';
            h3.style.color = 'var(--yt-spec-text-primary, #030303)';
            h3.style.fontWeight = 'bold';

            sectionDiv.appendChild(h3);

            if (description) {
                const desc = document.createElement('p');
                desc.textContent = description;
                desc.style.margin = '4px 0 8px 0';
                desc.style.fontSize = '0.9em';
                desc.style.color = 'var(--yt-spec-text-secondary, #606060)';
                sectionDiv.appendChild(desc);
            }

            return sectionDiv;
        };

        // Настройки сетки
        const gridSection = section('Настройки сетки видео', 'Оптимизация отображения видео в Яндекс Браузере');

        const createNumberInput = (id, label, value, min, max, description = '') => {
            const div = document.createElement('div');
            div.style.marginBottom = '16px';

            const labelDiv = document.createElement('div');
            labelDiv.style.display = 'flex';
            labelDiv.style.justifyContent = 'space-between';
            labelDiv.style.marginBottom = '8px';

            const labelEl = document.createElement('label');
            labelEl.htmlFor = id;
            labelEl.textContent = label;
            labelEl.style.fontWeight = '500';

            labelDiv.appendChild(labelEl);

            if (description) {
                const desc = document.createElement('div');
                desc.textContent = description;
                desc.style.fontSize = '0.85em';
                desc.style.color = 'var(--yt-spec-text-secondary, #606060)';
                labelDiv.appendChild(desc);
            }

            div.appendChild(labelDiv);

            const input = document.createElement('input');
            input.type = 'number';
            input.id = id;
            input.value = value;
            input.min = min;
            input.max = max;
            input.style.width = '100%';
            input.style.padding = '8px';
            input.style.borderRadius = '4px';
            input.style.border = '1px solid var(--yt-spec-10-percent-layer, #ddd)';

            div.appendChild(input);
            return div;
        };

        gridSection.appendChild(createNumberInput(
            'yandexVideoCount',
            'Количество видео в строке',
            config.yandexVideoCount,
            1, 6,
            'Рекомендуется 4 для широких экранов'
        ));

        gridSection.appendChild(createNumberInput(
            'yandexChipbarMargin',
            'Сдвиг Chipbar (px)',
            config.yandexChipbarMargin,
            -100, 100,
            'Отрицательное значение сдвигает вверх'
        ));

        const videoMarginInput = createNumberInput(
            'yandexVideoMargin',
            'Сдвиг блока видео (px)',
            config.yandexVideoMargin,
            0, 200
        );

        // Блокировка поля при экспериментальном фиксе
        if (config.yandexExperimentalFix) {
            videoMarginInput.querySelector('input').disabled = true;
            videoMarginInput.style.opacity = '0.6';
        }

        gridSection.appendChild(videoMarginInput);
        container.appendChild(gridSection);

        // Экспериментальные настройки
        const expSection = section('Экспериментальные функции', 'Используйте с осторожностью, могут быть нестабильными');

        const createCheckbox = (id, label, checked, description = '') => {
            const div = document.createElement('div');
            div.style.display = 'flex';
            div.style.alignItems = 'flex-start';
            div.style.marginBottom = '12px';

            const input = document.createElement('input');
            input.type = 'checkbox';
            input.id = id;
            input.checked = checked;
            input.style.marginRight = '10px';
            input.style.marginTop = '3px';

            const labelDiv = document.createElement('div');

            const labelEl = document.createElement('label');
            labelEl.htmlFor = id;
            labelEl.textContent = label;
            labelEl.style.userSelect = 'none';
            labelEl.style.fontWeight = '500';

            labelDiv.appendChild(labelEl);

            if (description) {
                const desc = document.createElement('div');
                desc.textContent = description;
                desc.style.fontSize = '0.85em';
                desc.style.color = 'var(--yt-spec-text-secondary, #606060)';
                desc.style.marginTop = '4px';
                labelDiv.appendChild(desc);
            }

            div.appendChild(input);
            div.appendChild(labelDiv);
            return div;
        };

        expSection.appendChild(createCheckbox(
            'yandexGridFix',
            'Исправить сетку видео',
            config.yandexGridFix,
            'Фиксит проблему с отображением 3 видео в строке'
        ));

        expSection.appendChild(createCheckbox(
            'yandexPerformanceMode',
            'Режим оптимизации',
            config.yandexPerformanceMode,
            'Улучшает производительность в Яндекс Браузере'
        ));

        const expFixCheckbox = createCheckbox(
            'yandexExperimentalFix',
            'Экспериментальный фикс сдвига',
            config.yandexExperimentalFix,
            'Альтернативный метод исправления интерфейса'
        );

        expSection.appendChild(expFixCheckbox);

        // Поле для сдвига сайта
        if (config.yandexExperimentalFix) {
            const shiftDiv = document.createElement('div');
            shiftDiv.style.marginBottom = '16px';
            shiftDiv.style.marginLeft = '28px';

            const shiftInput = createNumberInput(
                'yandexSiteShift',
                'Величина сдвига (px)',
                config.yandexSiteShift,
                0, 500
            );

            shiftDiv.appendChild(shiftInput);
            expSection.appendChild(shiftDiv);
        }

        container.appendChild(expSection);
    }

    // --- Внешний вид вкладка ---
    function createAppearanceTab(container) {
        const section = (title, description = '') => {
            const sectionDiv = document.createElement('div');
            sectionDiv.style.marginBottom = '16px';

            const h3 = document.createElement('h3');
            h3.textContent = title;
            h3.style.margin = '16px 0 8px 0';
            h3.style.fontSize = '1.1em';
            h3.style.color = 'var(--yt-spec-text-primary, #030303)';
            h3.style.fontWeight = 'bold';

            sectionDiv.appendChild(h3);

            if (description) {
                const desc = document.createElement('p');
                desc.textContent = description;
                desc.style.margin = '4px 0 8px 0';
                desc.style.fontSize = '0.9em';
                desc.style.color = 'var(--yt-spec-text-secondary, #606060)';
                sectionDiv.appendChild(desc);
            }

            return sectionDiv;
        };

        // Темный режим
        const darkModeSection = section('Темный режим', 'Настройки внешнего вида интерфейса');

        const createCheckbox = (id, label, checked, description = '') => {
            const div = document.createElement('div');
            div.style.display = 'flex';
            div.style.alignItems = 'flex-start';
            div.style.marginBottom = '12px';

            const input = document.createElement('input');
            input.type = 'checkbox';
            input.id = id;
            input.checked = checked;
            input.style.marginRight = '10px';
            input.style.marginTop = '3px';

            const labelDiv = document.createElement('div');

            const labelEl = document.createElement('label');
            labelEl.htmlFor = id;
            labelEl.textContent = label;
            labelEl.style.userSelect = 'none';
            labelEl.style.fontWeight = '500';

            labelDiv.appendChild(labelEl);

            if (description) {
                const desc = document.createElement('div');
                desc.textContent = description;
                desc.style.fontSize = '0.85em';
                desc.style.color = 'var(--yt-spec-text-secondary, #606060)';
                desc.style.marginTop = '4px';
                labelDiv.appendChild(desc);
            }

            div.appendChild(input);
            div.appendChild(labelDiv);
            return div;
        };

        darkModeSection.appendChild(createCheckbox(
            'darkModeSupport',
            'Поддержка темной темы',
            config.darkModeSupport,
            'Автоматическое переключение между светлой и темной темой'
        ));

        container.appendChild(darkModeSection);

        // Размер миниатюр
        const thumbSection = section('Размер миниатюр видео', 'Изменение размера и пропорций превью видео');

        const thumbSelect = document.createElement('select');
        thumbSelect.id = 'customThumbnailSize';
        thumbSelect.style.width = '100%';
        thumbSelect.style.padding = '8px';
        thumbSelect.style.borderRadius = '4px';
        thumbSelect.style.marginBottom = '16px';
        thumbSelect.style.border = '1px solid var(--yt-spec-10-percent-layer, #ddd)';

        [
            {value: 'default', label: 'По умолчанию (16:9)'},
            {value: 'small', label: 'Маленькие (16:9)'},
            {value: 'medium', label: 'Средние (4:3)'},
            {value: 'large', label: 'Большие (1:1)'}
        ].forEach(option => {
            const optEl = document.createElement('option');
            optEl.value = option.value;
            optEl.textContent = option.label;
            if (option.value === config.customThumbnailSize) optEl.selected = true;
            thumbSelect.appendChild(optEl);
        });

        thumbSection.appendChild(thumbSelect);
        container.appendChild(thumbSection);

        // Тема окна
        const themeSection = section('Тема окна настроек', 'Внешний вид этого окна с настройками');

        const themeSelect = document.createElement('select');
        themeSelect.id = 'enhancerTheme';
        themeSelect.style.width = '100%';
        themeSelect.style.padding = '8px';
        themeSelect.style.borderRadius = '4px';
        themeSelect.style.marginBottom = '16px';
        themeSelect.style.border = '1px solid var(--yt-spec-10-percent-layer, #ddd)';

        [
            {value: 'auto', label: 'Автоматически (по системе)'},
            {value: 'light', label: 'Светлая'},
            {value: 'dark', label: 'Темная'},
            {value: 'blue', label: 'Голубая'},
            {value: 'glass', label: 'Стеклянная'}
        ].forEach(option => {
            const optEl = document.createElement('option');
            optEl.value = option.value;
            optEl.textContent = option.label;
            if (option.value === config.enhancerTheme) optEl.selected = true;
            themeSelect.appendChild(optEl);
        });

        themeSection.appendChild(themeSelect);

        // Размер шрифта
        const fontSizeDiv = document.createElement('div');
        fontSizeDiv.style.marginBottom = '16px';

        const fontSizeLabel = document.createElement('label');
        fontSizeLabel.htmlFor = 'enhancerFontSize';
        fontSizeLabel.textContent = 'Размер шрифта: ';
        fontSizeLabel.style.marginRight = '10px';
        fontSizeLabel.style.fontWeight = '500';

        const fontSizeInput = document.createElement('input');
        fontSizeInput.type = 'range';
        fontSizeInput.id = 'enhancerFontSize';
        fontSizeInput.value = config.enhancerFontSize || 14;
        fontSizeInput.min = '12';
        fontSizeInput.max = '20';
        fontSizeInput.style.width = '200px';
        fontSizeInput.style.marginRight = '10px';

        const fontSizeValue = document.createElement('span');
        fontSizeValue.textContent = `${config.enhancerFontSize || 14}px`;
        fontSizeValue.style.fontWeight = '500';

        fontSizeInput.addEventListener('input', () => {
            fontSizeValue.textContent = `${fontSizeInput.value}px`;
        });

        fontSizeDiv.appendChild(fontSizeLabel);
        fontSizeDiv.appendChild(fontSizeInput);
        fontSizeDiv.appendChild(fontSizeValue);

        themeSection.appendChild(fontSizeDiv);
        container.appendChild(themeSection);
    }

    // --- Показать уведомление ---
    function showNotification(message, duration = 3000) {
        const oldNotifications = document.querySelectorAll('.yt-enhancer-notification');
        oldNotifications.forEach(n => n.remove());

        const notification = document.createElement('div');
        notification.className = 'yt-enhancer-notification';
        notification.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: var(--yt-spec-brand-button-background, #065fd4);
            color: white;
            padding: 12px 24px;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            z-index: 999999;
            animation: fadeIn 0.3s ease;
            font-family: 'Segoe UI', 'Roboto', Arial, sans-serif;
        `;

        notification.textContent = message;
        document.body.appendChild(notification);

        setTimeout(() => {
            notification.style.animation = 'fadeOut 0.3s ease';
            setTimeout(() => notification.remove(), 300);
        }, duration);

        // Добавление стилей анимации
        if (!document.getElementById('yt-enhancer-notification-style')) {
            const style = document.createElement('style');
            style.id = 'yt-enhancer-notification-style';
            style.textContent = `
                @keyframes fadeIn {
                    from { opacity: 0; transform: translateY(10px); }
                    to { opacity: 1; transform: translateY(0); }
                }
                @keyframes fadeOut {
                    from { opacity: 1; transform: translateY(0); }
                    to { opacity: 0; transform: translateY(10px); }
                }
            `;
            document.head.appendChild(style);
        }
    }

    // --- Добавить кнопку в интерфейс YouTube ---
    function addYouTubeButton() {
        const observer = new MutationObserver(() => {
            try {
                const header = document.querySelector('ytd-masthead #end');
                if (header && !document.getElementById('yt-enhancer-btn')) {
                    const button = document.createElement('button');
                    button.id = 'yt-enhancer-btn';
                    button.title = 'YouTube Yandex Optimizer';
                    button.style.cssText = `
                        background: transparent;
                        border: none;
                        cursor: pointer;
                        padding: 8px;
                        margin-left: 8px;
                        color: var(--yt-spec-text-primary);
                        display: flex;
                        align-items: center;
                        justify-content: center;
                    `;

                    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                    svg.setAttribute('viewBox', '0 0 24 24');
                    svg.setAttribute('width', '24');
                    svg.setAttribute('height', '24');
                    svg.style.verticalAlign = 'middle';

                    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                    path.setAttribute('fill', 'currentColor');
                    path.setAttribute('d', 'M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z');

                    svg.appendChild(path);
                    button.appendChild(svg);

                    button.addEventListener('click', (e) => {
                        e.stopPropagation();
                        createSettingsUI();
                    });

                    header.insertBefore(button, header.firstChild);
                }
            } catch (e) {
                console.error('YouTube Enhancer button error:', e);
            }
        });

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

        // Попытка добавить кнопку сразу
        setTimeout(() => {
            const header = document.querySelector('ytd-masthead #end');
            if (header && !document.getElementById('yt-enhancer-btn')) {
                const button = document.createElement('button');
                button.id = 'yt-enhancer-btn';
                button.title = isYandexBrowser() ? 'YouTube Yandex Optimizer' : 'YouTube Basic Enhancer';
                button.style.cssText = `
                    background: transparent;
                    border: none;
                    cursor: pointer;
                    padding: 8px;
                    margin-left: 8px;
                    color: var(--yt-spec-text-primary);
                    display: flex;
                    align-items: center;
                    justify-content: center;
                `;

                const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                svg.setAttribute('viewBox', '0 0 24 24');
                svg.setAttribute('width', '24');
                svg.setAttribute('height', '24');
                svg.style.verticalAlign = 'middle';

                const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                path.setAttribute('fill', 'currentColor');
                path.setAttribute('d', 'M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z');

                svg.appendChild(path);
                button.appendChild(svg);
                button.addEventListener('click', (e) => {
                    e.stopPropagation();
                    createSettingsUI();
                });
                header.insertBefore(button, header.firstChild);
            }
        }, 1000);
    }

    // --- Инициализация ---
    function init() {
        applyStyles();
        applyMainFeatures();
        applyYandexFixes();
        hideRFSlowWarning();
        addYouTubeButton();

        // Отслеживание изменений SPA
        let lastUrl = location.href;
        const spaObserver = new MutationObserver(() => {
            if (location.href !== lastUrl) {
                lastUrl = location.href;
                setTimeout(() => {
                    applyStyles();
                    applyMainFeatures();
                    applyYandexFixes();
                    hideRFSlowWarning();
                }, 300);
            }
        });

        spaObserver.observe(document, {subtree: true, childList: true});

        // Периодическая проверка
        setInterval(() => {
            applyStyles();
            applyMainFeatures();
            applyYandexFixes();
            hideRFSlowWarning();
        }, 5000);
    }

    // --- Безопасный запуск ---
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        setTimeout(init, 100);
    } else {
        document.addEventListener('DOMContentLoaded', init);
        window.addEventListener('load', init);
    }
})();