Greasy Fork

Greasy Fork is available in English.

YouTube Layout Plus

Home: collapse guide, 5 videos per row, hide Shorts. Watch: hide recommendations sidebar and center the player/content, while preserving live chat on streams/replays. Adds a topbar theme switcher that triggers YouTube's official Appearance modes.

当前为 2026-04-14 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         YouTube Layout Plus
// @namespace    https://qazwsx123.uk/
// @version      0.2.6
// @description  Home: collapse guide, 5 videos per row, hide Shorts. Watch: hide recommendations sidebar and center the player/content, while preserving live chat on streams/replays. Adds a topbar theme switcher that triggers YouTube's official Appearance modes.
// @author       Codex
// @match        https://www.youtube.com/*
// @run-at       document-idle
// @grant        none
// ==/UserScript==

(function () {
  'use strict';

  const STYLE_ID = 'tm-youtube-layout-plus-style';
  const THEME_SWITCHER_ID = 'tm-youtube-layout-plus-theme-switcher';
  const THEME_STATUS_ID = 'tm-youtube-layout-plus-theme-status';
  const THEME_BUSY_CLASS = 'tm-youtube-layout-plus-theme-busy';
  const THEME_MODE_STORAGE_KEY = 'tm-youtube-layout-plus-theme-mode';
  const THEME_MODES = [
    { mode: 'auto', label: 'Auto', prefF6: '80', signal: 'TOGGLE_DARK_THEME_DEVICE' },
    { mode: 'light', label: 'Light', prefF6: '80080', signal: 'TOGGLE_DARK_THEME_OFF' },
    { mode: 'dark', label: 'Dark', prefF6: '480', signal: 'TOGGLE_DARK_THEME_ON' },
  ];

  let currentUrl = location.href;
  let applyFrame = 0;
  let applyDelayTimer = null;
  let bodyObserver = null;
  let routeTimer = null;
  let watchLayoutRetryTimer = null;
  let watchLayoutRetryStep = 0;
  let watchChatStateTimer = null;
  let lastWatchChatExpanded = null;
  let playerSyncTimer = null;
  let lastPlayerSyncKey = '';
  let lastAutoCollapsedHomeUrl = '';
  let lastAutoCollapsedWatchChatKey = '';
  let currentThemeMode = loadStoredThemeMode();
  let themeSwitchInFlight = false;
  let pendingThemeMode = null;
  const WATCH_LAYOUT_RETRY_DELAYS = [0, 40, 120, 260, 520, 900, 1400, 2200, 3200, 4500];

  function isHomePage() {
    return location.pathname === '/';
  }

  function isWatchPage() {
    return location.pathname === '/watch';
  }

  function getWatchPageKey() {
    if (!isWatchPage()) return location.pathname;

    const params = new URLSearchParams(location.search);
    const videoId = params.get('v');
    return videoId ? `/watch?v=${videoId}` : location.pathname;
  }

  function getWatchTeaserText() {
    const teaserCarousel = document.querySelector('ytd-watch-metadata #teaser-carousel');
    return (teaserCarousel?.innerText || teaserCarousel?.textContent || '').trim();
  }

  function hasLiveWatchPrompt(teaserText = getWatchTeaserText()) {
    return /join the conversation to interact with the creator and others watching this live stream/i.test(teaserText)
      || (/watching now/i.test(document.body.innerText) && /started streaming/i.test(document.body.innerText));
  }

  function hasReplayWatchPrompt(teaserText = getWatchTeaserText()) {
    return /live chat replay/i.test(teaserText)
      || /see what others said about this video while it was live/i.test(teaserText);
  }

  function hasWatchSidebarChat(watchFlexy) {
    if (!watchFlexy) return false;

    if (
      watchFlexy.hasAttribute('is-live')
      || watchFlexy.hasAttribute('is-live-content')
      || watchFlexy.hasAttribute('live-chat-collapsed')
    ) {
      return true;
    }

    const liveBadge = watchFlexy.querySelector(
      'ytd-badge-supported-renderer[system-icons][icon="LIVE"], ' +
      'ytd-thumbnail-overlay-time-status-renderer[overlay-style="LIVE"], ' +
      'yt-icon[icon="yt-icons:live"]'
    );
    if (liveBadge && isVisibleElement(liveBadge)) {
      return true;
    }

    const teaserText = getWatchTeaserText();
    if (hasLiveWatchPrompt(teaserText)) {
      return true;
    }

    const chatFrame = watchFlexy.querySelector(
      'ytd-live-chat-frame#chat, #chat ytd-live-chat-frame, #chat-container ytd-live-chat-frame'
    );
    const chatHost = chatFrame?.closest('#chat') || watchFlexy.querySelector('#chat, #chat-container');
    const hasStampedChat = watchFlexy.hasAttribute('should-stamp-chat') || !!chatFrame || !!chatHost;
    if (hasReplayWatchPrompt(teaserText) && hasStampedChat) {
      return true;
    }

    if (!chatFrame) return false;
    if (chatFrame.hasAttribute('hidden')) return false;
    if (chatFrame.hasAttribute('collapsed')) {
      return hasStampedChat;
    }

    return isVisibleElement(chatFrame) || isVisibleElement(chatHost);
  }

  function ensureStyle() {
    if (document.getElementById(STYLE_ID)) return;

    const style = document.createElement('style');
    style.id = STYLE_ID;
    style.textContent = `
      html.tm-youtube-layout-plus-home {
        --tm-guide-collapsed-width: 72px;
        --tm-chip-overlay-shift: 18px;
        --tm-chip-strip-bg:
          radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.42) 0%, rgba(255, 255, 255, 0) 34%),
          radial-gradient(circle at 82% 6%, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0) 28%),
          linear-gradient(180deg, rgba(214, 223, 233, 0.32) 0%, rgba(191, 201, 212, 0.22) 100%);
        --tm-chip-active-bg:
          radial-gradient(circle at 20% 0%, rgba(255, 255, 255, 0.52) 0%, rgba(255, 255, 255, 0) 42%),
          linear-gradient(180deg, rgba(250, 252, 255, 0.52) 0%, rgba(229, 236, 243, 0.28) 100%);
        --tm-chip-text: #3b424b;
        --tm-chip-text-active: #1f2328;
        --tm-chip-separator: rgba(70, 77, 88, 0.18);
        --tm-chip-strip-border: rgba(255, 255, 255, 0.24);
        --tm-chip-strip-top-line: rgba(156, 164, 175, 0.32);
        --tm-chip-strip-shadow-top: rgba(255, 255, 255, 0.24);
        --tm-chip-strip-shadow-bottom: rgba(43, 50, 59, 0.12);
        --tm-chip-hover-bg: rgba(255, 255, 255, 0.12);
        --tm-chip-active-border: rgba(148, 157, 169, 0.22);
        --tm-chip-active-top-stroke: rgba(148, 157, 169, 0.2);
        --tm-chip-active-shadow-top: rgba(255, 255, 255, 0.4);
        --tm-chip-active-shadow-bottom: rgba(148, 157, 169, 0.24);
        --tm-chip-active-shadow-mid: rgba(60, 64, 67, 0.1);
        --tm-chip-active-shadow-ring: rgba(118, 126, 137, 0.1);
        --tm-chip-arrow-bg:
          radial-gradient(circle at 20% 0%, rgba(255, 255, 255, 0.28) 0%, rgba(255, 255, 255, 0) 38%),
          linear-gradient(180deg, rgba(248, 251, 255, 0.28) 0%, rgba(228, 235, 242, 0.18) 100%);
        --tm-chip-arrow-shadow-top: rgba(255, 255, 255, 0.18);
        --tm-chip-arrow-shadow-mid: rgba(60, 64, 67, 0.08);
        --tm-chip-glass-blur: 34px;
      }

      html[dark].tm-youtube-layout-plus-home {
        --tm-chip-strip-bg:
          radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0) 34%),
          linear-gradient(180deg, rgba(46, 51, 58, 0.52) 0%, rgba(28, 31, 37, 0.38) 100%);
        --tm-chip-active-bg:
          radial-gradient(circle at 20% 0%, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 40%),
          linear-gradient(180deg, rgba(86, 92, 100, 0.38) 0%, rgba(61, 66, 73, 0.26) 100%);
        --tm-chip-text: rgba(231, 234, 237, 0.9);
        --tm-chip-text-active: #ffffff;
        --tm-chip-separator: rgba(255, 255, 255, 0.1);
        --tm-chip-strip-border: rgba(255, 255, 255, 0.1);
        --tm-chip-strip-top-line: rgba(255, 255, 255, 0.12);
        --tm-chip-strip-shadow-top: rgba(255, 255, 255, 0.08);
        --tm-chip-strip-shadow-bottom: rgba(0, 0, 0, 0.28);
        --tm-chip-hover-bg: rgba(255, 255, 255, 0.08);
        --tm-chip-active-border: rgba(255, 255, 255, 0.12);
        --tm-chip-active-top-stroke: rgba(255, 255, 255, 0.08);
        --tm-chip-active-shadow-top: rgba(255, 255, 255, 0.06);
        --tm-chip-active-shadow-bottom: rgba(255, 255, 255, 0.04);
        --tm-chip-active-shadow-mid: rgba(0, 0, 0, 0.18);
        --tm-chip-active-shadow-ring: rgba(255, 255, 255, 0.06);
        --tm-chip-arrow-bg:
          radial-gradient(circle at 20% 0%, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 38%),
          linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.06) 100%);
        --tm-chip-arrow-shadow-top: rgba(255, 255, 255, 0.06);
        --tm-chip-arrow-shadow-mid: rgba(0, 0, 0, 0.2);
        --tm-chip-glass-blur: 28px;
      }

      #${THEME_SWITCHER_ID} {
        position: relative;
        display: flex;
        align-items: center;
        gap: 0;
        margin-left: 12px;
        padding: 4px 6px;
        border: 1px solid var(--yt-spec-10-percent-layer, rgba(0, 0, 0, 0.12));
        border-radius: 20px;
        background: var(--yt-spec-badge-chip-background, rgba(0, 0, 0, 0.05));
      }

      #${THEME_STATUS_ID} {
        position: fixed;
        top: 72px;
        right: 24px;
        z-index: 2200;
        max-width: 320px;
        padding: 10px 14px;
        border: 1px solid rgba(190, 60, 60, 0.28);
        border-radius: 14px;
        background: rgba(126, 28, 28, 0.92);
        color: #fff;
        font: 500 13px/1.4 Roboto, Arial, sans-serif;
        box-shadow: 0 10px 24px rgba(0, 0, 0, 0.24);
        opacity: 0;
        transform: translateY(-6px);
        pointer-events: none;
        transition: opacity 160ms ease, transform 160ms ease;
      }

      #${THEME_STATUS_ID}[data-visible="true"] {
        opacity: 1;
        transform: translateY(0);
      }

      #${THEME_SWITCHER_ID} .tm-theme-switch-track {
        display: inline-flex;
        align-items: center;
        gap: 4px;
      }

      #${THEME_SWITCHER_ID} .tm-theme-switch-option {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 52px;
        height: 28px;
        padding: 0 10px;
        border: 0;
        border-radius: 14px;
        background: transparent;
        color: var(--yt-spec-text-primary, #0f0f0f);
        cursor: pointer;
        font: 600 12px/1 Roboto, Arial, sans-serif;
        transition: background 140ms ease, color 140ms ease, box-shadow 140ms ease;
      }

      #${THEME_SWITCHER_ID} .tm-theme-switch-option:hover {
        background: var(--yt-spec-badge-chip-background-hover, rgba(0, 0, 0, 0.08));
      }

      #${THEME_SWITCHER_ID} .tm-theme-switch-option[data-active="true"] {
        background: var(--yt-spec-brand-background-solid, rgba(15, 15, 15, 0.92));
        color: var(--yt-spec-static-brand-white, #fff);
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
      }

      html[dark] #${THEME_SWITCHER_ID} {
        border-color: rgba(255, 255, 255, 0.14);
        background: rgba(255, 255, 255, 0.04);
      }

      html[dark] #${THEME_SWITCHER_ID} .tm-theme-switch-option {
        color: rgba(255, 255, 255, 0.92);
      }

      html[dark] #${THEME_SWITCHER_ID} .tm-theme-switch-option[data-active="true"] {
        background: rgba(255, 255, 255, 0.14);
        color: #fff;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.32);
      }

      html.tm-youtube-layout-plus-home ytd-app[mini-guide-visible]:not([guide-persistent-and-visible]) ytd-feed-filter-chip-bar-renderer,
      html.tm-youtube-layout-plus-home ytd-app[mini-guide-visible]:not([guide-persistent-and-visible]) #chips-wrapper {
        left: var(--tm-guide-collapsed-width) !important;
        width: calc(100vw - var(--tm-guide-collapsed-width)) !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer {
        padding: 0 14px !important;
        background: transparent !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #chips-wrapper,
      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #chips {
        align-items: center !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #chips-wrapper {
        transform: translateY(var(--tm-chip-overlay-shift)) !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #chips-content {
        position: relative !important;
        overflow: hidden !important;
        isolation: isolate !important;
        padding: 5px 8px !important;
        margin-top: 0 !important;
        border: 1px solid var(--tm-chip-strip-border) !important;
        border-radius: 22px !important;
        background: var(--tm-chip-strip-bg) !important;
        backdrop-filter: blur(var(--tm-chip-glass-blur)) saturate(220%) contrast(1.05) brightness(1.08) !important;
        -webkit-backdrop-filter: blur(var(--tm-chip-glass-blur)) saturate(220%) contrast(1.05) brightness(1.08) !important;
        box-shadow:
          inset 0 1px 0 var(--tm-chip-strip-top-line),
          inset 0 1px 0 var(--tm-chip-strip-shadow-top),
          0 2px 0 rgba(34, 40, 49, 0.11),
          0 3px 2px rgba(34, 40, 49, 0.06),
          0 5px 7px rgba(34, 40, 49, 0.03) !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #chips-content::before {
        content: '' !important;
        position: absolute !important;
        inset: 0 !important;
        border-radius: inherit !important;
        background:
          linear-gradient(180deg, rgba(255, 255, 255, 0.26) 0%, rgba(255, 255, 255, 0.08) 36%, rgba(255, 255, 255, 0.02) 100%) !important;
        pointer-events: none !important;
        z-index: 0 !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #chips-content::after {
        content: '' !important;
        position: absolute !important;
        inset: 0 !important;
        border-radius: inherit !important;
        background:
          radial-gradient(circle at 50% 100%, rgba(180, 198, 220, 0.12) 0%, rgba(180, 198, 220, 0) 58%) !important;
        pointer-events: none !important;
        z-index: 0 !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer {
        position: relative !important;
        z-index: 1 !important;
        margin: 0 !important;
        padding: 0 2px !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer + yt-chip-cloud-chip-renderer::before {
        content: '' !important;
        position: absolute !important;
        left: -1px !important;
        top: 9px !important;
        bottom: 9px !important;
        width: 1px !important;
        border-radius: 999px !important;
        background: var(--tm-chip-separator) !important;
        pointer-events: none !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer button.ytChipShapeButtonReset {
        border-radius: 18px !important;
        overflow: visible !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer .ytChipShapeChip {
        position: relative !important;
        min-height: 38px !important;
        padding: 0 22px !important;
        border: 0 !important;
        border-radius: 18px !important;
        background: transparent !important;
        box-shadow: none !important;
        color: var(--tm-chip-text) !important;
        font-weight: 600 !important;
        letter-spacing: -0.01em !important;
        transition:
          background 140ms ease,
          box-shadow 140ms ease,
          color 140ms ease,
          transform 140ms ease,
          backdrop-filter 140ms ease !important;
        backdrop-filter: blur(calc(var(--tm-chip-glass-blur) * 0.7)) saturate(170%) brightness(1.04) !important;
        -webkit-backdrop-filter: blur(calc(var(--tm-chip-glass-blur) * 0.7)) saturate(170%) brightness(1.04) !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer .ytChipShapeChip > div {
        font-size: 15px !important;
        line-height: 36px !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer:hover .ytChipShapeChip,
      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer button:focus-visible .ytChipShapeChip {
        background: var(--tm-chip-hover-bg) !important;
        color: var(--tm-chip-text-active) !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer[selected] .ytChipShapeChip,
      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer .ytChipShapeChip.ytChipShapeActive {
        background: var(--tm-chip-active-bg) !important;
        border: 1px solid var(--tm-chip-active-border) !important;
        box-shadow: none !important;
        color: var(--tm-chip-text-active) !important;
        transform: none !important;
        z-index: 1 !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer[selected]::before,
      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer[selected] + yt-chip-cloud-chip-renderer::before {
        opacity: 0 !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer yt-touch-feedback-shape,
      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer .yt-spec-touch-feedback-shape__stroke,
      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer .yt-spec-touch-feedback-shape__fill {
        border-radius: 18px !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #right-arrow.ytd-feed-filter-chip-bar-renderer,
      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #left-arrow.ytd-feed-filter-chip-bar-renderer {
        margin-top: 0 !important;
        transform: none !important;
      }

      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #right-arrow button,
      html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #left-arrow button {
        border: 0 !important;
        border-radius: 18px !important;
        background: var(--tm-chip-arrow-bg) !important;
        transform: none !important;
        backdrop-filter: blur(calc(var(--tm-chip-glass-blur) * 0.72)) saturate(175%) brightness(1.04) !important;
        -webkit-backdrop-filter: blur(calc(var(--tm-chip-glass-blur) * 0.72)) saturate(175%) brightness(1.04) !important;
        box-shadow:
          inset 0 1px 0 var(--tm-chip-arrow-shadow-top),
          0 4px 12px var(--tm-chip-arrow-shadow-mid) !important;
      }

      html.tm-youtube-layout-plus-home ytd-app[mini-guide-visible]:not([guide-persistent-and-visible]) ytd-page-manager {
        margin-left: var(--tm-guide-collapsed-width) !important;
        width: calc(100% - var(--tm-guide-collapsed-width)) !important;
      }

      html.tm-youtube-layout-plus-home ytd-browse {
        overflow: visible !important;
      }

      html.tm-youtube-layout-plus-home ytd-app[mini-guide-visible]:not([guide-persistent-and-visible]) ytd-two-column-browse-results-renderer,
      html.tm-youtube-layout-plus-home ytd-app[mini-guide-visible]:not([guide-persistent-and-visible]) ytd-rich-grid-renderer,
      html.tm-youtube-layout-plus-home ytd-app[mini-guide-visible]:not([guide-persistent-and-visible]) #contents.ytd-rich-grid-renderer {
        margin-left: 0 !important;
        width: auto !important;
      }

      html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer {
        margin-top: 0 !important;
        padding-top: calc(var(--tm-chip-overlay-shift) + 8px) !important;
        padding-left: 14px !important;
        padding-right: 12px !important;
        box-sizing: border-box !important;
      }

      html.tm-youtube-layout-plus-home ytd-rich-grid-renderer {
        --ytd-rich-grid-items-per-row: 5 !important;
        --ytd-rich-grid-posts-per-row: 5 !important;
      }

      html.tm-youtube-layout-plus-home ytd-rich-item-renderer,
      html.tm-youtube-layout-plus-home ytd-rich-grid-row,
      html.tm-youtube-layout-plus-home ytd-rich-grid-media,
      html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > * {
        max-width: none !important;
      }

      html.tm-youtube-layout-plus-home ytd-rich-item-renderer {
        position: relative !important;
        z-index: 0 !important;
        margin-left: 0 !important;
        margin-right: 10px !important;
        transform-origin: center top !important;
        transition:
          transform 160ms ease,
          box-shadow 160ms ease,
          z-index 160ms ease !important;
        will-change: transform !important;
      }

      html.tm-youtube-layout-plus-home ytd-rich-item-renderer:hover,
      html.tm-youtube-layout-plus-home ytd-rich-item-renderer:focus-within {
        transform: scale(1.1) !important;
        z-index: 4 !important;
      }

      html.tm-youtube-layout-plus-home ytd-rich-section-renderer,
      html.tm-youtube-layout-plus-home ytd-rich-shelf-renderer,
      html.tm-youtube-layout-plus-home ytd-reel-shelf-renderer {
        display: none !important;
      }

      html.tm-youtube-layout-plus-watch-plain ytd-watch-flexy #secondary,
      html.tm-youtube-layout-plus-watch-plain ytd-watch-flexy #related,
      html.tm-youtube-layout-plus-watch-plain ytd-watch-flexy #secondary-inner,
      html.tm-youtube-layout-plus-watch-plain ytd-watch-next-secondary-results-renderer,
      html.tm-youtube-layout-plus-watch-chat ytd-watch-flexy #related,
      html.tm-youtube-layout-plus-watch-chat ytd-watch-next-secondary-results-renderer {
        display: none !important;
      }

      html.tm-youtube-layout-plus-watch-plain ytd-watch-flexy[is-two-columns_] #primary {
        max-width: none !important;
        width: min(1400px, calc(100vw - 48px)) !important;
        margin: 0 auto !important;
      }

      html.tm-youtube-layout-plus-watch-plain ytd-watch-flexy[is-two-columns_] #columns {
        display: block !important;
      }

      html.tm-youtube-layout-plus-watch-plain ytd-watch-flexy[is-two-columns_] #primary-inner,
      html.tm-youtube-layout-plus-watch-plain ytd-watch-flexy[is-two-columns_] #above-the-fold,
      html.tm-youtube-layout-plus-watch-plain ytd-watch-flexy[is-two-columns_] #below {
        max-width: none !important;
      }

      html.tm-youtube-layout-plus-watch-chat-collapsed ytd-watch-flexy #secondary,
      html.tm-youtube-layout-plus-watch-chat-collapsed ytd-watch-flexy #secondary-inner {
        display: none !important;
      }

      html.tm-youtube-layout-plus-watch-chat-collapsed ytd-watch-flexy[is-two-columns_] #primary {
        max-width: none !important;
        width: min(1400px, calc(100vw - 48px)) !important;
        margin: 0 auto !important;
      }

      html.tm-youtube-layout-plus-watch-chat-collapsed ytd-watch-flexy[is-two-columns_] #columns {
        display: block !important;
      }

      html.tm-youtube-layout-plus-watch-chat-collapsed ytd-watch-flexy[is-two-columns_] #primary-inner,
      html.tm-youtube-layout-plus-watch-chat-collapsed ytd-watch-flexy[is-two-columns_] #above-the-fold,
      html.tm-youtube-layout-plus-watch-chat-collapsed ytd-watch-flexy[is-two-columns_] #below {
        max-width: none !important;
      }
    `;

    document.head.appendChild(style);
  }

  function collapseGuide() {
    const app = document.querySelector('ytd-app');
    if (app) {
      app.removeAttribute('guide-persistent-and-visible');
      app.setAttribute('mini-guide-visible', '');
    }

    const drawer = document.querySelector('tp-yt-app-drawer#guide');
    if (drawer) {
      drawer.removeAttribute('opened');
      drawer.style.width = '';
      drawer.style.minWidth = '';
      drawer.style.visibility = '';
    }

    const guideRenderer = document.querySelector('ytd-guide-renderer');
    if (guideRenderer) {
      guideRenderer.style.display = '';
      guideRenderer.style.width = '';
      guideRenderer.style.minWidth = '';
    }
  }

  function applyHomeLayout() {
    const richGrid = document.querySelector('ytd-rich-grid-renderer');
    if (!richGrid) return;

    document.documentElement.classList.add('tm-youtube-layout-plus-home');

    if (lastAutoCollapsedHomeUrl !== location.href) {
      collapseGuide();
      lastAutoCollapsedHomeUrl = location.href;
    }
  }

  function applyWatchLayout() {
    const watchFlexy = document.querySelector('ytd-watch-flexy');
    if (!watchFlexy) return;

    document.documentElement.classList.add('tm-youtube-layout-plus-watch');

    if (hasWatchSidebarChat(watchFlexy)) {
      document.documentElement.classList.add('tm-youtube-layout-plus-watch-chat');
      updateWatchChatPanelState(watchFlexy);
      autoCollapseLiveChatPanel(watchFlexy);
      syncWatchPlayerSize();
      schedulePlayerSync(120);
      return;
    }

    document.documentElement.classList.add('tm-youtube-layout-plus-watch-plain');
    hideWatchReplayPrompt();
    syncWatchPlayerSize();
    schedulePlayerSync(120);
  }

  function hideWatchReplayPrompt() {
    const teaserCarousel = document.querySelector('ytd-watch-metadata #teaser-carousel');
    if (!teaserCarousel) return;

    const teaserText = getWatchTeaserText();
    if (hasLiveWatchPrompt(teaserText)) {
      return;
    }

    const watchFlexy = document.querySelector('ytd-watch-flexy');
    if (watchFlexy && hasReplayWatchPrompt(teaserText) && hasWatchSidebarChat(watchFlexy)) {
      return;
    }

    const replayPrompt = Array.from(
      teaserCarousel.querySelectorAll('yt-video-metadata-carousel-view-model')
    ).find((card) => {
      const text = (card.innerText || card.textContent || '').trim();
      return /live chat replay/i.test(text)
        || /see what others said about this video while it was live/i.test(text);
    });

    if (!replayPrompt) return;

    teaserCarousel.style.display = 'none';
  }

  function updateWatchChatPanelState(watchFlexy) {
    const chatFrame = watchFlexy.querySelector('ytd-live-chat-frame#chat');
    const openPanelButton = findOpenPanelButton();

    const chatVisible = !!chatFrame && isVisibleElement(chatFrame);
    const panelExpanded = chatVisible || !!(openPanelButton && openPanelButton.disabled);

    document.documentElement.classList.toggle('tm-youtube-layout-plus-watch-chat-open', panelExpanded);
    document.documentElement.classList.toggle('tm-youtube-layout-plus-watch-chat-collapsed', !panelExpanded);

    if (lastWatchChatExpanded !== panelExpanded) {
      lastWatchChatExpanded = panelExpanded;

      // Let the class change apply first, then resync the player size so
      // collapsing/expanding chat updates the video dimensions immediately.
      window.requestAnimationFrame(() => {
        syncWatchPlayerSize();
        schedulePlayerSync(120);
      });
    }
  }

  function stopWatchChatStateSync() {
    if (!watchChatStateTimer) return;
    window.clearInterval(watchChatStateTimer);
    watchChatStateTimer = null;
  }

  function startWatchChatStateSync() {
    stopWatchChatStateSync();

    if (!isWatchPage()) return;

    watchChatStateTimer = window.setInterval(() => {
      if (!isWatchPage()) {
        stopWatchChatStateSync();
        return;
      }

      const watchFlexy = document.querySelector('ytd-watch-flexy');
      if (!watchFlexy) {
        return;
      }

      const hasSidebarChat = hasWatchSidebarChat(watchFlexy);
      const hasWatchChatClass = document.documentElement.classList.contains('tm-youtube-layout-plus-watch-chat');

      if (hasSidebarChat && !hasWatchChatClass) {
        scheduleApply();
        return;
      }

      if (!hasSidebarChat || !hasWatchChatClass) {
        return;
      }

      updateWatchChatPanelState(watchFlexy);
    }, 500);
  }

  function findOpenPanelButton() {
    return Array.from(document.querySelectorAll('button, yt-button-shape button, tp-yt-paper-button')).find(
      (button) => /open panel/i.test((button.innerText || button.textContent || '').trim())
    ) || null;
  }

  function autoCollapseLiveChatPanel(watchFlexy) {
    const watchPageKey = getWatchPageKey();
    if (lastAutoCollapsedWatchChatKey === watchPageKey) return;

    const chatFrameHost = watchFlexy.querySelector('ytd-live-chat-frame#chat');
    const openPanelButton = findOpenPanelButton();
    if (openPanelButton && !openPanelButton.disabled) {
      lastAutoCollapsedWatchChatKey = watchPageKey;
      return;
    }

    if (chatFrameHost?.hasAttribute('collapsed')) {
      lastAutoCollapsedWatchChatKey = watchPageKey;
      return;
    }

    const hostToggleButton = chatFrameHost?.querySelector(
      '#show-hide-button button, #show-hide-button yt-button-shape button, #show-hide-button tp-yt-paper-button'
    );
    if (hostToggleButton) {
      hostToggleButton.click();
      lastAutoCollapsedWatchChatKey = watchPageKey;
      window.setTimeout(scheduleApply, 80);
      return;
    }

    const chatFrame = watchFlexy.querySelector(
      'ytd-live-chat-frame#chat #chatframe, ytd-live-chat-frame#chat iframe, #chatframe'
    );
    const chatDoc = chatFrame?.contentDocument;
    if (!chatDoc) return;

    const closeButton = Array.from(chatDoc.querySelectorAll('button')).find(
      (button) => /close/i.test(button.getAttribute('aria-label') || '')
    );
    if (!closeButton) return;

    closeButton.click();
    lastAutoCollapsedWatchChatKey = watchPageKey;
    window.setTimeout(scheduleApply, 80);
  }

  function syncWatchPlayerSize() {
    if (!isWatchPage()) return;

    const playerContainer = document.getElementById('player');
    const moviePlayer = document.getElementById('movie_player');
    if (!playerContainer || !moviePlayer) return;

    const rect = playerContainer.getBoundingClientRect();
    const width = Math.round(rect.width);
    const height = Math.round(rect.height);
    if (!width || !height) return;

    const syncKey = `${location.href}|${width}x${height}`;
    if (lastPlayerSyncKey === syncKey) return;

    try {
      if (typeof moviePlayer.setInternalSize === 'function') {
        moviePlayer.setInternalSize(width, height);
      }
      if (typeof moviePlayer.setSize === 'function') {
        moviePlayer.setSize(width, height);
      }
      if (typeof moviePlayer.setSizeStyle === 'function') {
        moviePlayer.setSizeStyle(width, height);
      }
    } catch (error) {
      console.debug('YouTube Layout Plus player sync failed:', error);
    }

    window.dispatchEvent(new Event('resize'));
    lastPlayerSyncKey = syncKey;
  }

  function schedulePlayerSync(delay = 0) {
    if (playerSyncTimer) {
      window.clearTimeout(playerSyncTimer);
      playerSyncTimer = null;
    }

    playerSyncTimer = window.setTimeout(() => {
      playerSyncTimer = null;
      syncWatchPlayerSize();
    }, delay);
  }

  function clearModeClasses() {
    document.documentElement.classList.remove(
      'tm-youtube-layout-plus-home',
      'tm-youtube-layout-plus-watch',
      'tm-youtube-layout-plus-watch-chat',
      'tm-youtube-layout-plus-watch-chat-open',
      'tm-youtube-layout-plus-watch-chat-collapsed',
      'tm-youtube-layout-plus-watch-plain'
    );
  }

  function loadStoredThemeMode() {
    try {
      const mode = window.localStorage.getItem(THEME_MODE_STORAGE_KEY);
      return THEME_MODES.some((item) => item.mode === mode) ? mode : null;
    } catch {
      return null;
    }
  }

  function persistThemeMode(mode) {
    try {
      if (THEME_MODES.some((item) => item.mode === mode)) {
        window.localStorage.setItem(THEME_MODE_STORAGE_KEY, mode);
      } else {
        window.localStorage.removeItem(THEME_MODE_STORAGE_KEY);
      }
    } catch {
      // Ignore storage failures.
    }
  }

  function delay(ms) {
    return new Promise((resolve) => {
      window.setTimeout(resolve, ms);
    });
  }

  function getThemePrefValue(mode) {
    return THEME_MODES.find((item) => item.mode === mode)?.prefF6 || null;
  }

  function getThemeSignal(mode) {
    return THEME_MODES.find((item) => item.mode === mode)?.signal || null;
  }

  function getThemeModeFromOptionText(text) {
    const normalizedText = (text || '').trim();
    if (!normalizedText) return null;
    if (/use device theme|device theme/i.test(normalizedText)) return 'auto';
    if (/light theme/i.test(normalizedText)) return 'light';
    if (/dark theme/i.test(normalizedText)) return 'dark';
    return null;
  }

  function getThemeOptionSignal(option) {
    return option?.data?.serviceEndpoint?.signalServiceEndpoint?.actions?.[0]?.signalAction?.signal || null;
  }

  function getThemeModeFromPrefCookie() {
    const prefEntries = document.cookie
      .split('; ')
      .filter((entry) => entry.startsWith('PREF='));
    const lastEntry = prefEntries[prefEntries.length - 1];
    if (!lastEntry) return null;

    try {
      const pref = decodeURIComponent(lastEntry.slice(5));
      const f6Match = pref.match(/(?:^|&)f6=(\d+)/);
      if (!f6Match) return null;

      const f6Value = f6Match[1];
      if (/80080$/.test(f6Value)) return 'light';
      if (/480$/.test(f6Value)) return 'dark';
      if (/80$/.test(f6Value)) return 'auto';
      return 'auto';
    } catch {
      return null;
    }
  }

  function inferThemeModeFromDocument() {
    return document.documentElement.hasAttribute('dark') ? 'dark' : 'light';
  }

  function getObservedThemeMode() {
    return getThemeModeFromPrefCookie()
      || detectThemeModeFromOptions()
      || inferThemeModeFromDocument();
  }

  function showThemeStatusMessage(message) {
    let status = document.getElementById(THEME_STATUS_ID);
    if (!status) {
      status = document.createElement('div');
      status.id = THEME_STATUS_ID;
      status.dataset.visible = 'false';
      document.body.appendChild(status);
    }

    status.textContent = message;
    status.dataset.visible = 'true';
    window.clearTimeout(showThemeStatusMessage.hideTimer);
    showThemeStatusMessage.hideTimer = window.setTimeout(() => {
      status.dataset.visible = 'false';
    }, 2600);
  }

  function hideThemeStatusMessage() {
    const status = document.getElementById(THEME_STATUS_ID);
    if (!status) return;
    status.dataset.visible = 'false';
    window.clearTimeout(showThemeStatusMessage.hideTimer);
  }

  function isVisibleElement(element) {
    if (!element) return false;
    if (element.hidden) return false;

    const style = window.getComputedStyle(element);
    if (style.display === 'none' || style.visibility === 'hidden') return false;

    const rect = element.getBoundingClientRect();
    return rect.width > 0 && rect.height > 0;
  }

  function getOfficialThemeOptions(options = {}) {
    const { visibleOnly = false } = options;
    return Array.from(document.querySelectorAll('ytd-compact-link-renderer')).filter(
      (option) => {
        const optionSignal = getThemeOptionSignal(option);
        const optionMode = getThemeModeFromOptionText(option.innerText || option.textContent);
        return (
          (THEME_MODES.some((mode) => optionSignal === mode.signal) || !!optionMode)
        && (!visibleOnly || isVisibleElement(option))
        );
      }
    );
  }

  function detectThemeModeFromOptions(options = getOfficialThemeOptions({ visibleOnly: true })) {
    const selectedOption = options.find((option) => option?.data?.icon?.iconType === 'CHECK');
    if (!selectedOption) return null;
    return THEME_MODES.find((mode) => mode.signal === getThemeOptionSignal(selectedOption))?.mode
      || getThemeModeFromOptionText(selectedOption.innerText || selectedOption.textContent);
  }

  function findAccountMenuButton() {
    return document.querySelector('button#avatar-btn')
      || Array.from(document.querySelectorAll('ytd-topbar-menu-button-renderer button, button')).find((button) => {
        if (button.id === 'avatar-btn') return true;
        if (button.querySelector('img') && button.getAttribute('aria-haspopup') === 'true') return true;
        return false;
      })
      || null;
  }

  function findAppearanceMenuEntry() {
    return Array.from(
      document.querySelectorAll('ytd-toggle-theme-compact-link-renderer, a, button, tp-yt-paper-item')
    ).find((entry) => {
      const text = (entry.innerText || entry.textContent || '').trim();
      return /^appearance:/i.test(text) && isVisibleElement(entry);
    }) || null;
  }

  function clickMenuEntry(entry) {
    const target = entry?.querySelector?.('a#endpoint, button, tp-yt-paper-item')
      || entry?.closest?.('a, button')
      || entry;
    target?.click?.();
  }

  function closeOfficialThemeMenus() {
    document.dispatchEvent(
      new KeyboardEvent('keydown', { key: 'Escape', bubbles: true, cancelable: true })
    );
    document.dispatchEvent(
      new KeyboardEvent('keydown', { key: 'Escape', bubbles: true, cancelable: true })
    );
  }

  async function waitFor(getValue, timeout = 2200) {
    const startedAt = Date.now();
    while (Date.now() - startedAt < timeout) {
      const value = getValue();
      if (value) return value;
      await delay(50);
    }
    return null;
  }

  async function ensureOfficialThemeOptionsVisible() {
    const existingOptions = getOfficialThemeOptions({ visibleOnly: true });
    if (existingOptions.length) return existingOptions;

    const existingAppearanceEntry = findAppearanceMenuEntry();
    if (existingAppearanceEntry) {
      clickMenuEntry(existingAppearanceEntry);
      return await waitFor(() => {
        const options = getOfficialThemeOptions({ visibleOnly: true });
        return options.length ? options : null;
      });
    }

    closeOfficialThemeMenus();
    await delay(80);

    const accountMenuButton = findAccountMenuButton();
    if (!accountMenuButton) return null;

    accountMenuButton.click();
    const appearanceEntry = await waitFor(findAppearanceMenuEntry);
    if (!appearanceEntry) return null;

    clickMenuEntry(appearanceEntry);
    return await waitFor(() => {
      const options = getOfficialThemeOptions({ visibleOnly: true });
      return options.length ? options : null;
    });
  }

  function updateThemeSwitcherUI() {
    const switcher = document.getElementById(THEME_SWITCHER_ID);
    if (!switcher) return;

    if (!pendingThemeMode) {
      const observedMode = getObservedThemeMode();
      if (observedMode) {
        currentThemeMode = observedMode;
        persistThemeMode(observedMode);
      }
    } else if (!currentThemeMode) {
      currentThemeMode = loadStoredThemeMode()
        || inferThemeModeFromDocument();
    }

    const visibleMode = pendingThemeMode || currentThemeMode;

    const optionButtons = switcher.querySelectorAll('.tm-theme-switch-option[data-mode]');
    for (const button of optionButtons) {
      const isActive = button.dataset.mode === visibleMode;
      button.dataset.active = String(isActive);
      button.setAttribute('aria-pressed', String(isActive));
      button.disabled = themeSwitchInFlight;
    }
  }

  async function verifyThemeMode(mode) {
    const expectedDark = mode === 'dark'
      || (mode === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches);
    let lastResult = null;

    for (let attempt = 0; attempt < 12; attempt += 1) {
      const cookieMode = getThemeModeFromPrefCookie();
      const hasDark = document.documentElement.hasAttribute('dark');
      const actualMode = cookieMode || inferThemeModeFromDocument();
      const cookieConsistent = cookieMode === mode;
      const darkConsistent = hasDark === expectedDark;

      lastResult = {
        ok: cookieConsistent && darkConsistent,
        actualMode,
        cookieMode,
        hasDark,
      };

      if (lastResult.ok) {
        return lastResult;
      }

      await delay(120);
    }

    return lastResult || {
      ok: false,
      actualMode: getObservedThemeMode(),
      cookieMode: getThemeModeFromPrefCookie(),
      hasDark: document.documentElement.hasAttribute('dark'),
    };
  }

  async function setThemeMode(mode) {
    if (themeSwitchInFlight) return;
    if (!THEME_MODES.some((item) => item.mode === mode)) return;

    const previousMode = currentThemeMode
      || loadStoredThemeMode()
      || getThemeModeFromPrefCookie()
      || detectThemeModeFromOptions()
      || (document.documentElement.hasAttribute('dark') ? 'dark' : 'light');
    if (previousMode === mode) {
      currentThemeMode = mode;
      persistThemeMode(mode);
      pendingThemeMode = null;
      updateThemeSwitcherUI();
      return;
    }

    themeSwitchInFlight = true;
    document.documentElement.classList.add(THEME_BUSY_CLASS);
    pendingThemeMode = mode;

    try {
      updateThemeSwitcherUI();

      const options = await ensureOfficialThemeOptionsVisible();
      if (!options?.length) {
        currentThemeMode = previousMode;
        persistThemeMode(previousMode);
        updateThemeSwitcherUI();
        return;
      }

      const visibleMode = detectThemeModeFromOptions(options);
      let didRequestOfficialMode = visibleMode === mode;
      if (visibleMode !== mode) {
        const targetOption = options.find((option) => getThemeOptionSignal(option) === getThemeSignal(mode));
        if (!targetOption) {
          currentThemeMode = previousMode;
          persistThemeMode(previousMode);
          updateThemeSwitcherUI();
          return;
        }

        clickMenuEntry(targetOption);
        didRequestOfficialMode = true;
      }

      // Once the official menu action is triggered, trust the requested mode for the switcher UI.
      currentThemeMode = mode;
      persistThemeMode(mode);
      updateThemeSwitcherUI();

      const verification = await verifyThemeMode(mode);
      if (!verification.ok) {
        currentThemeMode = verification.actualMode || previousMode;
        persistThemeMode(currentThemeMode);
        pendingThemeMode = null;
        updateThemeSwitcherUI();
        showThemeStatusMessage(
          `Theme switch failed: expected ${mode}, actual ${currentThemeMode || 'unknown'}.`
        );
        return;
      }

      currentThemeMode = verification.actualMode || mode;
      persistThemeMode(currentThemeMode);
      hideThemeStatusMessage();
    } finally {
      closeOfficialThemeMenus();
      themeSwitchInFlight = false;
      document.documentElement.classList.remove(THEME_BUSY_CLASS);
      pendingThemeMode = null;
      currentThemeMode = currentThemeMode || loadStoredThemeMode() || getThemeModeFromPrefCookie() || previousMode;
      updateThemeSwitcherUI();
    }
  }

  function ensureThemeSwitcher() {
    const logoRenderer = document.querySelector('ytd-topbar-logo-renderer');
    if (!logoRenderer) return;

    let switcher = document.getElementById(THEME_SWITCHER_ID);
    if (!switcher) {
      const track = document.createElement('div');
      track.className = 'tm-theme-switch-track';
      track.setAttribute('role', 'group');
      track.setAttribute('aria-label', 'Theme switcher');

      switcher = document.createElement('div');
      switcher.id = THEME_SWITCHER_ID;

      for (const item of THEME_MODES) {
        const optionButton = document.createElement('button');
        optionButton.type = 'button';
        optionButton.className = 'tm-theme-switch-option';
        optionButton.dataset.mode = item.mode;
        optionButton.dataset.active = 'false';
        optionButton.textContent = item.label;
        optionButton.setAttribute('aria-pressed', 'false');
        optionButton.addEventListener('click', async (event) => {
          event.preventDefault();
          event.stopPropagation();
          await setThemeMode(item.mode);
        });
        track.appendChild(optionButton);
      }

      switcher.append(track);

      logoRenderer.insertAdjacentElement('afterend', switcher);
    } else if (switcher.previousElementSibling !== logoRenderer) {
      logoRenderer.insertAdjacentElement('afterend', switcher);
    }

    updateThemeSwitcherUI();
  }

  function applyLayout() {
    ensureStyle();
    clearModeClasses();

    try {
      ensureThemeSwitcher();
    } catch (error) {
      console.error('YouTube Layout Plus theme switcher failed:', error);
    }

    if (isHomePage()) {
      applyHomeLayout();
      return;
    }

    if (isWatchPage()) {
      applyWatchLayout();
    }
  }

  function queueApply() {
    if (applyFrame) return;

    applyFrame = window.requestAnimationFrame(() => {
      applyFrame = 0;
      applyLayout();
    });
  }

  function scheduleApply(delay = 0) {
    if (delay > 0) {
      window.clearTimeout(applyDelayTimer);
      applyDelayTimer = window.setTimeout(() => {
        applyDelayTimer = null;
        queueApply();
      }, delay);
      return;
    }

    if (applyDelayTimer) {
      window.clearTimeout(applyDelayTimer);
      applyDelayTimer = null;
    }

    queueApply();
  }

  function stopWatchLayoutRetry() {
    if (!watchLayoutRetryTimer) return;
    window.clearTimeout(watchLayoutRetryTimer);
    watchLayoutRetryTimer = null;
  }

  function startWatchLayoutRetry() {
    stopWatchLayoutRetry();

    if (!isWatchPage()) return;

    watchLayoutRetryStep = 0;

    const run = () => {
      if (!isWatchPage()) {
        stopWatchLayoutRetry();
        return;
      }

      scheduleApply();

      if (watchLayoutRetryStep >= WATCH_LAYOUT_RETRY_DELAYS.length - 1) {
        stopWatchLayoutRetry();
        return;
      }

      watchLayoutRetryStep += 1;
      watchLayoutRetryTimer = window.setTimeout(run, WATCH_LAYOUT_RETRY_DELAYS[watchLayoutRetryStep]);
    };

    run();
  }

  function handleRouteChange(force = false) {
    const nextUrl = location.href;
    if (!force && nextUrl === currentUrl) return;

    currentUrl = nextUrl;

    if (!isHomePage()) {
      lastAutoCollapsedHomeUrl = '';
    }

    if (!isWatchPage()) {
      lastAutoCollapsedWatchChatKey = '';
      stopWatchLayoutRetry();
      stopWatchChatStateSync();
      lastWatchChatExpanded = null;
      lastPlayerSyncKey = '';
      if (playerSyncTimer) {
        window.clearTimeout(playerSyncTimer);
        playerSyncTimer = null;
      }
    } else {
      lastWatchChatExpanded = null;
      lastPlayerSyncKey = '';
      startWatchLayoutRetry();
      startWatchChatStateSync();
    }

    scheduleApply();
  }

  function startObservers() {
    if (bodyObserver) return;

    bodyObserver = new MutationObserver((mutations) => {
      if (isWatchPage()) {
        return;
      }

      const hasRelevantMutation = mutations.some((mutation) => {
        const target = mutation.target instanceof Element
          ? mutation.target
          : mutation.target?.parentElement;
        if (!target) return false;

        // Ignore the player's internal UI churn elsewhere. Those mutations are
        // high-frequency and do not require reapplying layout classes.
        if (target.closest('#movie_player, .html5-video-player, #chatframe')) {
          return false;
        }

        return true;
      });

      if (hasRelevantMutation) {
        scheduleApply();
      }
    });

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

  function startNavigationListeners() {
    document.addEventListener('yt-navigate-finish', handleRouteChange, true);
    window.addEventListener('popstate', handleRouteChange, true);
  }

  function startInteractionListeners() {
    document.addEventListener('click', (event) => {
      const trigger = event.target instanceof Element
        ? event.target.closest('button, yt-button-shape button, tp-yt-paper-button')
        : null;
      if (!trigger) return;

      const text = (trigger.innerText || trigger.textContent || '').trim();
      if (/open panel/i.test(text) && isWatchPage()) {
        lastAutoCollapsedWatchChatKey = getWatchPageKey();
        scheduleApply(80);
      }
    }, true);
  }

  function watchRoute() {
    if (routeTimer) return;

    routeTimer = window.setInterval(() => {
      if (location.href === currentUrl) return;
      handleRouteChange();
    }, 1000);
  }

  function init() {
    ensureStyle();
    handleRouteChange(true);
    startObservers();
    startNavigationListeners();
    startInteractionListeners();
    watchRoute();
  }

  init();
})();