// ==UserScript==
// @name YouTube No Saturated Hover
// @namespace https://greasyfork.org/users/1476331-jon78
// @match *://*.youtube.com/*
// @run-at document-start
// @grant none
// @version 1.1
// @description Removes YouTube's 2025 saturated hover effects.
// @license CC0
// ==/UserScript==
(() => {
"use strict";
const ID = "no-saturated-hover";
let styleEl, dark, fixTimer, rafPending, obs;
const detectDark = () => {
const html = document.documentElement;
if (html.hasAttribute("dark") || html.classList.contains("dark-theme")) return true;
if (html.hasAttribute("light") || html.classList.contains("light-theme")) return false;
const bg = getComputedStyle(html).getPropertyValue("--yt-spec-base-background").trim();
if (bg.startsWith("rgb(")) {
const [r, g, b] = bg.match(/\d+/g).map(Number);
return (r + g + b) / 3 < 60;
}
return false;
};
const css = d => `
/* --- Theme Variable Setup --- */
html {
--ytc-base-background:${d ? "#0f0f0f" : "#fff"};
--ytc-additive-background:${d ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
--ytc-text-primary:${d ? "#f1f1f1" : "#0f0f0f"};
--ytc-text-secondary:${d ? "#aaa" : "#606060"};
/* Safely chain to YouTube's native variables */
--yt-spec-base-background:var(--yt-spec-base-background,var(--ytc-base-background));
--yt-spec-additive-background:var(--yt-spec-additive-background,var(--ytc-additive-background));
--yt-spec-text-primary:var(--yt-spec-text-primary,var(--ytc-text-primary));
--yt-spec-text-secondary:var(--yt-spec-text-secondary,var(--ytc-text-secondary));
}
/* === HOMEPAGE === */
/* --- Disable saturated hover shapes --- */
.yt-spec-touch-feedback-shape__hover-effect,
.yt-spec-touch-feedback-shape__stroke,
.yt-spec-touch-feedback-shape__fill {
display:none!important;
opacity:0!important;
pointer-events:none!important;
}
/* --- Remove highlight from promoted videos --- */
ytd-rich-item-renderer.ytd-rich-item-renderer-highlight {
background:transparent!important;
box-shadow:none!important;
--yt-spec-outline:transparent!important;
}
/* --- Title color --- */
ytd-rich-grid-renderer #video-title,
.yt-lockup-metadata-view-model__title,
.yt-lockup-metadata-view-model__title a {
color:var(--yt-spec-text-primary,var(--ytc-text-primary))!important;
}
/* --- Metadata color --- */
.yt-lockup-metadata-view-model__metadata,
.yt-lockup-metadata-view-model__metadata span,
#metadata-line span {
color:var(--yt-spec-text-secondary,var(--ytc-text-secondary))!important;
}
/* === WATCH PAGE === */
/* --- Description/metadata/snippet text color --- */
ytd-watch-metadata #description,
ytd-video-secondary-info-renderer #description,
ytd-watch-info-text,
#metadata.ytd-watch-info-text,
#metadata-line.ytd-video-primary-info-renderer span,
#snippet-text,
#snippet-text *,
#attributed-snippet-text,
#attributed-snippet-text * {
color: var(--yt-spec-text-primary, var(--ytc-text-primary)) !important;
}
/* --- Snippet/Metadata text hover color --- */
#snippet-text:hover,
#snippet-text *:hover,
#attributed-snippet-text:hover,
#attributed-snippet-text *:hover,
ytd-watch-info-text *:hover {
color: var(--yt-spec-text-primary, var(--ytc-text-primary)) !important;
filter: none !important;
opacity: 1 !important;
}
/* --- Highlighted links --- */
.yt-core-attributed-string--highlight-text-decorator a.yt-core-attributed-string__link--call-to-action-color,
.yt-core-attributed-string--link-inherit-color .yt-core-attributed-string--highlight-text-decorator a.yt-core-attributed-string__link--call-to-action-color {
color: var(--yt-spec-text-primary, var(--ytc-text-primary)) !important;
}
/* --- Call-to-action (blue links, hashtags) — exclude highlighted links --- */
ytd-watch-metadata :not(.yt-core-attributed-string--highlight-text-decorator) > .yt-core-attributed-string__link--call-to-action-color,
#snippet-text :not(.yt-core-attributed-string--highlight-text-decorator) > .yt-core-attributed-string__link--call-to-action-color,
#attributed-snippet-text :not(.yt-core-attributed-string--highlight-text-decorator) > .yt-core-attributed-string__link--call-to-action-color {
color: var(--yt-spec-call-to-action, #3ea6ff) !important;
}
/* --- Reset saturation vars --- */
ytd-watch-metadata, .ytd-watch-metadata {
--yt-saturated-base-background:var(--ytc-base-background);
--yt-saturated-raised-background:var(--yt-spec-additive-background,var(--ytc-additive-background));
--yt-saturated-additive-background:var(--yt-spec-additive-background,var(--ytc-additive-background));
--yt-saturated-text-primary:var(--yt-spec-text-primary,var(--ytc-text-primary));
--yt-saturated-text-secondary:var(--yt-spec-text-secondary,var(--ytc-text-secondary));
--yt-saturated-overlay-background:var(--yt-spec-additive-background,var(--ytc-additive-background));
--yt-spec-overlay-background:var(--yt-spec-additive-background,var(--ytc-additive-background));
--yt-spec-static-overlay-background-light:var(--yt-spec-additive-background,var(--ytc-additive-background));
}
/* --- Highlighted links background --- */
.yt-core-attributed-string--highlight-text-decorator {
background-color:var(--yt-spec-static-overlay-background-light,${d ? "rgba(255,255,255,0.102)" : "rgba(0,0,0,0.051)"})!important;
border-radius:8px!important;
padding-bottom:1px!important;
}
`.trim();
const applyStyle = d => {
if (!(styleEl = document.getElementById(ID))) {
styleEl = document.createElement("style");
styleEl.id = ID;
document.head.append(styleEl);
}
styleEl.textContent = css(d);
};
const fixHighlights = () => {
const expected = dark ? "rgba(255, 255, 255, 0.102)" : "rgba(0, 0, 0, 0.051)";
document.querySelectorAll(".yt-core-attributed-string--highlight-text-decorator").forEach(el => {
if (el.style.backgroundColor !== expected) el.style.backgroundColor = expected;
});
};
const scheduleFix = () => {
if (rafPending) return;
rafPending = true;
requestAnimationFrame(() => {
rafPending = false;
clearTimeout(fixTimer);
fixTimer = setTimeout(fixHighlights, 60);
});
};
const refresh = () => {
const d = detectDark();
if (d !== dark) {
dark = d;
applyStyle(d);
}
scheduleFix();
};
const init = () => {
dark = detectDark();
applyStyle(dark);
scheduleFix();
addEventListener("yt-navigate-start", refresh, { passive: true });
addEventListener("yt-navigate-finish", refresh, { passive: true });
addEventListener("yt-dark-mode-toggled", refresh, { passive: true });
obs = new MutationObserver(scheduleFix);
obs.observe(document.documentElement, { attributes: true, attributeFilter: ["dark", "light", "class"] });
addEventListener("pagehide", () => obs.disconnect(), { once: true });
};
document.head ? init() : addEventListener("DOMContentLoaded", init, { once: true });
})();