YouTube ✨ Enhancer Pro

Themes, cursors, effects, drawing!

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name YouTube ✨ Enhancer Pro
// @namespace http://tampermonkey.net/
// @version 1.3
// @description Themes, cursors, effects, drawing!
// @author Bveery
// @match https://www.youtube.com/*
// @license GPL-3.0-or-later
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-idle
// ==/UserScript==
(function () {
  'use strict';

  const cfg = {
    theme: GM_getValue('theme', 'none'),
    rbSpeed: GM_getValue('rbSpeed', 6),
    cursor: GM_getValue('cursor', 'none'),
    cursorEffect: GM_getValue('cursorEffect', 'none'),
    cinema: GM_getValue('cinema', false),
    menuColor: GM_getValue('menuColor', 'default'),
    menuBlur: GM_getValue('menuBlur', false),
    menuTransparent: GM_getValue('menuTransparent', false),
    pauseOnMenu: GM_getValue('pauseOnMenu', false),
    language: GM_getValue('language', 'en'),
    seasonal: GM_getValue('seasonal', 'none'),
    videoSpeed: GM_getValue('videoSpeed', 1),
    videoVolume: GM_getValue('videoVolume', 100),
    rememberPosition: GM_getValue('rememberPosition', false),
    drawMode: GM_getValue('drawMode', false),
    drawColor: GM_getValue('drawColor', '#ff2060'),
    drawSize: GM_getValue('drawSize', 4),
  };

  function save(k, v) { cfg[k] = v; GM_setValue(k, v); }

  const LANG = {
    en: {
      title: '✨ YT Enhancer Pro',
      categories: { youtube: '▶️ YouTube', menu: '▶️ Menu', design: '▶️ Design', cursor: '▶️ Cursor' },
      youtube: {
        speedSection: 'Playback Speed',
        speed: '⚡ Speed',
        volumeSection: 'Volume',
        volume: '▶️ Volume',
        rememberSection: 'Remember Position',
        remember: '▶️ Remember where I stopped',
      },
      menu: {
        colorTitle: 'Menu Color',
        blur: 'Blur Background',
        transparent: 'Glass Effect',
        pauseOnMenu: 'Pause on Menu',
        lang: 'Language',
        langEn: 'English',
        langRu: 'Russian',
      },
      design: {
        rbSection: 'Rainbow',
        rainbow: 'Rainbow',
        speed: 'Speed',
        seasonal: 'Seasonal Theme',
        s_none: 'None',
        s_ny: 'New Year',
        s_hw: 'Halloween',
        cinSection: 'Cinema',
        cinema: 'Cinema Mode',
      },
      cursor: {
        drawSection: 'Drawing Mode',
        drawMode: '▶️ Drawing Mode',
        drawColor: '▶️ Brush Color',
        drawSize: '▶️ Brush Size',
        drawClear: '▶️ Clear Canvas',
        cursorSection: 'Cursor Style',
        none: 'Default',
        heart: '❤️ Heart',
        crosshair: '➕ Crosshair',
        custom: '⭐ Star',
        diamond: '💎 Diamond',
        electro: '⚡ Electro',
        effectSection: 'Cursor Effect',
        fx_none: 'None',
        fx_sparks: '✨ Sparks',
        fx_hearts: '❤️ Hearts',
        fx_snow: '❄️ Snow',
        fx_rainbow: '🌈 Rainbow',
        fx_stars: '⭐ Stars',
      }
    },
    ru: {
      title: '✨ YT Enhancer Pro',
      categories: { youtube: '▶️ YouTube', menu: '▶️ Меню', design: '▶️ Дизайн', cursor: '▶️ Курсор' },
      youtube: {
        speedSection: 'Скорость воспроизведения',
        speed: '⚡ Скорость',
        volumeSection: 'Громкость',
        volume: '▶️ Громкость',
        rememberSection: 'Запомнить позицию',
        remember: '▶️ Запомнить где остановился',
      },
      menu: {
        colorTitle: 'Цвет меню',
        blur: 'Блюр фона',
        transparent: 'Эффект стекла',
        pauseOnMenu: 'Пауза при меню',
        lang: 'Язык',
        langEn: 'English',
        langRu: 'Русский',
      },
      design: {
        rbSection: 'Радуга',
        rainbow: 'Радуга',
        speed: 'Скорость',
        seasonal: 'Сезонная тема',
        s_none: 'Выкл',
        s_ny: 'Новый год',
        s_hw: 'Хеллоуин',
        cinSection: 'Кинотеатр',
        cinema: 'Кинотеатр',
      },
      cursor: {
        drawSection: 'Режим рисования',
        drawMode: '▶️ Режим рисования',
        drawColor: '▶️ Цвет кисти',
        drawSize: '▶️ Размер кисти',
        drawClear: '▶️ Очистить холст',
        cursorSection: 'Стиль курсора',
        none: 'Стандартный',
        heart: '❤️ Сердечко',
        crosshair: '➕ Перекрестие',
        custom: '⭐ Звезда',
        diamond: '💎 Алмаз',
        electro: '⚡ Электро',
        effectSection: 'Эффект курсора',
        fx_none: 'Выкл',
        fx_sparks: '✨ Искры',
        fx_hearts: '❤️ Сердечки',
        fx_snow: '❄️ Снег',
        fx_rainbow: '🌈 Радуга',
        fx_stars: '⭐ Звёзды',
      }
    }
  };

  function t(key) {
    const keys = key.split('.');
    let val = LANG[cfg.language] || LANG.en;
    for (const k of keys) val = val?.[k];
    return val ?? key;
  }

  const MENU_COLORS = {
    default: { bg: 'linear-gradient(160deg,rgba(14,14,26,.95),rgba(19,19,42,.95))', text: '#eef', border: 'rgba(255,255,255,.2)' },
    pink:    { bg: 'linear-gradient(160deg,rgba(26,10,20,.95),rgba(42,16,32,.95))', text: '#ffd6e7', border: 'rgba(255,120,180,.35)' },
    blue:    { bg: 'linear-gradient(160deg,rgba(10,16,26,.95),rgba(16,26,42,.95))', text: '#d6e7ff', border: 'rgba(120,180,255,.35)' },
    green:   { bg: 'linear-gradient(160deg,rgba(10,26,16,.95),rgba(16,42,24,.95))', text: '#d6ffe0', border: 'rgba(120,255,180,.35)' },
    purple:  { bg: 'linear-gradient(160deg,rgba(26,10,31,.95),rgba(42,16,48,.95))', text: '#e7d6ff', border: 'rgba(180,120,255,.35)' },
    orange:  { bg: 'linear-gradient(160deg,rgba(26,18,10,.95),rgba(42,28,16,.95))', text: '#ffe7d6', border: 'rgba(255,180,120,.35)' },
    red:     { bg: 'linear-gradient(160deg,rgba(26,8,8,.95),rgba(42,16,16,.95))',   text: '#ffd6d6', border: 'rgba(255,120,120,.35)' },
    cyan:    { bg: 'linear-gradient(160deg,rgba(10,26,31,.95),rgba(16,42,48,.95))', text: '#d6ffff', border: 'rgba(120,255,255,.35)' },
  };

  const COLOR_CHIPS = {
    default: '#8888ff', pink: '#ff78b4', blue: '#78b4ff', green: '#78ffb4',
    purple: '#b478ff', orange: '#ffb478', red: '#ff7878', cyan: '#78ffff',
  };

  // ══════════════════════════════════════════════════════════════
  // КУРСОРЫ
  // ══════════════════════════════════════════════════════════════
  function getCursorStyle(key) {
    if (key === 'none') return '';
    if (key === 'crosshair') return 'crosshair';

    if (key === 'heart') {
      const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">'
        + '<path d="M16 28s-14-9-14-18a8 8 0 0 1 14-5.3A8 8 0 0 1 30 10c0 9-14 18-14 18z" fill="#ff2060" stroke="#ff80a0" stroke-width="1.5"/>'
        + '</svg>';
      return 'url("data:image/svg+xml,' + encodeURIComponent(svg) + '") 16 28, auto';
    }

    if (key === 'custom') {
      const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">'
        + '<polygon points="16,2 20,12 30,12 22,19 25,30 16,23 7,30 10,19 2,12 12,12" fill="gold" stroke="orange" stroke-width="1"/>'
        + '</svg>';
      return 'url("data:image/svg+xml,' + encodeURIComponent(svg) + '") 16 16, auto';
    }

    if (key === 'diamond') {
      const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="36" viewBox="0 0 32 36">'
        + '<defs><linearGradient id="dg" x1="0" y1="0" x2="1" y2="1">'
        + '<stop offset="0%" stop-color="#a0f0ff" stop-opacity="0.7"/>'
        + '<stop offset="50%" stop-color="#00c8ff" stop-opacity="0.5"/>'
        + '<stop offset="100%" stop-color="#0055aa" stop-opacity="0.7"/>'
        + '</linearGradient></defs>'
        + '<polygon points="16,2 30,12 16,34 2,12" fill="url(#dg)" opacity="0.85"/>'
        + '<polygon points="16,2 30,12 16,34 2,12" fill="none" stroke="#00eeff" stroke-width="1.5" opacity="0.9"/>'
        + '<polygon points="16,2 30,12 16,12" fill="rgba(180,240,255,0.55)"/>'
        + '<polygon points="2,12 16,12 16,34" fill="rgba(0,180,220,0.45)"/>'
        + '<polygon points="30,12 16,12 16,34" fill="rgba(0,120,180,0.45)"/>'
        + '<line x1="2" y1="12" x2="30" y2="12" stroke="#00eeff" stroke-width="1" opacity="0.7"/>'
        + '<line x1="16" y1="2" x2="2" y2="12" stroke="#aaf8ff" stroke-width="0.8" opacity="0.6"/>'
        + '<line x1="16" y1="2" x2="30" y2="12" stroke="#aaf8ff" stroke-width="0.8" opacity="0.6"/>'
        + '<circle cx="16" cy="10" r="2.5" fill="white" opacity="0.9"/>'
        + '</svg>';
      return 'url("data:image/svg+xml,' + encodeURIComponent(svg) + '") 16 2, auto';
    }

    if (key === 'electro') {
      const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">'
        + '<defs>'
        + '<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">'
        + '<feGaussianBlur stdDeviation="1.5" result="blur"/>'
        + '<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>'
        + '</filter>'
        + '<linearGradient id="eg" x1="0" y1="0" x2="0" y2="1">'
        + '<stop offset="0%" stop-color="#ffffff" stop-opacity="0.9"/>'
        + '<stop offset="100%" stop-color="#ff9900" stop-opacity="0.3"/>'
        + '</linearGradient>'
        + '</defs>'
        + '<g filter="url(#glow)">'
        + '<polygon points="19,2 10,16 16,16 13,30 23,14 17,14" fill="#ffe44d" stroke="#ffffff" stroke-width="0.5" opacity="0.95"/>'
        + '<polygon points="19,2 10,16 16,16 13,30 23,14 17,14" fill="url(#eg)" opacity="0.6"/>'
        + '</g>'
        + '</svg>';
      return 'url("data:image/svg+xml,' + encodeURIComponent(svg) + '") 16 2, auto';
    }

    return '';
  }

  const CURSOR_KEYS = ['none', 'heart', 'crosshair', 'custom', 'diamond', 'electro'];

  // ══════════════════════════════════════════════════════════════
  // РЕЖИМ РИСОВАНИЯ
  // ══════════════════════════════════════════════════════════════
  let drawCanvas = null;
  let drawCtx = null;
  let isDrawing = false;
  let lastX = 0;
  let lastY = 0;

  const DRAW_COLORS = [
    { color: '#ff2060' }, { color: '#ff8c00' },
    { color: '#ffdd00' }, { color: '#00dd44' },
    { color: '#0088ff' }, { color: '#8855ff' },
    { color: '#ffffff' }, { color: '#000000' },
  ];

  function ensureDrawCanvas() {
    if (drawCanvas) return;
    drawCanvas = document.createElement('canvas');
    drawCanvas.id = 'yt-draw-canvas';
    drawCanvas.width = window.innerWidth;
    drawCanvas.height = window.innerHeight;
    drawCanvas.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2147483644;pointer-events:none;';
    document.documentElement.appendChild(drawCanvas);
    drawCtx = drawCanvas.getContext('2d');
    window.addEventListener('resize', () => {
      const img = drawCtx.getImageData(0, 0, drawCanvas.width, drawCanvas.height);
      drawCanvas.width = window.innerWidth;
      drawCanvas.height = window.innerHeight;
      drawCtx.putImageData(img, 0, 0);
    });
  }

  function startDrawMode() {
    ensureDrawCanvas();
    drawCanvas.style.pointerEvents = 'all';
    drawCanvas.style.cursor = 'crosshair';
    drawCanvas.addEventListener('mousedown', onDrawStart);
    drawCanvas.addEventListener('mousemove', onDrawMove);
    drawCanvas.addEventListener('mouseup', onDrawEnd);
    drawCanvas.addEventListener('mouseleave', onDrawEnd);
    showToast('✏️ Drawing ON — hold LMB to draw!');
  }

  function stopDrawMode() {
    if (!drawCanvas) return;
    drawCanvas.style.pointerEvents = 'none';
    drawCanvas.removeEventListener('mousedown', onDrawStart);
    drawCanvas.removeEventListener('mousemove', onDrawMove);
    drawCanvas.removeEventListener('mouseup', onDrawEnd);
    drawCanvas.removeEventListener('mouseleave', onDrawEnd);
    isDrawing = false;
    showToast('⏹️ Drawing OFF');
  }

  function clearDrawCanvas() {
    if (!drawCtx || !drawCanvas) return;
    drawCtx.clearRect(0, 0, drawCanvas.width, drawCanvas.height);
    showToast('🧹 Canvas cleared!');
  }

  function onDrawStart(e) {
    isDrawing = true;
    lastX = e.clientX; lastY = e.clientY;
    drawCtx.beginPath();
    drawCtx.arc(lastX, lastY, cfg.drawSize / 2, 0, Math.PI * 2);
    drawCtx.fillStyle = cfg.drawColor;
    drawCtx.shadowBlur = cfg.drawSize;
    drawCtx.shadowColor = cfg.drawColor;
    drawCtx.fill();
  }

  function onDrawMove(e) {
    if (!isDrawing) return;
    drawCtx.beginPath();
    drawCtx.moveTo(lastX, lastY);
    drawCtx.lineTo(e.clientX, e.clientY);
    drawCtx.strokeStyle = cfg.drawColor;
    drawCtx.lineWidth = cfg.drawSize;
    drawCtx.lineCap = 'round';
    drawCtx.lineJoin = 'round';
    drawCtx.shadowBlur = cfg.drawSize * 0.8;
    drawCtx.shadowColor = cfg.drawColor;
    drawCtx.stroke();
    lastX = e.clientX; lastY = e.clientY;
  }

  function onDrawEnd() {
    isDrawing = false;
    if (drawCtx) drawCtx.shadowBlur = 0;
  }

  function applyDrawMode() {
    const on = cfg.drawMode === true || cfg.drawMode === 'true';
    if (on) startDrawMode(); else stopDrawMode();
  }

  // ══════════════════════════════════════════════════════════════
  // ЭФФЕКТЫ КУРСОРА
  // ══════════════════════════════════════════════════════════════
  let fxCanvas = null, fxCtx = null, fxRAF = null;
  let fxParticles = [], fxMouseX = 0, fxMouseY = 0;
  let fxMouseMoved = false, fxMoveHandler = null;
  let fxActive = false, fxType = 'none';

  function ensureFxCanvas() {
    if (fxCanvas) return;
    fxCanvas = document.createElement('canvas');
    fxCanvas.id = 'yt-cursor-fx';
    fxCanvas.width = window.innerWidth;
    fxCanvas.height = window.innerHeight;
    fxCanvas.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:2147483643;';
    document.documentElement.appendChild(fxCanvas);
    fxCtx = fxCanvas.getContext('2d');
    window.addEventListener('resize', () => {
      fxCanvas.width = window.innerWidth;
      fxCanvas.height = window.innerHeight;
    });
  }

  function spawnFxParticles(x, y) {
    switch (fxType) {
      case 'sparks': {
        const colors = ['#ff2060','#ff8c00','#ffdd00','#ff4488','#ff6600','#ffffff'];
        for (let i = 0; i < 3 + Math.floor(Math.random()*4); i++) {
          const a = Math.random()*Math.PI*2, s = 2+Math.random()*4;
          fxParticles.push({ x, y, vx:Math.cos(a)*s, vy:Math.sin(a)*s-2, life:1,
            decay:0.035+Math.random()*0.035, size:2+Math.random()*3,
            color:colors[Math.floor(Math.random()*colors.length)], type:'spark' });
        }
        break;
      }
      case 'hearts':
        if (Math.random()>0.35) break;
        fxParticles.push({ x:x+(Math.random()-0.5)*24, y, vx:(Math.random()-0.5)*1.2,
          vy:-(1.5+Math.random()*2.5), life:1, decay:0.018+Math.random()*0.018,
          size:12+Math.random()*14, type:'heart' });
        break;
      case 'snow':
        if (Math.random()>0.3) break;
        fxParticles.push({ x:x+(Math.random()-0.5)*20, y, vx:(Math.random()-0.5)*0.6,
          vy:0.8+Math.random()*1.5, life:1, decay:0.012+Math.random()*0.012,
          size:10+Math.random()*12, type:'snow' });
        break;
      case 'rainbow': {
        for (let i = 0; i < 2+Math.floor(Math.random()*3); i++) {
          const hue=Math.random()*360, a=Math.random()*Math.PI*2, s=0.8+Math.random()*1.5;
          fxParticles.push({ x:x+(Math.random()-0.5)*8, y:y+(Math.random()-0.5)*8,
            vx:Math.cos(a)*s, vy:Math.sin(a)*s-0.5, life:1, decay:0.012+Math.random()*0.012,
            size:6+Math.random()*8, color:'hsl('+hue+',100%,65%)', type:'dot' });
        }
        break;
      }
      case 'stars':
        if (Math.random()>0.4) break;
        fxParticles.push({ x:x+(Math.random()-0.5)*24, y:y+(Math.random()-0.5)*24,
          vx:(Math.random()-0.5)*1, vy:-(0.5+Math.random()*1.5), life:1,
          decay:0.015+Math.random()*0.015, size:12+Math.random()*16, type:'star' });
        break;
    }
  }

  function renderParticle(p) {
    fxCtx.save();
    fxCtx.globalAlpha = Math.max(0, p.life);
    switch (p.type) {
      case 'spark':
        fxCtx.shadowBlur=12; fxCtx.shadowColor=p.color; fxCtx.strokeStyle=p.color;
        fxCtx.lineWidth=p.size*p.life; fxCtx.lineCap='round';
        fxCtx.beginPath(); fxCtx.moveTo(p.x,p.y); fxCtx.lineTo(p.x-p.vx*3,p.y-p.vy*3); fxCtx.stroke();
        fxCtx.fillStyle='#fff'; fxCtx.shadowBlur=6;
        fxCtx.beginPath(); fxCtx.arc(p.x,p.y,p.size*p.life*0.6,0,Math.PI*2); fxCtx.fill();
        break;
      case 'dot': {
        const g = fxCtx.createRadialGradient(p.x,p.y,0,p.x,p.y,p.size);
        g.addColorStop(0,p.color); g.addColorStop(1,'transparent');
        fxCtx.fillStyle=g; fxCtx.beginPath(); fxCtx.arc(p.x,p.y,p.size,0,Math.PI*2); fxCtx.fill();
        break;
      }
      default:
        fxCtx.font=p.size+'px serif'; fxCtx.textAlign='center'; fxCtx.textBaseline='middle';
        fxCtx.fillText(
          p.type==='heart' ? '❤️' : p.type==='snow' ? '❄️' : '⭐',
          p.x, p.y
        );
    }
    fxCtx.restore();
  }

  function fxLoop() {
    fxRAF = requestAnimationFrame(fxLoop);
    fxCtx.clearRect(0,0,fxCanvas.width,fxCanvas.height);
    if (fxActive && fxMouseMoved && fxType!=='none') {
      spawnFxParticles(fxMouseX, fxMouseY);
      fxMouseMoved = false;
    }
    const alive = [];
    for (const p of fxParticles) {
      p.x+=p.vx; p.y+=p.vy; p.vy+=0.06; p.life-=p.decay;
      if (p.life>0) { renderParticle(p); alive.push(p); }
    }
    fxParticles = alive;
  }

  function stopCursorEffect() {
    fxActive=false; fxType='none';
    if (fxMoveHandler) { document.removeEventListener('mousemove',fxMoveHandler); fxMoveHandler=null; }
    fxParticles=[];
    if (fxCtx&&fxCanvas) fxCtx.clearRect(0,0,fxCanvas.width,fxCanvas.height);
  }

  function startCursorEffect(type) {
    stopCursorEffect();
    if (type==='none') return;
    ensureFxCanvas();
    fxType=type; fxActive=true;
    if (!fxRAF) fxLoop();
    fxMoveHandler = e => { fxMouseX=e.clientX; fxMouseY=e.clientY; fxMouseMoved=true; };
    document.addEventListener('mousemove',fxMoveHandler);
  }

  // ══════════════════════════════════════════════════════════════
  // ЗАПОМНИТЬ ПОЗИЦИЮ
  // ══════════════════════════════════════════════════════════════
  const POSITIONS_KEY = 'yt_pro_positions';
  function loadPositions() { try { return JSON.parse(GM_getValue(POSITIONS_KEY,'{}')); } catch(e) { return {}; } }
  function savePosition(id,t) { const p=loadPositions(); p[id]=t; const k=Object.keys(p); if(k.length>200) delete p[k[0]]; GM_setValue(POSITIONS_KEY,JSON.stringify(p)); }
  function getSavedPosition(id) { return loadPositions()[id]||0; }
  let positionRestored=false;

  function startPositionWatcher() {
    setInterval(()=>{
      if (!(cfg.rememberPosition===true||cfg.rememberPosition==='true')) return;
      const id=new URLSearchParams(window.location.search).get('v');
      const v=document.querySelector('video');
      if (id&&v&&!v.paused&&v.currentTime>3) savePosition(id,v.currentTime);
    },1000);
    let lastUrl=location.href;
    new MutationObserver(()=>{
      if (location.href!==lastUrl) { lastUrl=location.href; positionRestored=false; setTimeout(restorePosition,2000); }
    }).observe(document.documentElement,{childList:true,subtree:true});
    setTimeout(restorePosition,2500);
  }

  function restorePosition() {
    if (!(cfg.rememberPosition===true||cfg.rememberPosition==='true')) return;
    if (positionRestored) return;
    const id=new URLSearchParams(window.location.search).get('v');
    if (!id) return;
    const saved=getSavedPosition(id);
    if (saved<3) return;
    const v=document.querySelector('video');
    if (!v) { setTimeout(restorePosition,1000); return; }
    if (v.duration&&saved<v.duration-10) { v.currentTime=saved; positionRestored=true; showToast('🕒 Resumed from '+formatTime(saved)); }
  }

  function formatTime(sec) {
    sec=Math.floor(sec);
    const h=Math.floor(sec/3600), m=Math.floor((sec%3600)/60), s=sec%60;
    if (h>0) return h+':'+String(m).padStart(2,'0')+':'+String(s).padStart(2,'0');
    return m+':'+String(s).padStart(2,'0');
  }

  // ══════════════════════════════════════════════════════════════
  // TOAST
  // ══════════════════════════════════════════════════════════════
  function showToast(msg) {
    let toast=document.getElementById('yt-pro-toast');
    if (!toast) { toast=document.createElement('div'); toast.id='yt-pro-toast'; document.documentElement.appendChild(toast); }
    toast.textContent=msg;
    toast.style.opacity='1';
    toast.style.transform='translateX(-50%) translateY(0)';
    clearTimeout(toast._timer);
    toast._timer=setTimeout(()=>{ toast.style.opacity='0'; toast.style.transform='translateX(-50%) translateY(20px)'; },3000);
  }

  // ══════════════════════════════════════════════════════════════
  // ВИДЕО
  // ══════════════════════════════════════════════════════════════
  let audioCtx=null, gainNode=null, mediaSource=null;

  function setupAudioBoost(v) {
    if (!v||v._ytProBoosted) return;
    try {
      if (!audioCtx) audioCtx=new (window.AudioContext||window.webkitAudioContext)();
      if (gainNode) { try{gainNode.disconnect();}catch(e){} }
      if (mediaSource) { try{mediaSource.disconnect();}catch(e){} }
      mediaSource=audioCtx.createMediaElementSource(v);
      gainNode=audioCtx.createGain();
      mediaSource.connect(gainNode); gainNode.connect(audioCtx.destination);
      v._ytProBoosted=true; applyVideoVolume(cfg.videoVolume);
    } catch(e) { console.warn('[YT Pro]',e); }
  }

  function applyVideoSpeed(val) { const v=document.querySelector('video'); if(v) v.playbackRate=parseFloat(val); }

  function applyVideoVolume(val) {
    const pct=parseFloat(val), v=document.querySelector('video');
    if (!v) return;
    if (pct<=100) { v.volume=pct/100; if(gainNode) gainNode.gain.value=1; }
    else { if(!v._ytProBoosted) setupAudioBoost(v); v.volume=1; if(gainNode) gainNode.gain.value=pct/100; }
  }

  function watchVideo() {
    new MutationObserver(()=>{
      const v=document.querySelector('video');
      if (v) { if(!v._ytProBoosted&&cfg.videoVolume>100) setupAudioBoost(v); v.playbackRate=parseFloat(cfg.videoSpeed); applyVideoVolume(cfg.videoVolume); }
    }).observe(document.body,{childList:true,subtree:true});
    document.addEventListener('loadeddata',()=>{
      const v=document.querySelector('video');
      if (v) { if(!v._ytProBoosted) setupAudioBoost(v); applyVideoSpeed(cfg.videoSpeed); applyVideoVolume(cfg.videoVolume); }
    },true);
  }

  let wePaused=false;
  function pauseVideo() { const v=document.querySelector('video'); if(v&&!v.paused){v.pause();return true;} return false; }
  function resumeVideo() { const v=document.querySelector('video'); if(v&&v.paused) v.play(); }

  // ══════════════════════════════════════════════════════════════
  // СЕЗОННЫЕ ТЕМЫ
  // ══════════════════════════════════════════════════════════════
  const PARTICLE_CONFIG = {
    ny:{ count:60, emojis:['❄️','❅','❆','⛄','🌨️'], sizes:[14,18,22,26], speed:[6,14],
      css:`html.yt-ny ytd-app,html.yt-ny #content{background:linear-gradient(180deg,#0a1628 0%,#0d2044 40%,#0a1628 100%)!important}
html.yt-ny #masthead{background:linear-gradient(90deg,#0d2a5e,#1a4a8a,#0d2a5e)!important;border-bottom:2px solid #4af!important;box-shadow:0 2px 20px rgba(100,180,255,0.4)!important}
html.yt-ny ytd-guide-renderer,html.yt-ny #guide-inner-content{background:linear-gradient(180deg,#0a1e40,#0d2855)!important}
html.yt-ny yt-formatted-string,html.yt-ny #video-title,html.yt-ny .title{color:#c8e8ff!important}
html.yt-ny ytd-thumbnail{border-radius:10px!important;box-shadow:0 0 12px rgba(150,210,255,0.25)!important}` },
    hw:{ count:40, emojis:['🎃','👻','🕷️','🦇','💀'], sizes:[18,22,28,34], speed:[5,12],
      css:`html.yt-hw ytd-app,html.yt-hw #content{background:linear-gradient(180deg,#0d0500 0%,#1a0a00 40%,#0d0500 100%)!important}
html.yt-hw #masthead{background:linear-gradient(90deg,#1a0a00,#2d1200,#1a0a00)!important;border-bottom:2px solid #c05000!important;box-shadow:0 2px 20px rgba(200,80,0,0.5)!important}
html.yt-hw ytd-guide-renderer,html.yt-hw #guide-inner-content{background:linear-gradient(180deg,#120600,#1e0e00)!important}
html.yt-hw yt-formatted-string,html.yt-hw #video-title,html.yt-hw .title{color:#ffb060!important}
html.yt-hw ytd-thumbnail{border-radius:10px!important;box-shadow:0 0 14px rgba(200,80,0,0.3)!important}` }
  };

  let particleContainer=null, particleInterval=null;
  function clearParticles() { particleContainer?.remove(); particleContainer=null; if(particleInterval){clearInterval(particleInterval);particleInterval=null;} }

  function spawnParticle(pcfg) {
    if (!particleContainer) return;
    const span=document.createElement('span');
    const emoji=pcfg.emojis[Math.floor(Math.random()*pcfg.emojis.length)];
    const size=pcfg.sizes[Math.floor(Math.random()*pcfg.sizes.length)];
    const left=Math.random()*100, dur=pcfg.speed[0]+Math.random()*(pcfg.speed[1]-pcfg.speed[0]);
    const delay=Math.random()*-dur, wobbleX=(Math.random()-0.5)*80;
    span.textContent=emoji;
    span.style.cssText=['position:fixed','top:-60px','left:'+left+'vw','font-size:'+size+'px',
      'opacity:'+(0.6+Math.random()*0.4),'pointer-events:none','z-index:2147483630','user-select:none',
      'animation:yt-particle-fall '+dur+'s linear '+delay+'s infinite','--wobble:'+wobbleX+'px'].join(';');
    particleContainer.appendChild(span);
    if (particleContainer.children.length>pcfg.count+10) particleContainer.children[0].remove();
  }

  function startParticles(type) {
    clearParticles(); if(type==='none') return;
    const pcfg=PARTICLE_CONFIG[type]; if(!pcfg) return;
    particleContainer=document.createElement('div');
    particleContainer.id='yt-particles';
    particleContainer.style.cssText='position:fixed;inset:0;pointer-events:none;z-index:2147483630;overflow:hidden';
    document.documentElement.appendChild(particleContainer);
    for (let i=0;i<pcfg.count;i++) setTimeout(()=>spawnParticle(pcfg),i*150);
    particleInterval=setInterval(()=>spawnParticle(pcfg),600);
  }

  let seasonStyleEl=null;
  function setSeasonStyle() {
    if (!seasonStyleEl) { seasonStyleEl=document.createElement('style'); seasonStyleEl.id='yt-season-style'; document.head.appendChild(seasonStyleEl); }
    document.documentElement.classList.remove('yt-ny','yt-hw');
    if (cfg.seasonal==='ny') {
      seasonStyleEl.textContent=PARTICLE_CONFIG.ny.css+'@keyframes yt-particle-fall{0%{transform:translateY(0) translateX(0) rotate(0deg);opacity:1}50%{transform:translateY(50vh) translateX(var(--wobble)) rotate(180deg)}100%{transform:translateY(110vh) translateX(0) rotate(360deg);opacity:0.3}}';
      document.documentElement.classList.add('yt-ny'); startParticles('ny');
    } else if (cfg.seasonal==='hw') {
      seasonStyleEl.textContent=PARTICLE_CONFIG.hw.css+'@keyframes yt-particle-fall{0%{transform:translateY(0) translateX(0) rotate(-10deg);opacity:1}25%{transform:translateY(25vh) translateX(var(--wobble)) rotate(10deg)}50%{transform:translateY(50vh) translateX(0) rotate(-15deg)}75%{transform:translateY(75vh) translateX(calc(var(--wobble)*-0.5)) rotate(8deg)}100%{transform:translateY(110vh) translateX(0) rotate(-5deg);opacity:0.2}}';
      document.documentElement.classList.add('yt-hw'); startParticles('hw');
    } else { seasonStyleEl.textContent=''; clearParticles(); }
  }

  let rbStyleEl=null;
  function setRainbowStyle() {
    if (!rbStyleEl) { rbStyleEl=document.createElement('style'); rbStyleEl.id='yt-rb-style'; document.head.appendChild(rbStyleEl); }
    if (cfg.theme!=='rainbow') { rbStyleEl.textContent=''; return; }
    const spd=Number(cfg.rbSpeed)+'s';
    rbStyleEl.textContent=[
      '@keyframes yt-rb-hue{0%{filter:hue-rotate(0deg)}100%{filter:hue-rotate(360deg)}}',
      '@keyframes yt-rb-pos{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}',
      'html.yt-rb-on{animation:yt-rb-hue '+spd+' linear infinite!important}',
      '#yt-rb-overlay{position:fixed!important;inset:0!important;z-index:2147483640!important;pointer-events:none!important;background:linear-gradient(135deg,rgba(255,0,0,.15),rgba(255,120,0,.15),rgba(255,255,0,.15),rgba(0,255,80,.15),rgba(0,200,255,.15),rgba(80,0,255,.15),rgba(255,0,200,.15),rgba(255,0,0,.15))!important;background-size:400% 400%!important;animation:yt-rb-pos '+spd+' ease infinite!important;mix-blend-mode:color!important;}'
    ].join('');
  }

  function syncRainbowOverlay() {
    let ov=document.getElementById('yt-rb-overlay');
    if (cfg.theme==='rainbow') {
      if(!ov){ov=document.createElement('div');ov.id='yt-rb-overlay';document.documentElement.appendChild(ov);}
      document.documentElement.classList.add('yt-rb-on');
    } else { ov?.remove(); document.documentElement.classList.remove('yt-rb-on'); }
  }

  // ══════════════════════════════════════════════════════════════
  // СТИЛИ
  // ══════════════════════════════════════════════════════════════
  GM_addStyle([
    "@import url('https://fonts.googleapis.com/css2?family=Exo+2:wght@400;600;900&display=swap');",
    '#yt-proroot{position:fixed!important;top:0!important;left:0!important;width:0!important;height:0!important;overflow:visible!important;z-index:2147483647!important;pointer-events:none!important;transform:none!important;}',
    '#yt-pro-menu{position:fixed!important;border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,0.9);display:flex;visibility:hidden;opacity:0;pointer-events:none;flex-direction:row;overflow:hidden;font-family:"Exo 2",sans-serif;color:#eef;z-index:2147483647;transition:opacity .35s ease,visibility 0s linear .35s;border:1px solid rgba(255,255,255,0.15);width:650px;height:530px;}',
    '#yt-pro-menu.active{visibility:visible!important;opacity:1!important;pointer-events:all!important;transition:opacity .35s ease,visibility 0s linear 0s;}',
    '#yt-pro-menu.dragging{transition:none!important;user-select:none!important;}',
    '.yt-sidebar{width:180px;background:rgba(0,0,0,0.3);border-right:1px solid rgba(255,255,255,0.08);padding:20px 10px;display:flex;flex-direction:column;gap:10px;flex-shrink:0;}',
    '.yt-sidebar-credit{margin-top:auto;padding-top:10px;font-size:10px;color:rgba(255,255,255,0.2);text-align:center;line-height:1.5;user-select:none;letter-spacing:0.3px;}',
    '.yt-nav-btn{padding:12px;border-radius:10px;cursor:pointer;font-weight:600;color:#888;transition:all .25s;display:flex;align-items:center;gap:10px;user-select:none;}',
    '.yt-nav-btn:hover{color:#ccc;background:rgba(255,255,255,0.05);}',
    '.yt-nav-btn.sel{background:linear-gradient(90deg,rgba(255,32,96,0.2),rgba(136,85,255,0.2));color:#fff;border-left:3px solid #ff2060;}',
    '.yt-content{flex:1;padding:20px;overflow-y:auto;}',
    '.yt-content::-webkit-scrollbar{width:4px;}',
    '.yt-content::-webkit-scrollbar-track{background:transparent;}',
    '.yt-content::-webkit-scrollbar-thumb{background:rgba(136,85,255,0.5);border-radius:2px;}',
    '.yt-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;border-bottom:1px solid rgba(255,255,255,0.1);padding-bottom:10px;cursor:grab;user-select:none;}',
    '.yt-header:active{cursor:grabbing;}',
    '.yt-title{font-size:20px;font-weight:900;background:linear-gradient(90deg,#ff2060,#8855ff);-webkit-background-clip:text;-webkit-text-fill-color:transparent;pointer-events:none;}',
    '.yt-close{cursor:pointer!important;font-size:24px;line-height:1;opacity:0.7;transition:opacity .2s;pointer-events:all!important;}',
    '.yt-close:hover{opacity:1;}',
    '.yt-section{display:none;}',
    '.yt-section.show{display:block;}',
    '.yt-row{display:flex;align-items:center;justify-content:space-between;padding:12px;background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:12px;margin-bottom:8px;cursor:pointer;transition:border-color .2s,background .2s;user-select:none;}',
    '.yt-row:hover{background:rgba(255,255,255,0.07);}',
    '.yt-row.active{border-color:#8855ff;background:rgba(136,85,255,0.13);}',
    '.yt-draw-colors{display:flex;flex-wrap:wrap;gap:8px;padding:10px;background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:12px;margin-bottom:8px;}',
    '.yt-draw-color{width:28px;height:28px;border-radius:50%;cursor:pointer;border:3px solid transparent;transition:all .2s;flex-shrink:0;}',
    '.yt-draw-color:hover{transform:scale(1.2);}',
    '.yt-draw-color.active{border-color:#fff!important;transform:scale(1.25);box-shadow:0 0 10px rgba(255,255,255,0.5);}',
    '.yt-clear-btn{width:100%;padding:10px;border-radius:12px;border:1.5px solid rgba(255,80,80,0.4);background:rgba(255,50,50,0.08);color:#ff8080;font-family:"Exo 2",sans-serif;font-size:13px;font-weight:700;cursor:pointer;transition:all .2s;margin-bottom:8px;letter-spacing:0.5px;}',
    '.yt-clear-btn:hover{background:rgba(255,50,50,0.2);border-color:rgba(255,80,80,0.8);color:#fff;box-shadow:0 0 12px rgba(255,50,50,0.3);}',
    '.yt-fx-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin-bottom:8px;}',
    '.yt-fx-card{border-radius:12px;border:2px solid rgba(255,255,255,0.08);padding:12px 6px;text-align:center;cursor:pointer;transition:all .25s;user-select:none;background:rgba(255,255,255,0.03);}',
    '.yt-fx-card:hover{background:rgba(255,255,255,0.07);border-color:rgba(255,255,255,0.2);}',
    '.yt-fx-card.active{border-color:#ff2060;background:rgba(255,32,96,0.13);box-shadow:0 0 14px rgba(255,32,96,0.2);}',
    '.yt-fx-icon{font-size:24px;display:block;margin-bottom:4px;}',
    '.yt-fx-label{font-size:11px;font-weight:700;letter-spacing:.3px;color:#aaa;}',
    '.yt-fx-card.active .yt-fx-label{color:#ff8099;}',
    '.yt-slider-row{padding:14px;background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:12px;margin-bottom:8px;}',
    '.yt-slider-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;}',
    '.yt-slider-label{font-size:13px;font-weight:600;}',
    '.yt-slider-val{font-size:13px;font-weight:700;background:linear-gradient(90deg,#ff2060,#8855ff);-webkit-background-clip:text;-webkit-text-fill-color:transparent;min-width:50px;text-align:right;}',
    '.yt-lang-block{background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:12px;margin-bottom:8px;overflow:hidden;}',
    '.yt-lang-header{display:flex;align-items:center;justify-content:space-between;padding:12px;cursor:pointer;user-select:none;transition:background .2s;}',
    '.yt-lang-header:hover{background:rgba(255,255,255,0.04);}',
    '.yt-lang-header-left{display:flex;align-items:center;gap:8px;}',
    '.yt-lang-arrow{font-size:10px;color:#666;transition:transform .3s;display:inline-block;}',
    '.yt-lang-arrow.open{transform:rotate(180deg);}',
    '.yt-lang-body{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(0.4,0,0.2,1);}',
    '.yt-lang-body.open{max-height:200px;}',
    '.yt-lang-options{padding:6px 10px 12px;display:flex;flex-direction:column;gap:6px;}',
    '.yt-lang-option{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:10px;cursor:pointer;transition:background .2s,border-color .2s;border:1.5px solid rgba(255,255,255,0.06);user-select:none;}',
    '.yt-lang-option:hover{background:rgba(255,255,255,0.06);}',
    '.yt-lang-option.active{border-color:#8855ff;background:rgba(136,85,255,0.13);}',
    '.yt-lang-flag{font-size:20px;}',
    '.yt-lang-name{font-weight:600;font-size:14px;}',
    '.yt-lang-check{margin-left:auto;color:#8855ff;font-size:16px;}',
    '.yt-season-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:8px;}',
    '.yt-season-card{border-radius:14px;border:2px solid rgba(255,255,255,0.08);padding:14px 8px;text-align:center;cursor:pointer;transition:all .25s;user-select:none;position:relative;overflow:hidden;}',
    '.yt-season-card::before{content:"";position:absolute;inset:0;opacity:0;transition:opacity .25s;}',
    '.yt-season-card:hover::before{opacity:1;}',
    '.yt-season-card .sc-icon{font-size:32px;display:block;margin-bottom:6px;}',
    '.yt-season-card .sc-label{font-size:12px;font-weight:700;letter-spacing:.5px;}',
    '.yt-season-card.sc-none{background:rgba(255,255,255,0.03);}',
    '.yt-season-card.sc-none::before{background:rgba(255,255,255,0.04);}',
    '.yt-season-card.sc-none.active{border-color:#8855ff;background:rgba(136,85,255,0.15);}',
    '.yt-season-card.sc-ny{background:linear-gradient(145deg,rgba(10,30,80,0.8),rgba(20,60,120,0.8));}',
    '.yt-season-card.sc-ny::before{background:linear-gradient(145deg,rgba(100,180,255,0.1),rgba(200,240,255,0.05));}',
    '.yt-season-card.sc-ny.active{border-color:#4af;box-shadow:0 0 20px rgba(80,180,255,0.4),inset 0 0 20px rgba(80,180,255,0.1);}',
    '.yt-season-card.sc-ny .sc-label{color:#9cf;}',
    '.yt-season-card.sc-hw{background:linear-gradient(145deg,rgba(40,15,0,0.9),rgba(80,30,0,0.9));}',
    '.yt-season-card.sc-hw::before{background:linear-gradient(145deg,rgba(255,100,0,0.1),rgba(255,60,0,0.05));}',
    '.yt-season-card.sc-hw.active{border-color:#f80;box-shadow:0 0 20px rgba(255,120,0,0.4),inset 0 0 20px rgba(255,80,0,0.1);}',
    '.yt-season-card.sc-hw .sc-label{color:#f90;}',
    '.yt-switch{width:38px;height:20px;background:rgba(255,255,255,0.15);border-radius:20px;position:relative;transition:background .3s;flex-shrink:0;}',
    '.yt-switch.on{background:linear-gradient(90deg,#ff2060,#8855ff);}',
    '.yt-switch::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;background:#fff;border-radius:50%;transition:left .3s;box-shadow:0 1px 3px rgba(0,0,0,0.4);}',
    '.yt-switch.on::after{left:20px;}',
    'input.yt-range{-webkit-appearance:none;width:100%;height:4px;background:linear-gradient(90deg,#ff2060,#8855ff);border-radius:2px;outline:none;cursor:pointer;}',
    'input.yt-range::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;background:#fff;border-radius:50%;cursor:pointer;box-shadow:0 0 8px rgba(255,32,96,0.8);}',
    '.yt-color-chip{width:18px;height:18px;border-radius:50%;border:2px solid rgba(255,255,255,0.3);flex-shrink:0;}',
    '#yt-blur-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2147483646;opacity:0;visibility:hidden;pointer-events:none;backdrop-filter:blur(8px);background:rgba(0,0,0,0.35);cursor:pointer;transition:opacity .35s ease,visibility 0s linear .35s;}',
    '#yt-blur-overlay.on{opacity:1;visibility:visible;pointer-events:all;transition:opacity .35s ease,visibility 0s linear 0s;}',
    'body.yt-cinema #masthead{opacity:0!important;pointer-events:none!important;transition:opacity .5s!important;}',
    'body.yt-cinema ytd-guide-renderer{opacity:0!important;pointer-events:none!important;transition:opacity .5s!important;}',
    'body.yt-cinema #secondary{opacity:0!important;pointer-events:none!important;transition:opacity .5s!important;}',
    'body.yt-cinema #below{opacity:0!important;pointer-events:none!important;transition:opacity .5s!important;}',
    'body.yt-cinema ytd-app{background:#000!important;}',
    '.yt-sep{height:1px;background:rgba(255,255,255,0.08);margin:10px 0;}',
    '.yt-section-label{font-size:11px;font-weight:700;letter-spacing:1px;color:#666;text-transform:uppercase;margin-bottom:8px;padding-left:4px;}',
    '#yt-pro-toast{position:fixed;bottom:80px;left:50%;transform:translateX(-50%) translateY(20px);background:linear-gradient(135deg,rgba(255,32,96,0.95),rgba(136,85,255,0.95));color:#fff;padding:10px 20px;border-radius:30px;font-family:"Exo 2",sans-serif;font-size:14px;font-weight:600;z-index:2147483647;opacity:0;transition:opacity .4s ease,transform .4s ease;pointer-events:none;box-shadow:0 4px 20px rgba(255,32,96,0.4);letter-spacing:0.3px;}',
  ].join(''));

  // ─── Хелперы ──────────────────────────────────────────────────
  function el(tag, cls, txt) {
    const e = document.createElement(tag);
    if (cls) e.className = cls;
    if (txt !== undefined) e.textContent = txt;
    return e;
  }
  function sep() { return el('div','yt-sep'); }
  function lbl(txt) { return el('div','yt-section-label',txt); }

  function makeSwitch(row, active, onToggle) {
    const sw = el('div','yt-switch'+(active?' on':''));
    row.addEventListener('click', e => { e.stopPropagation(); onToggle(sw.classList.toggle('on')); });
    row.appendChild(sw);
    return sw;
  }

  function makeSlider({ label, min, max, step, value, unit, onChange }) {
    const row=el('div','yt-slider-row'), top=el('div','yt-slider-top');
    const lblEl=el('span','yt-slider-label',label), valEl=el('span','yt-slider-val',value+unit);
    top.append(lblEl,valEl);
    const input=document.createElement('input');
    input.type='range'; input.min=min; input.max=max; input.step=step; input.value=value; input.className='yt-range';
    input.addEventListener('input', e => { e.stopPropagation(); const v=parseFloat(input.value); valEl.textContent=v+unit; onChange(v); });
    row.append(top,input);
    return { row, input, valEl };
  }

  function applySettings() {
    setRainbowStyle(); syncRainbowOverlay(); setSeasonStyle();
    document.body.classList.toggle('yt-cinema', cfg.cinema===true||cfg.cinema==='true');
    document.documentElement.style.setProperty('cursor', getCursorStyle(cfg.cursor), 'important');
    updateMenuStyle(); applyVideoSpeed(cfg.videoSpeed); applyVideoVolume(cfg.videoVolume);
    startCursorEffect(cfg.cursorEffect); applyDrawMode();
  }

  function updateMenuStyle() {
    const menu=document.getElementById('yt-pro-menu');
    if (!menu) return;
    const isGlass=cfg.menuTransparent===true||cfg.menuTransparent==='true';
    if (isGlass) {
      menu.style.background='rgba(200,200,220,0.06)';
      menu.style.backdropFilter='blur(28px) saturate(150%) brightness(1.15)';
      menu.style.borderColor='rgba(255,255,255,0.3)';
      menu.style.color='#fff';
      menu.style.boxShadow='0 8px 32px rgba(0,0,0,0.4),inset 0 0 0 1px rgba(255,255,255,0.15)';
    } else {
      const color=MENU_COLORS[cfg.menuColor]||MENU_COLORS.default;
      menu.style.background=color.bg; menu.style.backdropFilter='none';
      menu.style.borderColor=color.border; menu.style.color=color.text;
      menu.style.boxShadow='0 20px 60px rgba(0,0,0,0.9)';
    }
  }

  function syncOverlay(menuOpen) {
    const ov=document.getElementById('yt-blur-overlay');
    if (!ov) return;
    ov.classList.toggle('on', menuOpen&&(cfg.menuBlur===true||cfg.menuBlur==='true'));
  }

  // ─── Построение меню ──────────────────────────────────────────
  function createMenu() {
    if (document.getElementById('yt-pro-menu')) return;
    const root=el('div'); root.id='yt-pro-root';
    document.documentElement.appendChild(root);

    const overlay=el('div'); overlay.id='yt-blur-overlay';
    overlay.addEventListener('click', closeMenu);
    root.appendChild(overlay);

    const menu=el('div'); menu.id='yt-pro-menu';
    const startX = Math.round(window.innerWidth / 2 - 325);
    const startY = Math.round(window.innerHeight / 2 - 265);
    menu.style.left = startX + 'px';
    menu.style.top  = startY + 'px';

    const sidebar=el('div','yt-sidebar');
    const content=el('div','yt-content');

    const tabs=[
      {id:'y', label:t('categories.youtube')},
      {id:'m', label:t('categories.menu')},
      {id:'d', label:t('categories.design')},
      {id:'c', label:t('categories.cursor')},
    ];
    const sections={};
    tabs.forEach((tab,i)=>{
      const btn=el('div','yt-nav-btn'+(i===0?' sel':''),tab.label);
      btn.addEventListener('click',()=>{
        sidebar.querySelectorAll('.yt-nav-btn').forEach(b=>b.classList.remove('sel'));
        btn.classList.add('sel');
        Object.values(sections).forEach(s=>s.classList.remove('show'));
        sections[tab.id].classList.add('show');
      });
      sidebar.appendChild(btn);
      const sec=el('div','yt-section'+(i===0?' show':''));
      sec.id='tab-'+tab.id; sections[tab.id]=sec;
    });

    const credit=el('div','yt-sidebar-credit','YouTube menu\nby ');
    credit.style.whiteSpace='pre';
    const creditLink=document.createElement('a');
    creditLink.textContent='Bveery';
    creditLink.href='https://www.youtube.com/@Bveery';
    creditLink.target='_blank';
    creditLink.style.cssText='color:rgba(255,100,120,0.6);text-decoration:none;transition:color .2s;cursor:pointer;';
    creditLink.addEventListener('mouseenter',()=>{creditLink.style.color='#ff2060';creditLink.style.textShadow='0 0 8px rgba(255,32,96,0.6)';});
    creditLink.addEventListener('mouseleave',()=>{creditLink.style.color='rgba(255,100,120,0.6)';creditLink.style.textShadow='none';});
    credit.appendChild(creditLink);
    sidebar.appendChild(credit);

    const header=el('div','yt-header');
    const titleEl=el('div','yt-title',t('title'));
    const closeBtn=el('div','yt-close','×');
    closeBtn.addEventListener('click', closeMenu);
    header.append(titleEl, closeBtn);
    content.appendChild(header);

    // Перетаскивание
    let dragActive=false, dragOffX=0, dragOffY=0;
    header.addEventListener('mousedown', e => {
      if (e.target === closeBtn) return;
      dragActive = true;
      menu.classList.add('dragging');
      const rect = menu.getBoundingClientRect();
      dragOffX = e.clientX - rect.left;
      dragOffY = e.clientY - rect.top;
      e.preventDefault();
    });
    document.addEventListener('mousemove', e => {
      if (!dragActive) return;
      let nx = e.clientX - dragOffX;
      let ny = e.clientY - dragOffY;
      nx = Math.max(0, Math.min(window.innerWidth  - menu.offsetWidth,  nx));
      ny = Math.max(0, Math.min(window.innerHeight - menu.offsetHeight, ny));
      menu.style.left = nx + 'px';
      menu.style.top  = ny + 'px';
    });
    document.addEventListener('mouseup', () => {
      if (!dragActive) return;
      dragActive = false;
      menu.classList.remove('dragging');
    });

    // ══ TAB: YOUTUBE ══════════════════════════════════════════
    const tabY=sections.y;
    tabY.appendChild(lbl(t('youtube.speedSection')));
    const {row:speedRow}=makeSlider({label:t('youtube.speed'),min:0.25,max:16,step:0.25,value:cfg.videoSpeed,unit:'x',onChange:v=>{save('videoSpeed',v);applyVideoSpeed(v);}});
    tabY.appendChild(speedRow);
    tabY.appendChild(sep());
    tabY.appendChild(lbl(t('youtube.volumeSection')));
    const {row:volRow}=makeSlider({label:t('youtube.volume'),min:0,max:300,step:1,value:cfg.videoVolume,unit:'%',onChange:v=>{save('videoVolume',v);applyVideoVolume(v);}});
    tabY.appendChild(volRow);
    const volHint=el('div','','⚠️ Values above 100% may distort audio');
    volHint.style.cssText='font-size:10px;color:rgba(255,180,0,0.6);padding:4px 4px 8px;';
    tabY.appendChild(volHint);
    tabY.appendChild(sep());
    tabY.appendChild(lbl(t('youtube.rememberSection')));
    const remRow=el('div','yt-row',t('youtube.remember'));
    makeSwitch(remRow,cfg.rememberPosition,on=>{save('rememberPosition',on);if(on){showToast('🕒 Position memory ON');restorePosition();}else showToast('⏹️ Position memory OFF');});
    tabY.appendChild(remRow);

    // ══ TAB: MENU ═════════════════════════════════════════════
    const tabM=sections.m;
    const langBlock=el('div','yt-lang-block');
    const langHeader=el('div','yt-lang-header');
    const langLeft=el('div','yt-lang-header-left');
    langLeft.append(el('span','','⚙️'),el('span','',t('menu.lang')));
    const langArrow=el('span','yt-lang-arrow','▼');
    langHeader.append(langLeft,langArrow);
    const langBody=el('div','yt-lang-body');
    const langOptions=el('div','yt-lang-options');
    [{code:'en',flag:'🇬🇧',name:t('menu.langEn')},{code:'ru',flag:'🇷🇺',name:t('menu.langRu')}].forEach(lang=>{
      const opt=el('div','yt-lang-option'+(cfg.language===lang.code?' active':''));
      opt.append(el('span','yt-lang-flag',lang.flag),el('span','yt-lang-name',lang.name),el('span','yt-lang-check',cfg.language===lang.code?'✓':''));
      opt.addEventListener('click',()=>{if(cfg.language===lang.code)return;save('language',lang.code);location.reload();});
      langOptions.appendChild(opt);
    });
    langBody.appendChild(langOptions);
    langBlock.append(langHeader,langBody);
    let langOpen=false;
    langHeader.addEventListener('click',()=>{langOpen=!langOpen;langBody.classList.toggle('open',langOpen);langArrow.classList.toggle('open',langOpen);});
    tabM.appendChild(langBlock);

    const blurRow=el('div','yt-row',t('menu.blur'));
    makeSwitch(blurRow,cfg.menuBlur,on=>{save('menuBlur',on);syncOverlay(isVisible);});
    tabM.appendChild(blurRow);
    const glassRow=el('div','yt-row',t('menu.transparent'));
    makeSwitch(glassRow,cfg.menuTransparent,on=>{save('menuTransparent',on);updateMenuStyle();});
    tabM.appendChild(glassRow);
    const pauseRow=el('div','yt-row',t('menu.pauseOnMenu'));
    makeSwitch(pauseRow,cfg.pauseOnMenu,on=>{save('pauseOnMenu',on);});
    tabM.appendChild(pauseRow);
    tabM.appendChild(sep());
    tabM.appendChild(lbl(t('menu.colorTitle')));
    Object.keys(MENU_COLORS).forEach(c=>{
      const row=el('div','yt-row'+(cfg.menuColor===c?' active':''));
      const name=el('span','',c.charAt(0).toUpperCase()+c.slice(1));
      const chip=el('div','yt-color-chip'); chip.style.background=COLOR_CHIPS[c]||'#888';
      row.append(name,chip);
      row.addEventListener('click',()=>{save('menuColor',c);tabM.querySelectorAll('.yt-row').forEach(r=>r.classList.remove('active'));row.classList.add('active');updateMenuStyle();});
      tabM.appendChild(row);
    });

    // ══ TAB: DESIGN ═══════════════════════════════════════════
    const tabD=sections.d;
    tabD.appendChild(lbl(t('design.rbSection')));
    const rbRow=el('div','yt-row',t('design.rainbow'));
    makeSwitch(rbRow,cfg.theme==='rainbow',on=>{save('theme',on?'rainbow':'none');applySettings();});
    tabD.appendChild(rbRow);
    const {row:rbSpeedRow}=makeSlider({label:t('design.speed'),min:1,max:20,step:1,value:cfg.rbSpeed,unit:'s',onChange:v=>{save('rbSpeed',v);setRainbowStyle();}});
    tabD.appendChild(rbSpeedRow);
    tabD.appendChild(sep());
    tabD.appendChild(lbl(t('design.seasonal')));
    const grid=el('div','yt-season-grid');
    [{key:'none',cls:'sc-none',icon:'⚪',label:t('design.s_none')},{key:'ny',cls:'sc-ny',icon:'❄️',label:t('design.s_ny')},{key:'hw',cls:'sc-hw',icon:'🎃',label:t('design.s_hw')}].forEach(sc=>{
      const card=el('div','yt-season-card '+sc.cls+(cfg.seasonal===sc.key?' active':''));
      card.append(el('span','sc-icon',sc.icon),el('span','sc-label',sc.label));
      card.addEventListener('click',()=>{save('seasonal',sc.key);grid.querySelectorAll('.yt-season-card').forEach(c=>c.classList.remove('active'));card.classList.add('active');setSeasonStyle();});
      grid.appendChild(card);
    });
    tabD.appendChild(grid);
    tabD.appendChild(sep());
    tabD.appendChild(lbl(t('design.cinSection')));
    const cinRow=el('div','yt-row',t('design.cinema'));
    makeSwitch(cinRow,cfg.cinema,on=>{save('cinema',on);applySettings();});
    tabD.appendChild(cinRow);

    // ══ TAB: CURSOR ═══════════════════════════════════════════
    const tabC=sections.c;

    // Рисование
    tabC.appendChild(lbl(t('cursor.drawSection')));
    const drawRow=el('div','yt-row',t('cursor.drawMode'));
    makeSwitch(drawRow,cfg.drawMode,on=>{save('drawMode',on);applyDrawMode();});
    tabC.appendChild(drawRow);
    tabC.appendChild(lbl(t('cursor.drawColor')));
    const colorPicker=el('div','yt-draw-colors');
    DRAW_COLORS.forEach(dc=>{
      const chip=el('div','yt-draw-color'+(cfg.drawColor===dc.color?' active':''));
      chip.style.background=dc.color;
      chip.addEventListener('click',()=>{
        save('drawColor',dc.color);
        colorPicker.querySelectorAll('.yt-draw-color').forEach(c=>c.classList.remove('active'));
        chip.classList.add('active');
      });
      colorPicker.appendChild(chip);
    });
    tabC.appendChild(colorPicker);
    const {row:sizeRow}=makeSlider({label:t('cursor.drawSize'),min:1,max:40,step:1,value:cfg.drawSize,unit:'px',onChange:v=>{save('drawSize',v);}});
    tabC.appendChild(sizeRow);
    const clearBtn=document.createElement('button');
    clearBtn.className='yt-clear-btn';
    clearBtn.textContent=t('cursor.drawClear');
    clearBtn.addEventListener('click',e=>{e.stopPropagation();clearDrawCanvas();});
    tabC.appendChild(clearBtn);
    tabC.appendChild(sep());

    // Стиль курсора
    tabC.appendChild(lbl(t('cursor.cursorSection')));
    CURSOR_KEYS.forEach(key=>{
      const row=el('div','yt-row'+(cfg.cursor===key?' active':''),t('cursor.'+key));
      row.addEventListener('click',()=>{
        save('cursor',key);
        tabC.querySelectorAll('.yt-row').forEach(r=>r.classList.remove('active'));
        row.classList.add('active');
        applySettings();
      });
      tabC.appendChild(row);
    });
    tabC.appendChild(sep());

    // Эффекты курсора
    tabC.appendChild(lbl(t('cursor.effectSection')));
    const fxData=[
      {key:'none',   icon:'⚪', label:t('cursor.fx_none')},
      {key:'sparks', icon:'✨', label:t('cursor.fx_sparks')},
      {key:'hearts', icon:'❤️', label:t('cursor.fx_hearts')},
      {key:'snow',   icon:'❄️', label:t('cursor.fx_snow')},
      {key:'rainbow',icon:'🌈', label:t('cursor.fx_rainbow')},
      {key:'stars',  icon:'⭐', label:t('cursor.fx_stars')},
    ];
    const fxGrid=el('div','yt-fx-grid');
    fxData.forEach(fx=>{
      const card=el('div','yt-fx-card'+(cfg.cursorEffect===fx.key?' active':''));
      card.append(el('span','yt-fx-icon',fx.icon),el('span','yt-fx-label',fx.label));
      card.addEventListener('click',()=>{
        save('cursorEffect',fx.key);
        fxGrid.querySelectorAll('.yt-fx-card').forEach(c=>c.classList.remove('active'));
        card.classList.add('active');
        startCursorEffect(fx.key);
      });
      fxGrid.appendChild(card);
    });
    tabC.appendChild(fxGrid);

    Object.values(sections).forEach(s=>content.appendChild(s));
    menu.append(sidebar,content);
    root.appendChild(menu);
    applySettings();
  }

  // ─── Открытие / Закрытие ──────────────────────────────────────
  let isVisible=false;

  function openMenu() {
    if (!document.getElementById('yt-pro-menu')) createMenu();
    isVisible=true;
    document.getElementById('yt-pro-menu').classList.add('active');
    updateMenuStyle();
    syncOverlay(true);
    if (cfg.pauseOnMenu===true||cfg.pauseOnMenu==='true') wePaused=pauseVideo();
  }

  function closeMenu() {
    isVisible=false;
    document.getElementById('yt-pro-menu')?.classList.remove('active');
    syncOverlay(false);
    if (wePaused&&(cfg.pauseOnMenu===true||cfg.pauseOnMenu==='true')) resumeVideo();
    wePaused=false;
  }

  function toggleMenu() { isVisible?closeMenu():openMenu(); }
  window.addEventListener('keyup', e => { if (e.code==='ShiftRight') toggleMenu(); });

  watchVideo();
  startPositionWatcher();
  applySettings();
})();