YouTube - Force rounded corners + tweaks included

This script forces the rounded version of the layout (which includes some fewer tweaks applied which also improves bugs).

2024-11-07 या दिनांकाला. सर्वात नवीन आवृत्ती पाहा.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         YouTube - Force rounded corners + tweaks included
// @version      2024.11.07
// @description  This script forces the rounded version of the layout (which includes some fewer tweaks applied which also improves bugs).
// @author       Joey_JTS (original author: Magma_Craft)
// @license MIT
// @match        *://www.youtube.com/*
// @namespace    https://greatest.deepsurf.us/en/users/933798
// @icon         https://www.youtube.com/favicon.ico
// @run-at       document-start
// @grant        none
// ==/UserScript==
 
// Attributes to remove from <html>
const ATTRS = [
    "darker-dark-theme",
    "darker-dark-theme-deprecate"
];
 
// Regular config keys.
const CONFIGS = {
    BUTTON_REWORK: true
}
 
// Experiment flags.
const EXPFLAGS = {
    /* Force rounded corners */
    web_button_rework: true,
    web_button_rework_with_live: true,
    web_darker_dark_theme: true,
    web_filled_subscribed_button: true,
    web_guide_ui_refresh: true,
    web_modern_ads: true,
    web_modern_buttons: true,
    web_modern_chips: true,
    web_modern_dialogs: true,
    web_modern_playlists: true,
    web_modern_subscribe: true,
    web_rounded_containers: true,
    web_rounded_thumbnails: true,
    web_searchbar_style: "rounded_corner_borders_light_btn",
    web_segmented_like_dislike_button: true,
    web_sheets_ui_refresh: true,
    web_snackbar_ui_refresh: true,
    /* Force rounded watch layout and few tweaks to be included (such as disabling the useless 'watch grid' UI */
    kevlar_watch_metadata_refresh: true,
    kevlar_watch_metadata_refresh_no_old_secondary_data: false,
    kevlar_watch_metadata_refresh_attached_subscribe: true,
    kevlar_watch_metadata_refresh_clickable_description: true,
    kevlar_watch_metadata_refresh_compact_view_count: true,
    kevlar_watch_metadata_refresh_description_info_dedicated_line: true,
    kevlar_watch_metadata_refresh_description_inline_expander: true,
    kevlar_watch_metadata_refresh_description_primary_color: true,
    kevlar_watch_metadata_refresh_for_live_killswitch: true,
    kevlar_watch_metadata_refresh_full_width_description: true,
    kevlar_watch_metadata_refresh_narrower_item_wrap: true,
    kevlar_watch_metadata_refresh_relative_date: true,
    kevlar_watch_metadata_refresh_top_aligned_actions: true,
    kevlar_watch_modern_metapanel: true,
    kevlar_watch_modern_panels: true,
    kevlar_watch_panel_height_matches_player: true,
    kevlar_watch_grid: false,
    kevlar_watch_grid_hide_chips: false,
    small_avatars_for_comments: false,
    small_avatars_for_comments_ep: false,
    web_watch_compact_comments: false,
    web_watch_compact_comments_ep: false,
    web_watch_theater_chat: false,
    web_watch_theater_fixed_chat: false,
    live_chat_over_engagement_panels: false,
    live_chat_scaled_height: false,
    live_chat_smaller_min_height: false,
    wn_grid_max_item_width: 0,
    wn_grid_min_item_width: 0,
    kevlar_set_internal_player_size: false,
    kevlar_watch_flexy_metadata_height: "136",
    kevlar_watch_max_player_width: "1280",
    web_watch_rounded_player_large: false,
    kevlar_watch_cinematics: false,
    desktop_delay_player_resizing: false,
    /* Additional tweaks (which includes reverting new UI changes and disabling animations except for both web_modern_tabs and web_enable_youtab configs ) */
    kevlar_refresh_on_theme_change: false,
    smartimation_background: false,
    web_animated_actions: false,
    web_animated_like: false,
    web_animated_like_lazy_load: false,
    enable_channel_page_header_profile_section: false,
    kevlar_modern_sd_v2: false,
    web_modern_collections_v2: false,
    web_modern_tabs: false
}
 
// Player flags
// !!! USE STRINGS FOR VALUES !!!
// For example: "true" instead of true
const PLYRFLAGS = {
    web_rounded_containers: "true",
    web_rounded_thumbnails: "true"
}
 
class YTP {
    static observer = new MutationObserver(this.onNewScript);
 
    static _config = {};
 
    static isObject(item) {
        return (item && typeof item === "object" && !Array.isArray(item));
    }
 
    static mergeDeep(target, ...sources) {
        if (!sources.length) return target;
        const source = sources.shift();
 
        if (this.isObject(target) && this.isObject(source)) {
            for (const key in source) {
                if (this.isObject(source[key])) {
                    if (!target[key]) Object.assign(target, { [key]: {} });
                    this.mergeDeep(target[key], source[key]);
                } else {
                    Object.assign(target, { [key]: source[key] });
                }
            }
        }
 
        return this.mergeDeep(target, ...sources);
    }
 
 
    static onNewScript(mutations) {
        for (var mut of mutations) {
            for (var node of mut.addedNodes) {
                YTP.bruteforce();
            }
        }
    }
 
    static start() {
        this.observer.observe(document, {childList: true, subtree: true});
    }
 
    static stop() {
        this.observer.disconnect();
    }
 
    static bruteforce() {
        if (!window.yt) return;
        if (!window.yt.config_) return;
 
        this.mergeDeep(window.yt.config_, this._config);
    }
 
    static setCfg(name, value) {
        this._config[name] = value;
    }
 
    static setCfgMulti(configs) {
        this.mergeDeep(this._config, configs);
    }
 
    static setExp(name, value) {
        if (!("EXPERIMENT_FLAGS" in this._config)) this._config.EXPERIMENT_FLAGS = {};
 
        this._config.EXPERIMENT_FLAGS[name] = value;
    }
 
    static setExpMulti(exps) {
        if (!("EXPERIMENT_FLAGS" in this._config)) this._config.EXPERIMENT_FLAGS = {};
 
        this.mergeDeep(this._config.EXPERIMENT_FLAGS, exps);
    }
 
    static decodePlyrFlags(flags) {
        var obj = {},
            dflags = flags.split("&");
 
        for (var i = 0; i < dflags.length; i++) {
            var dflag = dflags[i].split("=");
            obj[dflag[0]] = dflag[1];
        }
 
        return obj;
    }
 
    static encodePlyrFlags(flags) {
        var keys = Object.keys(flags),
            response = "";
 
        for (var i = 0; i < keys.length; i++) {
            if (i > 0) {
                response += "&";
            }
            response += keys[i] + "=" + flags[keys[i]];
        }
 
        return response;
    }
 
    static setPlyrFlags(flags) {
        if (!window.yt) return;
        if (!window.yt.config_) return;
        if (!window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS) return;
        var conCfgs = window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS;
        if (!("WEB_PLAYER_CONTEXT_CONFIGS" in this._config)) this._config.WEB_PLAYER_CONTEXT_CONFIGS = {};
 
        for (var cfg in conCfgs) {
            var dflags = this.decodePlyrFlags(conCfgs[cfg].serializedExperimentFlags);
            this.mergeDeep(dflags, flags);
            this._config.WEB_PLAYER_CONTEXT_CONFIGS[cfg] = {
                serializedExperimentFlags: this.encodePlyrFlags(dflags)
            }
        }
    }
}
 
window.addEventListener("yt-page-data-updated", function tmp() {
    YTP.stop();
    for (i = 0; i < ATTRS.length; i++) {
        document.getElementsByTagName("html")[0].removeAttribute(ATTRS[i]);
    }
    window.removeEventListener("yt-page-date-updated", tmp);
});
 
YTP.start();
 
YTP.setCfgMulti(CONFIGS);
YTP.setExpMulti(EXPFLAGS);
YTP.setPlyrFlags(PLYRFLAGS);
 
function $(q) {
    return document.querySelector(q);
}
 
(function() {
let css = `
/* Add rounded corners under the player */
div#ytp-id-17.ytp-popup.ytp-settings-menu,
div#ytp-id-18.ytp-popup.ytp-settings-menu {
border-radius: 12px !important
}
 
div.branding-context-container-inner.ytp-rounded-branding-context {
border-radius: 8px !important
}
 
.iv-card {
border-radius: 8px !important
}
 
.ytp-ad-overlay-container.ytp-overlay-ad .ytp-ad-overlay-image img, .ytp-ad-overlay-container.ytp-overlay-ad .ytp-ad-text-overlay, .ytp-ad-overlay-container.ytp-overlay-ad .ytp-ad-enhanced-overlay {
border-radius: 8px !important
}
 
.ytp-tooltip.ytp-text-detail.ytp-preview .ytp-tooltip-bg {
border-top-left-radius: 12px !important;
border-bottom-left-radius: 12px !important
}
 
.ytp-tooltip.ytp-text-detail.ytp-preview {
border-radius: 12px !important
}
 
.ytp-ce-video.ytp-ce-medium, .ytp-ce-playlist.ytp-ce-medium, .ytp-ce-medium .ytp-ce-expanding-overlay-background {
border-radius: 8px !important
}
 
.ytp-autonav-endscreen-upnext-thumbnail {
border-radius: 8px !important
}
 
.ytp-autonav-endscreen-upnext-button {
border-radius: 18px !important
}
 
.ytp-videowall-still-image {
border-radius: 8px !important
}
 
.ytp-sb-subscribe, .ytp-sb-unsubscribe {
border-radius: 18px !important
}
 
/* Watch page tweaks (including the 'Revert video list' CSS) */
ytd-watch-flexy[rounded-player-large]:not([fullscreen]):not([theater]) #ytd-player.ytd-watch-flexy {
border-radius: 0px !important
}
 
#actions.ytd-watch-metadata {
min-width: auto !important
}
 
ytd-watch-flexy[default-layout][reduced-top-margin] #primary.ytd-watch-flexy, ytd-watch-flexy[default-layout][reduced-top-margin] #secondary.ytd-watch-flexy {
padding-top: var(--ytd-margin-6x) !important
}
 
ytd-watch-metadata[title-headline-xs] h1.ytd-watch-metadata, ytd-watch-metadata[title-headline-m] h1.ytd-watch-metadata {
font-family: "YouTube Sans","Roboto",sans-serif !important;
font-weight: 600 !important;
font-size: 2rem !important;
line-height: 2.8rem !important
}

ytd-comments-header-renderer[compact-header] #title.ytd-comments-header-renderer {
margin-bottom: 24px !important
}

ytd-comments-header-renderer[modern-typography][compact-header] .count-text.ytd-comments-header-renderer {
font-size: 2rem !important;
line-height: 2.8rem !important;
font-weight: 700 !important;
max-height: 2.8rem !important;
display: flex !important;
flex-direction: row-reverse !important
}

[compact-header] .count-text.ytd-comments-header-renderer {
display: flex !important;
flex-direction: row-reverse !important
}

[compact-header] .count-text.ytd-comments-header-renderer span {
margin-right: 6px !important
}
 
ytd-watch-flexy #comment-teaser.ytd-watch-metadata {
display: none
}

ytd-watch-flexy ytd-rich-item-renderer[rendered-from-rich-grid] {
--ytd-rich-item-row-usable-width: 100% !important
}

ytd-watch-flexy ytd-rich-item-renderer[rendered-from-rich-grid][is-in-first-column] {
margin-left: 0
}

ytd-watch-flexy ytd-rich-item-renderer ytd-menu-renderer .ytd-menu-renderer[style-target=button] {
width: 24px !important;
height: 24px !important
}

ytd-watch-flexy #dismissible.ytd-rich-grid-media {
flex-direction: row
}
 
ytd-watch-flexy #attached-survey.ytd-rich-grid-media,
ytd-watch-flexy #avatar-link.ytd-rich-grid-media,
ytd-watch-flexy #avatar-container.ytd-rich-grid-media {
display: none
}
 
ytd-watch-flexy ytd-thumbnail.ytd-rich-grid-media,
ytd-watch-flexy ytd-playlist-thumbnail.ytd-rich-grid-media {
margin-right: 8px;
height: 94px;
width: 168px
}
 
ytd-watch-flexy ytd-thumbnail[size=large] a.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large]:before,
ytd-watch-flexy ytd-thumbnail[size=large][large-margin] a.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large][large-margin]:before {
border-radius: 8px
}
 
ytd-watch-flexy ytd-thumbnail[size=large][large-margin] ytd-thumbnail-overlay-time-status-renderer.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large][large-margin] ytd-thumbnail-overlay-button-renderer.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large][large-margin] ytd-thumbnail-overlay-toggle-button-renderer.ytd-thumbnail,
ytd-watch-flexy ytd-thumbnail[size=large] ytd-thumbnail-overlay-time-status-renderer.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large] ytd-thumbnail-overlay-button-renderer.ytd-thumbnail, ytd-watch-flexy ytd-thumbnail[size=large] ytd-thumbnail-overlay-toggle-button-renderer.ytd-thumbnail {
margin: 4px
}
 
ytd-watch-flexy ytd-rich-item-renderer,
ytd-watch-flexy ytd-rich-grid-row #contents.ytd-rich-grid-row {
margin: 0
}
 
ytd-watch-flexy ytd-rich-item-renderer[reduced-bottom-margin] {
margin-top: 8px;
margin-bottom: 0
}
 
ytd-watch-flexy ytd-rich-grid-renderer[reduced-top-margin] #contents.ytd-rich-grid-renderer {
padding-top: 0px
}
 
ytd-watch-flexy ytd-rich-grid-media {
margin-bottom: 8px
}
 
ytd-watch-flexy #details.ytd-rich-grid-media {
width: 100%;
min-width: 0
}
 
ytd-watch-flexy ytd-video-meta-block[rich-meta] #metadata-line.ytd-video-meta-block,
ytd-watch-flexy #channel-name.ytd-video-meta-block {
font-family: "Roboto", "Arial", sans-serif;
font-size: 1.2rem;
line-height: 1.8rem;
font-weight: 400
}
 
ytd-watch-flexy #video-title.ytd-rich-grid-media {
margin: 0 0 4px 0;
display: block;
font-family: "Roboto", "Arial", sans-serif;
font-size: 1.4rem;
line-height: 2rem;
font-weight: 500;
overflow: hidden;
display: block;
max-height: 4rem;
-webkit-line-clamp: 2;
display: box;
display: -webkit-box;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
white-space: normal
}
 
ytd-watch-flexy h3.ytd-rich-grid-media {
margin: 0
}
 
ytd-watch-flexy .title-badge.ytd-rich-grid-media, ytd-watch-flexy .video-badge.ytd-rich-grid-media {
margin-top: 0
}
 
ytd-watch-flexy ytd-rich-section-renderer.style-scope.ytd-rich-grid-renderer {
display: none
}
 
ytd-watch-flexy ytd-rich-grid-renderer[hide-chips-bar] ytd-feed-filter-chip-bar-renderer.ytd-rich-grid-renderer, ytd-watch-flexy ytd-rich-grid-renderer[hide-chips-bar-on-watch] ytd-feed-filter-chip-bar-renderer.ytd-rich-grid-renderer, ytd-watch-flexy ytd-rich-grid-renderer[hide-chips-bar-on-home] #header.ytd-rich-grid-renderer ytd-feed-filter-chip-bar-renderer.ytd-rich-grid-renderer {
display: flex;
height: 51px;
margin-bottom: 8px
}
 
ytd-watch-flexy #chips-wrapper.ytd-feed-filter-chip-bar-renderer {
position: relative;
top: 0
}
 
ytd-watch-flexy ytd-feed-filter-chip-bar-renderer[fluid-width] #chips-content.ytd-feed-filter-chip-bar-renderer {
padding: 0
}
 
ytd-watch-flexy yt-chip-cloud-chip-renderer.ytd-feed-filter-chip-bar-renderer, ytd-watch-flexy yt-chip-cloud-chip-renderer.ytd-feed-filter-chip-bar-renderer:first-of-type {
margin: 8px;
margin-left: 0
}
 
ytd-watch-flexy ytd-button-renderer.ytd-feed-filter-chip-bar-renderer {
margin: 0;
padding: 0 8px
}
 
/* More tweaks to be applied */
#buttons.ytd-c4-tabbed-header-renderer {
flex-direction: row-reverse !important
}

ytd-channel-tagline-renderer {
display: block !important;
padding: 0 !important
}

#content.ytd-channel-tagline-renderer::before {
content: "More about this channel";
font-weight: 500 !important
}

#content.ytd-channel-tagline-renderer {
max-width: 162px !important
}

#avatar.ytd-c4-tabbed-header-renderer {
width: 80px !important;
height: 80px !important;
margin: 0 24px 0 0 !important;
flex: none !important;
overflow: hidden !important
}

.yt-spec-avatar-shape__button--button-giant, .yt-spec-avatar-shape--avatar-size-giant {
width: 128px !important;
height: 128px !important
}

#avatar-editor.ytd-c4-tabbed-header-renderer {
--ytd-channel-avatar-editor-size: 80px !important
}

#channel-name.ytd-c4-tabbed-header-renderer {
margin-bottom: 0 !important
}

#channel-header-container.ytd-c4-tabbed-header-renderer {
padding-top: 0 !important;
align-items: center !important
}

#inner-header-container.ytd-c4-tabbed-header-renderer {
margin-top: 0 !important;
align-items: center !important
}

yt-formatted-string#channel-pronouns.style-scope.ytd-c4-tabbed-header-renderer, #videos-count {
display: none !important
}

.meta-item.ytd-c4-tabbed-header-renderer {
display: block !important
}

div#channel-header-links.style-scope.ytd-c4-tabbed-header-renderer, .page-header-view-model-wiz__page-header-attribution {
display: none !important
}

ytd-c4-tabbed-header-renderer[use-page-header-style] #channel-name.ytd-c4-tabbed-header-renderer, [page-subtype="channels"] .page-header-view-model-wiz__page-header-title--page-header-title-large {
font-size: 2.4em !important;
font-weight: 400 !important;
line-height: var(--yt-channel-title-line-height, 3rem) !important
}

span.delimiter.style-scope.ytd-c4-tabbed-header-renderer, .yt-content-metadata-view-model-wiz__delimiter {
display: none !important
}

div#meta.style-scope.ytd-c4-tabbed-header-renderer {
width: auto !important
}

ytd-c4-tabbed-header-renderer[use-page-header-style] #inner-header-container.ytd-c4-tabbed-header-renderer {
flex-direction: row !important
}

div.page-header-banner.style-scope.ytd-c4-tabbed-header-renderer {
margin-left: 0px !important;
margin-right: 8px !important;
border-radius: 0px !important
}

[has-inset-banner] #page-header-banner.ytd-tabbed-page-header {
padding-left: 0 !important;
padding-right: 0 !important
}

ytd-c4-tabbed-header-renderer[use-page-header-style] .page-header-banner.ytd-c4-tabbed-header-renderer,
.yt-image-banner-view-model-wiz--inset {
border-radius: 0px !important
}

.yt-content-metadata-view-model-wiz__metadata-text {
margin-right: 8px !important
}

.yt-content-metadata-view-model-wiz__metadata-text, .truncated-text-wiz, .truncated-text-wiz__absolute-button {
font-size: 1.4rem !important
}

.yt-tab-shape-wiz {
padding: 0 32px !important;
margin-right: 0 !important
}

.yt-tab-shape-wiz__tab {
font-size: 14px !important;
font-weight: 500 !important;
letter-spacing: var(--ytd-tab-system-letter-spacing) !important;
text-transform: uppercase !important
}

.yt-tab-group-shape-wiz__slider {
display: none !important
}

#title.ytd-playlist-sidebar-primary-info-renderer,
ytd-inline-form-renderer[component-style=INLINE_FORM_STYLE_TITLE] #text-displayed.ytd-inline-form-renderer {
font-family: YouTube Sans !important;
font-weight: 700 !important
}
 
ytd-comments-header-renderer[use-space-between] #title.ytd-comments-header-renderer {
justify-content: start !important
}
 
#panel-button.ytd-comments-header-renderer {
margin-left: 32px;
margin-right: 8px
}
 
#panel-button .yt-spec-button-shape-next__icon {
margin-right: 0
}
 
#panel-button .yt-spec-button-shape-next--size-m {
padding-left: 12px;
padding-right: 6px
}
 
#panel-button .yt-spec-button-shape-next__button-text-content {
display: none !important
}
 
#panel-button .yt-spec-button-shape-next__icon path {
d: path("M10 3H17V7H10V3ZM20 0H0V14H20V0ZM1 1H19V13H1V1Z");
transform: scale(1.20)
}
 
div#end.style-scope.ytd-masthead .yt-spec-button-shape-next--size-m[aria-label="Create"] {
height: 40px !important;
border-radius: 50px !important;
color: var(--yt-spec-icon-active-other) !important;
background-color: transparent !important
}
 
div#end.style-scope.ytd-masthead .yt-spec-button-shape-next--size-m.yt-spec-button-shape-next--icon-leading[aria-label="Create"] .yt-spec-button-shape-next__button-text-content {
display: none !important
}
 
div#end.style-scope.ytd-masthead .yt-spec-button-shape-next--size-m.yt-spec-button-shape-next--icon-leading[aria-label="Create"] .yt-spec-button-shape-next__icon {
margin-left: -8px !important;
margin-right: -8px !important
}
 
div#end.style-scope.ytd-masthead .yt-spec-button-shape-next--size-m.yt-spec-button-shape-next--icon-leading[aria-label="Create"] path {
d: path("M14 13h-3v3H9v-3H6v-2h3V8h2v3h3v2zm3-7H3v12h14v-6.39l4 1.83V8.56l-4 1.83V6m1-1v3.83L22 7v8l-4-1.83V19H2V5h16z")
}

div#end.style-scope.ytd-masthead .yt-spec-icon-badge-shape--style-overlay.yt-spec-icon-badge-shape--type-cart-refresh .yt-spec-icon-badge-shape__badge {
color: #fff !important
}

ytd-feed-filter-chip-bar-renderer[frosted-glass] ytd-button-renderer.ytd-feed-filter-chip-bar-renderer {
background-color: transparent !important
}

ytd-feed-filter-chip-bar-renderer[frosted-glass] #left-arrow-button.ytd-feed-filter-chip-bar-renderer,
ytd-feed-filter-chip-bar-renderer[frosted-glass] #right-arrow-button.ytd-feed-filter-chip-bar-renderer {
background-color: var(--yt-spec-base-background) !important
}

ytd-feed-filter-chip-bar-renderer[frosted-glass] #left-arrow.ytd-feed-filter-chip-bar-renderer:after {
background: linear-gradient(to right, var(--yt-spec-base-background) 20%, rgba(255, 255, 255, 0) 80%) !important
}

ytd-feed-filter-chip-bar-renderer[frosted-glass] #right-arrow.ytd-feed-filter-chip-bar-renderer:before {
background: linear-gradient(to left, var(--yt-spec-base-background) 20%, rgba(255, 255, 255, 0) 80%) !important
}
 
ytd-masthead[frosted-glass=with-chipbar] #background.ytd-masthead,
ytd-masthead[frosted-glass=without-chipbar] #background.ytd-masthead,
ytd-app[frosted-glass-mode=with-chipbar] #frosted-glass.ytd-app,
ytd-app[frosted-glass-mode=without-chipbar] #frosted-glass.ytd-app {
background: var(--yt-spec-base-background) !important;
backdrop-filter: none !important
}

.ytp-cairo-refresh-signature-moments .ytp-play-progress, ytd-thumbnail-overlay-resume-playback-renderer[enable-refresh-signature-moments-web] #progress.ytd-thumbnail-overlay-resume-playback-renderer, .YtThumbnailOverlayProgressBarHostWatchedProgressBarSegmentModern, .YtChapteredProgressBarChapteredPlayerBarChapterRefresh, .YtChapteredProgressBarChapteredPlayerBarFillRefresh, .YtProgressBarLineProgressBarPlayedRefresh, yt-page-navigation-progress[enable-refresh-signature-moments-web] #progress.yt-page-navigation-progress, ytd-progress-bar-line[enable-refresh-signature-moments-web] .progress-bar-played.ytd-progress-bar-line, #logo-icon > .yt-spec-icon-shape.yt-icon.style-scope.yt-icon-shape > div > svg > g:first-of-type > path:first-of-type {
background: #ff0000 !important
}`;
if (typeof GM_addStyle !== "undefined") {
  GM_addStyle(css);
} else {
  let styleNode = document.createElement("style");
  styleNode.appendChild(document.createTextNode(css));
  (document.querySelector("head") || document.documentElement).appendChild(styleNode);
}
})();
 
// Integrate 'YouTube Video Resize Fix' script (special thanks to CY Fung)
/* jshint esversion:8 */
 
((__CONTEXT01__) => {
  'use strict';
 
 
  const win = this instanceof Window ? this : window;
 
  // Create a unique key for the script and check if it is already running
  const hkey_script = 'ahceihvpbosz';
  if (win[hkey_script]) throw new Error('Duplicated Userscript Calling'); // avoid duplicated scripting
  win[hkey_script] = true;
 
  const insp = o => o ? (o.polymerController || o.inst || o || 0) : (o || 0);
  const indr = o => insp(o).$ || o.$ || 0;
 
  /** @type {globalThis.PromiseConstructor} */
  const Promise = (async () => { })().constructor; // YouTube hacks Promise in WaterFox Classic and "Promise.resolve(0)" nevers resolve.
  const cleanContext = async (win) => {
    const waitFn = requestAnimationFrame; // shall have been binded to window
    try {
      let mx = 16; // MAX TRIAL
      const frameId = 'vanillajs-iframe-v1'
      let frame = document.getElementById(frameId);
      let removeIframeFn = null;
      if (!frame) {
        frame = document.createElement('iframe');
        frame.id = frameId;
        const blobURL = typeof webkitCancelAnimationFrame === 'function' && typeof kagi === 'undefined' ? (frame.src = URL.createObjectURL(new Blob([], { type: 'text/html' }))) : null; // avoid Brave Crash
        frame.sandbox = 'allow-same-origin'; // script cannot be run inside iframe but API can be obtained from iframe
        let n = document.createElement('noscript'); // wrap into NOSCRPIT to avoid reflow (layouting)
        n.appendChild(frame);
        while (!document.documentElement && mx-- > 0) await new Promise(waitFn); // requestAnimationFrame here could get modified by YouTube engine
        const root = document.documentElement;
        root.appendChild(n); // throw error if root is null due to exceeding MAX TRIAL
        if (blobURL) Promise.resolve().then(() => URL.revokeObjectURL(blobURL));
 
        removeIframeFn = (setTimeout) => {
          const removeIframeOnDocumentReady = (e) => {
            e && win.removeEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false);
            e = n;
            n = win = removeIframeFn = 0;
            setTimeout ? setTimeout(() => e.remove(), 200) : e.remove();
          }
          if (!setTimeout || document.readyState !== 'loading') {
            removeIframeOnDocumentReady();
          } else {
            win.addEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false);
          }
        }
      }
      while (!frame.contentWindow && mx-- > 0) await new Promise(waitFn);
      const fc = frame.contentWindow;
      if (!fc) throw "window is not found."; // throw error if root is null due to exceeding MAX TRIAL
      try {
        const { requestAnimationFrame, setTimeout, clearTimeout } = fc;
        const res = { requestAnimationFrame, setTimeout, clearTimeout };
        for (let k in res) res[k] = res[k].bind(win); // necessary
        if (removeIframeFn) Promise.resolve(res.setTimeout).then(removeIframeFn);
        return res;
      } catch (e) {
        if (removeIframeFn) removeIframeFn();
        return null;
      }
    } catch (e) {
      console.warn(e);
      return null;
    }
  };
 
  const isWatchPageURL = (url) => {
    url = url || location;
    return location.pathname === '/watch' || location.pathname.startsWith('/live/')
  };
 
  cleanContext(win).then(__CONTEXT02__ => {
    if (!__CONTEXT02__) return null;
 
    const { ResizeObserver } = __CONTEXT01__;
    const { requestAnimationFrame, setTimeout, clearTimeout } = __CONTEXT02__;
    const elements = {};
    let rid1 = 0;
    let rid2 = 0;
    /** @type {MutationObserver | null} */
    let attrObserver = null;
    /** @type {ResizeObserver | null} */
    let resizeObserver = null;
    let isHTMLAttrApplied = false;
    const core = {
      begin() {
        document.addEventListener('yt-player-updated', core.hanlder, true);
        document.addEventListener('ytd-navigate-finish', core.hanlder, true);
      },
      hanlder: () => {
        rid1++;
        if (rid1 > 1e9) rid1 = 9;
        const tid = rid1;
        requestAnimationFrame(() => {
          if (tid !== rid1) return;
          core.runner();
        })
      },
      async runner() {
        if (!location.href.startsWith('https://www.youtube.com/')) return;
        if (!isWatchPageURL()) return;
 
        elements.ytdFlexy = document.querySelector('ytd-watch-flexy');
        elements.video = document.querySelector('ytd-watch-flexy #movie_player video, ytd-watch-flexy #movie_player audio.video-stream.html5-main-video');
        if (elements.ytdFlexy && elements.video) { } else return;
        elements.moviePlayer = elements.video.closest('#movie_player');
        if (!elements.moviePlayer) return;
 
        // resize Video
        let { ytdFlexy } = elements;
        if (!ytdFlexy.ElYTL) {
          ytdFlexy.ElYTL = 1;
          const ytdFlexyCnt = insp(ytdFlexy);
          if (typeof ytdFlexyCnt.calculateNormalPlayerSize_ === 'function') {
            ytdFlexyCnt.calculateNormalPlayerSize_ = core.resizeFunc(ytdFlexyCnt.calculateNormalPlayerSize_, 1);
          } else {
            console.warn('ytdFlexyCnt.calculateNormalPlayerSize_ is not a function.')
          }
          if (typeof ytdFlexyCnt.calculateCurrentPlayerSize_ === 'function') {
            ytdFlexyCnt.calculateCurrentPlayerSize_ = core.resizeFunc(ytdFlexyCnt.calculateCurrentPlayerSize_, 0);
          } else {
            console.warn('ytdFlexyCnt.calculateCurrentPlayerSize_ is not a function.')
          }
        }
        ytdFlexy = null;
 
        // when video is fetched
        elements.video.removeEventListener('canplay', core.triggerResizeDelayed, false);
        elements.video.addEventListener('canplay', core.triggerResizeDelayed, false);
 
        // when video is resized
        if (resizeObserver) {
          resizeObserver.disconnect();
          resizeObserver = null;
        }
        if (typeof ResizeObserver === 'function') {
          resizeObserver = new ResizeObserver(core.triggerResizeDelayed);
          resizeObserver.observe(elements.moviePlayer);
        }
 
        // MutationObserver:[collapsed] @ ytd-live-chat-frame#chat
        if (attrObserver) {
          attrObserver.takeRecords();
          attrObserver.disconnect();
          attrObserver = null;
        }
        let chat = document.querySelector('ytd-watch-flexy ytd-live-chat-frame#chat');
        if (chat) {
          // resize due to DOM update
          attrObserver = new MutationObserver(core.triggerResizeDelayed);
          attrObserver.observe(chat, { attributes: true, attributeFilter: ["collapsed"] });
          chat = null;
        }
 
        // resize on idle
        Promise.resolve().then(core.triggerResizeDelayed);
      },
      resizeFunc(originalFunc, kb) {
        return function () {
          rid2++;
          if (!isHTMLAttrApplied) {
            isHTMLAttrApplied = true;
            Promise.resolve(0).then(() => {
              document.documentElement.classList.add('youtube-video-resize-fix');
            }).catch(console.warn);
          }
          if (document.fullscreenElement === null) {
 
            // calculateCurrentPlayerSize_ shall be always return NaN to make correct positioning of toolbars
            if (!kb) return { width: NaN, height: NaN };
 
            let ret = core.calculateSize();
            if (ret.height > 0 && ret.width > 0) {
              return ret;
            }
          }
          return originalFunc.apply(this, arguments);
        }
      },
      calculateSize_() {
        const { moviePlayer, video } = elements;
        const rect1 = { width: video.videoWidth, height: video.videoHeight }; // native values independent of css rules
        if (rect1.width > 0 && rect1.height > 0) {
          const rect2 = moviePlayer.getBoundingClientRect();
          const aspectRatio = rect1.width / rect1.height;
          let h2 = rect2.width / aspectRatio;
          let w2 = rect2.height * aspectRatio;
          return { rect2, h2, w2 };
        }
        return null;
      },
      calculateSize() {
        let rs = core.calculateSize_();
        if (!rs) return { width: NaN, height: NaN };
        const { rect2, h2, w2 } = rs;
        if (h2 > rect2.height) {
          return { width: w2, height: rect2.height };
        } else {
          return { width: rect2.width, height: h2 };
        }
      },
      triggerResizeDelayed: () => {
        rid2++;
        if (rid2 > 1e9) rid2 = 9;
        const tid = rid2;
        requestAnimationFrame(() => {
          if (tid !== rid2) return;
          const { ytdFlexy } = elements;
          let r = false;
          const ytdFlexyCnt = insp(ytdFlexy);
          const windowSize_ = ytdFlexyCnt.windowSize_;
          if (windowSize_ && typeof ytdFlexyCnt.onWindowResized_ === 'function') {
            try {
              ytdFlexyCnt.onWindowResized_(windowSize_);
              r = true;
            } catch (e) { }
          }
          if (!r) window.dispatchEvent(new Event('resize'));
        })
      }
    };
    core.begin();
 
 
 
 
 
 
 
    // YouTube Watch Page Reflect (WPR)
 
 
 
    // This script enhances the functionality of YouTube pages by reflecting changes in the page state.
 
    (async function youTubeWPR() {
 
      let checkPageVisibilityChanged = false;
 
      // A WeakSet to keep track of elements being monitored for mutations.
      const monitorWeakSet = new WeakSet();
 
      /** @type {globalThis.PromiseConstructor} */
      const Promise = (async () => { })().constructor;
 
      // Function to reflect the current state of the YouTube page.
      async function _reflect() {
        await Promise.resolve();
 
        const youtubeWpr = document.documentElement.getAttribute("youtube-wpr");
        let s = '';
 
        // Check if the current page is the video watch page.
        if (isWatchPageURL()) {
          let watch = document.querySelector("ytd-watch-flexy");
          let chat = document.querySelector("ytd-live-chat-frame#chat");
 
          if (watch) {
            // Determine the state of the chat and video player on the watch page and generate a state string.
            s += !chat ? 'h0' : (chat.hasAttribute('collapsed') || !document.querySelector('iframe#chatframe')) ? 'h1' : 'h2';
            s += watch.hasAttribute('is-two-columns_') ? 's' : 'S';
            s += watch.hasAttribute('fullscreen') ? 'F' : 'f';
            s += watch.hasAttribute('theater') ? 'T' : 't';
          }
        }
 
        // Update the reflected state if it has changed.
        if (s !== youtubeWpr) {
          document.documentElement.setAttribute("youtube-wpr", s);
        }
 
      }
 
      // Function to reflect changes in specific attributes of monitored elements.
      async function reflect(nodeName, attrNames, forced) {
        await Promise.resolve();
 
        if (!forced) {
          let skip = true;
          for (const attrName of attrNames) {
            if (nodeName === 'ytd-live-chat-frame') {
              if (attrName === 'collapsed') skip = false;
            } else if (nodeName === 'ytd-watch-flexy') {
              if (attrName === 'is-two-columns_') skip = false;
              else if (attrName === 'fullscreen') skip = false;
              else if (attrName === 'theater') skip = false;
            }
          }
          if (skip) return;
        }
 
        // Log the mutated element and its attributes.
        // console.log(nodeName, attrNames);
 
        // Call _reflect() to update the reflected state.
        _reflect();
      }
 
      // Callback function for the MutationObserver that tracks mutations in monitored elements.
      function callback(mutationsList) {
        const attrNames = new Set();
        let nodeName = null;
        for (const mutation of mutationsList) {
          if (nodeName === null && mutation.target) nodeName = mutation.target.nodeName.toLowerCase();
          attrNames.add(mutation.attributeName);
        }
        reflect(nodeName, attrNames, false);
      }
 
      function getParent(element) {
        return element.__shady_native_parentNode || element.__shady_parentNode || element.parentNode;
      }
 
      let lastPageTypeChanged = 0;
      function chatContainerMutationHandler() {
        if (Date.now() - lastPageTypeChanged < 800) _reflect();
      }
 
      // Function to start monitoring an element for mutations.
      function monitor(element) {
        if (!element) return;
        if (monitorWeakSet.has(element)) {
          return;
        }
 
        monitorWeakSet.add(element);
 
        const observer = new MutationObserver(callback);
        observer.observe(element, { attributes: true });
 
        if (element.id === 'chat') {
          const parentNode = getParent(element);
          if (parentNode instanceof Element && parentNode.id === 'chat-container' && !monitorWeakSet.has(parentNode)) {
            monitorWeakSet.add(parentNode);
            const observer = new MutationObserver(chatContainerMutationHandler);
            observer.observe(parentNode, { childList: true, subtree: false });
          }
        }
 
        return 1;
      }
 
      let timeout = 0;
 
      // Function to monitor relevant elements and update the reflected state.
      let g = async (forced) => {
        await Promise.resolve();
        let b = 0;
        b = b | monitor(document.querySelector("ytd-watch-flexy"));
        b = b | monitor(document.querySelector("ytd-live-chat-frame#chat"));
        if (b || forced) {
          _reflect();
        }
      }
      // let renderId = 0;
      // Event handler function that triggers when the page finishes navigation or page data updates.
      let eventHandlerFunc = async (evt) => {
        checkPageVisibilityChanged = true;
        timeout = Date.now() + 800;
        g(1);
        if (evt.type === 'yt-navigate-finish') {
          // delay required when page type is changed for #chat (home -> watch).
          setTimeout(() => {
            g(1);
          }, 80);
        } else if (evt.type === 'yt-page-type-changed') {
          lastPageTypeChanged = Date.now();
          // setTimeout(() => {
          //   if (renderId > 1e9) renderId = 9;
          //   const t = ++renderId;
          //   requestAnimationFrame(() => {
          //     if (t !== renderId) return;
          //     g(1);
          //   });
          // }, 180);
          if (typeof requestIdleCallback === 'function') {
            requestIdleCallback(() => {
              g(1);
            });
          }
        }
      }
 
      let loadState = 0;
 
      // Function to initialize the script and start monitoring the page.
      async function actor() {
        if (loadState === 0) {
          if (!document.documentElement.hasAttribute("youtube-wpr")) {
            loadState = 1;
            document.documentElement.setAttribute("youtube-wpr", "");
            document.addEventListener("yt-navigate-finish", eventHandlerFunc, false);
            document.addEventListener("yt-page-data-updated", eventHandlerFunc, false);
            document.addEventListener("yt-page-type-changed", eventHandlerFunc, false);
          } else {
            loadState = -1;
            document.removeEventListener("yt-page-data-fetched", actor, false);
            return;
          }
        }
        if (loadState === 1) {
          timeout = Date.now() + 800;
          // Function to continuously monitor elements and update the reflected state.
          let pf = () => {
            g(0);
            if (Date.now() < timeout) requestAnimationFrame(pf);
          };
          pf();
        }
      }
 
      // Event listener that triggers when page data is fetched.
      document.addEventListener("yt-page-data-fetched", actor, false);
 
      // Update after visibility changed (looks like there are bugs due to inactive tab)
      document.addEventListener('visibilitychange', () => {
        if (document.visibilityState !== 'visible') return;
        if (checkPageVisibilityChanged) {
          checkPageVisibilityChanged = false;
          setTimeout(() => {
            g(1);
          }, 100);
          requestAnimationFrame(() => {
            g(1);
          });
        }
      }, false);
 
 
    })();
 
  });
 
})({ ResizeObserver });