Greasy Fork is available in English.
Home: collapse guide, fixed hero layout (left text + large image + 4 side cards) for the first 5 videos, then 4/5 col grid below, hide Shorts. Flat chip bar. Watch: hide recommendations sidebar and center the player/content, while preserving live chat on streams/replays and engagement panels. Adds topbar theme and home grid switchers.
当前为
// ==UserScript==
// @name YouTube Layout Plus
// @namespace https://qazwsx123.uk/
// @version 0.3.26
// @description Home: collapse guide, fixed hero layout (left text + large image + 4 side cards) for the first 5 videos, then 4/5 col grid below, hide Shorts. Flat chip bar. Watch: hide recommendations sidebar and center the player/content, while preserving live chat on streams/replays and engagement panels. Adds topbar theme and home grid switchers.
// @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 STYLE_VERSION = '0.3.25';
const THEME_SWITCHER_ID = 'tm-youtube-layout-plus-theme-switcher';
const HOME_GRID_SWITCHER_ID = 'tm-youtube-layout-plus-home-grid-switcher';
const THEME_STATUS_ID = 'tm-youtube-layout-plus-theme-status';
const REPLAY_HIDE_CLASS = 'tm-youtube-layout-plus-hide-replay-prompt';
const WATCH_PANEL_OPEN_CLASS = 'tm-youtube-layout-plus-watch-panel-open';
const WATCH_THEATER_CLASS = 'tm-youtube-layout-plus-watch-theater';
const THEME_MODE_STORAGE_KEY = 'tm-youtube-layout-plus-theme-mode';
const HOME_GRID_COLUMNS_STORAGE_KEY = 'tm-youtube-layout-plus-home-grid-columns';
const THEME_MODES = [
{ mode: 'auto', label: 'Auto', actionName: 'yt-signal-action-toggle-dark-theme-device' },
{ mode: 'light', label: 'Light', actionName: 'yt-signal-action-toggle-dark-theme-off' },
{ mode: 'dark', label: 'Dark', actionName: 'yt-signal-action-toggle-dark-theme-on' },
];
const HOME_GRID_COLUMN_OPTIONS = [4, 5];
const HOME_GRID_TRACK_COUNT = 20;
const LAYOUT_MODE_CLASSES = [
'tm-youtube-layout-plus-home',
'tm-youtube-layout-plus-watch',
'tm-youtube-layout-plus-watch-chat',
'tm-youtube-layout-plus-watch-plain',
];
const PLAYER_CONTAINER_SELECTOR =
'#player-theater-container, #player-full-bleed-container, #player';
const OBSERVER_APPLY_DEBOUNCE_MS = 150;
const ROUTE_POLL_INTERVAL_MS = 3000;
const PREF_F6_PREF_BIT = 0x80;
const PREF_F6_DARK_BIT = 0x400;
const PREF_F6_LIGHT_BIT = 0x80000;
let currentUrl = location.href;
let applyFrame = 0;
let applyDelayTimer = null;
let bodyObserver = null;
let routeTimer = null;
let resizeTimer = null;
let resizeFrame = 0;
let watchLayoutRetryTimer = null;
let watchLayoutRetryStep = 0;
let watchChatStateTimer = null;
let lastWatchChatExpanded = null;
let lastEngagementPanelOpen = null;
let lastTheaterMode = null;
let playerSyncTimer = null;
let lastPlayerSyncKey = '';
let lastAutoCollapsedHomeUrl = '';
let lastAutoCollapsedWatchChatKey = '';
let currentThemeMode = loadStoredThemeMode();
let currentHomeGridColumns = loadStoredHomeGridColumns();
let themeSwitchInFlight = false;
let pendingThemeMode = null;
let themeStatusHideTimer = null;
let lastRenderedThemeMode = null;
let lastRenderedThemeDisabled = null;
let lastRenderedHomeGridColumns = null;
let lastPersistedThemeMode = currentThemeMode;
const WATCH_LAYOUT_RETRY_DELAYS = [0, 40, 120, 260, 520, 900, 1400, 2200, 3200, 4500];
function extractVideoId(value) {
const text = String(value || '');
const directMatch = text.match(/(?:\/vi(?:_webp)?\/|[?&]v=)([a-zA-Z0-9_-]{11})/);
if (directMatch) return directMatch[1];
try {
const url = new URL(text, location.origin);
return url.searchParams.get('v');
} catch {
return null;
}
}
function upgradeHomeHeroThumbnail() {
const item = document.querySelector('#contents.ytd-rich-grid-renderer > ytd-rich-item-renderer');
if (!item) return;
const link = item.querySelector('a#thumbnail[href], a[href*="/watch?v="]');
const img = item.querySelector('img[src*="ytimg.com"]');
const videoId = extractVideoId(link?.href) || extractVideoId(img?.src);
if (!videoId) return;
const images = Array.from(item.querySelectorAll('img[src*="ytimg.com"], img'));
if (!images.length) return;
const key = videoId;
const currentUrl = item.dataset.tmHeroThumbUrl || '';
if (
item.dataset.tmHeroThumbKey === key &&
currentUrl &&
images.some((image) => image.src === currentUrl || image.srcset.includes(currentUrl))
) {
return;
}
const candidates = [
`https://i.ytimg.com/vi/${videoId}/maxresdefault.jpg`,
`https://i.ytimg.com/vi/${videoId}/hq720.jpg`,
`https://i.ytimg.com/vi/${videoId}/sddefault.jpg`,
`https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`,
];
const applyCandidate = (url, width) => {
item.dataset.tmHeroThumbKey = key;
item.dataset.tmHeroThumbUrl = url;
for (const image of images) {
image.src = url;
image.srcset = `${url} ${width || 1280}w`;
image.sizes = '(min-width: 1180px) 60vw, 100vw';
image.loading = 'eager';
image.fetchPriority = 'high';
image.decoding = 'async';
}
};
const tryCandidate = (index = 0) => {
const url = candidates[index];
if (!url) return;
const probe = new Image();
probe.onload = () => {
if (probe.naturalWidth >= 640 || index === candidates.length - 1) {
applyCandidate(url, probe.naturalWidth);
return;
}
tryCandidate(index + 1);
};
probe.onerror = () => tryCandidate(index + 1);
probe.src = url;
};
tryCandidate();
}
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 hasOpenEngagementPanel(watchFlexy) {
const host = watchFlexy || document.querySelector('ytd-watch-flexy');
if (!host) return false;
return !!host.querySelector(
'ytd-engagement-panel-section-list-renderer[visibility="ENGAGEMENT_PANEL_VISIBILITY_EXPANDED"]'
);
}
function isTheaterModeActive(watchFlexy) {
if (!isWatchPage()) return false;
const flexy = watchFlexy || document.querySelector('ytd-watch-flexy');
return !!(flexy && flexy.hasAttribute('theater'));
}
function ensureStyle() {
let style = document.getElementById(STYLE_ID);
if (style?.dataset.version === STYLE_VERSION) return;
if (!style) {
style = document.createElement('style');
style.id = STYLE_ID;
document.head.appendChild(style);
}
style.dataset.version = STYLE_VERSION;
style.textContent = `
html.tm-youtube-layout-plus-home {
--tm-guide-collapsed-width: 72px;
--tm-card-bg: #ffffff;
--tm-card-border: rgba(15, 15, 15, 0.06);
--tm-card-shadow: 0 1px 2px rgba(15, 15, 15, 0.04), 0 6px 18px rgba(15, 15, 15, 0.05);
--tm-text-primary: #0f0f0f;
--tm-text-secondary: rgba(15, 15, 15, 0.62);
--tm-meta-secondary: rgba(15, 15, 15, 0.55);
--tm-chip-bg: rgba(15, 15, 15, 0.05);
--tm-chip-bg-hover: rgba(15, 15, 15, 0.09);
--tm-chip-bg-active: #0f0f0f;
--tm-chip-text: #0f0f0f;
--tm-chip-text-active: #ffffff;
--tm-font: 'Inter', -apple-system, BlinkMacSystemFont, 'SF Pro Display',
'Segoe UI', 'Helvetica Neue', Roboto, Arial, sans-serif;
}
html[dark].tm-youtube-layout-plus-home {
--tm-card-bg: #1f1f1f;
--tm-card-border: rgba(255, 255, 255, 0.08);
--tm-card-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 6px 18px rgba(0, 0, 0, 0.18);
--tm-text-primary: #f1f1f1;
--tm-text-secondary: rgba(255, 255, 255, 0.72);
--tm-meta-secondary: rgba(255, 255, 255, 0.6);
--tm-chip-bg: rgba(255, 255, 255, 0.08);
--tm-chip-bg-hover: rgba(255, 255, 255, 0.14);
--tm-chip-bg-active: #ffffff;
--tm-chip-text: rgba(255, 255, 255, 0.92);
--tm-chip-text-active: #0f0f0f;
}
.${REPLAY_HIDE_CLASS} {
display: none !important;
}
/* ============================================================ */
/* Top bar switchers (theme + grid columns) */
/* ============================================================ */
#${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.1));
border-radius: 999px;
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: 999px;
background: transparent;
color: var(--yt-spec-text-primary, #0f0f0f);
cursor: pointer;
font: 600 12px/1 'Inter', -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
letter-spacing: 0;
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);
}
#${HOME_GRID_SWITCHER_ID} {
position: relative;
display: inline-flex;
align-items: center;
gap: 6px;
margin-left: 8px;
padding: 4px 6px;
border: 1px solid var(--yt-spec-10-percent-layer, rgba(0, 0, 0, 0.1));
border-radius: 999px;
background: var(--yt-spec-badge-chip-background, rgba(0, 0, 0, 0.05));
}
#${HOME_GRID_SWITCHER_ID} .tm-home-grid-option {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border: 0;
border-radius: 999px;
background: transparent;
color: var(--yt-spec-text-primary, #0f0f0f);
cursor: pointer;
font: 700 12px/1 'Inter', -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
transition: background 140ms ease, color 140ms ease, box-shadow 140ms ease;
}
#${HOME_GRID_SWITCHER_ID} .tm-home-grid-option:hover {
background: var(--yt-spec-badge-chip-background-hover, rgba(0, 0, 0, 0.08));
}
#${HOME_GRID_SWITCHER_ID} .tm-home-grid-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] #${HOME_GRID_SWITCHER_ID} {
border-color: rgba(255, 255, 255, 0.14);
background: rgba(255, 255, 255, 0.04);
}
html[dark] #${HOME_GRID_SWITCHER_ID} .tm-home-grid-option {
color: rgba(255, 255, 255, 0.92);
}
html[dark] #${HOME_GRID_SWITCHER_ID} .tm-home-grid-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.${WATCH_THEATER_CLASS} #${THEME_SWITCHER_ID},
html.${WATCH_THEATER_CLASS} #${HOME_GRID_SWITCHER_ID} {
border-color: rgba(255, 255, 255, 0.18) !important;
background: rgba(255, 255, 255, 0.06) !important;
}
html.${WATCH_THEATER_CLASS} #${THEME_SWITCHER_ID} .tm-theme-switch-option,
html.${WATCH_THEATER_CLASS} #${HOME_GRID_SWITCHER_ID} .tm-home-grid-option {
color: rgba(255, 255, 255, 0.92) !important;
}
html.${WATCH_THEATER_CLASS} #${THEME_SWITCHER_ID} .tm-theme-switch-option:hover,
html.${WATCH_THEATER_CLASS} #${HOME_GRID_SWITCHER_ID} .tm-home-grid-option:hover {
background: rgba(255, 255, 255, 0.1) !important;
}
html.${WATCH_THEATER_CLASS} #${THEME_SWITCHER_ID} .tm-theme-switch-option[data-active="true"],
html.${WATCH_THEATER_CLASS} #${HOME_GRID_SWITCHER_ID} .tm-home-grid-option[data-active="true"] {
background: rgba(255, 255, 255, 0.22) !important;
color: #fff !important;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.42) !important;
}
/* ============================================================ */
/* Home: keep mini-guide collapsed, align chip bar & content */
/* ============================================================ */
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 #chips-wrapper {
top: 66px !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;
}
/* ============================================================ */
/* Flat chip bar */
/* ============================================================ */
html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer {
padding: 20px 24px 6px !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-content {
position: static !important;
overflow: visible !important;
isolation: auto !important;
padding: 0 !important;
margin: 0 !important;
border: 0 !important;
border-radius: 0 !important;
background: transparent !important;
backdrop-filter: none !important;
-webkit-backdrop-filter: none !important;
box-shadow: none !important;
}
html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #chips-content::before,
html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer #chips-content::after {
content: none !important;
display: none !important;
}
html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer {
position: relative !important;
margin: 0 8px 0 0 !important;
padding: 0 !important;
}
html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer + yt-chip-cloud-chip-renderer::before {
display: none !important;
content: none !important;
}
html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer button.ytChipShapeButtonReset {
border-radius: 999px !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer .ytChipShapeChip {
position: relative !important;
min-height: 34px !important;
padding: 0 14px !important;
border: 1px solid transparent !important;
border-radius: 999px !important;
background: var(--tm-chip-bg) !important;
color: var(--tm-chip-text) !important;
font-family: var(--tm-font) !important;
font-weight: 500 !important;
letter-spacing: 0 !important;
backdrop-filter: none !important;
-webkit-backdrop-filter: none !important;
box-shadow: none !important;
transition: background 140ms ease, color 140ms ease !important;
}
html.tm-youtube-layout-plus-home ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer .ytChipShapeChip > div {
font-size: 14px !important;
line-height: 32px !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-bg-hover) !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-bg-active) !important;
color: var(--tm-chip-text-active) !important;
border-color: transparent !important;
box-shadow: none !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: 999px !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 {
top: 0px !important;
margin-top: 0 !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: 999px !important;
background: var(--tm-chip-bg) !important;
backdrop-filter: none !important;
-webkit-backdrop-filter: none !important;
box-shadow: none !important;
transform: none !important;
}
/* ============================================================ */
/* Hero grid: fixed top layout + switchable regular grid below */
/* ============================================================ */
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer {
display: grid !important;
grid-template-columns: repeat(20, minmax(0, 1fr)) !important;
grid-template-rows: repeat(4, auto) !important;
grid-auto-rows: min-content !important;
gap: 8px 16px !important;
margin-top: 0 !important;
padding: 5px 48px 40px 16px !important;
box-sizing: border-box !important;
font-family: var(--tm-font) !important;
align-items: start !important;
}
html.tm-youtube-layout-plus-home ytd-rich-grid-renderer {
--ytd-rich-grid-items-per-row: var(--tm-home-grid-items-per-row, 5) !important;
--ytd-rich-grid-posts-per-row: var(--tm-home-grid-items-per-row, 5) !important;
margin-top: -20px !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer {
width: auto !important;
max-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
transform-origin: center top !important;
transition: transform 160ms ease, box-shadow 160ms ease !important;
will-change: transform !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-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) {
grid-column: 1 / 13 !important;
grid-row: 1 / span 4 !important;
align-self: start !important;
height: auto !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) > #content {
height: auto !important;
min-height: 0 !important;
max-height: none !important;
background: var(--tm-card-bg) !important;
border: 1px solid var(--tm-card-border) !important;
border-radius: 20px !important;
box-shadow: var(--tm-card-shadow) !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-rich-grid-media {
height: auto !important;
max-height: none !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-lockup-view-model,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .yt-lockup-view-model-wiz,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-lockup-view-model > div {
height: auto !important;
max-height: none !important;
min-height: 0 !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .yt-lockup-view-model-wiz,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-lockup-view-model > div {
display: grid !important;
grid-template-columns: minmax(210px, 0.42fr) minmax(360px, 1fr) !important;
gap: 0 !important;
align-items: stretch !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-rich-grid-media #dismissible {
display: grid !important;
grid-template-columns: minmax(210px, 0.42fr) minmax(360px, 1fr) !important;
gap: 0 !important;
align-items: stretch !important;
height: 100% !important;
min-height: 0 !important;
max-height: 410px !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-thumbnail-view-model,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .yt-lockup-view-model-wiz__content-image {
grid-column: 2 !important;
grid-row: 1 !important;
width: 100% !important;
height: 100% !important;
min-height: 0 !important;
aspect-ratio: auto !important;
margin: 0 !important;
border-radius: 18px !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-thumbnail a,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #thumbnail a,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-thumbnail img,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #thumbnail img,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-thumbnail-view-model a,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-thumbnail-view-model img,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .yt-lockup-view-model-wiz__content-image a,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .yt-lockup-view-model-wiz__content-image img {
width: 100% !important;
height: 100% !important;
object-fit: cover !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #details,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .yt-lockup-view-model-wiz__metadata,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-lockup-metadata-view-model {
grid-column: 1 !important;
grid-row: 1 !important;
display: flex !important;
flex-direction: column !important;
min-width: 0 !important;
margin: 0 !important;
padding: clamp(28px, 3vw, 48px) clamp(24px, 3vw, 42px) !important;
background: rgba(15, 15, 15, 0.025) !important;
box-sizing: border-box !important;
}
html[dark].tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #details,
html[dark].tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .yt-lockup-view-model-wiz__metadata,
html[dark].tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-lockup-metadata-view-model {
background: rgba(255, 255, 255, 0.035) !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #avatar-link,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #channel-thumbnail {
display: none !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #meta,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #meta ytd-video-meta-block {
min-width: 0 !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #details ytd-channel-name {
order: 1 !important;
margin-bottom: 18px !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-channel-name #text,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-channel-name a {
font-family: var(--tm-font) !important;
font-size: 13px !important;
font-weight: 600 !important;
color: var(--tm-text-secondary) !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #video-title,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-formatted-string#video-title {
order: 2 !important;
font-family: var(--tm-font) !important;
font-size: clamp(28px, 2.5vw, 42px) !important;
font-weight: 800 !important;
line-height: 1.16 !important;
letter-spacing: 0 !important;
color: var(--tm-text-primary) !important;
display: -webkit-box !important;
-webkit-line-clamp: 3 !important;
-webkit-box-orient: vertical !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #metadata-line {
order: 3 !important;
margin-top: 18px !important;
font-family: var(--tm-font) !important;
font-size: 15px !important;
line-height: 1.55 !important;
color: var(--tm-meta-secondary) !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #details::after {
content: "Play Video";
display: inline-flex;
align-items: center;
justify-content: center;
width: fit-content;
min-height: 48px;
margin-top: auto;
padding: 0 22px;
border-radius: 999px;
background: #fff;
color: #0f0f0f;
font: 700 15px/1 var(--tm-font);
box-shadow: 0 8px 22px rgba(15, 15, 15, 0.08);
}
html[dark].tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #details::after {
background: rgba(255, 255, 255, 0.14);
color: #fff;
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.24);
}
/* First card: keep the large thumbnail on top and metadata below. */
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) > #content,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-rich-grid-media,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-lockup-view-model {
height: auto !important;
max-height: none !important;
min-height: 0 !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-rich-grid-media #dismissible,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-lockup-view-model > div,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .ytLockupViewModelHost {
display: grid !important;
grid-template-columns: minmax(0, 1fr) !important;
grid-template-rows: auto auto !important;
gap: 10px !important;
align-items: stretch !important;
height: auto !important;
min-height: 0 !important;
max-height: none !important;
overflow: visible !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-thumbnail-view-model,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-collection-thumbnail-view-model,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .ytLockupViewModelContentImage,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .yt-lockup-view-model-wiz__content-image {
grid-column: 1 !important;
grid-row: 1 !important;
width: 100% !important;
max-width: 100% !important;
height: auto !important;
min-height: 0 !important;
max-height: none !important;
aspect-ratio: 16 / 9 !important;
margin: 0 !important;
border-radius: 18px !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .ytLockupViewModelContentImage > *,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-collection-thumbnail-view-model > *,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-thumbnail-view-model > * {
width: 100% !important;
height: 100% !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #details,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .ytLockupViewModelMetadata,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .yt-lockup-view-model-wiz__metadata,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-lockup-metadata-view-model {
grid-column: 1 !important;
grid-row: 2 !important;
display: block !important;
min-width: 0 !important;
width: 100% !important;
max-width: 100% !important;
min-height: 0 !important;
margin: 0 !important;
padding: 2px 10px 6px !important;
background: transparent !important;
box-sizing: border-box !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) yt-lockup-metadata-view-model {
display: grid !important;
grid-template-columns: auto minmax(0, 1fr) auto !important;
grid-template-rows: auto auto !important;
column-gap: 12px !important;
row-gap: 2px !important;
align-items: start !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .ytLockupMetadataViewModelTextContainer {
grid-column: 2 !important;
grid-row: 1 / span 2 !important;
min-width: 0 !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .ytLockupMetadataViewModelAvatar {
grid-column: 1 !important;
grid-row: 1 / span 2 !important;
align-self: start !important;
margin: 0 !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) .ytLockupMetadataViewModelMenuButton {
grid-column: 3 !important;
grid-row: 1 / span 2 !important;
align-self: start !important;
margin-top: -4px !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #details::after {
content: none !important;
display: none !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(2) { grid-column: 13 / 21 !important; grid-row: 1 !important; }
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(3) { grid-column: 13 / 21 !important; grid-row: 2 !important; }
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(4) { grid-column: 13 / 21 !important; grid-row: 3 !important; }
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(5) { grid-column: 13 / 21 !important; grid-row: 4 !important; }
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) {
align-self: stretch !important;
height: 100% !important;
min-height: 0 !important;
padding: 0 !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) > #content,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-rich-grid-media,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) yt-lockup-view-model,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .yt-lockup-view-model-wiz,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) yt-lockup-view-model > div,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-ad-slot-renderer,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-in-feed-ad-layout-renderer {
height: auto !important;
min-height: 0 !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-rich-grid-media,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) yt-lockup-view-model,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-ad-slot-renderer,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-in-feed-ad-layout-renderer {
background: var(--tm-card-bg) !important;
border: 1px solid var(--tm-card-border) !important;
border-radius: 16px !important;
padding: 5px !important;
box-shadow: var(--tm-card-shadow) !important;
box-sizing: border-box !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-rich-grid-media #dismissible,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .ytLockupViewModelHost,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .yt-lockup-view-model-wiz,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) yt-lockup-view-model > div,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-ad-slot-renderer #dismissible,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-in-feed-ad-layout-renderer #dismissible,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-in-feed-ad-layout-renderer > div {
display: flex !important;
flex-direction: row !important;
grid-template-columns: 154px minmax(0, 1fr) !important;
gap: 10px !important;
align-items: center !important;
height: 100% !important;
min-height: 0 !important;
background: transparent !important;
border: 0 !important;
border-radius: 0 !important;
padding: 0 !important;
box-shadow: none !important;
box-sizing: border-box !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) yt-thumbnail-view-model,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .ytLockupViewModelContentImage,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .yt-lockup-view-model-wiz__content-image,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .yt-lockup-view-model-wiz__content,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-in-feed-ad-layout-renderer #thumbnail {
grid-column: 1 !important;
grid-row: 1 !important;
width: 154px !important;
min-width: 0 !important;
max-width: 154px !important;
flex: 0 0 154px !important;
height: 87px !important;
min-height: 87px !important;
max-height: 87px !important;
aspect-ratio: 16 / 9 !important;
margin: 0 !important;
border-radius: 12px !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-thumbnail a,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #thumbnail a,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-thumbnail img,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #thumbnail img,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .ytLockupViewModelContentImage > *,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .ytLockupViewModelContentImage img,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .ytLockupViewModelContentImage yt-thumbnail-view-model,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .ytLockupViewModelContentImage yt-thumbnail-view-model > *,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) yt-thumbnail-view-model a,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) yt-thumbnail-view-model img,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .yt-lockup-view-model-wiz__content-image a,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .yt-lockup-view-model-wiz__content-image img {
width: 100% !important;
height: 100% !important;
object-fit: cover !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #avatar-link,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #avatar,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #avatar-container,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #channel-thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-channel-name yt-img-shadow {
display: none !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #details,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #meta,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .ytLockupViewModelMetadata,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) .yt-lockup-view-model-wiz__metadata,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) yt-lockup-metadata-view-model,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-in-feed-ad-layout-renderer #details,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-in-feed-ad-layout-renderer #meta {
padding: 0 !important;
margin: 0 !important;
min-width: 0 !important;
max-width: 100% !important;
grid-column: 2 !important;
grid-row: 1 !important;
flex: 1 1 auto !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #video-title,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) yt-formatted-string#video-title {
font-family: var(--tm-font) !important;
font-size: 15px !important;
font-weight: 700 !important;
line-height: 1.25 !important;
letter-spacing: 0 !important;
margin: 0 0 5px 0 !important;
color: var(--tm-text-primary) !important;
display: -webkit-box !important;
-webkit-line-clamp: 2 !important;
-webkit-box-orient: vertical !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-channel-name #text,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) ytd-channel-name a,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+2):nth-of-type(-n+5) #metadata-line {
font-family: var(--tm-font) !important;
font-size: 13px !important;
line-height: 1.35 !important;
color: var(--tm-meta-secondary) !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+6) {
grid-column: span var(--tm-home-grid-card-span, 4) !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+6) ytd-thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+6) #thumbnail {
border-radius: 12px !important;
overflow: hidden !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+6) #video-title,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+6) yt-formatted-string#video-title {
font-family: var(--tm-font) !important;
font-weight: 600 !important;
letter-spacing: 0 !important;
color: var(--tm-text-primary) !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+6) ytd-channel-name #text,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+6) #metadata-line {
font-family: var(--tm-font) !important;
color: var(--tm-meta-secondary) !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:hover,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:focus-within {
transform: translateY(-2px) !important;
z-index: 4 !important;
}
@media (max-width: 1180px) {
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) {
grid-column: 1 / 21 !important;
grid-row: auto !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(2),
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(3),
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(4),
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(5) {
grid-column: span 10 !important;
grid-row: auto !important;
}
}
@media (max-width: 760px) {
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer {
padding: 12px 14px 32px !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-rich-grid-media #dismissible {
grid-template-columns: 1fr !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #details {
grid-column: 1 !important;
grid-row: auto !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) ytd-thumbnail,
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(1) #thumbnail {
min-height: 220px !important;
}
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(2),
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(3),
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(4),
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(5),
html.tm-youtube-layout-plus-home #contents.ytd-rich-grid-renderer > ytd-rich-item-renderer:nth-of-type(n+6) {
grid-column: 1 / 21 !important;
}
}
/* ============================================================ */
/* Watch page */
/* ============================================================ */
html.tm-youtube-layout-plus-watch,
html.tm-youtube-layout-plus-watch body,
html.tm-youtube-layout-plus-watch ytd-app,
html.tm-youtube-layout-plus-watch ytd-watch-flexy,
html.tm-youtube-layout-plus-watch ytd-watch-flexy #columns,
html.tm-youtube-layout-plus-watch ytd-watch-flexy #primary,
html.tm-youtube-layout-plus-watch ytd-watch-flexy #primary-inner,
html.tm-youtube-layout-plus-watch ytd-watch-flexy #below {
overflow-x: hidden !important;
overscroll-behavior-x: none !important;
max-width: 100% !important;
}
html.tm-youtube-layout-plus-watch-plain ytd-watch-flexy #related,
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:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy #secondary,
html.tm-youtube-layout-plus-watch-plain:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy #secondary-inner {
display: none !important;
}
html.tm-youtube-layout-plus-watch-plain:not(.${WATCH_PANEL_OPEN_CLASS}) 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:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy[is-two-columns_] #columns {
display: block !important;
width: 100% !important;
max-width: 100% !important;
}
html.tm-youtube-layout-plus-watch-plain:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy[is-two-columns_] #primary-inner,
html.tm-youtube-layout-plus-watch-plain:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy[is-two-columns_] #above-the-fold,
html.tm-youtube-layout-plus-watch-plain:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy[is-two-columns_] #below {
max-width: none !important;
}
html.tm-youtube-layout-plus-watch-chat-collapsed:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy #secondary,
html.tm-youtube-layout-plus-watch-chat-collapsed:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy #secondary-inner {
display: none !important;
}
html.tm-youtube-layout-plus-watch-chat-collapsed:not(.${WATCH_PANEL_OPEN_CLASS}) 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:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy[is-two-columns_] #columns {
display: block !important;
width: 100% !important;
max-width: 100% !important;
}
html.tm-youtube-layout-plus-watch-chat-collapsed:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy[is-two-columns_] #primary-inner,
html.tm-youtube-layout-plus-watch-chat-collapsed:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy[is-two-columns_] #above-the-fold,
html.tm-youtube-layout-plus-watch-chat-collapsed:not(.${WATCH_PANEL_OPEN_CLASS}) ytd-watch-flexy[is-two-columns_] #below {
max-width: none !important;
}
`;
}
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 setLayoutModeClasses(targetClasses) {
const target = new Set(targetClasses);
const root = document.documentElement;
for (const cls of LAYOUT_MODE_CLASSES) {
const shouldHave = target.has(cls);
const hasIt = root.classList.contains(cls);
if (shouldHave && !hasIt) root.classList.add(cls);
else if (!shouldHave && hasIt) root.classList.remove(cls);
}
}
function applyHomeLayout() {
const richGrid = document.querySelector('ytd-rich-grid-renderer');
if (!richGrid) {
setLayoutModeClasses([]);
return;
}
setLayoutModeClasses(['tm-youtube-layout-plus-home']);
applyHomeGridColumns();
applyHomeHeroInlineLayout();
if (lastAutoCollapsedHomeUrl !== location.href) {
collapseGuide();
lastAutoCollapsedHomeUrl = location.href;
}
}
function applyHomeHeroInlineLayout() {
const items = Array.from(
document.querySelectorAll('#contents.ytd-rich-grid-renderer > ytd-rich-item-renderer')
);
if (items.length < 5) return;
items[0].style.setProperty('grid-column', '1 / 13', 'important');
items[0].style.setProperty('grid-row', '1 / span 4', 'important');
for (let index = 1; index < 5; index += 1) {
items[index].style.setProperty('grid-column', '13 / 21', 'important');
items[index].style.setProperty('grid-row', String(index), 'important');
}
upgradeHomeHeroThumbnail();
}
function applyWatchLayout() {
const watchFlexy = document.querySelector('ytd-watch-flexy');
if (!watchFlexy) {
setLayoutModeClasses([]);
document.documentElement.classList.remove(WATCH_THEATER_CLASS);
return;
}
updateWatchEngagementPanelState(watchFlexy);
updateTheaterModeState(watchFlexy);
if (hasWatchSidebarChat(watchFlexy)) {
setLayoutModeClasses([
'tm-youtube-layout-plus-watch',
'tm-youtube-layout-plus-watch-chat',
]);
updateWatchChatPanelState(watchFlexy);
autoCollapseLiveChatPanel(watchFlexy);
syncWatchPlayerSize();
schedulePlayerSync(120);
return;
}
setLayoutModeClasses([
'tm-youtube-layout-plus-watch',
'tm-youtube-layout-plus-watch-plain',
]);
hideWatchReplayPrompt();
syncWatchPlayerSize();
schedulePlayerSync(120);
}
function clearHiddenReplayPrompts() {
for (const el of document.querySelectorAll('.' + REPLAY_HIDE_CLASS)) {
el.classList.remove(REPLAY_HIDE_CLASS);
}
}
function hideWatchReplayPrompt() {
const teaserCarousel = document.querySelector('ytd-watch-metadata #teaser-carousel');
if (!teaserCarousel) return;
const teaserText = getWatchTeaserText();
if (hasLiveWatchPrompt(teaserText)) {
teaserCarousel.classList.remove(REPLAY_HIDE_CLASS);
return;
}
const watchFlexy = document.querySelector('ytd-watch-flexy');
if (watchFlexy && hasReplayWatchPrompt(teaserText) && hasWatchSidebarChat(watchFlexy)) {
teaserCarousel.classList.remove(REPLAY_HIDE_CLASS);
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) {
teaserCarousel.classList.remove(REPLAY_HIDE_CLASS);
return;
}
teaserCarousel.classList.add(REPLAY_HIDE_CLASS);
}
function updateWatchEngagementPanelState(watchFlexy) {
const open = isWatchPage() && hasOpenEngagementPanel(watchFlexy);
document.documentElement.classList.toggle(WATCH_PANEL_OPEN_CLASS, open);
if (lastEngagementPanelOpen !== open) {
lastEngagementPanelOpen = open;
lastPlayerSyncKey = '';
window.requestAnimationFrame(() => {
syncWatchPlayerSize();
schedulePlayerSync(120);
});
}
}
function updateTheaterModeState(watchFlexy) {
const inTheater = isTheaterModeActive(watchFlexy);
document.documentElement.classList.toggle(WATCH_THEATER_CLASS, inTheater);
if (lastTheaterMode !== inTheater) {
lastTheaterMode = inTheater;
lastPlayerSyncKey = '';
window.requestAnimationFrame(() => {
syncWatchPlayerSize();
schedulePlayerSync(120);
schedulePlayerSync(360);
});
}
}
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;
lastPlayerSyncKey = '';
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;
}
updateWatchEngagementPanelState(watchFlexy);
updateTheaterModeState(watchFlexy);
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 safeGetIframeDocument(frame) {
try {
return frame?.contentDocument || null;
} catch {
return 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 = safeGetIframeDocument(chatFrame);
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;
if (document.fullscreenElement) return;
const moviePlayer = document.getElementById('movie_player');
if (!moviePlayer) return;
const playerContainer = moviePlayer.closest(PLAYER_CONTAINER_SELECTOR);
if (!playerContainer) 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}|${playerContainer.id}|${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);
}
} catch (error) {
console.debug('YouTube Layout Plus player sync failed:', error);
}
lastPlayerSyncKey = syncKey;
}
function schedulePlayerSync(delay = 0) {
if (delay <= 0) {
if (playerSyncTimer) {
window.clearTimeout(playerSyncTimer);
playerSyncTimer = null;
}
syncWatchPlayerSize();
return;
}
window.setTimeout(syncWatchPlayerSize, delay);
}
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 normalizeHomeGridColumns(value) {
const columns = Number(value);
return HOME_GRID_COLUMN_OPTIONS.includes(columns) ? columns : 5;
}
function loadStoredHomeGridColumns() {
try {
return normalizeHomeGridColumns(window.localStorage.getItem(HOME_GRID_COLUMNS_STORAGE_KEY));
} catch {
return 5;
}
}
function persistThemeMode(mode) {
if (lastPersistedThemeMode === mode) return;
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);
}
lastPersistedThemeMode = mode;
} catch {
// Ignore storage failures.
}
}
function persistHomeGridColumns(columns) {
try {
window.localStorage.setItem(
HOME_GRID_COLUMNS_STORAGE_KEY,
String(normalizeHomeGridColumns(columns))
);
} catch {
// Ignore storage failures.
}
}
function applyHomeGridColumns() {
const columns = normalizeHomeGridColumns(currentHomeGridColumns);
document.documentElement.style.setProperty(
'--tm-home-grid-items-per-row',
String(columns)
);
document.documentElement.style.setProperty(
'--tm-home-grid-card-span',
String(HOME_GRID_TRACK_COUNT / columns)
);
}
function delay(ms) {
return new Promise((resolve) => {
window.setTimeout(resolve, ms);
});
}
function getThemeActionName(mode) {
return THEME_MODES.find((item) => item.mode === mode)?.actionName || 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=([0-9a-fA-F]+)/);
if (!f6Match) return null;
const f6 = parseInt(f6Match[1], 16);
if (!Number.isFinite(f6)) return null;
if ((f6 & PREF_F6_LIGHT_BIT) !== 0) return 'light';
if ((f6 & PREF_F6_DARK_BIT) !== 0) return 'dark';
if ((f6 & PREF_F6_PREF_BIT) !== 0) return 'auto';
return null;
} catch {
return null;
}
}
function inferThemeModeFromDocument() {
return document.documentElement.hasAttribute('dark') ? 'dark' : 'light';
}
function getObservedThemeMode() {
return getThemeModeFromPrefCookie() || 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';
if (themeStatusHideTimer) window.clearTimeout(themeStatusHideTimer);
themeStatusHideTimer = window.setTimeout(() => {
status.dataset.visible = 'false';
themeStatusHideTimer = null;
}, 2600);
}
function hideThemeStatusMessage() {
const status = document.getElementById(THEME_STATUS_ID);
if (status) status.dataset.visible = 'false';
if (themeStatusHideTimer) {
window.clearTimeout(themeStatusHideTimer);
themeStatusHideTimer = null;
}
}
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 dispatchThemeSignal(mode) {
const actionName = getThemeActionName(mode);
if (!actionName) return false;
const target = document.querySelector('ytd-app') || document.documentElement;
try {
target.dispatchEvent(new CustomEvent('yt-action', {
detail: {
actionName,
args: [],
optionalAction: false,
returnValue: [],
},
bubbles: true,
cancelable: false,
composed: true,
}));
return true;
} catch (error) {
console.debug('YouTube Layout Plus theme dispatch failed:', error);
return false;
}
}
function updateThemeSwitcherUI({ force = false } = {}) {
const switcher = document.getElementById(THEME_SWITCHER_ID);
if (!switcher) return;
if (!pendingThemeMode) {
const observedMode = getObservedThemeMode();
if (observedMode && observedMode !== currentThemeMode) {
currentThemeMode = observedMode;
persistThemeMode(observedMode);
}
} else if (!currentThemeMode) {
currentThemeMode = loadStoredThemeMode() || inferThemeModeFromDocument();
}
const visibleMode = pendingThemeMode || currentThemeMode;
const disabled = themeSwitchInFlight;
if (!force
&& lastRenderedThemeMode === visibleMode
&& lastRenderedThemeDisabled === disabled) {
return;
}
lastRenderedThemeMode = visibleMode;
lastRenderedThemeDisabled = disabled;
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 = disabled;
}
}
async function verifyThemeMode(mode, { attempts = 10, intervalMs = 120 } = {}) {
const expectedDarkAttr = mode === 'dark';
let lastResult = null;
for (let attempt = 0; attempt < attempts; attempt += 1) {
const cookieMode = getThemeModeFromPrefCookie();
const hasDark = document.documentElement.hasAttribute('dark');
const actualMode = cookieMode || inferThemeModeFromDocument();
const cookieConsistent = cookieMode ? cookieMode === mode : true;
const darkConsistent = mode === 'auto' ? true : hasDark === expectedDarkAttr;
lastResult = {
ok: cookieConsistent && darkConsistent,
actualMode,
cookieMode,
hasDark,
};
if (lastResult.ok) {
return lastResult;
}
await delay(intervalMs);
}
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()
|| inferThemeModeFromDocument();
const expectedDarkAttr = mode === 'dark'
|| (mode === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches);
if (previousMode === mode
&& document.documentElement.hasAttribute('dark') === expectedDarkAttr) {
currentThemeMode = mode;
persistThemeMode(mode);
pendingThemeMode = null;
updateThemeSwitcherUI();
return;
}
themeSwitchInFlight = true;
pendingThemeMode = mode;
try {
updateThemeSwitcherUI();
if (!dispatchThemeSignal(mode)) {
currentThemeMode = previousMode;
persistThemeMode(previousMode);
showThemeStatusMessage(`Theme switch failed: unable to dispatch ${mode}.`);
return;
}
currentThemeMode = mode;
persistThemeMode(mode);
updateThemeSwitcherUI();
let verification = await verifyThemeMode(mode);
if (!verification.ok) {
dispatchThemeSignal(mode);
verification = await verifyThemeMode(mode, { attempts: 14, intervalMs: 140 });
}
if (!verification.ok) {
currentThemeMode = verification.actualMode || previousMode;
persistThemeMode(currentThemeMode);
showThemeStatusMessage(
`Theme switch failed: expected ${mode}, actual ${currentThemeMode || 'unknown'}.`
);
return;
}
currentThemeMode = verification.actualMode || mode;
persistThemeMode(currentThemeMode);
hideThemeStatusMessage();
} finally {
themeSwitchInFlight = false;
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);
let justCreated = false;
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);
justCreated = true;
} else if (switcher.previousElementSibling !== logoRenderer) {
logoRenderer.insertAdjacentElement('afterend', switcher);
}
updateThemeSwitcherUI({ force: justCreated });
}
function updateHomeGridSwitcherUI({ force = false } = {}) {
const switcher = document.getElementById(HOME_GRID_SWITCHER_ID);
if (!switcher) return;
const activeColumns = normalizeHomeGridColumns(currentHomeGridColumns);
if (!force && lastRenderedHomeGridColumns === activeColumns) return;
lastRenderedHomeGridColumns = activeColumns;
for (const button of switcher.querySelectorAll('.tm-home-grid-option[data-columns]')) {
const isActive = Number(button.dataset.columns) === activeColumns;
button.dataset.active = String(isActive);
button.setAttribute('aria-pressed', String(isActive));
}
}
function setHomeGridColumns(columns) {
const normalized = normalizeHomeGridColumns(columns);
if (normalized === currentHomeGridColumns) return;
currentHomeGridColumns = normalized;
persistHomeGridColumns(currentHomeGridColumns);
applyHomeGridColumns();
updateHomeGridSwitcherUI();
if (isHomePage()) {
scheduleApply();
window.setTimeout(() => {
window.dispatchEvent(new Event('resize'));
}, 60);
}
}
function ensureHomeGridSwitcher() {
const anchor = document.getElementById(THEME_SWITCHER_ID)
|| document.querySelector('ytd-topbar-logo-renderer');
if (!anchor) return;
let switcher = document.getElementById(HOME_GRID_SWITCHER_ID);
let justCreated = false;
if (!switcher) {
switcher = document.createElement('div');
switcher.id = HOME_GRID_SWITCHER_ID;
switcher.setAttribute('role', 'group');
switcher.setAttribute('aria-label', 'Home grid columns');
for (const columns of HOME_GRID_COLUMN_OPTIONS) {
const optionButton = document.createElement('button');
optionButton.type = 'button';
optionButton.className = 'tm-home-grid-option';
optionButton.dataset.columns = String(columns);
optionButton.dataset.active = 'false';
optionButton.textContent = String(columns);
optionButton.setAttribute('aria-pressed', 'false');
optionButton.addEventListener('click', (event) => {
event.preventDefault();
event.stopPropagation();
setHomeGridColumns(columns);
});
switcher.appendChild(optionButton);
}
anchor.insertAdjacentElement('afterend', switcher);
justCreated = true;
} else if (switcher.previousElementSibling !== anchor) {
anchor.insertAdjacentElement('afterend', switcher);
}
updateHomeGridSwitcherUI({ force: justCreated });
}
function applyLayout() {
ensureStyle();
applyHomeGridColumns();
try {
ensureThemeSwitcher();
ensureHomeGridSwitcher();
} catch (error) {
console.error('YouTube Layout Plus switcher insertion failed:', error);
}
if (isHomePage()) {
applyHomeLayout();
return;
}
if (isWatchPage()) {
applyWatchLayout();
return;
}
setLayoutModeClasses([]);
document.documentElement.classList.remove(WATCH_PANEL_OPEN_CLASS);
document.documentElement.classList.remove(WATCH_THEATER_CLASS);
}
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;
clearHiddenReplayPrompts();
if (!isHomePage()) {
lastAutoCollapsedHomeUrl = '';
}
if (!isWatchPage()) {
lastAutoCollapsedWatchChatKey = '';
stopWatchLayoutRetry();
stopWatchChatStateSync();
lastWatchChatExpanded = null;
lastEngagementPanelOpen = null;
lastTheaterMode = null;
lastPlayerSyncKey = '';
document.documentElement.classList.remove(WATCH_PANEL_OPEN_CLASS);
document.documentElement.classList.remove(WATCH_THEATER_CLASS);
if (playerSyncTimer) {
window.clearTimeout(playerSyncTimer);
playerSyncTimer = null;
}
} else {
lastWatchChatExpanded = null;
lastEngagementPanelOpen = null;
lastTheaterMode = 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;
if (target.closest('#movie_player, .html5-video-player, #chatframe')) {
return false;
}
return true;
});
if (hasRelevantMutation) {
scheduleApply(OBSERVER_APPLY_DEBOUNCE_MS);
}
});
bodyObserver.observe(document.body, {
childList: true,
subtree: true,
});
}
function startNavigationListeners() {
document.addEventListener('yt-navigate-finish', handleRouteChange, true);
window.addEventListener('popstate', handleRouteChange, true);
}
function startWindowListeners() {
window.addEventListener('resize', () => {
if (resizeTimer) {
window.clearTimeout(resizeTimer);
}
if (resizeFrame) {
window.cancelAnimationFrame(resizeFrame);
}
resizeFrame = window.requestAnimationFrame(() => {
resizeFrame = 0;
if (!isWatchPage()) return;
lastPlayerSyncKey = '';
syncWatchPlayerSize();
});
resizeTimer = window.setTimeout(() => {
resizeTimer = null;
if (!isWatchPage()) {
scheduleApply();
return;
}
lastPlayerSyncKey = '';
scheduleApply();
schedulePlayerSync(120);
}, 30);
}, 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);
}
if (isWatchPage()) {
window.setTimeout(() => {
const watchFlexy = document.querySelector('ytd-watch-flexy');
if (watchFlexy) {
updateWatchEngagementPanelState(watchFlexy);
updateTheaterModeState(watchFlexy);
}
}, 120);
}
}, true);
document.addEventListener('keyup', (event) => {
if (!isWatchPage()) return;
if (event.key !== 't' && event.key !== 'T') return;
const target = event.target;
if (target instanceof HTMLElement) {
const tag = target.tagName;
if (tag === 'INPUT' || tag === 'TEXTAREA' || target.isContentEditable) return;
}
window.setTimeout(() => {
const watchFlexy = document.querySelector('ytd-watch-flexy');
if (watchFlexy) updateTheaterModeState(watchFlexy);
}, 80);
}, true);
}
function watchRoute() {
if (routeTimer) return;
routeTimer = window.setInterval(() => {
if (location.href === currentUrl) return;
handleRouteChange();
}, ROUTE_POLL_INTERVAL_MS);
}
function init() {
ensureStyle();
handleRouteChange(true);
startObservers();
startNavigationListeners();
startWindowListeners();
startInteractionListeners();
watchRoute();
}
init();
})();