Repository: NYRI4/Comfy-spicetify Branch: main Commit: 32ff101e27cf Files: 28 Total size: 229.1 KB Directory structure: gitextract_zuo02ba5/ ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ └── workflows/ │ └── build.yml ├── .gitignore ├── .prettierrc ├── Comfy/ │ ├── README.md │ ├── app.css │ ├── app.scss │ ├── assets/ │ │ ├── _main.scss │ │ ├── _navbar.scss │ │ ├── _now_playing.scss │ │ ├── _settings.scss │ │ ├── _snippets.scss │ │ ├── _top_bar.scss │ │ └── _tracklist.scss │ ├── color.ini │ ├── package.json │ ├── theme.js │ ├── theme.script.js │ └── user.css ├── LICENCE ├── README.md ├── install.ps1 ├── install.sh ├── manifest.json ├── uninstall.ps1 └── uninstall.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms ko_fi: OhItsTom ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Please provide as much information as possible! title: '' labels: bug assignees: ohitstom --- **Environment** - Spotify Version: `placeholder` - Spicetify Version: `placeholder` - Platform (WIN, MAC, LINUX): `placeholder` **Addons** *`[name1, name2]` or `[]` if none* - Extensions: `placeholder` - Custom Apps: `placeholder` - Snippets: `placeholder` **Spicetify Config** *Screenshot / File Upload* - spicetify config-dir in terminal - config-xpui.ini **Theme Information** - Export Of Comfy Settings: `placeholder` - Installed via Marketplace Or CLI: `placeholder` **Describe the bug** A clear and concise description of what the bug is. **Screenshots** If applicable, add screenshots to help explain your problem. Please also provide devtools errors/debug messages if possible: - Spicetify enable-devtools - open devtools (ctrl+shift+i on windows) - enable verbose -> https://imgur.com/a/0NIAiuP - press ctrl + r to reload ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .github/workflows/build.yml ================================================ on: push: branches: [main, beta] name: Build jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: "lts/*" - name: Compile Sass run: npx sass Comfy/app.scss:Comfy/app.css --no-source-map --style=compressed - name: Push Changes uses: stefanzweifel/git-auto-commit-action@v4 if: ${{ github.repository == 'Comfy-Themes/Spicetify' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta') }} with: commit_message: "chore: compile sass" commit_author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" branch: ${{ github.ref }} ================================================ FILE: .gitignore ================================================ CHECKUP.txt /.vscode/ .prettierignore Comfy/node_modules Comfy/package-lock.json Comfy/app.css.map ================================================ FILE: .prettierrc ================================================ { "printWidth": 150, "tabWidth": 2, "useTabs": true, "trailingComma": "none", "arrowParens": "avoid" } ================================================ FILE: Comfy/README.md ================================================ ![banner](../images/banner.png) ### 🎨 Color Schemes #### Collection
Catppuccin
🌻 Latte ![png](../images/color-schemes/catppuccin/latte.png)
🍨 Frappé ![png](../images/color-schemes/catppuccin/frappe.png)
🌺 Macchiato ![png](../images/color-schemes/catppuccin/macchiato.png)
🌿 Mocha ![png](../images/color-schemes/catppuccin/mocha.png)
Rosé Pine
Original ![png](../images/color-schemes/rose-pine/original.png)
Moon ![png](../images/color-schemes/rose-pine/moon.png)
Dawn ![png](../images/color-schemes/rose-pine/dawn.png)
Mono
Original ![png](../images/color-schemes/mono/mono.png)
Forest ![png](../images/color-schemes/mono/forest.png)
Neon ![png](../images/color-schemes/mono/neon.png)
Sakura ![png](../images/color-schemes/mono/sakura.png)
Sunset ![png](../images/color-schemes/mono/sunset.png)
Vaporwave ![png](../images/color-schemes/mono/vaporwave.png)
#### Individual
Comfy ![png](../images/color-schemes/comfy.png)
Spotify ![png](../images/color-schemes/spotify.png)
Nord ![png](../images/color-schemes/nord.png)
Everforest ![png](../images/color-schemes/everforest.png)
Kanagawa ![png](../images/color-schemes/kanagawa.png)
Houjicha ![png](../images/color-schemes/houjicha.png)
Kitty ![png](../images/color-schemes/kitty.png)
Lunar ![png](../images/color-schemes/lunar.png)
Deep ![png](../images/color-schemes/deep.png)
Velvet ![png](../images/color-schemes/velvet.png)
Yami ![png](../images/color-schemes/yami.png)
Hikari ![png](../images/color-schemes/hikari.png)
### 📑 Pages
Album ![png](../images/pages/album.png)
Artist ![png](../images/pages/artist.png)
Browse ![png](../images/pages/browse.png)
Discography ![png](../images/pages/discography.png)
Home ![png](../images/pages/home.png)
Lyrics Plus ![png](../images/pages/lyrics-plus.png)
Marketplace ![png](../images/pages/marketplace.png)
New Releases ![png](../images/pages/new-releases.png)
Playlist ![png](../images/pages/playlist.png)
Podcasts ![png](../images/pages/podcasts.png)
Profile ![png](../images/pages/profile.png)
Radio ![png](../images/pages/radio.png)
Search ![png](../images/pages/search.png)
Search Results ![png](../images/pages/search-results.png)
### 📳 Panels
Friends ![png](../images/panels/friends.png)
Library ![png](../images/panels/library.png)
Library Expanded ![png](../images/panels/library-expanded.png)
Library Closed ![png](../images/panels/library-closed.png)
Library Compact ![png](../images/panels/library-compact.png)
Now Playing View ![png](../images/panels/npv.png)
Queue ![png](../images/panels/queue.png)
### ⚙️ Settings
Apple Music Gradient ![png](../images/settings/am-blur.png) ![png](../images/settings/am-blur.png)
Application Title ![png](../images/settings/application-title.png)
Blur ![png](../images/settings/blur.png)
Button Radius ![png](../images/settings/button-radius.png)
Custom Image ![png](../images/settings/custom-image.png)
Flatten Colors ![png](../images/settings/flatten-colors.png)
Horizontal Page Links ![png](../images/settings/horizontal-pagelinks.png)
Oblong Cover Art ![png](../images/settings/oblong-cover-art.png)
Topbar in Titlebar ![png](../images/settings/topbar-in-titlebar.png)
================================================ FILE: Comfy/app.css ================================================ :root .global-nav .Root__main-view .main-view-container .main-entityHeader-container{padding:32px;align-items:center;margin-top:64px}:root #main.Banner-Enabled .comfy-banner-frame{display:block}:root #main.Banner-Enabled .comfy-banner-frame .comfy-banner-image{position:absolute;width:100%;height:100%;top:0;left:0;background-size:cover;background-position:top;background-image:var(--image-url);filter:blur(var(--image-blur));-webkit-mask-image:linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6));mask-image:linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6));transition:background .5s ease}:root #main.Banner-Enabled .comfy-banner-frame .comfy-banner-image:last-of-type{display:none}:root #main.Banner-Enabled .main-entityHeader-backgroundColor{background:none !important}:root #main.Banner-Enabled.Custom-Playbar-Snippet:not(.Comfy-nord-Snippet,.Comfy-nord-flat-Snippet,.Playbar-Above-Right-Panel-Snippet) .artist-artistOverview-artistOverviewContent,:root #main.Banner-Enabled.Custom-Playbar-Snippet:not(.Comfy-nord-Snippet,.Comfy-nord-flat-Snippet,.Playbar-Above-Right-Panel-Snippet) .main-actionBarBackground-background{min-height:calc(100vh - min(30vh,clamp(250px,250px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*150,400px)) - 128px - 12px) !important}:root #main.Banner-Enabled .artist-artistOverview-artistOverviewContent,:root #main.Banner-Enabled .main-actionBarBackground-background{background-image:linear-gradient(rgba(var(--spice-rgb-main-transition), var(--tracklist-gradient-opacity)) 0, var(--spice-main) var(--tracklist-gradient-height)),var(--tracklist-gradient-noise) !important;background-color:rgba(0,0,0,0) !important;height:calc(100% - 250px);min-height:calc(100vh - min(30vh,clamp(250px,250px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*150,400px)) - 128px);background-size:auto 100%,300px var(--tracklist-gradient-height);background-repeat:repeat-x}:root #main.Banner-Enabled .artist-artistOverview-artistOverviewContent{position:relative !important}:root #main.Banner-Enabled .artist-artistOverview-artistOverviewContent .main-actionBarBackground-background{background-image:none !important;background-color:unset !important}:root #main.Banner-Enabled .playlist-playlist-playlistContent,:root #main.Banner-Enabled .dTKw7B8X1ybw7SHebMH3,:root #main.Banner-Enabled .xcTrtCsYOPtSElbX9inq,:root #main.Banner-Enabled .EmeHQXR87mUskYK6xEde,:root #main.Banner-Enabled .N_8iI7NKHP0iG2jp3g0R{background:none}:root #main.Banner-Enabled .main-entityHeader-background{height:calc(40vh + var(--tracklist-gradient-height));max-height:100%}:root #main.Banner-Enabled .main-entityHeader-background.main-entityHeader-overlay{--bgColor: unset !important}:root .Root__main-view .comfy-banner-frame{display:none}:root .Root__main-view .main-entityHeader-withBackgroundImage{height:40vh !important}:root .Root__main-view .main-leaderboardComponent-container,:root .Root__main-view .sponsor-container{display:none !important}:root .Root__main-view .main-view-container main:not(:has(.lyrics-lyricsContainer-LyricsContainer)):not(:has(>.visualizer-container)){position:sticky;padding-bottom:32px}:root .Root__main-view .main-view-container main:not(:has(.lyrics-lyricsContainer-LyricsContainer)):not(:has(>.visualizer-container)) .os-host-overflow,:root .Root__main-view .main-view-container main:not(:has(.lyrics-lyricsContainer-LyricsContainer)):not(:has(>.visualizer-container)) .os-padding,:root .Root__main-view .main-view-container main:not(:has(.lyrics-lyricsContainer-LyricsContainer)):not(:has(>.visualizer-container)) .os-viewport,:root .Root__main-view .main-view-container main:not(:has(.lyrics-lyricsContainer-LyricsContainer)):not(:has(>.visualizer-container)) div[data-overlayscrollbars~=host],:root .Root__main-view .main-view-container main:not(:has(.lyrics-lyricsContainer-LyricsContainer)):not(:has(>.visualizer-container)) [data-overlayscrollbars-viewport~=scrollbarHidden]{overflow:visible !important}:root .Root__main-view .main-view-container input:checked~.x-toggle-indicatorWrapper{background-color:var(--spice-radio-btn-active)}:root .Root__main-view .main-view-container:not(:has(#stats-app)) .main-card-card{background:var(--spice-sidebar);border-radius:var(--border-radius);padding:0;overflow:hidden}:root .Root__main-view .main-view-container:not(:has(#stats-app)) .main-card-card:hover{background:var(--spice-card)}:root .Root__main-view .main-view-container:not(:has(#stats-app)) .main-card-card .main-card-PlayButtonContainer{right:12px !important}:root .Root__main-view .main-view-container:not(:has(#stats-app)) .main-card-card .main-card-imageContainer{margin-bottom:-4px}:root .Root__main-view .main-view-container:not(:has(#stats-app)) .main-card-card .main-card-imageContainer .main-cardImage-circular,:root .Root__main-view .main-view-container:not(:has(#stats-app)) .main-card-card .main-card-imageContainer img{border-radius:0 !important}:root .Root__main-view .main-view-container:not(:has(#stats-app)) .main-card-card .main-card-imageContainer .main-cardImage-imageWrapper{box-shadow:none !important}:root .Root__main-view .main-view-container:not(:has(#stats-app)) .main-card-card .main-card-cardMetadata{padding:16px}:root .Root__main-view .main-view-container .rX_OmqCngvY5ZCoYBZgb.zyeJ9w99yrvGokL3BsMc:after,:root .Root__main-view .main-view-container .hIFR8WDm_54EEIa1gwpC.fIvMht6B9HdROywMNJZ4:after,:root .Root__main-view .main-view-container .main-home-filterChipsContainer>div:first-child:after{background-color:var(--spice-main)}:root .Root__main-view .main-view-container .main-home-homeHeader{display:none}:root .Root__main-view .main-view-container .main-entityHeader-container{padding:32px;justify-content:center}:root .Root__main-view .main-view-container .main-entityHeader-container>div:nth-last-of-type(2),:root .Root__main-view .main-view-container .main-entityHeader-container>div.contentSpacing,:root .Root__main-view .main-view-container .main-entityHeader-container .main-entityHeader-imageContainer{align-self:center;justify-content:center}:root .Root__main-view .main-view-container .main-entityHeader-container>div:nth-last-of-type(2)+.main-entityHeader-headerText,:root .Root__main-view .main-view-container .main-entityHeader-container>div.contentSpacing+.main-entityHeader-headerText,:root .Root__main-view .main-view-container .main-entityHeader-container .main-entityHeader-imageContainer+.main-entityHeader-headerText{flex:unset;justify-content:center}:root .Root__main-view .main-view-container .main-entityHeader-container>div:nth-last-of-type(2)+.main-entityHeader-headerText .main-entityHeader-title h1,:root .Root__main-view .main-view-container .main-entityHeader-container>div.contentSpacing+.main-entityHeader-headerText .main-entityHeader-title h1,:root .Root__main-view .main-view-container .main-entityHeader-container .main-entityHeader-imageContainer+.main-entityHeader-headerText .main-entityHeader-title h1{font-size:3rem !important}:root .Root__main-view .main-view-container .main-actionBar-ActionBar{padding:8px 16px 16px 16px}:root .Root__main-view .main-view-container .main-actionBar-ActionBar .main-actionBar-ActionBarRow:first-of-type>*:first-child{margin-top:-24px}:root .Root__main-view .main-view-container .main-actionBar-ActionBar .main-actionBar-ActionBarRow>*:first-child{margin-left:calc(var(--content-spacing) + 3px)}:root .Root__main-view .main-view-container .main-actionBar-ActionBar .main-actionBar-ActionBarRow>:first-child:not(:only-child){margin-right:calc(var(--content-spacing) + 4px)}:root .Root__main-view .main-view-container .main-actionBar-ActionBar .main-actionBar-ActionBarRow [class*=Button]{min-block-size:32px;padding-block:0}:root .Root__main-view .main-view-container .artist-artistOverview-artistOverviewContent .contentSpacing>.main-gridContainer-gridContainer{padding-bottom:var(--grid-gap)}:root .Root__main-view .main-view-container .view-homeShortcutsGrid-shortcut{border-radius:var(--border-radius)}:root .Root__main-view .main-view-container .view-homeShortcutsGrid-shortcut .view-homeShortcutsGrid-imageWrapper{border-radius:calc(var(--border-radius) + 15px)}:root .Root__main-view .main-view-container .view-homeShortcutsGrid-shortcut .main-playButton-PlayButton{background:none !important}:root .Root__main-view .main-view-container .lyrics-lyricsContainer-Provider{font-size:0}:root .Root__main-view .main-view-container .lyrics-lyricsContainer-LyricsContainer::-webkit-scrollbar{width:0 !important;height:0 !important}:root .Root__main-view .main-view-container .lyrics-lyricsContainer-LyricsContainer .lyrics-lyricsContainer-LyricsBackground{z-index:-1;background-repeat:no-repeat;background-size:cover;-webkit-mask-image:linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6));mask-image:linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6))}:root .Root__main-view .main-view-container section[data-testid=your-episodes-page] .main-actionBarBackground-background{height:calc(100vh - 494px) !important}:root .Root__main-view .main-view-container section[data-testid=episode] .main-actionBar-ActionBar{flex-direction:column-reverse}:root .Root__main-view .main-view-container section[data-testid=episode] .main-actionBar-ActionBar .main-actionBar-ActionBarRow{margin-top:0 !important}:root .Root__main-view .main-view-container section[data-testid=episode] .main-actionBar-ActionBar .main-actionBar-ActionBarRow:nth-child(1){padding-top:2rem}:root .Root__nav-bar .main-rootlist-wrapper div:nth-child(2)>li .main-yourLibraryX-listRowEntityImage{border-radius:var(--border-radius) !important}:root .Root__nav-bar .main-rootlist-wrapper div:nth-child(2)>li>div:active::after{background-color:var(--spice-highlight-elevated);top:0;bottom:0;left:0;right:0}:root .Root__nav-bar .main-rootlist-wrapper [role=presentation]>li>div>div>div>div>div>.x-entityImage-imageContainer{box-shadow:0 4px 60px rgba(var(--spice-rgb-shadow), 0) !important}:root .Root__nav-bar .main-yourLibraryX-isScrolled{box-shadow:none !important}:root .Root__nav-bar .os-scrollbar{display:none}:root .Root__nav-bar #Desktop_LeftSidebar_Id .main-yourLibraryX-entryPoints span.LineClamp{-webkit-line-clamp:1 !important;line-clamp:1 !important}:root .Root__top-container .main-nowPlayingWidget-nowPlaying{height:0;z-index:1;left:var(--cover-art-left)}:root .Root__top-container .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container{bottom:var(--cover-art-bottom);border-radius:var(--cover-art-radius)}:root .Root__top-container .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container>div button{border-radius:var(--cover-art-radius) !important;background:none}:root .Root__top-container .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container .cover-art,:root .Root__top-container .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container .VideoPlayer__container video{width:var(--cover-art-width) !important;height:var(--cover-art-height) !important;border-radius:var(--cover-art-radius);overflow:hidden;object-fit:cover;max-height:none;max-width:none}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container{position:relative;border-top:none;flex-direction:column-reverse !important;background-clip:text}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container::before{z-index:auto !important}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container:has(.main-connectBar-connectBar)::before{height:calc(100% - 40px);top:40px}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar{margin-bottom:12px}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .player-controls__buttons--new-icons{margin-bottom:0px !important}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar{position:fixed;display:grid;grid-template-columns:auto auto;grid-template-areas:"time-left time-right" "bar bar";bottom:0;right:0;gap:0}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar .saber-hilt{height:0}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar>div:not(.playback-progressbar-container){text-align:center}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar>div:not(.playback-progressbar-container):first-of-type{grid-area:time-left}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar>div:not(.playback-progressbar-container):last-of-type{grid-area:time-right}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar .playback-progressbar-container{display:contents}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar .playback-progressbar{grid-column:1/3;grid-area:bar;height:11px}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar .playback-progressbar .progress-bar{--bg-color: rgba(var(--spice-rgb-progress-bg), 0.5);--fg-color: var(--spice-progress-fg);--progress-bar-height: 12px;--progress-bar-radius: 0}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar .playback-progressbar .progress-bar .x-progressBar-fillColor{width:107%;background-color:rgba(0,0,0,0);background-image:linear-gradient(90deg, var(--spice-progress-fg) 93%, transparent 100%)}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center .playback-bar .playback-progressbar .progress-bar .progress-bar__slider{display:none}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-right .main-nowPlayingBar-volumeBar .progress-bar{--bg-color: rgba(var(--spice-rgb-progress-bg), 0.5)}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-right .main-nowPlayingBar-extraControls button:not(.main-genericButton-buttonActive){color:rgba(var(--spice-rgb-selected-row), 0.7)}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-right .main-nowPlayingBar-extraControls button:not(.main-genericButton-buttonActive):hover{color:var(--spice-text) !important}:root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-right .main-nowPlayingBar-extraControls .main-devicePicker-indicator{display:none}.x-settings-container{max-width:unset}.x-toggle-indicatorWrapper{border-radius:var(--button-radius)}#main.Settings-Open~generic-modal .GenericModal__overlay{--background-tinted-base: rgba(var(--spice-rgb-selected-row), 0.07);--background-tinted-highlight: rgba(var(--spice-rgb-selected-row), 0.1)}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-header{padding:12px 12px 12px 16px}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-header .main-type-alto{font-size:25px}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-header .main-trackCreditsModal-closeBtn{background-color:var(--background-tinted-base);height:34px;cursor:pointer}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-header .main-trackCreditsModal-closeBtn:hover{transform:scale(1.04) !important;color:var(--spice-text)}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-header .main-trackCreditsModal-closeBtn:focus{transform:scale(1)}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-header .main-trackCreditsModal-closeBtn:active{transform:scale(0.98) !important;color:var(--spice-text)}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-header .main-trackCreditsModal-closeBtn:first-of-type{margin-left:auto}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-header .main-trackCreditsModal-closeBtn:not(:last-of-type){margin-right:8px}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-header .main-trackCreditsModal-closeBtn:last-of-type svg{scale:.8}#main.Settings-Open~generic-modal .GenericModal__overlay .main-embedWidgetGenerator-container{max-height:75vh !important;width:550px !important}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-mainSection{padding:0px 16px 0;scrollbar-width:thin;min-height:calc(100% - 60px)}#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-mainSection::after{content:"";position:absolute;bottom:0;width:calc(100% - 12px);left:0;height:25px;background:linear-gradient(to bottom, transparent, rgba(var(--spice-rgb-player), 0.5));pointer-events:none;border-radius:8px;z-index:0;border-bottom-right-radius:0}#main.Settings-Open~generic-modal .GenericModal__overlay .GenericModal ::-webkit-scrollbar,#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-mainSection ::-webkit-scrollbar,#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-originalCredits ::-webkit-scrollbar{width:8px !important}#main.Settings-Open~generic-modal .GenericModal__overlay .GenericModal ::-webkit-scrollbar-thumb,#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-mainSection ::-webkit-scrollbar-thumb,#main.Settings-Open~generic-modal .GenericModal__overlay .main-trackCreditsModal-originalCredits ::-webkit-scrollbar-thumb{border-radius:1em !important}#main.Settings-Open~generic-modal .GenericModal__overlay .GenericModal{border-radius:10px}.comfy-settings .search-searchCategory-SearchCategory{background:var(--spice-player);grid-column:1/-1;height:48px;padding-top:7px;position:sticky;top:0px;z-index:1}.comfy-settings .search-searchCategory-SearchCategory{height:unset;padding-bottom:12px;padding-top:12px;top:0}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;overflow:hidden;width:100%;padding-inline:0px}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea.search-searchCategory-showLeftButton .search-searchCategory-categoryGrid{-webkit-mask-image:linear-gradient(90deg, transparent, var(--spice-sidebar) 120px);mask-image:linear-gradient(90deg, transparent, var(--spice-sidebar) 120px)}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea.search-searchCategory-showRightButton .search-searchCategory-categoryGrid{-webkit-mask-image:linear-gradient(90deg, var(--spice-sidebar) calc(100% - 120px), transparent);mask-image:linear-gradient(90deg, var(--spice-sidebar) calc(100% - 120px), transparent)}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea.search-searchCategory-showLeftButton.search-searchCategory-showRightButton .search-searchCategory-categoryGrid{-webkit-mask-image:linear-gradient(90deg, transparent, var(--spice-sidebar) 120px, var(--spice-sidebar) calc(100% - 120px), transparent);mask-image:linear-gradient(90deg, transparent, var(--spice-sidebar) 120px, var(--spice-sidebar) calc(100% - 120px), transparent)}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea .search-searchCategory-categoryGrid{overflow-y:hidden}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea .search-searchCategory-categoryGridItem{cursor:pointer;padding:2px}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea .search-searchCategory-categoryGridItem button::after{border:none !important}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea .search-searchCategory-categoryGridItem:active,.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea .search-searchCategory-categoryGridItem:focus,.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea .search-searchCategory-categoryGridItem:hover{text-decoration:none}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea .search-searchCategory-categoryGridItem:focus-visible{outline:none;text-decoration:none}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea .search-searchCategory-categoryGridItem:focus-visible>*{outline:5px auto #3673d4}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-wrapper .search-searchCategory-contentArea .search-searchCategory-categoryGridItem>*{margin-inline-end:8px;margin-block-end:0 !important}.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-showRightButton .search-searchCategory-carouselButtonRight,.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-showRightButton:hover .search-searchCategory-carouselButtonRight,.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-showLeftButton .search-searchCategory-carouselButtonLeft,.comfy-settings .search-searchCategory-SearchCategory .search-searchCategory-showLeftButton:hover .search-searchCategory-carouselButtonLeft{cursor:pointer;opacity:1;pointer-events:auto}.comfy-settings .setting-header{text-align:center;padding:5px 0}.comfy-settings .setting-card{background-color:var(--background-tinted-base);border-radius:10px;margin:8px 0}.comfy-settings .setting-card .setting-container{padding:12px 16px;display:flex;flex-direction:column}.comfy-settings .setting-card .setting-container .setting-item{display:flex;flex-direction:row;justify-content:space-between}.comfy-settings .setting-card .setting-container .setting-item .setting-title{padding-right:15px;font-weight:600}.comfy-settings .setting-card .setting-container .setting-item .x-settings-tooltip{cursor:help !important}.comfy-settings .setting-card .setting-container .setting-item .x-settings-tooltip .x-settings-tooltipIconWrapper{padding:0px 8px 0px 8px !important}.comfy-settings .setting-card .setting-container .setting-item .x-settings-tooltip .x-settings-tooltipIconWrapper svg{fill:var(--spice-subtext);transition:fill .2s}.comfy-settings .setting-card .setting-container .setting-item .x-settings-tooltip .x-settings-tooltipIconWrapper:focus-within svg,.comfy-settings .setting-card .setting-container .setting-item .x-settings-tooltip .x-settings-tooltipIconWrapper:hover svg{fill:var(--spice-text) !important}.comfy-settings .setting-card .setting-container .setting-action,.comfy-settings .setting-card .setting-container .setting-title{display:flex;align-items:center;padding:8px 0}.comfy-settings .setting-card .setting-description{font-size:.9rem;color:var(--spice-subtext)}.comfy-settings .setting-card .setting-description-spacer{height:.9rem}.comfy-settings .setting-card .setting-action{text-align:right}.comfy-settings .setting-card .setting-action .x-toggle-wrapper{cursor:pointer}.comfy-settings .setting-card .setting-action .x-toggle-wrapper .x-toggle-input{width:100%}.comfy-settings .setting-card .setting-action .x-toggle-wrapper .x-toggle-indicatorWrapper{transition:background-color .2s;--spice-button-disabled: var(--background-tinted-base)}.comfy-settings .setting-card .setting-action .x-toggle-wrapper input:hover:not([disabled],:active)~.x-toggle-indicatorWrapper{background-color:var(--background-tinted-highlight)}.comfy-settings .setting-card .setting-action .x-toggle-wrapper input:checked:hover:not([disabled],:active)~.x-toggle-indicatorWrapper{background-color:var(--spice-button-active)}.comfy-settings .setting-card .setting-action button.switch{border:0px;background-color:var(--background-tinted-base);cursor:pointer;display:flex;padding:8px;margin-inline-end:12px}.comfy-settings .setting-card .setting-action button.switch:hover{transform:scale(1.04);color:var(--spice-text)}.comfy-settings .setting-card .setting-action button.switch:active{transform:scale(0.98);color:var(--spice-text)}.comfy-settings .setting-card .setting-action input{padding-inline:10px;text-align:center;background-color:var(--background-tinted-base);color:var(--spice-text);border:none;height:32px;width:120px}.comfy-settings .setting-card .setting-action input::placeholder{color:rgba(var(--spice-rgb-text), 0.3)}.comfy-settings .setting-card .setting-action input[type=number]{width:50px;transition:width .2s}.comfy-settings .setting-card .setting-action input[type=number]::-webkit-inner-spin-button,.comfy-settings .setting-card .setting-action input[type=number]::-webkit-outer-spin-button{display:none}.comfy-settings .setting-card .setting-action input[type=number]:hover{width:60px}.comfy-settings .setting-card .setting-action input[type=number]:hover::-webkit-inner-spin-button,.comfy-settings .setting-card .setting-action input[type=number]:hover::-webkit-outer-spin-button{display:block}.comfy-settings .setting-card .setting-action input[type=color]{width:32px;padding:3px;transition:all .2s ease;cursor:pointer;margin-left:8px}.comfy-settings .setting-card .setting-action input[type=color]:hover,.comfy-settings .setting-card .setting-action input[type=color]:focus,.comfy-settings .setting-card .setting-action input[type=color]:active{scale:1.04;background-color:var(--background-tinted-highlight)}.comfy-settings .setting-card .setting-action input[type=color]::-webkit-color-swatch-wrapper{padding:0;margin:0}.comfy-settings .setting-card .setting-action input[type=color]::-webkit-color-swatch{border:none;border-radius:var(--button-radius)}.comfy-settings .setting-card .setting-action .dropdown-wrapper{position:relative}.comfy-settings .setting-card .setting-action .dropdown-wrapper.menu-open .dropdown-button{border-bottom-left-radius:0;border-bottom-right-radius:0}.comfy-settings .setting-card .setting-action .dropdown-wrapper.menu-open .dropdown-arrow{border-color:rgba(0,0,0,0) rgba(0,0,0,0) rgba(var(--spice-rgb-text), 0.7);border-width:0 5px 5px}.comfy-settings .setting-card .setting-action .dropdown-wrapper.menu-open .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0}.comfy-settings .setting-card .setting-action .dropdown-wrapper .dropdown-button{position:relative;background-color:var(--background-tinted-base);border:0;border-radius:var(--button-radius);box-sizing:border-box;color:rgba(var(--spice-rgb-text), 0.7);cursor:default;outline:0;padding:0 36px 0 16px;transition:all .2s ease;height:32px;cursor:pointer !important}.comfy-settings .setting-card .setting-action .dropdown-wrapper .dropdown-button:hover{color:var(--spice-rgb-text);background-color:var(--background-tinted-highlight)}.comfy-settings .setting-card .setting-action .dropdown-wrapper .dropdown-button .dropdown-selection{display:flex;align-items:center;height:32px}.comfy-settings .setting-card .setting-action .dropdown-wrapper .dropdown-arrow{border-color:rgba(var(--spice-rgb-text), 0.7) rgba(0,0,0,0) rgba(0,0,0,0);border-style:solid;border-width:5px 5px 0;content:" ";display:block;height:0;margin-top:-ceil(2.5);position:absolute;right:16px;top:14px;width:0}.comfy-settings .setting-card .setting-action .dropdown-wrapper .dropdown-menu{scrollbar-width:thin;background-color:var(--spice-card);opacity:1;border:0;border-radius:8px;box-shadow:0 1px 0 rgba(0,0,0,.06);box-sizing:border-box;margin-top:-1px;max-height:200px;overflow-y:auto;overflow-x:hidden;position:absolute;top:100%;width:100%;z-index:1000;-webkit-overflow-scrolling:touch}.comfy-settings .setting-card .setting-action .dropdown-wrapper .dropdown-option{box-sizing:border-box;color:rgba(var(--spice-rgb-text), 0.7);background-color:var(--background-tinted-highlight);cursor:pointer;display:block;padding:8px 10px;text-align:center}.comfy-settings .setting-card .setting-action .dropdown-wrapper .dropdown-option.selected{background-color:rgba(var(--spice-rgb-text), 0.7);color:var(--spice-sidebar)}.comfy-settings .setting-card .setting-action .dropdown-wrapper .dropdown-option:hover{background-color:rgb(var(--spice-rgb-text));color:var(--spice-sidebar)}.comfy-settings .setting-subSection#enabled .setting-card{border-radius:0;margin:0}.comfy-settings .setting-subSection#enabled .setting-card:first-child{border-radius:10px 10px 0px 0px;background-color:var(--spice-sidebar);margin-top:8px;transition:.2s}.comfy-settings .setting-subSection#enabled .setting-card:first-child:hover{background-color:var(--spice-button-disabled);transition:background-color .2s;cursor:pointer}.comfy-settings .setting-subSection#enabled .setting-card:first-child .setting-title{cursor:pointer !important}.comfy-settings .setting-subSection#enabled .setting-card:last-child{border-radius:0 0 10px 10px;margin-bottom:8px}.comfy-settings .setting-subSection#collapsed .setting-card{background-color:var(--spice-sidebar);transition:background-color .2s;cursor:pointer}.comfy-settings .setting-subSection#collapsed .setting-card:hover{background-color:var(--spice-button-disabled)}.comfy-settings .setting-subSection#collapsed .setting-card .setting-title{cursor:pointer !important}.comfy-settings .setting-button-row{display:flex;align-items:center;justify-content:space-between;padding:8px}.comfy-settings .main-buttons-button{background-color:rgba(0,0,0,0);color:var(--spice-button);border:2px solid var(--spice-button) !important;margin:5px 10px;border:2px solid rgba(0,0,0,0);border-radius:10px;cursor:pointer;display:inline-block;font-size:12px;font-weight:700;letter-spacing:1.76px;line-height:18px;padding:8px 8%;text-align:center;text-transform:uppercase;transition:all 33ms cubic-bezier(0.3, 0, 0, 1);white-space:nowrap;will-change:transform}.comfy-settings .main-buttons-button:hover{transform:scale(1.02);filter:brightness(1.2)}.comfy-settings .main-buttons-button:active{transform:scale(0.98);filter:brightness(0.8)}:root .main-topBar-container .main-topBar-topbarContent *,:root .main-topBar-container .main-topBar-topbarContentWrapper *{justify-content:center;text-align:center}:root .main-topBar-container .main-topBar-searchBar>form input::placeholder{color:rgba(var(--spice-rgb-selected-row), 0.7)}:root .main-topBar-container .main-topBar-searchBar>form input{height:32px;background-color:rgba(var(--spice-rgb-shadow), 0.7)}:root .main-topBar-container .main-topBar-historyButtons button:hover{transform:scale(1.1)}:root .main-topBar-container .main-topBar-topbarContent>div:has([data-encore-id=buttonPrimary]):first-child{display:none !important}:root .main-topBar-container .main-topBar-background{background-color:var(--spice-main) !important}:root .main-topBar-container .main-topBar-overlay{background-color:rgba(0,0,0,0) !important}:root .main-topBar-container .main-topBar-UpgradeButton{font-size:0;overflow:hidden;background:url("https://i.imgur.com/nzAfcIL.png") 50%/contain no-repeat;border:none;padding:5px;box-sizing:content-box;width:12px}:root.spotify__container--is-desktop.spotify__os--is-windows #main.Topbar-Inside-Titlebar-Snippet .main-topBar-container{padding-inline:60px 150px !important}:root.spotify__container--is-desktop.spotify__os--is-linux #main.Topbar-Inside-Titlebar-Snippet .main-topBar-container{padding-inline:0px 150px !important}:root.spotify__container--is-desktop.spotify__os--is-macos #main.Topbar-Inside-Titlebar-Snippet .main-topBar-container{padding-inline:72px 0px !important}:root.spotify__container--is-desktop:not(.fullscreen):has(#main.Topbar-Inside-Titlebar-Snippet) .body-drag-top{height:calc(var(--comfy-topbar-height, 40px) + 8px) !important}:root:has(#main.Flatten-Colors-normal){--spice-main: var(--spice-sidebar);--spice-main-transition: var(--spice-sidebar);--spice-rgb-main: var(--spice-rgb-sidebar);--spice-rgb-main-transition: var(--spice-rgb-sidebar)}:root:has(#main.Flatten-Colors-reverse){--spice-sidebar: var(--spice-main);--spice-rgb-sidebar: var(--spice-rgb-main)}:root:has(#main.Comfy-Dark-Modals-Snippet) .ABD0FGjBGqGZG33bP7Lc,:root:has(#main.Comfy-Dark-Modals-Snippet) .main-duplicateTrackModal-container{background-color:var(--spice-main);color:var(--spice-text)}:root:has(#main.Remove-DJ-Prompt) ._EFIA9HjgZxxgTSZzQcg>*:not(:first-child){display:none}:root:has(#main.Compact-Context-Menu) .main-contextMenu-menu .main-popper-arrow{width:13px !important;height:13px !important;z-index:0 !important;border-right:1px solid var(--spice-button-disabled) !important;border-bottom:1px solid var(--spice-button-disabled) !important}:root:has(#main.Compact-Context-Menu) .main-rootlist-rootlistDivider,:root:has(#main.Compact-Context-Menu) .main-contextMenu-dividerBefore::before,:root:has(#main.Compact-Context-Menu) .main-contextMenu-dividerAfter::after,:root:has(#main.Compact-Context-Menu) .show-episodeList-divider,:root:has(#main.Compact-Context-Menu) .main-rootlist-rootlistDividerContainer{display:none}:root:has(#main.Compact-Context-Menu) .main-contextMenu-menuItemButton,:root:has(#main.Compact-Context-Menu) .main-userWidget-dropDownMenuItemButton{border-radius:8px !important;color:var(--spice-text);height:32px;padding-left:8px}:root:has(#main.Compact-Context-Menu) .main-contextMenu-menuItem,:root:has(#main.Compact-Context-Menu) ._60cb742e518d084c3c959007b9463b51-scss>li{margin:2px 6px}:root:has(#main.Compact-Context-Menu) .main-contextMenu-menuItem:first-child,:root:has(#main.Compact-Context-Menu) ._60cb742e518d084c3c959007b9463b51-scss>:first-child{margin:6px 6px 2px}:root:has(#main.Compact-Context-Menu) .main-contextMenu-menuItem:last-child{margin:2px 6px 6px}:root:has(#main.Compact-Context-Menu) ._60cb742e518d084c3c959007b9463b51-scss>:last-child{margin:2px 6px 8px}:root:has(#main.Compact-Context-Menu) .main-contextMenu-menu,:root:has(#main.Compact-Context-Menu) ._60cb742e518d084c3c959007b9463b51-scss{border-radius:8px;border:1px solid var(--spice-button-disabled)}:root:has(#main.Compact-Context-Menu) .main-userWidget-dropDownMenu li.main-contextMenu-menuItem>div{left:410px !important;width:225px}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .Root__now-playing-bar.LibraryX,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .Root__now-playing-bar.LibraryX{--cover-ambience-background: var(--spice-player, var(--spice-sidebar))}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-connectBar-connectBar,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-connectBar-connectBar{margin-bottom:8px}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar{padding:0 8px 6px 0 !important;margin-bottom:0 !important;background:var(--bg-img, var(--spice-player));border-radius:var(--border-radius)}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar{position:absolute !important}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .playback-bar__progress-time-elapsed,:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .main-playbackBarRemainingTime-container,:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .encore-text,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .playback-bar__progress-time-elapsed,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .main-playbackBarRemainingTime-container,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .encore-text{position:fixed;bottom:14px;right:8px}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .playback-bar__progress-time-elapsed,:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .encore-text:first-of-type,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .playback-bar__progress-time-elapsed,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .encore-text:first-of-type{transform:translateX(calc(-100% - 20px))}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .playback-bar__progress-time-elapsed::after,:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .encore-text:first-of-type::after,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .playback-bar__progress-time-elapsed::after,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .encore-text:first-of-type::after{position:absolute;left:calc(100% + 10px);font-weight:bold;color:rgba(var(--spice-rgb-custom-subdued), 0.8);content:"/";transform:translateX(-50%)}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .x-progressBar-progressBarBg,:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .x-progressBar-sliderArea,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .x-progressBar-progressBarBg,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .x-progressBar-sliderArea{border-radius:0 0 8px 8px !important;height:6px !important}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .x-progressBar-progressBarBg:after,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .x-progressBar-progressBarBg:after{content:"";padding:8px;position:absolute;top:-6px;width:calc(100% - 16px)}:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .playback-progressbar,:root #main.Comfy-nord-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .x-progressBar-fillColor,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .playback-progressbar,:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__top-container .main-nowPlayingBar-nowPlayingBar .playback-bar .x-progressBar-fillColor{height:6px !important;border-radius:50px !important}:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .Root__now-playing-bar.LibraryX{--cover-ambience-background: var(--spice-main) !important}:root #main.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet .main-nowPlayingBar-nowPlayingBar{background:var(--bg-img, var(--spice-main))}:root #main.Comfy-kitty-Snippet .Root__main-view{background-image:url("https://media0.giphy.com/media/lVHOm4nZ0yfFXI8cgd/giphy.gif?cid=790b7611hvc1po0u3gn3yrlgmhu5gqhjv9cve7hp84f9aoox&ep=v1_gifs_search&rid=giphy.gif") !important;background-position-x:center !important;background-position-y:center !important;background-size:610px !important;background-repeat:no-repeat !important}:root #main.Remove-Column-Bar-Snippet .main-trackList-trackListHeader{display:none}:root #main.Home-Header-Snippet .main-home-homeHeader{display:block !important}:root #main.Home-Header-Color .main-home-homeHeader{background-color:var(--home-header-color) !important}:root #main.Horizontal-pageLinks-Snippet ul#spicetify-sticky-list{justify-content:center;align-items:center;display:flex;flex-wrap:wrap}:root #main.Horizontal-pageLinks-Snippet ul#spicetify-sticky-list span{display:none}:root #main.Horizontal-pageLinks-Snippet .main-yourLibraryX-navItem{padding:4px 8px !important}:root #main.Playbar-Above-Right-Panel-Snippet .artist-artistOverview-artistOverviewContent,:root #main.Playbar-Above-Right-Panel-Snippet .main-actionBarBackground-background{min-height:calc(100vh - min(30vh,clamp(250px,250px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*150,400px)) - 50px) !important}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container{grid-template-areas:"left-sidebar main-view now-playing-bar" "left-sidebar main-view right-sidebar"}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container[data-right-sidebar-hidden] .Root__main-view{grid-area:main-view/main-view/main-view/span 1}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__main-view,:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__nav-bar{margin-bottom:8px}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__right-sidebar{height:calc(100vh - 450px);width:min-content;padding-bottom:8px}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar{width:var(--comfy-panel-width);background-color:var(--spice-main);border-radius:8px}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container{flex-direction:column;min-width:280px;max-width:420px}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar{flex-direction:column;padding:8px;min-height:400px}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-center,:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-left{width:100%}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .player-controls__buttons.player-controls__buttons--new-icons{order:2}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .playback-bar,:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .pn5V0OzovI9p6b8nWq8p.gglUjikTBtMzCZFgSmpS{order:1}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-right{width:calc(var(--comfy-panel-width) - 16px)}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingBar-right .main-nowPlayingBar-extraControls{width:calc(var(--comfy-panel-width) - 16px);justify-content:space-evenly}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingWidget-nowPlaying{width:100%;height:auto;flex-direction:row;flex-wrap:wrap;justify-content:center}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container{width:100%;height:100%;bottom:0}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container>:first-child{width:100%;height:100%}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container>:first-child>:first-child{width:100%;height:100%;background-color:rgba(0,0,0,0)}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container .main-coverSlotCollapsed-expandButton{top:3%}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container .HD9s7U5E1RLSWKpXmrqx{background-color:rgba(0,0,0,0);margin:auto;width:100%}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container .HD9s7U5E1RLSWKpXmrqx .main-nowPlayingWidget-coverArt{width:100%;height:100%;padding-bottom:5px;background-color:rgba(0,0,0,0)}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container .HD9s7U5E1RLSWKpXmrqx .main-nowPlayingWidget-coverArt .cover-art{height:220px !important;width:220px !important;margin:auto;background-color:rgba(0,0,0,0)}:root #main.Playbar-Above-Right-Panel-Snippet .Root__top-container .Root__now-playing-bar .main-nowPlayingBar-container .main-nowPlayingBar-nowPlayingBar .main-nowPlayingWidget-nowPlaying .main-coverSlotCollapsed-container .HD9s7U5E1RLSWKpXmrqx .main-nowPlayingWidget-coverArt .cover-art img{background-color:rgba(0,0,0,0);box-shadow:0 0 5px 5px var(--spice-text)}:root #main.Smooth-Progress-Bar-Snippet .playback-bar>div,:root #main.Smooth-Progress-Bar-Snippet .playback-bar~div,:root #main.Smooth-Progress-Bar-Snippet .pn5V0OzovI9p6b8nWq8p.gglUjikTBtMzCZFgSmpS .x-progressBar-sliderArea>div,:root #main.Smooth-Progress-Bar-Snippet .pn5V0OzovI9p6b8nWq8p.gglUjikTBtMzCZFgSmpS .x-progressBar-sliderArea~div{-webkit-transition-delay:0s;transition-delay:0s;-webkit-transition-duration:1000ms;transition-duration:1000ms;-webkit-transition-property:left,-webkit-transform;transition-property:left,-webkit-transform;transition-property:transform,left;transition-property:transform,left,-webkit-transform;-webkit-transition-timing-function:linear;transition-timing-function:linear}:root #main.Remove-Progress-Bar-Gradient-Snippet .x-progressBar-fillColor{background-color:var(--fg-color) !important;border-radius:var(--progress-bar-radius) !important;height:var(--progress-bar-height) !important;transform:translateX(calc(-100% + var(--progress-bar-transform))) !important;width:100% !important}:root #main.Remove-Connect-Bar-Snippet .main-connectBar-connectBar,:root #main.Remove-Connect-Bar-Snippet .main-devicePicker-indicator{display:none !important}:root #main.Remove-Lyrics-Button-Snippet .main-nowPlayingBar-lyricsButton{display:none !important}:root #main.Hoverable-Timers-Snippet .playback-bar>div,:root #main.Hoverable-Timers-Snippet .pn5V0OzovI9p6b8nWq8p.gglUjikTBtMzCZFgSmpS>div{transition:all .3s ease;opacity:0}:root #main.Hoverable-Timers-Snippet .playback-bar:hover>div,:root #main.Hoverable-Timers-Snippet .pn5V0OzovI9p6b8nWq8p.gglUjikTBtMzCZFgSmpS:hover>div{transition:all .3s ease;opacity:1 !important}:root #main.Hoverable-Timers-Snippet .playback-bar .playback-progressbar,:root #main.Hoverable-Timers-Snippet .pn5V0OzovI9p6b8nWq8p.gglUjikTBtMzCZFgSmpS .playback-progressbar{opacity:1 !important}:root #main.Topbar-Inside-Titlebar-Snippet .Root__top-container{grid-template-areas:"top-bar top-bar top-bar" "left-sidebar main-view right-sidebar" "now-playing-bar now-playing-bar now-playing-bar" !important;grid-template-rows:0 1fr auto !important}:root #main.Topbar-Inside-Titlebar-Snippet .Root__top-container .main-topBar-container{pointer-events:none;grid-area:top-bar;contain:unset;top:calc(var(--comfy-topbar-height, 40px)*-1 + 1px);height:calc(var(--comfy-topbar-height, 40px) + 8px);padding-block:8px}:root #main.Topbar-Inside-Titlebar-Snippet .Root__top-container .main-topBar-container .main-topBar-topbarContentWrapper>*:not(.main-topBar-searchBar):not(:has(ul)){justify-content:center;display:flex}:root #main.Topbar-Inside-Titlebar-Snippet .Root__top-container .main-topBar-container .main-topBar-topbarContentWrapper ul{text-align:center !important;justify-content:center}:root #main.Topbar-Inside-Titlebar-Snippet .Root__top-container .main-topBar-container .main-topBar-topbarContentWrapper .queue-tabBar-headerItemLink{padding:5px 16px}:root #main.Topbar-Inside-Titlebar-Snippet .Root__top-container .main-topBar-container .main-topBar-topbarContent{app-region:drag !important}:root #main.Topbar-Inside-Titlebar-Snippet .Root__top-container .main-topBar-container .main-topBar-topbarContent .main-entityHeader-topbarTitle{height:100%}:root #main.Topbar-Inside-Titlebar-Snippet .Root__top-container .main-topBar-container .main-topBar-background{display:none}:root #main.Topbar-Inside-Titlebar-Snippet main:not(:has(.main-home-filterChipsContainer)),:root #main.Topbar-Inside-Titlebar-Snippet .queue-queuePage-queuePage,:root #main.Topbar-Inside-Titlebar-Snippet .search-searchCategory-SearchCategory,:root #main.Topbar-Inside-Titlebar-Snippet .artist-artistDiscography-topBar,:root #main.Topbar-Inside-Titlebar-Snippet .marketplace-header,:root #main.Topbar-Inside-Titlebar-Snippet .f59DF4qQ_FphIrVeRYkI,:root #main.Topbar-Inside-Titlebar-Snippet .cj6vRk3nFAi80HSVqX91,:root #main.Topbar-Inside-Titlebar-Snippet .main-home-filterChipsContainer{margin-top:-64px !important;top:0 !important}:root #main.Topbar-Inside-Titlebar-Snippet .marketplace-header,:root #main.Topbar-Inside-Titlebar-Snippet .f59DF4qQ_FphIrVeRYkI,:root #main.Topbar-Inside-Titlebar-Snippet .cj6vRk3nFAi80HSVqX91{padding-top:15px !important}:root #main.Topbar-Inside-Titlebar-Snippet .main-home-filterChipsContainer{padding-top:8px}:root #main.Topbar-Inside-Titlebar-Snippet .artist-artistDiscography-topBar{height:64px !important;box-shadow:none}:root #main.Topbar-Inside-Titlebar-Snippet .artist-artistDiscography-headerContainer.artist-artistDiscography-firstAlbum{padding-top:32px}:root #main.Topbar-Inside-Titlebar-Snippet .main-view-container .search-searchCategory-SearchCategory{height:64px;padding-top:17px}:root #main.Collapse-Topbar-Snippet .main-topBar-topbarContentWrapper nav{justify-content:center;display:flex}:root #main.Header-Background .main-entityHeader-imageContainerNew{align-self:center;left:calc(clamp(128px,128px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*104,232px) + 24px + var(--content-spacing));position:relative;z-index:1}:root #main.Header-Background .main-entityHeader-headerText{background-color:rgba(var(--spice-rgb-main-transition), var(--header-opacity));padding:24px 32px;border-radius:var(--border-radius);min-width:fit-content;box-shadow:0 2px 4px rgba(var(--spice-rgb-shadow), 0.1);justify-content:space-evenly !important;height:calc(clamp(128px,128px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*104,232px) + 48px)}:root #main.Header-Background .main-entityHeader-imageContainerNew+.main-entityHeader-headerText{padding-left:calc(clamp(128px,128px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*104,232px) + 32px + var(--content-spacing));margin-right:calc(clamp(128px,128px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*104,232px) + var(--content-spacing))}:root #main.Header-Background:not(.Topbar-Inside-Titlebar-Snippet) .main-entityHeader-topbarContentFadeIn>*{opacity:var(--top-bar-opacity) !important}:root #main.AM-Gradient-Include-Existing-Snippet.Banner-Enabled .under-main-view>div:not(.comfy-banner-frame),:root #main.Replace-Existing-Banners.Banner-Enabled .under-main-view>div:not(.comfy-banner-frame){display:none !important}:root #main.Lyrics main>div>div:empty{--lyrics-color-background: transparent !important}:root #main.Apple-Music-Gradient-Snippet .comfy-banner-frame{position:absolute;width:100%;height:100%;z-index:0;filter:blur(calc(var(--image-blur) * 10));background-image:var(--gradient-background-image)}:root #main.Apple-Music-Gradient-Snippet .comfy-banner-frame .comfy-banner-image{position:absolute !important;width:var(--gradient-width) !important;aspect-ratio:1;animation:rotate var(--gradient-speed) linear infinite;border-radius:var(--gradient-radius) !important;mix-blend-mode:var(--gradient-blend-mode);background-size:cover !important}:root #main.Apple-Music-Gradient-Snippet .comfy-banner-frame .comfy-banner-image:first-of-type{height:revert;left:unset;background-size:unset;background-position:unset;filter:none;-webkit-mask-image:none;mask-image:none;right:0;top:0;z-index:10}:root #main.Apple-Music-Gradient-Snippet .comfy-banner-frame .comfy-banner-image:last-of-type{display:revert;left:0;bottom:0;animation-direction:reverse}@keyframes rotate{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}:root .main-trackList-active .main-trackList-rowTitle{color:var(--spice-text) !important;text-shadow:0px 0px 6px var(--spice-text);-webkit-text-stroke:thin}:root .main-trackList-trackListHeader._2ajKWDiy6YvJu5wo8I1g{background:var(--spice-main) !important;top:0 !important}:root .main-trackList-trackListHeader:not(._2ajKWDiy6YvJu5wo8I1g) .main-trackList-trackListRow:hover,:root .main-trackList-trackListHeader:not(._2ajKWDiy6YvJu5wo8I1g) .main-trackList-trackListHeaderRow:hover{background-color:rgba(var(--spice-rgb-selected-row), 0.05)}:root .main-trackList-trackListRow,:root .main-trackList-trackListHeaderRow{border-radius:var(--border-radius);border:none;transition:200ms background-color}:root .main-trackList-trackListRow.main-trackList-selected,:root .main-trackList-trackListHeaderRow.main-trackList-selected{background-color:rgba(var(--spice-rgb-selected-row), 0.1)}:root .main-trackList-trackListRow.main-trackList-selected:hover,:root .main-trackList-trackListHeaderRow.main-trackList-selected:hover{background-color:rgba(var(--spice-rgb-selected-row), 0.15)}:root .main-trackList-trackListRow .main-type-mesto,:root .main-trackList-trackListRow .main-type-ballad,:root .main-trackList-trackListHeaderRow .main-type-mesto,:root .main-trackList-trackListHeaderRow .main-type-ballad{transition:300ms color}:root .main-trackList-trackListRow .main-trackList-rowImageFallback,:root .main-trackList-trackListHeaderRow .main-trackList-rowImageFallback{border-radius:var(--border-radius) !important}:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListHeader .main-trackList-rowSectionIndex,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListHeader .main-trackList-rowSectionIndex{opacity:0}:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow:hover .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow:hover .main-trackList-rowSectionIndex,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow:focus-within .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow:focus-within .main-trackList-rowSectionIndex,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow.main-trackList-active .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow.main-trackList-active .main-trackList-rowSectionIndex,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow:hover .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow:hover .main-trackList-rowSectionIndex,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow:focus-within .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow:focus-within .main-trackList-rowSectionIndex,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow.main-trackList-active .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow.main-trackList-active .main-trackList-rowSectionIndex{background:rgba(var(--spice-rgb-play-button), 0.5)}:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow:hover .main-trackList-rowImagePlayButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow:hover .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow:focus-within .main-trackList-rowImagePlayButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow:focus-within .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow.main-trackList-active .main-trackList-rowImagePlayButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow.main-trackList-active .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow:hover .main-trackList-rowImagePlayButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow:hover .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow:focus-within .main-trackList-rowImagePlayButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow:focus-within .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow.main-trackList-active .main-trackList-rowImagePlayButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow.main-trackList-active .main-trackList-rowImagePlayPauseButton{opacity:1}:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow .main-trackList-rowImagePlayButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow .main-trackList-rowSectionIndex,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow .main-trackList-rowImagePlayButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow .main-trackList-rowImagePlayPauseButton,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow .main-trackList-rowSectionIndex{color:var(--spice-sidebar);border-radius:var(--border-radius);transition:200ms opacity,200ms background}:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart img) .main-trackList-trackListRow>.main-trackList-rowSectionIndex,:root #main.Remove-Tracklist-Index .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) .main-trackList-trackListRow>.main-trackList-rowSectionIndex{position:relative;z-index:1000;top:8px;left:56px;width:40px;height:40px;justify-content:center;text-indent:-1000px}:root #main.Remove-Tracklist-Index .main-trackList-indexable:has(.main-trackList-rowSectionStart img)[aria-colcount="3"] .main-trackList-trackListRowGrid{padding-left:2px;grid-template-columns:[index] 0px [first] var(--col1, 4fr) [last] minmax(120px, var(--col2, 1fr)) !important}:root #main.Remove-Tracklist-Index .main-trackList-indexable:has(.main-trackList-rowSectionStart img)[aria-colcount="4"] .main-trackList-trackListRowGrid{padding-left:2px;grid-template-columns:[index] 0px [first] minmax(120px, var(--col1, 4fr)) [var1] minmax(120px, var(--col2, 2fr)) [last] minmax(120px, var(--col3, 1fr)) !important}:root #main.Remove-Tracklist-Index .main-trackList-indexable:has(.main-trackList-rowSectionStart img)[aria-colcount="5"] .main-trackList-trackListRowGrid{padding-left:2px;grid-template-columns:[index] 0px [first] minmax(120px, var(--col1, 6fr)) [var1] minmax(120px, var(--col2, 4fr)) [var2] minmax(120px, var(--col3, 3fr)) [last] minmax(120px, var(--col4, 1fr)) !important}:root #main.Remove-Tracklist-Index .main-trackList-indexable:has(.main-trackList-rowSectionStart img)[aria-colcount="6"] .main-trackList-trackListRowGrid{padding-left:2px;grid-template-columns:[index] 0px [first] minmax(120px, var(--col1, 6fr)) [var1] minmax(120px, var(--col2, 4fr)) [var2] minmax(120px, var(--col3, 3fr)) [var3] minmax(120px, var(--col4, 2fr)) [last] minmax(120px, var(--col5, 1fr)) !important}:root{--border-radius: 8px;--button-radius: 8px;--image-blur: 4px;--gradient-speed: 50s;--gradient-width: 150%;--gradient-blend-mode: luminosity;--gradient-background-image: none;--gradient-radius: 50%;--cover-art-width: 84px;--cover-art-height: 84px;--cover-art-radius: 8px;--cover-art-left: 0px;--cover-art-bottom: 20px;--header-opacity: 0.6;--tracklist-gradient-height: 232px;--tracklist-gradient-opacity: 0.6;--tracklist-gradient-noise: var(--background-noise);--image-url: none}:root button,:root button span,:root input,:root select,:root img,:root .x-entityImage-xsmall,:root div[style*=background-image]:has(img),:root .profile-userEditDetails-image div:nth-child(2),:root [data-encore-id=buttonSecondary]{border-radius:var(--border-radius) !important}:root button:not(.main-editImageButton-overlay):not([style*=background-image]):not(.main-buddyFeed-overlay),:root button span:not(.Lyric.Synced.Line):not([data-encore-id=text]),:root button figure img,:root button:has(span:empty),:root input:not([style*=background-image]),:root select,:root [data-encore-id=buttonSecondary]{border-radius:var(--button-radius) !important}:root .Card .main-card-imageContainer *{border-radius:var(--border-radius) !important}:root .Root__top-container{overflow:hidden}:root:not(:has(.global-nav)) .Root__top-container{padding-top:max(var(--comfy-topbar-height, 40px)/var(--zoom, 1),8px) !important}:root .global-nav .Root__top-container{grid-template-rows:max(48px,var(--comfy-topbar-height, 64px)/var(--zoom, 1) - 16px) minmax(0, 1fr) auto}:root.spotify__container--is-desktop.spotify__os--is-windows:not(.fullscreen):has(.global-nav) body::after{height:calc(var(--comfy-topbar-height, 64px)/var(--zoom, 1)) !important}:root.spotify__container--is-desktop.spotify__os--is-windows:not(.fullscreen):has(.global-nav-centered) body::after{height:min(32px/var(--zoom, 1),var(--comfy-topbar-height, 64px)/var(--zoom, 1)) !important;top:calc((var(--comfy-topbar-height, 64px)/var(--zoom, 1) - min(32px/var(--zoom, 1),var(--comfy-topbar-height, 64px)))/2)}:root.spotify__container--is-desktop.spotify__os--is-windows .Root__globalNav{padding-block:calc(var(--comfy-topbar-height, 64px)/2 - 8px)}:root.spotify__container--is-desktop.spotify__os--is-windows:not(.fullscreen) body::after{content:"";position:absolute;right:0;z-index:999;backdrop-filter:brightness(2.12);width:calc(135px/var(--zoom, 1));height:calc(var(--comfy-topbar-height, 40px)/var(--zoom, 1))}:root .main-trackList-playingIcon,:root .view-homeShortcutsGrid-playingIcon,:root [src*=equaliser]{-webkit-mask-image:url("data:image/svg+xml,%3Csvg id='playing-icon' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 24'%3E%3Cdefs%3E%3Cstyle%3E %23playing-icon %7B fill: %2320BC54; %7D @keyframes play %7B 0%25 %7Btransform: scaleY(1);%7D 3.3%25 %7Btransform: scaleY(0.9583);%7D 6.6%25 %7Btransform: scaleY(0.9166);%7D 9.9%25 %7Btransform: scaleY(0.8333);%7D 13.3%25 %7Btransform: scaleY(0.7083);%7D 16.6%25 %7Btransform: scaleY(0.5416);%7D 19.9%25 %7Btransform: scaleY(0.4166);%7D 23.3%25 %7Btransform: scaleY(0.25);%7D 26.6%25 %7Btransform: scaleY(0.1666);%7D 29.9%25 %7Btransform: scaleY(0.125);%7D 33.3%25 %7Btransform: scaleY(0.125);%7D 36.6%25 %7Btransform: scaleY(0.1666);%7D 39.9%25 %7Btransform: scaleY(0.1666);%7D 43.3%25 %7Btransform: scaleY(0.2083);%7D 46.6%25 %7Btransform: scaleY(0.2916);%7D 49.9%25 %7Btransform: scaleY(0.375);%7D 53.3%25 %7Btransform: scaleY(0.5);%7D 56.6%25 %7Btransform: scaleY(0.5833);%7D 59.9%25 %7Btransform: scaleY(0.625);%7D 63.3%25 %7Btransform: scaleY(0.6666);%7D 66.6%25 %7Btransform: scaleY(0.6666);%7D 69.9%25 %7Btransform: scaleY(0.6666);%7D 73.3%25 %7Btransform: scaleY(0.6666);%7D 76.6%25 %7Btransform: scaleY(0.7083);%7D 79.9%25 %7Btransform: scaleY(0.75);%7D 83.3%25 %7Btransform: scaleY(0.8333);%7D 86.6%25 %7Btransform: scaleY(0.875);%7D 89.9%25 %7Btransform: scaleY(0.9166);%7D 93.3%25 %7Btransform: scaleY(0.9583);%7D 96.6%25 %7Btransform: scaleY(1);%7D %7D %23bar1 %7B transform-origin: bottom; animation: play 0.9s -0.51s infinite; %7D %23bar2 %7B transform-origin: bottom; animation: play 0.9s infinite; %7D %23bar3 %7B transform-origin: bottom; animation: play 0.9s -0.15s infinite; %7D %23bar4 %7B transform-origin: bottom; animation: play 0.9s -0.75s infinite; %7D %3C/style%3E%3C/defs%3E%3Ctitle%3Eplaying-icon%3C/title%3E%3Crect id='bar1' class='cls-1' width='4' height='24'/%3E%3Crect id='bar2' class='cls-1' x='6' width='4' height='24'/%3E%3Crect id='bar3' class='cls-1' x='12' width='4' height='24'/%3E%3Crect id='bar4' class='cls-1' x='18' width='4' height='24'/%3E%3C/svg%3E");background:var(--spice-button-active);content-visibility:hidden;-webkit-mask-repeat:no-repeat;border-radius:0 !important}:root .x-settings-equalizerPanelCanvas{filter:brightness(0) saturate(100%) invert(100%) sepia(0%) saturate(1181%) hue-rotate(346deg) brightness(101%) contrast(105%) !important;border-radius:0 !important}:root .encore-dark-theme,:root .encore-dark-theme .encore-base-set{--background-elevated-base: var(--spice-main-elevated);--background-highlight: var(--spice-highlight)}:root .encore-bright-accent-set{--background-base: var(--spice-play-button);--background-highlight: var(--spice-play-button-active);--background-press: var(--spice-play-button-active)}:root .encore-inverted-light-set{--background-highlight: var(--spice-text);--background-press: var(--spice-subtext)}:root .npv-background-image__overlay{background:linear-gradient(rgba(var(--spice-rgb-shadow), 0.5) 0, transparent 100%),var(--background-noise);background-color:unset}:root .Root__main-view .main-view-container__scroll-node-child{padding-bottom:0}:root aside#Desktop_PanelContainer_Id .os-scrollbar-vertical,:root .os-scrollbar-horizontal{display:none !important}:root .os-scrollbar-track,:root ::-webkit-scrollbar{width:8px}:root .os-scrollbar-handle,:root ::-webkit-scrollbar-thumb{border-radius:1em;--os-handle-perpendicular-size-active: 8px;--os-handle-perpendicular-size-hover: 8px;--os-handle-perpendicular-size: 8px}:root .os-scrollbar{--os-padding-perpendicular: 4px}:root ::-webkit-scrollbar-track{margin-bottom:10px}:root .Button-textBrightAccent-lg-32-buttonTertiary-iconOnly-condensed-useBrowserDefaultFocusStyle,:root .main-addButton-active{color:var(--spice-heart)}:root .Button-textBrightAccent-lg-32-buttonTertiary-iconOnly-condensed-useBrowserDefaultFocusStyle:hover,:root .main-addButton-active:hover{color:rgba(var(--spice-rgb-heart), 0.7)}:root #_R_G *:not([stroke=none]){stroke:var(--spice-heart)}:root .main-trackList-rowHeartButton *:not([fill=none]),:root .control-button-heart *:not([fill=none]),:root #_R_G *:not([fill=none]){fill:var(--spice-heart) !important}:root .main-contextMenu-tippy.main-contextMenu-tippyEnterActive{box-shadow:none !important}:root #context-menu{overflow:hidden}:root #context-menu .main-userWidget-dropDownMenu .main-contextMenu-menuItemButton:has(span+svg)::before{border-bottom:1px solid rgba(var(--spice-rgb-selected-row), 0.1);content:"";left:0;pointer-events:none;position:absolute;right:0;top:0}:root #context-menu .main-popper-arrow,:root #context-menu .main-popper-arrow::before{background-color:var(--spice-player) !important}:root #context-menu ul:not([aria-labelledby~=device-picker-header]){background-color:var(--spice-player)}:root #context-menu ul:not([aria-labelledby~=device-picker-header]) button,:root #context-menu ul:not([aria-labelledby~=device-picker-header]) a{border-radius:2px !important}:root #context-menu ul:not([aria-labelledby~=device-picker-header]) button:not(.main-contextMenu-disabled):focus,:root #context-menu ul:not([aria-labelledby~=device-picker-header]) button:not(.main-contextMenu-disabled):hover,:root #context-menu ul:not([aria-labelledby~=device-picker-header]) button[aria-expanded=true],:root #context-menu ul:not([aria-labelledby~=device-picker-header]) a:not(.main-contextMenu-disabled):focus,:root #context-menu ul:not([aria-labelledby~=device-picker-header]) a:not(.main-contextMenu-disabled):hover,:root #context-menu ul:not([aria-labelledby~=device-picker-header]) a[aria-expanded=true]{background-color:rgba(var(--spice-rgb-pagelink-active), 0.15);transition:150ms background-color}:root #bookmark-menu{background-color:var(--spice-player);border-radius:var(--border-radius)}:root #bookmark-menu .bookmark-filter{background-color:var(--spice-player)}:root #bookmark-menu button,:root #bookmark-menu a{border-radius:0}:root #bookmark-menu button::before,:root #bookmark-menu button::after,:root #bookmark-menu a::before,:root #bookmark-menu a::after{content:none}:root #bookmark-menu button:not(.main-contextMenu-disabled):focus,:root #bookmark-menu button:not(.main-contextMenu-disabled):hover,:root #bookmark-menu button[aria-expanded=true],:root #bookmark-menu a:not(.main-contextMenu-disabled):focus,:root #bookmark-menu a:not(.main-contextMenu-disabled):hover,:root #bookmark-menu a[aria-expanded=true]{background-color:rgba(var(--spice-rgb-pagelink-active), 0.15);transition:150ms background-color} ================================================ FILE: Comfy/app.scss ================================================ @forward "assets/main"; @forward "assets/navbar"; @forward "assets/now_playing"; @forward "assets/settings"; @forward "assets/top_bar"; @forward "assets/snippets"; @forward "assets/tracklist"; :root { // Variables --border-radius: 8px; --button-radius: 8px; --image-blur: 4px; --gradient-speed: 50s; --gradient-width: 150%; --gradient-blend-mode: luminosity; --gradient-background-image: none; --gradient-radius: 50%; --cover-art-width: 84px; --cover-art-height: 84px; --cover-art-radius: 8px; --cover-art-left: 0px; --cover-art-bottom: 20px; --header-opacity: 0.6; --tracklist-gradient-height: 232px; --tracklist-gradient-opacity: 0.6; --tracklist-gradient-noise: var(--background-noise); --image-url: none; // Custom Radii button, button span, input, select, img, .x-entityImage-xsmall, div[style*="background-image"]:has(img), .profile-userEditDetails-image div:nth-child(2), [data-encore-id="buttonSecondary"] { border-radius: var(--border-radius) !important; } button:not(.main-editImageButton-overlay):not([style*="background-image"]):not(.main-buddyFeed-overlay), button span:not(.Lyric.Synced.Line):not([data-encore-id="text"]), button figure img, button:has(span:empty), input:not([style*="background-image"]), select, [data-encore-id="buttonSecondary"] { border-radius: var(--button-radius) !important; } .Card .main-card-imageContainer * { border-radius: var(--border-radius) !important; } // Remove Overflow .Root__top-container { overflow: hidden; } // Custom Topbar Height + Bg Colour Matching &:not(:has(.global-nav)) .Root__top-container { padding-top: max(calc(var(--comfy-topbar-height, 40px) / var(--zoom, 1)), 8px) !important; } .global-nav .Root__top-container { grid-template-rows: max(48px, calc(var(--comfy-topbar-height, 64px) / var(--zoom, 1) - 16px)) minmax(0, 1fr) auto; } &.spotify__container--is-desktop.spotify__os--is-windows:not(.fullscreen) { &:has(.global-nav) body::after { height: calc(var(--comfy-topbar-height, 64px) / var(--zoom, 1)) !important; } &:has(.global-nav-centered) body::after { height: min(calc(32px / var(--zoom, 1)), calc(var(--comfy-topbar-height, 64px) / var(--zoom, 1))) !important; top: calc((var(--comfy-topbar-height, 64px) / var(--zoom, 1) - min(calc(32px / var(--zoom, 1)), var(--comfy-topbar-height, 64px))) / 2); } } &.spotify__container--is-desktop.spotify__os--is-windows .Root__globalNav { padding-block: calc(var(--comfy-topbar-height, 64px) / 2 - 8px); } &.spotify__container--is-desktop.spotify__os--is-windows:not(.fullscreen) body::after { content: ""; position: absolute; right: 0; z-index: 999; backdrop-filter: brightness(2.12); width: calc(135px / var(--zoom, 1)); height: calc(var(--comfy-topbar-height, 40px) / var(--zoom, 1)); } // Filtering .main-trackList-playingIcon, .view-homeShortcutsGrid-playingIcon, [src*="equaliser"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg id='playing-icon' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 24'%3E%3Cdefs%3E%3Cstyle%3E %23playing-icon %7B fill: %2320BC54; %7D @keyframes play %7B 0%25 %7Btransform: scaleY(1);%7D 3.3%25 %7Btransform: scaleY(0.9583);%7D 6.6%25 %7Btransform: scaleY(0.9166);%7D 9.9%25 %7Btransform: scaleY(0.8333);%7D 13.3%25 %7Btransform: scaleY(0.7083);%7D 16.6%25 %7Btransform: scaleY(0.5416);%7D 19.9%25 %7Btransform: scaleY(0.4166);%7D 23.3%25 %7Btransform: scaleY(0.25);%7D 26.6%25 %7Btransform: scaleY(0.1666);%7D 29.9%25 %7Btransform: scaleY(0.125);%7D 33.3%25 %7Btransform: scaleY(0.125);%7D 36.6%25 %7Btransform: scaleY(0.1666);%7D 39.9%25 %7Btransform: scaleY(0.1666);%7D 43.3%25 %7Btransform: scaleY(0.2083);%7D 46.6%25 %7Btransform: scaleY(0.2916);%7D 49.9%25 %7Btransform: scaleY(0.375);%7D 53.3%25 %7Btransform: scaleY(0.5);%7D 56.6%25 %7Btransform: scaleY(0.5833);%7D 59.9%25 %7Btransform: scaleY(0.625);%7D 63.3%25 %7Btransform: scaleY(0.6666);%7D 66.6%25 %7Btransform: scaleY(0.6666);%7D 69.9%25 %7Btransform: scaleY(0.6666);%7D 73.3%25 %7Btransform: scaleY(0.6666);%7D 76.6%25 %7Btransform: scaleY(0.7083);%7D 79.9%25 %7Btransform: scaleY(0.75);%7D 83.3%25 %7Btransform: scaleY(0.8333);%7D 86.6%25 %7Btransform: scaleY(0.875);%7D 89.9%25 %7Btransform: scaleY(0.9166);%7D 93.3%25 %7Btransform: scaleY(0.9583);%7D 96.6%25 %7Btransform: scaleY(1);%7D %7D %23bar1 %7B transform-origin: bottom; animation: play 0.9s -0.51s infinite; %7D %23bar2 %7B transform-origin: bottom; animation: play 0.9s infinite; %7D %23bar3 %7B transform-origin: bottom; animation: play 0.9s -0.15s infinite; %7D %23bar4 %7B transform-origin: bottom; animation: play 0.9s -0.75s infinite; %7D %3C/style%3E%3C/defs%3E%3Ctitle%3Eplaying-icon%3C/title%3E%3Crect id='bar1' class='cls-1' width='4' height='24'/%3E%3Crect id='bar2' class='cls-1' x='6' width='4' height='24'/%3E%3Crect id='bar3' class='cls-1' x='12' width='4' height='24'/%3E%3Crect id='bar4' class='cls-1' x='18' width='4' height='24'/%3E%3C/svg%3E"); background: var(--spice-button-active); content-visibility: hidden; -webkit-mask-repeat: no-repeat; border-radius: 0 !important; } .x-settings-equalizerPanelCanvas { filter: brightness(0) saturate(100%) invert(100%) sepia(0%) saturate(1181%) hue-rotate(346deg) brightness(101%) contrast(105%) !important; border-radius: 0 !important; } // Base Sets .encore-dark-theme, .encore-dark-theme .encore-base-set { --background-elevated-base: var(--spice-main-elevated); --background-highlight: var(--spice-highlight); } .encore-bright-accent-set { --background-base: var(--spice-play-button); --background-highlight: var(--spice-play-button-active); --background-press: var(--spice-play-button-active); } .encore-inverted-light-set { --background-highlight: var(--spice-text); --background-press: var(--spice-subtext); } // Premium Fullscreen Overlay .npv-background-image__overlay { background: linear-gradient(rgba(var(--spice-rgb-shadow), 0.5) 0, transparent 100%), var(--background-noise); background-color: unset; } // Scrollbars .Root__main-view .main-view-container__scroll-node-child { padding-bottom: 0; } aside#Desktop_PanelContainer_Id .os-scrollbar-vertical, .os-scrollbar-horizontal { display: none !important; } .os-scrollbar-track, ::-webkit-scrollbar { width: 8px; } .os-scrollbar-handle, ::-webkit-scrollbar-thumb { border-radius: 1em; --os-handle-perpendicular-size-active: 8px; --os-handle-perpendicular-size-hover: 8px; --os-handle-perpendicular-size: 8px; } .os-scrollbar { --os-padding-perpendicular: 4px; } ::-webkit-scrollbar-track { margin-bottom: 10px; } // Coloured heart .Button-textBrightAccent-lg-32-buttonTertiary-iconOnly-condensed-useBrowserDefaultFocusStyle, .main-addButton-active { color: var(--spice-heart); &:hover { color: rgba(var(--spice-rgb-heart), 0.7); } } #_R_G *:not([stroke="none"]) { stroke: var(--spice-heart); } .main-trackList-rowHeartButton, .control-button-heart, #_R_G { & *:not([fill="none"]) { fill: var(--spice-heart) !important; } } // Menus .main-contextMenu-tippy.main-contextMenu-tippyEnterActive { box-shadow: none !important; } #context-menu { overflow: hidden; .main-userWidget-dropDownMenu .main-contextMenu-menuItemButton:has(span + svg)::before { border-bottom: 1px solid rgba(var(--spice-rgb-selected-row), .1); content: ""; left: 0; pointer-events: none; position: absolute; right: 0; top: 0; } .main-popper-arrow, .main-popper-arrow::before { background-color: var(--spice-player) !important; } ul:not([aria-labelledby~="device-picker-header"]) { background-color: var(--spice-player); button, a { border-radius: 2px !important; &:not(.main-contextMenu-disabled):focus, &:not(.main-contextMenu-disabled):hover, &[aria-expanded="true"] { background-color: rgba(var(--spice-rgb-pagelink-active), 0.15); transition: 150ms background-color; } } } } #bookmark-menu { background-color: var(--spice-player); border-radius: var(--border-radius); .bookmark-filter { background-color: var(--spice-player); } button, a { border-radius: 0; &::before, &::after { content: none; } &:not(.main-contextMenu-disabled):focus, &:not(.main-contextMenu-disabled):hover, &[aria-expanded="true"] { background-color: rgba(var(--spice-rgb-pagelink-active), 0.15); transition: 150ms background-color; } } } } ================================================ FILE: Comfy/assets/_main.scss ================================================ // Global Nav Support :root .global-nav { .Root__main-view .main-view-container .main-entityHeader-container { padding: 32px; align-items: center; margin-top: 64px; } } :root #main.Banner-Enabled { .comfy-banner-frame { display: block; .comfy-banner-image { position: absolute; width: 100%; height: 100%; top: 0; left: 0; background-size: cover; background-position: top; background-image: var(--image-url); filter: blur(var(--image-blur)); -webkit-mask-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)); mask-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)); transition: background 0.5s ease; } .comfy-banner-image:last-of-type { display: none; } } .main-entityHeader-backgroundColor { background: none !important; } // gradient noise gets stretched vertically with this approach - but no black lines &.Custom-Playbar-Snippet:not(.Comfy-nord-Snippet, .Comfy-nord-flat-Snippet, .Playbar-Above-Right-Panel-Snippet) { .artist-artistOverview-artistOverviewContent, .main-actionBarBackground-background { min-height: calc(100vh - min(30vh, clamp(250px, 250px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*150, 400px)) - 128px - 12px) !important; } } .artist-artistOverview-artistOverviewContent, .main-actionBarBackground-background { background-image: linear-gradient(rgba(var(--spice-rgb-main-transition), var(--tracklist-gradient-opacity)) 0, var(--spice-main) var(--tracklist-gradient-height)), var(--tracklist-gradient-noise) !important; background-color: transparent !important; height: calc(100% - 250px); min-height: calc(100vh - min(30vh, clamp(250px, 250px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*150, 400px)) - 128px); background-size: auto 100%, 300px var(--tracklist-gradient-height); background-repeat: repeat-x; } .artist-artistOverview-artistOverviewContent { position: relative !important; .main-actionBarBackground-background { background-image: none !important; background-color: unset !important; } } .playlist-playlist-playlistContent, .dTKw7B8X1ybw7SHebMH3, .xcTrtCsYOPtSElbX9inq, .EmeHQXR87mUskYK6xEde, .N_8iI7NKHP0iG2jp3g0R { background: none; // Remove background } .main-entityHeader-background { height: calc(40vh + var(--tracklist-gradient-height)); max-height: 100%; &.main-entityHeader-overlay { --bgColor: unset !important; } } } :root .Root__main-view { // Banner .comfy-banner-frame { display: none; } .main-entityHeader-withBackgroundImage { height: 40vh !important; } // Ad containers .main-leaderboardComponent-container, .sponsor-container { display: none !important; } .main-view-container { // Main Page Tweaks main:not(:has(.lyrics-lyricsContainer-LyricsContainer)):not(:has(> .visualizer-container)) { position: sticky; padding-bottom: 32px; .os-host-overflow, .os-padding, .os-viewport, div[data-overlayscrollbars~="host"], [data-overlayscrollbars-viewport~="scrollbarHidden"] { overflow: visible !important; // Override overflow property } } // Radio Button Coloring input:checked~.x-toggle-indicatorWrapper { background-color: var(--spice-radio-btn-active); } // Cards &:not(:has(#stats-app)) .main-card-card { background: var(--spice-sidebar); border-radius: var(--border-radius); padding: 0; overflow: hidden; &:hover { background: var(--spice-card); } .main-card-PlayButtonContainer { right: 12px !important; } .main-card-imageContainer { margin-bottom: -4px; .main-cardImage-circular, img { border-radius: 0 !important; // Remove border-radius } .main-cardImage-imageWrapper { box-shadow: none !important; } } .main-card-cardMetadata { padding: 16px; } } // Headers .rX_OmqCngvY5ZCoYBZgb.zyeJ9w99yrvGokL3BsMc, .hIFR8WDm_54EEIa1gwpC.fIvMht6B9HdROywMNJZ4, .main-home-filterChipsContainer>div:first-child { &:after { background-color: var(--spice-main); } } .main-home-homeHeader { display: none; } .main-entityHeader-container { padding: 32px; justify-content: center; &>div:nth-last-of-type(2), &>div.contentSpacing, .main-entityHeader-imageContainer { align-self: center; justify-content: center; &+.main-entityHeader-headerText { flex: unset; justify-content: center; .main-entityHeader-title h1 { font-size: 3rem !important; } } } } // Action bar .main-actionBar-ActionBar { padding: 8px 16px 16px 16px; // Adjust padding .main-actionBar-ActionBarRow { &:first-of-type { >*:first-child { margin-top: -24px; } } >*:first-child { margin-left: calc(var(--content-spacing) + 3px); } >:first-child:not(:only-child) { margin-right: calc(var(--content-spacing) + 4px); } [class*="Button"] { min-block-size: 32px; padding-block: 0; } } } // Artist Page .artist-artistOverview-artistOverviewContent .contentSpacing>.main-gridContainer-gridContainer { padding-bottom: var(--grid-gap); } // Home Page .view-homeShortcutsGrid-shortcut { border-radius: var(--border-radius); .view-homeShortcutsGrid-imageWrapper { border-radius: calc(var(--border-radius) + 15px); } .main-playButton-PlayButton { background: none !important; } } // Lyrics plus .lyrics-lyricsContainer-Provider { font-size: 0; } .lyrics-lyricsContainer-LyricsContainer { &::-webkit-scrollbar { width: 0 !important; height: 0 !important; } .lyrics-lyricsContainer-LyricsBackground { z-index: -1; background-repeat: no-repeat; background-size: cover; -webkit-mask-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)); mask-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)); } } // Shows section[data-testid="your-episodes-page"] { .main-actionBarBackground-background { height: calc(100vh - 494px) !important; } } section[data-testid="episode"] { .main-actionBar-ActionBar { flex-direction: column-reverse; .main-actionBar-ActionBarRow { margin-top: 0 !important; &:nth-child(1) { padding-top: 2rem; } } } } } } ================================================ FILE: Comfy/assets/_navbar.scss ================================================ :root .Root__nav-bar { .main-rootlist-wrapper { div:nth-child(2) { >li { .main-yourLibraryX-listRowEntityImage { border-radius: var(--border-radius) !important; } >div { &:active::after { background-color: var(--spice-highlight-elevated); top: 0; bottom: 0; left: 0; right: 0; } } } } [role="presentation"]>li>div>div>div>div>div>.x-entityImage-imageContainer { box-shadow: 0 4px 60px rgba(var(--spice-rgb-shadow), .0) !important; } } // Library header shadow .main-yourLibraryX-isScrolled { box-shadow: none !important; } // Scrollbar .os-scrollbar { display: none; } // Forcing line-breaking on long text #Desktop_LeftSidebar_Id { .main-yourLibraryX-entryPoints { span.LineClamp { -webkit-line-clamp: 1 !important; line-clamp: 1 !important; } } } } ================================================ FILE: Comfy/assets/_now_playing.scss ================================================ :root .Root__top-container { // Cover-art .main-nowPlayingWidget-nowPlaying { height: 0; z-index: 1; left: var(--cover-art-left); .main-coverSlotCollapsed-container { bottom: var(--cover-art-bottom); border-radius: var(--cover-art-radius); >div button { border-radius: var(--cover-art-radius) !important; background: none; } .cover-art, .VideoPlayer__container video { width: var(--cover-art-width) !important; height: var(--cover-art-height) !important; border-radius: var(--cover-art-radius); overflow: hidden; object-fit: cover; max-height: none; max-width: none; } } } } :root #main.Custom-Playbar-Snippet:not(.Playbar-Above-Right-Panel-Snippet) .Root__top-container { .Root__now-playing-bar { .main-nowPlayingBar-container { position: relative; border-top: none; flex-direction: column-reverse !important; background-clip: text; &::before { z-index: auto !important; } &:has(.main-connectBar-connectBar)::before { height: calc(100% - 40px); top: 40px; } .main-nowPlayingBar-nowPlayingBar { margin-bottom: 12px; // Center .main-nowPlayingBar-center { // Player Controls .player-controls__buttons--new-icons { margin-bottom: 0px !important; } // Playback Area .playback-bar { position: fixed; display: grid; grid-template-columns: auto auto; grid-template-areas: "time-left time-right" "bar bar"; bottom: 0; right: 0; gap: 0; .saber-hilt { height: 0; } // Timers &>div:not(.playback-progressbar-container) { text-align: center; &:first-of-type { grid-area: time-left; } &:last-of-type { grid-area: time-right; } } // Progess Bar .playback-progressbar-container { display: contents; } .playback-progressbar { grid-column: 1/3; grid-area: bar; height: 11px; .progress-bar { --bg-color: rgba(var(--spice-rgb-progress-bg), 0.5); --fg-color: var(--spice-progress-fg); --progress-bar-height: 12px; --progress-bar-radius: 0; .x-progressBar-fillColor { width: 107%; background-color: transparent; background-image: linear-gradient(90deg, var(--spice-progress-fg) 93%, transparent 100%); } .progress-bar__slider { display: none; } } } } } // Right .main-nowPlayingBar-right { // Volume Bar .main-nowPlayingBar-volumeBar .progress-bar { --bg-color: rgba(var(--spice-rgb-progress-bg), 0.5); } // Miscolored right side button svgs .main-nowPlayingBar-extraControls { button:not(.main-genericButton-buttonActive) { color: rgba(var(--spice-rgb-selected-row), 0.7); &:hover { color: var(--spice-text) !important; } } .main-devicePicker-indicator { display: none; } } } } } } } ================================================ FILE: Comfy/assets/_settings.scss ================================================ // Spotify settings .x-settings-container { max-width: unset; } .x-toggle-indicatorWrapper { border-radius: var(--button-radius); } // Comfy settings #main.Settings-Open~generic-modal .GenericModal__overlay { // Failsafe incase spotify's variables are not present --background-tinted-base: rgba(var(--spice-rgb-selected-row), 0.07); --background-tinted-highlight: rgba(var(--spice-rgb-selected-row), 0.1); // Header Section Styling .main-trackCreditsModal-header { padding: 12px 12px 12px 16px; .main-type-alto { font-size: 25px; } .main-trackCreditsModal-closeBtn { background-color: var(--background-tinted-base); height: 34px; cursor: pointer; &:hover { transform: scale(1.04) !important; color: var(--spice-text); } &:focus { transform: scale(1); } &:active { transform: scale(0.98) !important; color: var(--spice-text); } &:first-of-type { margin-left: auto; } &:not(:last-of-type) { margin-right: 8px; } &:last-of-type { svg { scale: 0.8; } } } } // Scrollbars And Modal Sizing .main-embedWidgetGenerator-container { max-height: 75vh !important; width: 550px !important; } .main-trackCreditsModal-mainSection { padding: 0px 16px 0; scrollbar-width: thin; min-height: calc(100% - 60px); &::after { content: ''; position: absolute; bottom: 0; width: calc(100% - 12px); left: 0; height: 25px; background: linear-gradient(to bottom, transparent, rgba(var(--spice-rgb-player), 0.5)); pointer-events: none; border-radius: 8px; z-index: 0; border-bottom-right-radius: 0; } } .GenericModal ::-webkit-scrollbar, .main-trackCreditsModal-mainSection ::-webkit-scrollbar, .main-trackCreditsModal-originalCredits ::-webkit-scrollbar { width: 8px !important; } .GenericModal ::-webkit-scrollbar-thumb, .main-trackCreditsModal-mainSection ::-webkit-scrollbar-thumb, .main-trackCreditsModal-originalCredits ::-webkit-scrollbar-thumb { border-radius: 1em !important; } .GenericModal { border-radius: 10px; } } // Main Section Styling .comfy-settings { // Carousel Styling .search-searchCategory-SearchCategory { background: var(--spice-player); grid-column: 1 / -1; height: 48px; padding-top: 7px; position: sticky; top: 0px; z-index: 1; & { height: unset; padding-bottom: 12px; padding-top: 12px; top: 0; } .search-searchCategory-wrapper { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: center; -ms-flex-align: center; align-items: center; overflow: hidden; width: 100%; padding-inline: 0px; .search-searchCategory-contentArea { &.search-searchCategory-showLeftButton .search-searchCategory-categoryGrid { -webkit-mask-image: linear-gradient(90deg, transparent, var(--spice-sidebar) 120px); mask-image: linear-gradient(90deg, transparent, var(--spice-sidebar) 120px); } &.search-searchCategory-showRightButton .search-searchCategory-categoryGrid { -webkit-mask-image: linear-gradient(90deg, var(--spice-sidebar) calc(100% - 120px), transparent); mask-image: linear-gradient(90deg, var(--spice-sidebar) calc(100% - 120px), transparent); } &.search-searchCategory-showLeftButton.search-searchCategory-showRightButton .search-searchCategory-categoryGrid { -webkit-mask-image: linear-gradient(90deg, transparent, var(--spice-sidebar) 120px, var(--spice-sidebar) calc(100% - 120px), transparent); mask-image: linear-gradient(90deg, transparent, var(--spice-sidebar) 120px, var(--spice-sidebar) calc(100% - 120px), transparent); } .search-searchCategory-categoryGrid { overflow-y: hidden; &Item { cursor: pointer; padding: 2px; button::after { border: none !important; } &:active, &:focus, &:hover { text-decoration: none; } &:focus-visible { outline: none; text-decoration: none; &>* { outline: 5px auto #3673d4; } } &>* { margin-inline-end: 8px; margin-block-end: 0 !important; } } } } } .search-searchCategory-showRightButton .search-searchCategory-carouselButtonRight, .search-searchCategory-showRightButton:hover .search-searchCategory-carouselButtonRight, .search-searchCategory-showLeftButton .search-searchCategory-carouselButtonLeft, .search-searchCategory-showLeftButton:hover .search-searchCategory-carouselButtonLeft { cursor: pointer; opacity: 1; pointer-events: auto; } } // Contents Styling .setting-header { text-align: center; padding: 5px 0; } .setting-card { background-color: var(--background-tinted-base); border-radius: 10px; margin: 8px 0; .setting-container { padding: 12px 16px; display: flex; flex-direction: column; .setting-item { display: flex; flex-direction: row; justify-content: space-between; .setting-title { padding-right: 15px; font-weight: 600; } .x-settings-tooltip { cursor: help !important; .x-settings-tooltipIconWrapper { padding: 0px 8px 0px 8px !important; svg { fill: var(--spice-subtext); transition: fill 0.2s; } &:focus-within, &:hover { svg { fill: var(--spice-text) !important; } } } } } .setting-action, .setting-title { display: flex; align-items: center; padding: 8px 0; } } .setting-description { font-size: 0.9rem; color: var(--spice-subtext); } .setting-description-spacer { height: 0.9rem; } .setting-action { text-align: right; .x-toggle-wrapper { cursor: pointer; .x-toggle-input { width: 100%; } .x-toggle-indicatorWrapper { transition: background-color 0.2s; --spice-button-disabled: var(--background-tinted-base); } input:hover:not([disabled], :active)~.x-toggle-indicatorWrapper { background-color: var(--background-tinted-highlight); } input:checked:hover:not([disabled], :active)~.x-toggle-indicatorWrapper { background-color: var(--spice-button-active); } } button.switch { border: 0px; background-color: var(--background-tinted-base); cursor: pointer; display: flex; padding: 8px; margin-inline-end: 12px; &:hover { transform: scale(1.04); color: var(--spice-text); } &:active { transform: scale(0.98); color: var(--spice-text); } } input { padding-inline: 10px; text-align: center; background-color: var(--background-tinted-base); color: var(--spice-text); border: none; height: 32px; width: 120px; &::placeholder { color: rgba(var(--spice-rgb-text), 0.3); } &[type="number"] { width: 50px; transition: width 0.2s; &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { display: none; } &:hover { width: 60px; &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { display: block; } } } &[type="color"] { width: 32px; padding: 3px; transition: all 0.2s ease; cursor: pointer; margin-left: 8px; &:hover, &:focus, &:active { scale: 1.04; background-color: var(--background-tinted-highlight); } &::-webkit-color-swatch-wrapper { padding: 0; margin: 0; } &::-webkit-color-swatch { border: none; border-radius: var(--button-radius); } } } .dropdown-wrapper { position: relative; &.menu-open { .dropdown-button { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .dropdown-arrow { border-color: transparent transparent rgba(var(--spice-rgb-text), 0.7); border-width: 0 5px 5px; } .dropdown-menu { border-top-left-radius: 0; border-top-right-radius: 0; } } .dropdown-button { position: relative; background-color: var(--background-tinted-base); border: 0; border-radius: var(--button-radius); box-sizing: border-box; color: rgba(var(--spice-rgb-text), 0.7); cursor: default; outline: 0; padding: 0 36px 0 16px; transition: all 0.2s ease; height: 32px; cursor: pointer !important; &:hover { color: var(--spice-rgb-text); background-color: var(--background-tinted-highlight); } .dropdown-selection { display: flex; align-items: center; height: 32px; } } .dropdown-arrow { border-color: rgba(var(--spice-rgb-text), 0.7) transparent transparent; border-style: solid; border-width: 5px 5px 0; content: " "; display: block; height: 0; margin-top: -ceil(2.5); position: absolute; right: 16px; top: 14px; width: 0; } .dropdown-menu { scrollbar-width: thin; background-color: var(--spice-card); opacity: 1; border: 0; border-radius: 8px; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06); box-sizing: border-box; margin-top: -1px; max-height: 200px; overflow-y: auto; overflow-x: hidden; position: absolute; top: 100%; width: 100%; z-index: 1000; -webkit-overflow-scrolling: touch; } .dropdown-option { box-sizing: border-box; color: rgba(var(--spice-rgb-text), 0.7); background-color: var(--background-tinted-highlight); cursor: pointer; display: block; padding: 8px 10px; text-align: center; &.selected { background-color: rgba(var(--spice-rgb-text), 0.7); color: var(--spice-sidebar); } &:hover { background-color: rgb(var(--spice-rgb-text)); color: var(--spice-sidebar); } } } } } // Subsection Specific Styling .setting-subSection { &#enabled { .setting-card { border-radius: 0; margin: 0; &:first-child { border-radius: 10px 10px 0px 0px; background-color: var(--spice-sidebar); margin-top: 8px; transition: 0.2s; &:hover { background-color: var(--spice-button-disabled); transition: background-color 0.2s; cursor: pointer; } .setting-title { cursor: pointer !important; } } &:last-child { border-radius: 0 0 10px 10px; margin-bottom: 8px; } } } &#collapsed { .setting-card { background-color: var(--spice-sidebar); transition: background-color 0.2s; cursor: pointer; &:hover { background-color: var(--spice-button-disabled); } .setting-title { cursor: pointer !important; } } } } // Button and Button Row .setting-button-row { display: flex; align-items: center; justify-content: space-between; padding: 8px; } .main-buttons-button { background-color: transparent; color: var(--spice-button); border: 2px solid var(--spice-button) !important; margin: 5px 10px; border: 2px solid transparent; border-radius: 10px; cursor: pointer; display: inline-block; font-size: 12px; font-weight: 700; letter-spacing: 1.76px; line-height: 18px; padding: 8px 8%; text-align: center; text-transform: uppercase; transition: all 33ms cubic-bezier(0.3, 0, 0, 1); white-space: nowrap; will-change: transform; &:hover { transform: scale(1.02); filter: brightness(1.2); } &:active { transform: scale(0.98); filter: brightness(0.8); } } } ================================================ FILE: Comfy/assets/_snippets.scss ================================================ :root { &.spotify__container--is-desktop.spotify__os--is-windows #main.Topbar-Inside-Titlebar-Snippet { .main-topBar-container { padding-inline: 60px 150px !important; } } &.spotify__container--is-desktop.spotify__os--is-linux #main.Topbar-Inside-Titlebar-Snippet { .main-topBar-container { padding-inline: 0px 150px !important; } } &.spotify__container--is-desktop.spotify__os--is-macos #main.Topbar-Inside-Titlebar-Snippet { .main-topBar-container { padding-inline: 72px 0px !important; } } &.spotify__container--is-desktop:not(.fullscreen):has(#main.Topbar-Inside-Titlebar-Snippet) .body-drag-top { height: calc(var(--comfy-topbar-height, 40px) + 8px) !important; } &:has(#main.Flatten-Colors-normal) { --spice-main: var(--spice-sidebar); --spice-main-transition: var(--spice-sidebar); --spice-rgb-main: var(--spice-rgb-sidebar); --spice-rgb-main-transition: var(--spice-rgb-sidebar); } &:has(#main.Flatten-Colors-reverse) { --spice-sidebar: var(--spice-main); --spice-rgb-sidebar: var(--spice-rgb-main); } &:has(#main.Comfy-Dark-Modals-Snippet) { .ABD0FGjBGqGZG33bP7Lc, .main-duplicateTrackModal-container { background-color: var(--spice-main); color: var(--spice-text); } } &:has(#main.Remove-DJ-Prompt) { ._EFIA9HjgZxxgTSZzQcg>*:not(:first-child) { display: none; } } &:has(#main.Compact-Context-Menu) { .main-contextMenu-menu .main-popper-arrow { width: 13px !important; height: 13px !important; z-index: 0 !important; border-right: 1px solid var(--spice-button-disabled) !important; border-bottom: 1px solid var(--spice-button-disabled) !important; } .main-rootlist-rootlistDivider, .main-contextMenu-dividerBefore::before, .main-contextMenu-dividerAfter::after, .show-episodeList-divider, .main-rootlist-rootlistDividerContainer { display: none; } .main-contextMenu-menuItemButton, .main-userWidget-dropDownMenuItemButton { border-radius: 8px !important; color: var(--spice-text); height: 32px; padding-left: 8px; } .main-contextMenu-menuItem, ._60cb742e518d084c3c959007b9463b51-scss>li { margin: 2px 6px; } .main-contextMenu-menuItem:first-child, ._60cb742e518d084c3c959007b9463b51-scss> :first-child { margin: 6px 6px 2px; } .main-contextMenu-menuItem:last-child { margin: 2px 6px 6px; } ._60cb742e518d084c3c959007b9463b51-scss> :last-child { margin: 2px 6px 8px; } .main-contextMenu-menu, ._60cb742e518d084c3c959007b9463b51-scss { border-radius: 8px; border: 1px solid var(--spice-button-disabled); } .main-userWidget-dropDownMenu li.main-contextMenu-menuItem>div { left: calc(225px + 185px) !important; width: 225px; } } #main { &.Comfy-nord-Snippet.Custom-Playbar-Snippet, &.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet { .Root__top-container { .Root__now-playing-bar.LibraryX { --cover-ambience-background: var(--spice-player, var(--spice-sidebar)); } .main-connectBar-connectBar { margin-bottom: 8px; } .main-nowPlayingBar-nowPlayingBar { padding: 0 8px 6px 0 !important; margin-bottom: 0 !important; background: var(--bg-img, var(--spice-player)); border-radius: var(--border-radius); .playback-bar { position: absolute !important; .playback-bar__progress-time-elapsed, .main-playbackBarRemainingTime-container, .encore-text { position: fixed; bottom: 14px; right: 8px; } .playback-bar__progress-time-elapsed, .encore-text:first-of-type { transform: translateX(calc(-100% - 20px)); } .playback-bar__progress-time-elapsed::after, .encore-text:first-of-type::after { position: absolute; left: calc(100% + 10px); font-weight: bold; color: rgba(var(--spice-rgb-custom-subdued), 0.8); content: "/"; transform: translateX(-50%); } .x-progressBar-progressBarBg, .x-progressBar-sliderArea { border-radius: 0 0 8px 8px !important; height: 6px !important; } .x-progressBar-progressBarBg { &:after { content: ""; padding: 8px; position: absolute; top: -6px; width: calc(100% - 16px); } } .playback-progressbar, .x-progressBar-fillColor { height: 6px !important; border-radius: 50px !important; } } } } } &.Comfy-nord-flat-Snippet.Custom-Playbar-Snippet { .Root__now-playing-bar.LibraryX { --cover-ambience-background: var(--spice-main) !important; } .main-nowPlayingBar-nowPlayingBar { background: var(--bg-img, var(--spice-main)); } } &.Comfy-kitty-Snippet { .Root__main-view { background-image: url("https://media0.giphy.com/media/lVHOm4nZ0yfFXI8cgd/giphy.gif?cid=790b7611hvc1po0u3gn3yrlgmhu5gqhjv9cve7hp84f9aoox&ep=v1_gifs_search&rid=giphy.gif") !important; background-position-x: center !important; background-position-y: center !important; background-size: 610px !important; background-repeat: no-repeat !important; } } &.Remove-Column-Bar-Snippet { .main-trackList-trackListHeader { display: none; } } &.Home-Header-Snippet { .main-home-homeHeader { display: block !important; } } &.Home-Header-Color { .main-home-homeHeader { background-color: var(--home-header-color) !important; } } &.Horizontal-pageLinks-Snippet { ul#spicetify-sticky-list { justify-content: center; align-items: center; display: flex; flex-wrap: wrap; span { display: none; } } .main-yourLibraryX-navItem { padding: 4px 8px !important; } } &.Playbar-Above-Right-Panel-Snippet { .artist-artistOverview-artistOverviewContent, .main-actionBarBackground-background { min-height: calc(100vh - min(30vh, clamp(250px, 250px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px) / 424 * 150, 400px)) - 50px) !important; } .Root__top-container { grid-template-areas: "left-sidebar main-view now-playing-bar" "left-sidebar main-view right-sidebar"; &[data-right-sidebar-hidden] .Root__main-view { grid-area: main-view/main-view/main-view/span 1; } .Root__main-view, .Root__nav-bar { margin-bottom: 8px; } .Root__right-sidebar { height: calc(100vh - 450px); width: min-content; padding-bottom: 8px; } .Root__now-playing-bar { width: var(--comfy-panel-width); background-color: var(--spice-main); border-radius: 8px; .main-nowPlayingBar-container { flex-direction: column; min-width: 280px; max-width: 420px; .main-nowPlayingBar-nowPlayingBar { flex-direction: column; padding: 8px; min-height: 400px; .main-nowPlayingBar-center, .main-nowPlayingBar-left { width: 100%; } .player-controls__buttons.player-controls__buttons--new-icons { order: 2; } .playback-bar, .pn5V0OzovI9p6b8nWq8p.gglUjikTBtMzCZFgSmpS { order: 1; } .main-nowPlayingBar-right { width: calc(var(--comfy-panel-width) - 16px); .main-nowPlayingBar-extraControls { width: calc(var(--comfy-panel-width) - 16px); justify-content: space-evenly; } } .main-nowPlayingWidget-nowPlaying { width: 100%; height: auto; flex-direction: row; flex-wrap: wrap; justify-content: center; .main-coverSlotCollapsed-container { width: 100%; height: 100%; bottom: 0; > :first-child { width: 100%; height: 100%; > :first-child { width: 100%; height: 100%; background-color: #00000000; } } .main-coverSlotCollapsed-expandButton { top: 3%; } .HD9s7U5E1RLSWKpXmrqx { background-color: #00000000; margin: auto; width: 100%; .main-nowPlayingWidget-coverArt { width: 100%; height: 100%; padding-bottom: 5px; background-color: #00000000; .cover-art { height: 220px !important; width: 220px !important; margin: auto; background-color: #00000000; img { background-color: #00000000; box-shadow: 0 0 5px 5px var(--spice-text); } } } } } } } } } } } &.Smooth-Progress-Bar-Snippet { .playback-bar, .pn5V0OzovI9p6b8nWq8p.gglUjikTBtMzCZFgSmpS .x-progressBar-sliderArea { >div, ~div { -webkit-transition-delay: 0s; transition-delay: 0s; -webkit-transition-duration: 1000ms; transition-duration: 1000ms; -webkit-transition-property: left, -webkit-transform; transition-property: left, -webkit-transform; transition-property: transform, left; transition-property: transform, left, -webkit-transform; -webkit-transition-timing-function: linear; transition-timing-function: linear } } } &.Remove-Progress-Bar-Gradient-Snippet { .x-progressBar-fillColor { background-color: var(--fg-color) !important; border-radius: var(--progress-bar-radius) !important; height: var(--progress-bar-height) !important; transform: translateX(calc(-100% + var(--progress-bar-transform))) !important; width: 100% !important; } } &.Remove-Connect-Bar-Snippet { .main-connectBar-connectBar, .main-devicePicker-indicator { display: none !important; } } &.Remove-Lyrics-Button-Snippet { .main-nowPlayingBar-lyricsButton { display: none !important; } } &.Hoverable-Timers-Snippet { .playback-bar, .pn5V0OzovI9p6b8nWq8p.gglUjikTBtMzCZFgSmpS { >div { transition: all 0.3s ease; opacity: 0; } &:hover>div { transition: all 0.3s ease; opacity: 1 !important; } .playback-progressbar { opacity: 1 !important; } } } &.Topbar-Inside-Titlebar-Snippet { .Root__top-container { grid-template-areas: "top-bar top-bar top-bar" "left-sidebar main-view right-sidebar" "now-playing-bar now-playing-bar now-playing-bar" !important; grid-template-rows: 0 1fr auto !important; .main-topBar-container { pointer-events: none; grid-area: top-bar; contain: unset; top: calc(var(--comfy-topbar-height, 40px) * -1 + 1px); height: calc(var(--comfy-topbar-height, 40px) + 8px); padding-block: 8px; .main-topBar-topbarContentWrapper { >*:not(.main-topBar-searchBar):not(:has(ul)) { justify-content: center; display: flex; } ul { text-align: center !important; justify-content: center; } .queue-tabBar-headerItemLink { padding: 5px 16px; } } .main-topBar-topbarContent { app-region: drag !important; .main-entityHeader-topbarTitle { height: 100%; } } .main-topBar-background { display: none; } } } main:not(:has(.main-home-filterChipsContainer)), .queue-queuePage-queuePage, .search-searchCategory-SearchCategory, .artist-artistDiscography-topBar, .marketplace-header, .f59DF4qQ_FphIrVeRYkI, .cj6vRk3nFAi80HSVqX91, .main-home-filterChipsContainer { margin-top: -64px !important; top: 0 !important; } .marketplace-header, .f59DF4qQ_FphIrVeRYkI, .cj6vRk3nFAi80HSVqX91 { padding-top: 15px !important; } .main-home-filterChipsContainer { padding-top: 8px; } .artist-artistDiscography-topBar { height: 64px !important; box-shadow: none; } .artist-artistDiscography-headerContainer.artist-artistDiscography-firstAlbum { padding-top: 32px; } .main-view-container .search-searchCategory-SearchCategory { height: 64px; padding-top: 17px; } } &.Collapse-Topbar-Snippet { .main-topBar-topbarContentWrapper nav { justify-content: center; display: flex; } } &.Header-Background { .main-entityHeader-imageContainerNew { align-self: center; left: calc(clamp(128px, 128px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*104, 232px) + 24px + var(--content-spacing)); position: relative; z-index: 1; } .main-entityHeader-headerText { background-color: rgba(var(--spice-rgb-main-transition), var(--header-opacity)); padding: 24px 32px; border-radius: var(--border-radius); min-width: fit-content; box-shadow: 0 2px 4px rgba(var(--spice-rgb-shadow), 0.1); justify-content: space-evenly !important; height: calc(clamp(128px, 128px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px)/424*104, 232px) + 48px); } .main-entityHeader-imageContainerNew+.main-entityHeader-headerText { padding-left: calc(clamp(128px, 128px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px) / 424 * 104, 232px) + 32px + var(--content-spacing)); margin-right: calc(clamp(128px, 128px + (100vw - var(--comfy-left-sidebar-width, 0px) - var(--comfy-panel-width, 0px) - 600px) / 424 * 104, 232px) + var(--content-spacing)); } &:not(.Topbar-Inside-Titlebar-Snippet) .main-entityHeader-topbarContentFadeIn>* { opacity: var(--top-bar-opacity) !important; } } &.AM-Gradient-Include-Existing-Snippet.Banner-Enabled, &.Replace-Existing-Banners.Banner-Enabled { .under-main-view>div:not(.comfy-banner-frame) { display: none !important; } } &.Lyrics { main>div>div:empty { --lyrics-color-background: transparent !important; } } &.Apple-Music-Gradient-Snippet { .comfy-banner-frame { position: absolute; width: 100%; height: 100%; z-index: 0; filter: blur(calc(var(--image-blur) * 10)); background-image: var(--gradient-background-image); .comfy-banner-image { position: absolute !important; width: var(--gradient-width) !important; aspect-ratio: 1; animation: rotate var(--gradient-speed) linear infinite; border-radius: var(--gradient-radius) !important; mix-blend-mode: var(--gradient-blend-mode); background-size: cover !important; &:first-of-type { height: revert; left: unset; background-size: unset; background-position: unset; filter: none; -webkit-mask-image: none; mask-image: none; right: 0; top: 0; z-index: 10; } &:last-of-type { display: revert; left: 0; bottom: 0; animation-direction: reverse; } } } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } } } } ================================================ FILE: Comfy/assets/_top_bar.scss ================================================ :root .main-topBar-container { .main-topBar-topbarContent *, .main-topBar-topbarContentWrapper * { justify-content: center; text-align: center; } .main-topBar-searchBar { >form input { &::placeholder { color: rgba(var(--spice-rgb-selected-row), 0.7); } height: 32px; background-color: rgba(var(--spice-rgb-shadow), 0.7); } } .main-topBar-historyButtons button:hover { transform: scale(1.1); } .main-topBar-topbarContent>div:has([data-encore-id="buttonPrimary"]):first-child { display: none !important; } .main-topBar-background { background-color: var(--spice-main) !important; } .main-topBar-overlay { background-color: transparent !important; } .main-topBar-UpgradeButton { font-size: 0; overflow: hidden; background: url("https://i.imgur.com/nzAfcIL.png") 50% / contain no-repeat; border: none; padding: 5px; box-sizing: content-box; width: 12px; } } ================================================ FILE: Comfy/assets/_tracklist.scss ================================================ :root { // Tracklist .main-trackList-active .main-trackList-rowTitle { color: var(--spice-text) !important; text-shadow: 0px 0px 6px var(--spice-text); -webkit-text-stroke: thin; } .main-trackList-trackListHeader { &._2ajKWDiy6YvJu5wo8I1g { background: var(--spice-main) !important; top: 0 !important; } &:not(._2ajKWDiy6YvJu5wo8I1g) { .main-trackList-trackListRow, .main-trackList-trackListHeaderRow { &:hover { background-color: rgba(var(--spice-rgb-selected-row), 0.05); } } } } .main-trackList-trackListRow, .main-trackList-trackListHeaderRow { border-radius: var(--border-radius); border: none; transition: 200ms background-color; &.main-trackList-selected { background-color: rgba(var(--spice-rgb-selected-row), 0.1); &:hover { background-color: rgba(var(--spice-rgb-selected-row), 0.15); } } .main-type-mesto, .main-type-ballad { transition: 300ms color; } .main-trackList-rowImageFallback { border-radius: var(--border-radius) !important; } } #main.Remove-Tracklist-Index { // Image Tracklist .main-trackList-trackList:has(.main-trackList-rowSectionStart img), .main-trackList-trackList:has(.main-trackList-rowSectionStart .main-trackList-rowImageFallback) { .main-trackList-trackListHeader { .main-trackList-rowSectionIndex { opacity: 0; } } .main-trackList-trackListRow { &:hover, &:focus-within, &.main-trackList-active { .main-trackList-rowImagePlayPauseButton, .main-trackList-rowSectionIndex { background: rgba(var(--spice-rgb-play-button), 0.5); } .main-trackList-rowImagePlayButton, .main-trackList-rowImagePlayPauseButton { opacity: 1; } } .main-trackList-rowImagePlayButton, .main-trackList-rowImagePlayPauseButton, .main-trackList-rowSectionIndex { color: var(--spice-sidebar); border-radius: var(--border-radius); transition: 200ms opacity, 200ms background; } >.main-trackList-rowSectionIndex { position: relative; z-index: 1000; top: 8px; left: 56px; width: 40px; height: 40px; justify-content: center; text-indent: -1000px; } } } // Image Tracklist with Index .main-trackList-indexable:has(.main-trackList-rowSectionStart img) { @for $i from 3 through 6 { &[aria-colcount="#{$i}"] .main-trackList-trackListRowGrid { padding-left: 2px; @if $i ==3 { grid-template-columns: [index] 0px [first] var(--col1, 4fr) [last] minmax(120px, var(--col2, 1fr)) !important; } @else if $i ==4 { grid-template-columns: [index] 0px [first] minmax(120px, var(--col1, 4fr)) [var1] minmax(120px, var(--col2, 2fr)) [last] minmax(120px, var(--col3, 1fr)) !important; } @else if $i ==5 { grid-template-columns: [index] 0px [first] minmax(120px, var(--col1, 6fr)) [var1] minmax(120px, var(--col2, 4fr)) [var2] minmax(120px, var(--col3, 3fr)) [last] minmax(120px, var(--col4, 1fr)) !important; } @else if $i ==6 { grid-template-columns: [index] 0px [first] minmax(120px, var(--col1, 6fr)) [var1] minmax(120px, var(--col2, 4fr)) [var2] minmax(120px, var(--col3, 3fr)) [var3] minmax(120px, var(--col4, 2fr)) [last] minmax(120px, var(--col5, 1fr)) !important; } @else if $i ==7 { grid-template-columns: [index] 0px [first] minmax(120px, var(--col1, 6fr)) [var1] minmax(120px, var(--col2, 4fr)) [var2] minmax(120px, var(--col3, 3fr)) [var3] minmax(120px, var(--col4, 2fr)) [var4] minmax(120px, var(--col5, 2fr)) [last] minmax(120px, var(--col6, 1fr)) !important; } } } } } } ================================================ FILE: Comfy/color.ini ================================================ [Comfy] text = FFFFFF subtext = B9BBBE main = 23283D main-elevated = 32364A main-transition = 1E2233 highlight = 45495B highlight-elevated = 383D50 sidebar = 1E2233 player = 101320 card = 101320 shadow = 1E2233 selected-row = F1F1F1 button = 7289DA button-active = 5C6FB1 button-disabled = 4B588C tab-active = 1E2233 notification = 7289DA notification-error = D25050 misc = 000000 play-button = 7289DA play-button-active = 869ADF progress-fg = 1ED760 progress-bg = 7289DA heart = D25050 pagelink-active = 5C6EB1 radio-btn-active = 7289DA [Spotify] text = FFFFFF subtext = B3B3B3 main = 121212 main-elevated = 242424 main-transition = 000000 highlight = 1A1A1A highlight-elevated = 2A2A2A sidebar = 000000 player = 181818 card = 282828 shadow = 000000 selected-row = FFFFFF button = 1DB954 button-active = 1ED760 button-disabled = 535353 tab-active = 333333 notification = 4687D6 notification-error = E22134 misc = 7F7F7F play-button = 1DB954 play-button-active = 1DB954 progress-fg = 1DB954 progress-bg = 636363 heart = 1DB954 pagelink-active = 333333 radio-btn-active = 1DB954 [Nord] text = B2BCCC subtext = B2BCCC main = 2E3440 main-elevated = 3C414C main-transition = 262B35 highlight = 50555F highlight-elevated = 424852 sidebar = 262B35 player = 2E3440 card = 363D4C shadow = 1D2128 selected-row = B2BCCC button = 8A99AF button-active = 718CAD button-disabled = 434C5E tab-active = 363D4C notification = 363D4C notification-error = A9555E misc = FFFFFF play-button = 8A99AF play-button-active = 718CAD progress-fg = 8A99AF progress-bg = 4B566A heart = 718CAD pagelink-active = B7C1D5 radio-btn-active = 363D4C [Everforest] text = D3C6AA subtext = 9AA79D main = 272E33 main-elevated = 30363A main-transition = 495156 highlight = 444747 highlight-elevated = 34393D sidebar = 2E383C player = 272E33 card = 374145 shadow = 374145 selected-row = D3C6AA button = A7C080 button-active = AEC984 button-disabled = 374145 tab-active = 181C1E notification = 86AF87 notification-error = E67E80 misc = 000000 play-button = A7C080 play-button-active = AEC984 progress-fg = A7C080 progress-bg = 9DA9A0 heart = A7C080 pagelink-active = 181C1E radio-btn-active = 86AF87 [Kanagawa] text = 545464 subtext = 545464 main = F2EBBC main-elevated = E6DFB7 main-transition = D5CEA3 highlight = D5CfAf highlight-elevated = E0DAB4 sidebar = E7DBA0 player = F2EBBC card = D5CEA3 shadow = E0DAB4 selected-row = 43436C button = 43242B button-active = 39395D button-disabled = D5CEA3 tab-active = E7DBA0 notification = 43242B notification-error = E82423 misc = 000000 play-button = 43242B play-button-active = 43242B progress-fg = 43242B progress-bg = 77713E heart = E82423 pagelink-active = FFFFFF radio-btn-active = E7DBA0 [Houjicha] text = B59F92 subtext = 997B6F main = 473F3C main-elevated = 534C49 main-transition = 5C514D highlight = 574F4B highlight-elevated = 59524F sidebar = 514741 player = 473F3C card = 78645C shadow = 78645C selected-row = A49A96 button = 6E916F button-active = B3A49A button-disabled = 67564D tab-active = 6D5D54 notification = 86AF87 notification-error = D25050 misc = 000000 play-button = B59F92 play-button-active = C7AfA1 progress-fg = 86AF87 progress-bg = B59F92 heart = 86AF87 pagelink-active = FFFFFF radio-btn-active = 877063 [Kitty] text = FFFFFF subtext = FFDDDC main = C94985 main-elevated = CD548C main-transition = DE4B90 highlight = DE4B90 highlight-elevated = CF598D sidebar = E072A6 player = 941550 card = DE5BA5 shadow = 2B0718 selected-row = FFDDDC button = 941550 button-active = FFFFFF button-disabled = 941550 tab-active = E072A6 notification = E072A6 notification-error = 994B6F misc = 000000 play-button = FFFFFF play-button-active = A13267 progress-fg = DE4B90 progress-bg = 994B6F heart = A13267 pagelink-active = DE4B90 radio-btn-active = 994B6F [Lunar] text = F3F3F3 subtext = CECECE main = 161616 main-elevated = 232323 main-transition = 101010 highlight = 2A2A2A highlight-elevated = 292929 sidebar = 202020 player = 161616 card = 303030 shadow = 252525 selected-row = CECECE button = 3281EA button-active = 0284E8 button-disabled = 303030 tab-active = EBBCBA notification = 3281EA notification-error = B10C0C misc = 252525 play-button = EBBCBA play-button-active = EBA9A7 progress-fg = 025CA1 progress-bg = 202020 heart = EBBCBA pagelink-active = FFFFFF radio-btn-active = 0284E8 [Deep] text = 4F9A87 subtext = 406560 main = 040614 main-elevated = 0A111D main-transition = 0F111A highlight = 0F1F28 highlight-elevated = 0C1520 sidebar = 0F111A player = 040614 card = 0F1118 shadow = 0F1118 selected-row = 4F9A87 button = 106165 button-active = 4F9A87 button-disabled = 0C1C19 tab-active = 0A1527 notification = 051024 notification-error = 051024 misc = 406560 play-button = 106165 play-button-active = 4F9A87 progress-fg = 4F9A87 progress-bg = 106165 heart = D25050 pagelink-active = 4F9A87 radio-btn-active = 106165 [Velvet] text = AD434E subtext = 762F37 main = 1E1E1E main-elevated = 272021 main-transition = 161616 highlight = 322324 highlight-elevated = 2A2122 sidebar = 161616 player = 080808 card = 0F0F0F shadow = 161616 selected-row = 973B45 button = 6B2B32 button-active = 552328 button-disabled = 262626 tab-active = 161616 notification = 6B2B32 notification-error = 60272D misc = 000000 play-button = 552328 play-button-active = 6B2B32 progress-fg = 81333B progress-bg = A23F49 heart = 60272D pagelink-active = 4A1F23 radio-btn-active = 6B2B32 [Yami] text = D4D4D4 subtext = D4D4D4 main = 0A0A10 main-elevated = 0D0D14 main-transition = 0A0A10 highlight = 191923 highlight-elevated = 0E0E15 sidebar = 0A0A10 player = 0A0A10 card = 191923 shadow = AF8BF3 selected-row = 353447 button = 191923 button-active = 353447 button-disabled = 111117 tab-active = 191923 notification = 0A0A10 notification-error = F7407B misc = 0A0A10 play-button = 2B2A3D play-button-active = 353447 progress-fg = F7407B progress-bg = 0A0A10 heart = F7407B pagelink-active = F7407B radio-btn-active = 191923 [Hikari] text = CDBBF9 subtext = 8A7EA8 main = 050406 main-elevated = 0D0D14 main-transition = 0B0910 highlight = 1B1923 highlight-elevated = 0E0E15 sidebar = 0D0D14 player = 0D0D14 card = 1F132D shadow = 1F132D selected-row = F1F1F1 button = 90128B button-active = 90128B button-disabled = 1C0033 tab-active = 1B1923 notification = 0A0A10 notification-error = 90128B misc = 0A0A10 play-button = CDBBF9 play-button-active = 8A7EA8 progress-fg = 90128B progress-bg = 0D0D14 heart = CDBBF9 pagelink-active = 1B1923 radio-btn-active = 191923 [catppuccin-latte] text = 4C4F69 subtext = 5C5F77 main = E6E9EF main-elevated = DCE0E6 main-transition = E6E9EF highlight = CED3DB highlight-elevated = D8DBE3 sidebar = EFF1F5 player = E6E9EF card = BCC0CC shadow = E6E9EF selected-row = 5C5F77 button = 1E66F5 button-active = 209FB5 button-disabled = BCC0CC tab-active = CCD0DA notification = 1E66F5 notification-error = D20F39 misc = ACB0BE play-button = EA76CB play-button-active = DD7878 progress-fg = 04A5E5 progress-bg = BCC0CC heart = FE640B pagelink-active = FFFFFF radio-btn-active = 209FB5 [catppuccin-frappe] text = C6D0F5 subtext = B5BFE2 main = 292C3C main-elevated = 333648 main-transition = 292C3C highlight = 3B4058 highlight-elevated = 373B4D sidebar = 303446 player = 292C3C card = 51576D shadow = 626880 selected-row = B5BFE2 button = 8CAAEE button-active = 85C1DC button-disabled = 51576D tab-active = 414559 notification = 8CAAEE notification-error = E78284 misc = 626880 play-button = F4B8E4 play-button-active = EECEBE progress-fg = 99D1DB progress-bg = 51576D heart = EF9F76 pagelink-active = FFFFFF radio-btn-active = 85C1DC [catppuccin-macchiato] text = CAD3F5 subtext = B8C0E0 main = 181926 main-elevated = 232533 main-transition = 181926 highlight = 333645 highlight-elevated = 292A39 sidebar = 24273A player = 181926 card = 494D64 shadow = 5B6078 selected-row = B8C0E0 button = 8AADF4 button-active = 7DC4E4 button-disabled = 494D64 tab-active = 363A4F notification = 8AADF4 notification-error = ED8796 misc = 5B6078 play-button = F5BDE6 play-button-active = F0C6C6 progress-fg = 91D7E3 progress-bg = 494D64 heart = F5A97F pagelink-active = FFFFFF radio-btn-active = 7DC4E4 [catppuccin-mocha] text = CDD6F4 subtext = BAC2DE main = 181825 main-elevated = 232432 main-transition = 181825 highlight = 333645 highlight-elevated = 292A38 sidebar = 1E1E2E player = 181825 card = 45475A shadow = 585B70 selected-row = BAC2DE button = 89B4FA button-active = 74C7EC button-disabled = 45475A tab-active = 313244 notification = 89B4FA notification-error = F38BA8 misc = 585B70 play-button = F5C2E7 play-button-active = F2CDCD progress-fg = 89DCEB progress-bg = 45475A heart = FAB387 pagelink-active = FFFFFF radio-btn-active = 74C7EC [rose-pine] text = E0DEF4 subtext = 908CAA main = 1F1D2E main-elevated = 2D2B3C main-transition = 26233A highlight = 403D52 highlight-elevated = 333142 sidebar = 191724 player = 1F1D2E card = 403D52 shadow = 524F67 selected-row = E0DEF4 button = EBBCBA button-active = EBBCBA button-disabled = 6E6A86 tab-active = 524F67 notification = 9CCFD8 notification-error = EB6F92 misc = FFFFFF play-button = EBBCBA play-button-active = EBBCBA progress-fg = EBBCBA progress-bg = 403D52 heart = EB6F92 pagelink-active = EBBCBA radio-btn-active = 9CCFD8 [rose-pine-moon] text = E0DEF4 subtext = 908CAA main = 2A273F main-elevated = 37344C main-transition = 393552 highlight = 44415A highlight-elevated = 3D3A52 sidebar = 232136 player = 2A273F card = 44415A shadow = 56526E selected-row = E0DEF4 button = EA9A97 button-active = EA9A97 button-disabled = 6E6A86 tab-active = 56526E notification = 9CCFD8 notification-error = EB6F92 misc = FFFFFF play-button = EA9A97 play-button-active = EA9A97 progress-fg = EA9A97 progress-bg = 44415A heart = EB6F92 pagelink-active = EA9A97 radio-btn-active = 9CCFD8 [rose-pine-dawn] text = 575279 subtext = 797593 main = FFFAF3 main-elevated = F3EEEB main-transition = F2E9E1 highlight = DFDAD9 highlight-elevated = EEE9E6 sidebar = FAF4ED player = FFFAF3 card = DFDAD9 shadow = FAF4ED selected-row = 575279 button = D7827E button-active = D7827E button-disabled = 9893A5 tab-active = CECACD notification = 56949F notification-error = B4637A misc = FFFFFF play-button = D7827E play-button-active = D7827E progress-fg = D7827E progress-bg = DFDAD9 heart = B4637A pagelink-active = D7827E radio-btn-active = 907AA9 [Mono] text = FFFFFF subtext = B9BBBE main = 171717 main-elevated = 262626 main-transition = FFFFFF highlight = 3B3B3B highlight-elevated = 2E2E2E sidebar = 101010 player = 171717 card = 343434 shadow = 595858 selected-row = F1F1F1 button = FFFFFF button-active = C5C5C5 button-disabled = 4A4949 tab-active = 303030 notification = 101010 notification-error = D25050 misc = 000000 play-button = FFFFFF play-button-active = FFFFFF progress-fg = FFFFFF progress-bg = 343434 heart = FFFFFF pagelink-active = 787878 radio-btn-active = 737373 [Sunset] text = FFCE3F subtext = FEF3BB main = 171717 main-elevated = 272622 main-transition = 000000 highlight = 3D3C32 highlight-elevated = 2F2E28 sidebar = 101010 player = 171717 card = CC9756 shadow = E3B47B selected-row = FEF3BB button = FFCE3F button-active = BF9B30 button-disabled = 4A4949 tab-active = 303030 notification = FFFFFF notification-error = D25050 misc = 000000 play-button = FFCE3F play-button-active = FC9E3A progress-fg = FF8300 progress-bg = 343434 heart = FF8300 pagelink-active = FEF3BB radio-btn-active = FEF3BB [Neon] text = 588BAE subtext = EAFFFF main = 171717 main-elevated = 262626 main-transition = 000000 highlight = 3B3B3B highlight-elevated = 2E2E2E sidebar = 101010 player = 171717 card = 7FA1B5 shadow = A9C9DB selected-row = F1F1F1 button = 588BAE button-active = 3B5D75 button-disabled = 4A4949 tab-active = 303030 notification = FFFFFF notification-error = D25050 misc = 000000 play-button = 588BAE play-button-active = 5085AB progress-fg = 00AFDB progress-bg = 343434 heart = 00AFDB pagelink-active = BBE7FE radio-btn-active = EAFFFF [Forest] text = B2C5B3 subtext = D5DDDE main = 171717 main-elevated = 262626 main-transition = 000000 highlight = 3B3B3B highlight-elevated = 2E2E2E sidebar = 101010 player = 171717 card = 5C6E59 shadow = 3C5148 selected-row = F1F1F1 button = B2C5B3 button-active = F1F1F1 button-disabled = 4A4949 tab-active = 303030 notification = FFFFFF notification-error = D25050 misc = 000000 play-button = 3C5148 play-button-active = 43705D progress-fg = 3C5148 progress-bg = 343434 heart = 3C5148 pagelink-active = 3C5148 radio-btn-active = 737373 [Sakura] text = FCB4CA subtext = FFDCDC main = 171717 main-elevated = 262626 main-transition = 000000 highlight = 3D3838 highlight-elevated = 2E2E2E sidebar = 101010 player = 171717 card = D68BA2 shadow = FCB4CA selected-row = FFDCDC button = FCB4CA button-active = D48AA0 button-disabled = 4A4949 tab-active = 303030 notification = FFFFFF notification-error = D25050 misc = 000000 play-button = F42C38 play-button-active = BA182B progress-fg = CFEEFA progress-bg = 343434 heart = F25477 pagelink-active = F5BCDB radio-btn-active = FFDCDC [Vaporwave] text = 01CDFE subtext = EAFFFF main = 171717 main-elevated = 262626 main-transition = 000000 highlight = 3B3B3B highlight-elevated = 2E2E2E sidebar = 101010 player = 171717 card = 007F9E shadow = 2EC2E6 selected-row = F1F1F1 button = 01CDFE button-active = 118BA8 button-disabled = 4A4949 tab-active = 303030 notification = FFFFFF notification-error = D25050 misc = 000000 play-button = FFD300 play-button-active = E3C01B progress-fg = F706CF progress-bg = 343434 heart = F706CF pagelink-active = C0D6FA radio-btn-active = EAFFFF [wal16] text = ${xrdb:color15} subtext = ${xrdb:color7} main = ${xrdb:color0} main-elevated = ${xrdb:color1} main-transition = ${xrdb:color0} highlight = ${xrdb:color5} highlight-elevated = ${xrdb:color13} sidebar = ${xrdb:color0} player = ${xrdb:color0} card = ${xrdb:color0} shadow = ${xrdb:color8} selected-row = ${xrdb:color15} button = ${xrdb:color6} button-active = ${xrdb:color14} button-disabled = ${xrdb:color8} tab-active = ${xrdb:color0} notification = FFFFFF notification-error = D25050 misc = ${xrdb:color0} play-button = ${xrdb:color3} play-button-active = ${xrdb:color11} progress-fg = ${xrdb:color10} progress-bg = ${xrdb:color0} heart = ${xrdb:color12} pagelink-active = ${xrdb:color3} radio-btn-active = ${xrdb:color3} ================================================ FILE: Comfy/package.json ================================================ { "name": "comfy", "version": "1.0.0", "description": "Stay comfy while listening to music", "main": "theme.script.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "compile-scss": "sass app.scss app.css" }, "repository": { "type": "git", "url": "git+https://github.com/Comfy-Themes/Spicetify.git" }, "keywords": ["comfy", "spicetify"], "author": "Comfy-Themes", "license": "WTFPL", "bugs": { "url": "https://github.com/Comfy-Themes/Spicetify/issues" }, "homepage": "https://github.com/Comfy-Themes/Spicetify#readme", "dependencies": { "node-sass": "^7.0.3" } } ================================================ FILE: Comfy/theme.js ================================================ (() => { const themeScript = document.createElement("SCRIPT"); themeScript.setAttribute("type", "text/javascript"); themeScript.setAttribute("src", "https://comfy-themes.github.io/Spicetify/Comfy/theme.script.js"); document.head.appendChild(themeScript); })(); ================================================ FILE: Comfy/theme.script.js ================================================ /* tofix: - negative values - Reloading when filtered causes options to not be applied - fonts titles and stuff css todo: - add warning message if using unsupported versions - add custom colour schemes - add overrides for topbar background and padding */ (async function comfy() { // Block Until Mass Usage Deps Loaded if (!(Spicetify.React && Spicetify.ReactDOM && Spicetify.Config)) { setTimeout(comfy, 10); return; } console.debug("[Comfy-Event]: Global Dependencies loaded"); // Add Global Functions window.Comfy = { Reset: () => { localStorage.removeItem("comfy:config"); location.reload(); }, Config: () => { console.log(JSON.parse(localStorage.getItem("comfy:config") || "{}")); } }; console.debug(`[Comfy-Event]: Global Functions Added`); // Initialize Config let config = JSON.parse(localStorage.getItem("comfy:config") || "{}"); let configScheme = Spicetify.Config?.color_scheme || "Comfy"; let preloadedScheme = false; let startup = true; let preloadContainer = document.createElement("div"); console.debug(`[Comfy-Event]: Config Initialized`); // Preload Applied Colorscheme const colorScheme = getConfig("Color-Scheme"); if (colorScheme) { preloadedScheme = true; updateScheme(colorScheme, "preloaded"); } // Update Colorschemes fetch("https://raw.githubusercontent.com/Comfy-Themes/Spicetify/main/Comfy/color.ini") .then(response => response.text()) .then(iniContent => { setConfig("Color-Schemes", parseIni(iniContent), "Successfully updated color schemes"); configScheme = (getConfig("Color-Schemes") && Object.keys(getConfig("Color-Schemes")).find(scheme => scheme.toLowerCase() === configScheme.toLowerCase())) || configScheme; updateScheme(getConfig("Color-Scheme"), "updated"); }) .catch(error => { console.warn("[Comfy-Warning]: Failed to update color schemes:", error); }); // Window Zoom Variable // todo: improve this? seems unoptimal but spotify messes with window.outerWidth on minimize so this is required currently function updateZoomVariable() { let prevOuterWidth = window.outerWidth; let prevInnerWidth = window.innerWidth; let prevRatio = window.devicePixelRatio; let startup = true; function checkChanges() { const newOuterWidth = window.outerWidth; const newInnerWidth = window.innerWidth; const newRatio = window.devicePixelRatio; if (startup || ((prevOuterWidth <= 160 || prevRatio !== newRatio) && (prevOuterWidth !== newOuterWidth || prevInnerWidth !== newInnerWidth))) { const modified = newOuterWidth / newInnerWidth || 1; document.documentElement.style.setProperty("--zoom", modified); console.debug(`[Comfy-Event]: Zoom Updated: ${newOuterWidth} / ${newInnerWidth} = ${modified}`); prevOuterWidth = newOuterWidth; prevInnerWidth = newInnerWidth; prevRatio = newRatio; } requestAnimationFrame(checkChanges); } checkChanges(); startup = false; } updateZoomVariable(); // Layout Variables let panelWidth = document.documentElement.style.getPropertyValue("--panel-width"); let sidebarWidth = document.documentElement.style.getPropertyValue("--left-sidebar-width"); document.documentElement.style.setProperty("--comfy-panel-width", `${panelWidth}px`); document.documentElement.style.setProperty("--comfy-left-sidebar-width", `${sidebarWidth}px`); new MutationObserver(mutations => { const newPanelWidth = mutations[0].target.style.getPropertyValue("--panel-width"); const newSidebarWidth = mutations[0].target.style.getPropertyValue("--left-sidebar-width"); if (newPanelWidth !== panelWidth || newSidebarWidth !== sidebarWidth) { const trimmedPanelWidth = parseInt(newPanelWidth); const trimmedSidebarWidth = parseInt(newSidebarWidth); document.documentElement.style.setProperty("--comfy-panel-width", `${trimmedPanelWidth}px`); document.documentElement.style.setProperty("--comfy-left-sidebar-width", `${trimmedSidebarWidth}px`); panelWidth = newPanelWidth; sidebarWidth = newSidebarWidth; } }).observe(document.documentElement, { attributes: true, attributeFilter: ["style"] }); waitForDeps("Spicetify.Platform.version", version => { if (version >= "1.2.46.462") { waitForDeps( ":root .global-nav", root => { if (!root.classList.contains("global-nav-centered")) { root.classList.add("global-nav-centered"); } }, true ); } }); // Banner Image(s) let channels = { Lyrics: { regex: /^\/lyrics$/, enabled: getConfig("Lyrics") ?? false }, Playlist: { regex: /^\/playlist\//, enabled: getConfig("Playlist") ?? true }, Station: { regex: /^\/station\/playlist\//, enabled: getConfig("Station") ?? true }, Artist: { regex: /^\/artist\/(?!artists\b)\w+$/, enabled: getConfig("Artist") ?? true }, Album: { regex: /^\/album\//, enabled: getConfig("Album") ?? true }, Collection: { regex: /^\/collection\/tracks$/, enabled: getConfig("Collection") ?? true }, "Your-Episodes": { regex: /^\/collection\/your-episodes$/, enabled: getConfig("Your-Episodes") ?? true }, "Local-Files": { regex: /^\/collection\/local-files$/, enabled: getConfig("Local-Files") ?? true }, Show: { regex: /^\/show\//, enabled: getConfig("Show") ?? true }, Episode: { regex: /^\/episode\//, enabled: getConfig("Episode") ?? true }, "Lyrics-Plus": { regex: /^\/lyrics-plus$/, enabled: getConfig("Lyrics-Plus") ?? true }, User: { regex: /^\/user\/(?!users\b)\w+$/, enabled: getConfig("User") ?? true }, Genre: { regex: /^\/genre\//, enabled: getConfig("Genre") ?? true } }; const frame = document.createElement("div"); const banner = [document.createElement("div"), document.createElement("div")]; frame.className = "comfy-banner-frame"; banner.forEach(image => { image.className = "comfy-banner-image"; frame.append(image); }); waitForDeps( ".under-main-view", underMainView => { console.debug("[Comfy-Event]: Banner Frame Added"); underMainView.appendChild(frame); }, true ); waitForDeps("Spicetify.Platform.History", () => Spicetify.Platform.History.listen(updateBanner)); waitForDeps("Spicetify.Player", () => Spicetify.Player.addEventListener("songchange", updateBanner)); updateBanner(); // React components const Dialog = Spicetify.React.memo(props => { const [state, setState] = Spicetify.React.useState(true); const self = document.querySelector(".ReactModalPortal:last-of-type"); const ConfirmDialog = Spicetify.ReactComponent.ConfirmDialog; const isForwardRef = typeof ConfirmDialog === "function"; const commonProps = { ...props, isOpen: state, onClose: () => { setState(false); props.onClose?.(); self.remove(); }, onConfirm: () => { setState(false); props.onConfirm?.(); self.remove(); } }; Spicetify.React.useEffect(() => { if (state) { props.onOpen?.(); } }, [state]); return isForwardRef ? ConfirmDialog(commonProps) : Spicetify.React.createElement(ConfirmDialog, commonProps); }); const Section = ({ name, children, condition = true, filter }) => { filter = !filter || name === filter.label || filter.index === 0; if (condition === false) return null; return ( filter && Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement( "div", { className: "setting-section", id: name }, Spicetify.React.createElement("h2", { className: "setting-header" }, name), children.map(child => Spicetify.React.createElement(child.type, { ...child, tippy: Spicetify.React.createElement(Tippy, { label: child.tippy }) }) ) ) ) ); }; const Row = ({ name, items }) => { return Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement( "div", { className: name }, items.map(item => Spicetify.React.createElement(item.type, { ...item, tippy: Spicetify.React.createElement(Tippy, { label: item.tippy }) }) ) ) ); }; const Button = ({ name, title, condition = true, callback }) => { const [state, setState] = Spicetify.React.useState(title); if (condition === false) return; return Spicetify.React.createElement( "button", { className: "main-buttons-button", id: name, onClick: () => { callback(state, setState); } }, state ); }; const CardLayout = Spicetify.React.memo(({ title, desc, tippy, action, onClick }) => { return Spicetify.React.createElement( "div", { className: "setting-card" }, Spicetify.React.createElement( "div", { className: "setting-container", onClick: onClick }, Spicetify.React.createElement( "div", { className: "setting-item" }, Spicetify.React.createElement("label", { className: "setting-title" }, title, tippy), Spicetify.React.createElement("div", { className: "setting-action" }, action) ), Spicetify.React.createElement("div", { className: "setting-description" }, desc), desc && Spicetify.React.createElement("div", { className: "setting-description-spacer" }) ) ); }); const SubSection = Spicetify.React.memo(({ name, condition = true, items, collapseItems: initialCollapseItems = false, callback, ...props }) => { const [state, setState] = Spicetify.React.useState(getConfig(name) ?? true); const [collapseItems, setCollapseItems] = Spicetify.React.useState(getConfig(`${name}-Collapsed`) ?? initialCollapseItems); if (condition === false) return null; return Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement( "div", { className: "setting-subSection", id: state ? (collapseItems ? "collapsed" : "enabled") : "disabled" }, Spicetify.React.createElement(Toggle, { name, callback: value => { callback?.(value); setState(value); items.forEach(item => { const both = () => (item.type === Input ? "" : item.defaultVal); const state = getConfig(item.name) ?? both(); setConfig(item.name, state); if (item.type === Toggle) { if (state || !value) waitForDeps( "main", main => { console.debug(`[Comfy-subCallback]: ${item.name} =`, state); main.classList.toggle(item.name, value ? state : false); item.callback?.(state); }, true, "getElementById" ); } else if (value && state !== both()) { console.debug(`[Comfy-subCallback]: ${item.name}`, state); item.callback?.(state, item.name); } }); }, onClick: () => { if (state) { setConfig(`${name}-Collapsed`, !collapseItems, null, true); setCollapseItems(!collapseItems); } }, ...props }), state && !collapseItems && !startup && items.map(item => Spicetify.React.createElement(item.type, { ...item, tippy: Spicetify.React.createElement(Tippy, { label: item.tippy }) }) ) ) ); }); const Tippy = ({ label }) => { if (!label) return null; return Spicetify.React.createElement( Spicetify.ReactComponent.TooltipWrapper, { label, showDelay: 0, placement: "left", trigger: "mouseenter" }, Spicetify.React.createElement( "div", { className: "x-settings-tooltip" }, Spicetify.React.createElement( "div", { className: "x-settings-tooltipIconWrapper" }, Spicetify.React.createElement( "svg", { role: "img", height: "16", width: "16", tabindex: "0", className: "Svg-sc-ytk21e-0 Svg-img-icon x-settings-tooltipIcon", viewBox: "0 0 16 16" }, Spicetify.React.createElement("path", { d: "M8 1.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13zM0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8z" }), Spicetify.React.createElement("path", { d: "M7.25 12.026v-1.5h1.5v1.5h-1.5zm.884-7.096A1.125 1.125 0 0 0 7.06 6.39l-1.431.448a2.625 2.625 0 1 1 5.13-.784c0 .54-.156 1.015-.503 1.488-.3.408-.7.652-.973.818l-.112.068c-.185.116-.26.203-.302.283-.046.087-.097.245-.097.57h-1.5c0-.47.072-.898.274-1.277.206-.385.507-.645.827-.846l.147-.092c.285-.177.413-.257.526-.41.169-.23.213-.397.213-.602 0-.622-.503-1.125-1.125-1.125z" }) ) ) ) ); }; const Toggle = Spicetify.React.memo(({ name, title, desc, tippy, defaultVal, condition = true, callback, onClick }) => { const [state, setState] = Spicetify.React.useState(getConfig(name) ?? defaultVal); const isFirstRender = Spicetify.React.useRef(true); Spicetify.React.useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; if (!startup) return; } setConfig(name, state); if (state || !startup) { waitForDeps( "main", main => { console.debug(`[Comfy-Callback]: ${name} =`, state); main.classList.toggle(name, state); callback?.(state); }, true, "getElementById" ); } }, [state]); if (condition === false) return null; return Spicetify.React.createElement(CardLayout, { title, desc, tippy, action: Spicetify.React.createElement( "label", { className: "x-toggle-wrapper" }, Spicetify.React.createElement("input", { className: "x-toggle-input", type: "checkbox", defaultChecked: state, onClick: () => setState(!state) }), Spicetify.React.createElement( "span", { className: "x-toggle-indicatorWrapper" }, Spicetify.React.createElement("span", { className: "x-toggle-indicator" }) ) ), onClick }); }); const Input = Spicetify.React.memo( ({ inputType, includePicker, name, title, desc, min, max, step, tippy, defaultVal, condition = true, callback, callbackOverride }) => { const [value, setValue] = Spicetify.React.useState(getConfig(name) ?? ""); const [defaultState, setDefaultState] = Spicetify.React.useState(defaultVal); const isFirstRender = Spicetify.React.useRef(true); const textFieldRef = Spicetify.React.useRef(null); Spicetify.React.useEffect(() => { if (textFieldRef.current) { textFieldRef.current.addEventListener("wheel", e => { if (document.focusedElement === textFieldRef.current) { e.preventDefault(); } }); } }, []); Spicetify.React.useEffect(() => { if (isPromise(defaultVal)) defaultVal.then(val => setDefaultState(val)); }, [defaultVal]); Spicetify.React.useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; if (!startup) return; } setConfig(name, value); if (value !== "" || !startup || callbackOverride) { console.debug(`[Comfy-Callback]: ${name} =`, value); callback?.(value, name, defaultVal); } }, [value, name]); if (condition === false) return null; return Spicetify.React.createElement(CardLayout, { title, desc, tippy, action: [ Spicetify.React.createElement("input", { type: inputType, className: "input", ref: textFieldRef, value, min: inputType === "number" ? Number(min) : null, max: inputType === "number" ? Number(max) : null, step: inputType === "number" ? Number(step) : null, placeholder: defaultState, onChange: e => setValue(e.target.value) }), includePicker && Spicetify.React.createElement("input", { type: "color", className: "input", value, placeholder: defaultState, onChange: e => setValue(e.target.value) }) ] }); } ); const Dropdown = Spicetify.React.memo(({ name, title, desc, options, defaultVal, condition = true, tippy, callback }) => { if (!condition) return null; if (!defaultVal) defaultVal = "Select an option"; if (typeof options === "function") options = options(); const [selectedValue, setSelectedValue] = Spicetify.React.useState(getConfig(name) ?? defaultVal); const [buttonEnabled, setButtonEnabled] = Spicetify.React.useState(selectedValue !== defaultVal); const [menuOpen, setMenuOpen] = Spicetify.React.useState(false); const isFirstRender = Spicetify.React.useRef(true); Spicetify.React.useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; if (!startup) { const parent = document.querySelector("generic-modal [aria-label='Comfy Settings']"); const current = document.getElementById(name); parent.addEventListener("click", event => { if (event.target.closest(".dropdown-wrapper") !== current) { setMenuOpen(false); } }); return; } } setConfig(name, selectedValue); if ((condition && selectedValue !== defaultVal) || !startup) { console.debug(`[Comfy-Callback]: ${name} =`, selectedValue); callback?.(name, selectedValue, options, defaultVal); setButtonEnabled(selectedValue !== defaultVal); } }, [selectedValue]); return Spicetify.React.createElement(CardLayout, { title, desc, tippy, action: [ buttonEnabled && Spicetify.React.createElement( "button", { className: `switch`, onClick: event => { event.stopPropagation(); // Prevent event from propagating up setSelectedValue(defaultVal); } }, Spicetify.React.createElement("svg", { height: "16", width: "16", viewBox: "0 0 16 16", fill: "currentColor", dangerouslySetInnerHTML: { __html: Spicetify.SVGIcons.x } }) ), Spicetify.React.createElement( "div", { className: `dropdown-wrapper main-type-mestoBold ${menuOpen ? "menu-open" : ""}`, id: name }, Spicetify.React.createElement( "div", { className: "dropdown-button", onClick: () => setMenuOpen(!menuOpen) }, Spicetify.React.createElement("div", { className: "dropdown-selection" }, selectedValue), Spicetify.React.createElement( "div", { className: "dropdown-arrow-wrapper" }, Spicetify.React.createElement("span", { className: "dropdown-arrow" }) ) ), menuOpen && Spicetify.React.createElement( "div", { className: "dropdown-menu" }, options.map(option => Spicetify.React.createElement( "div", { key: option, className: `dropdown-option${selectedValue === option ? " selected" : ""}`, role: "option", "aria-selected": selectedValue === option, onClick: event => { event.stopPropagation(); // Prevent event from propagating up setSelectedValue(option); setMenuOpen(false); } }, option ) ) ) ) ] }); }); const Carousel = ({ chips, checked, setChecked }) => { const containerRef = Spicetify.React.useRef(null); const [showLeftButton, setShowLeftButton] = Spicetify.React.useState(false); const [showRightButton, setShowRightButton] = Spicetify.React.useState(false); const [startX, setStartX] = Spicetify.React.useState(0); const [scrollLeft, setScrollLeft] = Spicetify.React.useState(0); const [mouseDown, setMouseDown] = Spicetify.React.useState(false); const isFirstRender = Spicetify.React.useRef(true); const section = document.querySelector(".main-trackCreditsModal-mainSection"); // Handle resizing and scroll visibility const handleResize = Spicetify.React.useCallback(() => { if (containerRef.current) { const container = containerRef.current; setShowLeftButton(container.scrollLeft > 0); setShowRightButton(container.scrollLeft < container.scrollWidth - container.clientWidth - 2); } }, []); Spicetify.React.useEffect(() => { handleResize(); // Initial call window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, [handleResize]); // Scroll to active item on first render Spicetify.React.useEffect(() => { if (containerRef.current && isFirstRender.current) { const activeItem = containerRef.current.querySelector(`.search-searchCategory-categoryGridItem:nth-child(${checked.index + 1})`); if (activeItem) { const container = containerRef.current; const containerScrollLeft = container.scrollLeft; const containerWidth = container.clientWidth; const itemOffsetLeft = activeItem.offsetLeft; const itemWidth = activeItem.clientWidth; if (itemOffsetLeft < containerScrollLeft + 32 || itemOffsetLeft + itemWidth > containerScrollLeft + containerWidth - 32) { const scrollPosition = itemOffsetLeft - (containerWidth / 2 - itemWidth / 2); container.scrollTo({ left: scrollPosition, behavior: "instant" }); } isFirstRender.current = false; } } }, [checked.index]); // Handle dragging const handleMouseDown = event => { setStartX(event.pageX - containerRef.current.offsetLeft); setScrollLeft(containerRef.current.scrollLeft); setMouseDown(true); containerRef.current.style.cursor = "grabbing"; containerRef.current.style.userSelect = "none"; containerRef.current.style.scrollBehavior = "auto"; }; const handleMouseMove = event => { if (!mouseDown) return; event.preventDefault(); const x = event.pageX - containerRef.current.offsetLeft; const walk = (x - startX) * 1; // Adjust scrolling speed containerRef.current.scrollLeft = scrollLeft - walk; }; const handleMouseUpOrLeave = () => { if (mouseDown) { containerRef.current.style.cursor = ""; containerRef.current.style.userSelect = ""; containerRef.current.style.scrollBehavior = ""; setMouseDown(false); } }; Spicetify.React.useEffect(() => { document.addEventListener("mouseup", handleMouseUpOrLeave); document.addEventListener("mousemove", handleMouseMove); document.addEventListener("mouseleave", handleMouseUpOrLeave); return () => { document.removeEventListener("mouseup", handleMouseUpOrLeave); document.removeEventListener("mousemove", handleMouseMove); document.removeEventListener("mouseleave", handleMouseUpOrLeave); }; }, [mouseDown]); // Handle arrow key navigation const handleKeyDown = Spicetify.React.useCallback( event => { let newIndex; let startingIndex = checked.index; if (document.activeElement.classList.contains("search-searchCategory-categoryGridItem")) { startingIndex = Array.from(containerRef.current.querySelectorAll(".search-searchCategory-categoryGridItem")).indexOf( document.activeElement ); } if (event.key === "ArrowLeft") { event.preventDefault(); newIndex = startingIndex - 1; if (newIndex < 0) newIndex = chips.length - 1; } else if (event.key === "ArrowRight") { event.preventDefault(); newIndex = (startingIndex + 1) % chips.length; } else if (event.key === "Enter") { const focusedChip = document.activeElement; const index = Array.from(containerRef.current.querySelectorAll(".search-searchCategory-categoryGridItem")).indexOf(focusedChip); if (index !== -1) { setChecked({ index, label: chips[index].label }); return; } } if (newIndex !== undefined) { const chipElement = containerRef.current.querySelector(`.search-searchCategory-categoryGridItem:nth-child(${newIndex + 1})`); if (chipElement) chipElement.focus(); } }, [checked.index, chips, setChecked] ); // Handle button clicks const handleButtonClick = direction => { const multiplier = direction === "LEFT" ? -1 : 1; containerRef.current.scrollBy({ left: multiplier * (containerRef.current.clientWidth / 2), behavior: "smooth" }); }; const clickCallback = (index, label) => { if (scrollLeft === containerRef.current.scrollLeft) setChecked({ index, label }); if (section) section.scrollTo(null, 0); }; return Spicetify.React.createElement( "div", { className: "search-searchCategory-SearchCategory encore-dark-theme" }, Spicetify.React.createElement( "div", { className: "search-searchCategory-wrapper contentSpacing" }, Spicetify.React.createElement( "div", { className: `search-searchCategory-contentArea ${showLeftButton ? "search-searchCategory-showLeftButton" : ""} ${showRightButton ? "search-searchCategory-showRightButton" : ""} ${showRightButton && showLeftButton ? "search-searchCategory-showLeftButton search-searchCategory-showRightButton" : ""}` .trim() .replace(/\s+/g, " ") }, Spicetify.React.createElement( "div", { ref: containerRef, className: "search-searchCategory-categoryGrid", onScroll: handleResize, onKeyDown: handleKeyDown, role: "list", tabIndex: 0, onMouseDown: handleMouseDown }, Spicetify.React.createElement( "div", { role: "presentation" }, chips.map((chip, index) => Spicetify.React.createElement( "a", { key: index, draggable: "false", className: "search-searchCategory-categoryGridItem", tabIndex: "-1", onClick: () => clickCallback(index, chip.label) }, Spicetify.React.createElement( Spicetify.ReactComponent.Chip, { isUsingKeyboard: false, onClick: () => clickCallback(index, chip.label), selected: checked.index === index, selectedColorSet: "invertedLight", tabIndex: "-1" }, chip.label ) ) ) ) ), Spicetify.React.createElement( "div", { className: "search-searchCategory-carousel" }, Spicetify.React.createElement( "button", { className: `search-searchCategory-carouselButton search-searchCategory-carouselButtonLeft`, tabIndex: -1, onClick: () => handleButtonClick("LEFT"), inert: true }, Spicetify.React.createElement("svg", { viewBox: "0 0 16 16", className: "Svg-img-icon-small-textBase", dangerouslySetInnerHTML: { __html: Spicetify.SVGIcons["chevron-left"] } }) ), Spicetify.React.createElement( "button", { className: `search-searchCategory-carouselButton search-searchCategory-carouselButtonRight`, tabIndex: -1, onClick: () => handleButtonClick("RIGHT"), inert: true }, Spicetify.React.createElement("svg", { viewBox: "0 0 16 16", className: "Svg-img-icon-small-textBase", dangerouslySetInnerHTML: { __html: Spicetify.SVGIcons["chevron-right"] } }) ) ) ) ) ); }; const Content = () => { const defaultFilter = sessionStorage.getItem("comfy-settings-filter") ? JSON.parse(sessionStorage.getItem("comfy-settings-filter")) : null; const [filter, setFilter] = Spicetify.React.useState(defaultFilter ?? { index: 0, label: "All" }); Spicetify.React.useEffect(() => { if (startup) { return; } sessionStorage.setItem("comfy-settings-filter", JSON.stringify(filter)); }, [filter]); return Spicetify.React.createElement( "div", { className: "comfy-settings" }, Spicetify.React.createElement(Carousel, { chips: [ { label: "All" }, { label: "Settings" }, { label: "Banner Image" }, { label: "Cover Art" }, { label: "Playbar" }, { label: "Tracklist" }, { label: "Interface" }, { label: "Colorscheme" } ], checked: filter, setChecked: setFilter }), Spicetify.React.createElement(Section, { name: "Colorscheme", filter }, [ { type: Dropdown, name: "Color-Scheme", title: `Color Scheme`, desc: "For faster loadtimes use cli to change color schemes", options: () => { const schemes = Object.keys(getConfig("Color-Schemes")); const decapSchemes = schemes.map(function (x) { return x.toLowerCase(); }); if (!decapSchemes.includes(configScheme.toLowerCase())) { schemes.unshift(configScheme); } return schemes; }, defaultVal: (configScheme = (getConfig("Color-Schemes") && Object.keys(getConfig("Color-Schemes")).find(scheme => scheme.toLowerCase() === configScheme.toLowerCase())) || configScheme), condition: getConfig("Color-Schemes") && !preloadedScheme && !document.querySelector("body > style.marketplaceCSS.marketplaceScheme"), callback: (name, value) => { updateScheme(value); } }, { type: Dropdown, name: `Scheme-Features`, title: `Additional Features`, description: "Extra tweaks to complete specific color schemes", options: ["nord", "nord-flat", "kitty"], callback: (name, value, options, defaultVal) => { waitForDeps( "main", main => { main.classList.remove(...options.map(option => `Comfy-${option}-Snippet`)); if (value !== defaultVal) main.classList.add(`Comfy-${value}-Snippet`); }, true, "getElementById" ); } }, { type: Dropdown, name: "Flatten-Colors", title: "Flatten Theme Colors", desc: "Sets main color to the same color as sidebar", defaultVal: "off", options: ["off", "normal", "reverse"], callback: (name, value, options, defaultVal) => { waitForDeps( "main", main => { main.classList.remove(...options.map(option => `${name}-${option}`)); if (value !== defaultVal) main.classList.add(`${name}-${value}`); }, true, "getElementById" ); } }, { type: Dropdown, name: "Dark-Modals", title: "Modal Colors", desc: "Forces modals to be dark/light, useful for light mode schemes", defaultVal: "light", options: ["light", "dark"], callback: (name, value, options, defaultVal) => { waitForDeps( "main", main => { const customXpui = document.getElementById("/xpui.css"); if (value === defaultVal && customXpui) { customXpui.remove(); main.classList.remove(`Comfy-${name}-Snippet`); } if (value !== defaultVal && !customXpui) { fetch("xpui.css") .then(res => res.text()) .then(text => { const result = text.replace( /(\.encore-dark-theme,\.encore-dark-theme)/g, ".GenericModal__overlay .encore-light-theme,dialog .encore-light-theme,$1" ); const newStyle = document.createElement("style"); newStyle.textContent = result; newStyle.id = "/xpui.css"; document.head.appendChild(newStyle); main.classList.add(`Comfy-${name}-Snippet`); }) .catch(e => console.error(`[Comfy-Error]: ${name}`, e)); } }, true, "getElementById" ); } } ]), Spicetify.React.createElement(Section, { name: "Interface", filter }, [ { type: Input, inputType: "text", name: "App-Title", title: "Application Title", defaultVal: Spicetify.AppTitle?.get(), desc: "Change the title of the application, leave blank to reset", callback: value => { waitForDeps("Spicetify.Platform.UserAPI", async () => { const productState = Spicetify.Platform.UserAPI._product_state || Spicetify.Platform.UserAPI._product_state_service; await productState.delOverridesValues({ keys: ["name"] }); if (value) await productState.putOverridesValues({ pairs: { name: value } }); }); } }, { type: Input, inputType: "number", name: "App-Titlebar-Height", title: "Titlebar Height", defaultVal: Spicetify.Platform.version >= "1.2.46.462" ? "64" : "40", min: "0", condition: Spicetify.Platform.version >= "1.2.32.997", callback: (value, name, defaultVal) => { waitForDeps(["Spicetify.CosmosAsync"], async () => { await Spicetify.CosmosAsync.post("sp://messages/v1/container/control", { type: "update_titlebar", height: `${(value === "0" ? "1" : value) || defaultVal}px` }); document.documentElement.style.setProperty("--comfy-topbar-height", value ? value + "px" : ""); }); }, callbackOverride: true }, { type: Input, inputType: "number", name: "Button-Radius", title: "Button Radius", defaultVal: "8", min: "0", tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("h4", null, "Change how circular buttons are:"), Spicetify.React.createElement("li", null, "Comfy default: 8px"), Spicetify.React.createElement("li", null, "Spotify default: 50px") ), callback: value => document.documentElement.style.setProperty("--button-radius", value ? value + "px" : "") }, { type: SubSection, name: "Topbar-Inside-Titlebar-Snippet", title: "Move Topbar Inside Titlebar", defaultVal: false, condition: Spicetify.Platform.version <= "1.2.46.462" && !document.querySelector(":root .global-nav"), callback: value => { if (document.querySelector(":root .global-nav")) return; waitForDeps( [".Root__top-container", ".main-topBar-container"], elements => { const [container, topbar] = elements; const entryPoint = document.querySelector(".Root__top-bar") ?? document.querySelector(".Root__main-view"); const grid = value ? container : entryPoint; grid.insertBefore(topbar, grid.firstChild); }, true ); }, items: [ { type: Toggle, name: "Collapse-Topbar-Snippet", title: "Collapse List Items", defaultVal: true } ], collapseItems: true }, { type: Toggle, name: "Remove-DJ-Prompt", title: "Remove your DJ prompt", desc: "Hides the prompt 'Click to start listening' in the library", defaultVal: true }, { type: Toggle, name: "Compact-Context-Menu", title: "Compact Context Menu", defaultVal: true }, { type: SubSection, name: "Custom-Font", title: "Custom Font", defaultVal: false, callback: value => { if (!value) { document.documentElement.style.setProperty("--font-family", ""); document.documentElement.style.setProperty("--encore-title-font-stack", ""); document.documentElement.style.setProperty("--encore-body-font-stack", ""); } }, tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement( "div", { style: { // tippy doesnt like loading images height: "375px", width: "242px" } }, Spicetify.React.createElement("img", { src: "https://raw.githubusercontent.com/Tetrax-10/Nord-Spotify/master/assets/font/font-url.png", alt: "preview", style: { height: "300px" } }), Spicetify.React.createElement("h4", null, "Usage:"), Spicetify.React.createElement("li", null, "Font Name (if installed)"), Spicetify.React.createElement("li", null, "URL (Google Fonts)") ) ), items: [ { type: Input, inputType: "text", name: "Font", title: "Font", defaultVal: "Placeholder", callback: value => { let fontFamily = value; if (isValidUrl(value)) { fontFamily = decodeURIComponent(value.match(/family=([^&:]+)/)?.[1]?.replace(/\+/g, " ")); if (!document.getElementById("custom-font")) { const link = document.createElement("link"); link.rel = "preload stylesheet"; link.as = "style"; link.href = value; link.id = "custom-font"; document.head.appendChild(link); } else { document.getElementById("custom-font").href = value; } } document.documentElement.style.setProperty("--font-family", fontFamily); document.documentElement.style.setProperty("--encore-title-font-stack", fontFamily); document.documentElement.style.setProperty("--encore-body-font-stack", fontFamily); } } ] }, { type: SubSection, name: "Home-Header-Snippet", title: "Colorful Home Header", defaultVal: true, callback: value => { if (!value) { waitForDeps( "main", main => { main.classList.remove("Home-Header-Snippet"); document.documentElement.style.setProperty("--home-header-color", ""); }, true, "getElementById" ); } }, items: [ { type: Input, inputType: "text", includePicker: true, name: "Home-Header-Color", title: "Custom Color", defaultVal: "none", tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("li", null, "name (red, blue, (--var), etc)"), Spicetify.React.createElement("li", null, "hex (#000000)"), Spicetify.React.createElement("li", null, "rgb (0, 0, 0)"), Spicetify.React.createElement("li", null, "rgba (0, 0, 0, 1)") ), callback: (value, name) => { waitForDeps( "main", main => { document.documentElement.style.setProperty("--home-header-color", value); if (value === "") { main.classList.remove(name); } else { main.classList.add(name); } }, true, "getElementById" ); } } ], collapseItems: true }, { type: Toggle, name: "Horizontal-pageLinks-Snippet", title: "Horizontal Page Links", defaultVal: false, condition: Spicetify.Platform.version <= "1.2.46.462" && !document.querySelector(":root .global-nav") } ]), Spicetify.React.createElement(Section, { name: "Tracklist", filter }, [ { type: Toggle, name: "Remove-Tracklist-Index", title: "Remove Tracklist Index", desc: "Hides the numbers / count next to songs", defaultVal: true }, { type: Toggle, name: "Remove-Column-Bar-Snippet", title: "Remove Column Bar", desc: "Hides the column bar above tracklist", defaultVal: true, tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement( "div", { style: { // tippy doesnt like loading images height: "120px" } }, Spicetify.React.createElement("img", { src: "https://github.com/Comfy-Themes/Spicetify/blob/main/images/settings/column-bar.png?raw=true", alt: "preview", style: { width: "100%" } }) ) ) }, { type: Toggle, name: "Remove-Tracklist-Gradient-Noise", title: "Remove Gradient Noise", defaultVal: false, desc: "Remove the noise from the gradient", callback: value => { document.documentElement.style.setProperty("--tracklist-gradient-noise", value ? "none" : ""); } }, { type: Input, inputType: "number", name: "Tracklist-Gradient-Height", title: "Gradient Height", defaultVal: "232", min: "0", desc: "Change the height of the gradient (the transparent part of the tracklist)", tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("h4", null, "Set to 0 to disable the gradient!") ), callback: value => document.documentElement.style.setProperty("--tracklist-gradient-height", value ? value + "px" : "") }, { type: Input, inputType: "number", name: "Tracklist-Gradient-Opacity", title: "Gradient Opacity", defaultVal: "0.6", min: "0", max: "1", step: "0.1", desc: "Change the opacity of the gradient (0 -> 1)", tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("h4", null, "Set to 0 for no gradient color!") ), callback: value => document.documentElement.style.setProperty("--tracklist-gradient-opacity", value || "") } ]), Spicetify.React.createElement(Section, { name: "Playbar", filter }, [ { type: Toggle, name: "Custom-Playbar-Snippet", title: "Custom Playbar Layout", defaultVal: true, desc: "Comfy's out of box playbar design" }, { type: Toggle, name: "Playbar-Above-Right-Panel-Snippet", title: "Above Right Panel", desc: "Moves the playbar above the right panel", defaultVal: false, condition: Spicetify.Platform.version <= "1.2.46.462" && !document.querySelector(":root .global-nav"), callback: value => { waitForDeps( ".Root__top-container", topContainer => { const playbar = topContainer.querySelector(".Root__now-playing-bar"); if (value) { const rightbar = topContainer.querySelector(".Root__right-sidebar"); const resizeObserver = new ResizeObserver(entries => { if (getConfig("Playbar-Above-Right-Panel-Snippet")) { for (let entry of entries) { if (entry.target === rightbar) { let newWidth = entry.contentRect.width; if (newWidth == 0) { const localStorageWidth = localStorage.getItem("223ni6f2epqcidhx5etjafeai:panel-width-saved"); if (localStorageWidth) { newWidth = localStorageWidth; } else { newWidth = 420; } } playbar.style.width = `${newWidth}px`; break; } } } else { resizeObserver.disconnect(); } }); resizeObserver.observe(rightbar); } else { playbar.style.width = ""; } }, true ); } }, { type: Toggle, name: "Smooth-Progress-Bar-Snippet", title: "Smooth Progress Bar", desc: "Makes the progress bar ease its movement giving the appearance of a smoother transition", defaultVal: true }, { type: Toggle, name: "Hoverable-Timers-Snippet", title: "Hoverable Playback Timers", defaultVal: false }, { type: Toggle, name: "Remove-Connect-Bar-Snippet", title: "Remove Connect Bar", defaultVal: false }, { type: Toggle, name: "Remove-Progress-Bar-Gradient-Snippet", title: "Remove Progress Bar Gradient", defaultVal: false }, { type: Toggle, name: "Remove-Lyrics-Button-Snippet", title: "Remove Lyrics Button", defaultVal: false } ]), Spicetify.React.createElement(Section, { name: "Cover Art", filter }, [ { type: SubSection, name: "Custom-Cover-Art-Dimensions", title: "Custom Dimensions", defaultVal: false, callback: value => { if (!value) { document.documentElement.style.setProperty("--cover-art-width", ""); document.documentElement.style.setProperty("--cover-art-height", ""); document.documentElement.style.setProperty("--cover-art-radius", ""); document.documentElement.style.setProperty("--cover-art-left", ""); document.documentElement.style.setProperty("--cover-art-bottom", ""); } }, tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("h4", null, "Change the size of the cover art:"), Spicetify.React.createElement("li", null, "Comfy default: (84px, 84px, 8px, 20px)"), Spicetify.React.createElement("li", null, "Spotify default: (56px, 56px, 4px, 0px)"), Spicetify.React.createElement("li", null, "Oblong: (115px, 84px, 15px, 20px)") ), items: [ { type: Input, inputType: "number", name: "Cover-Art-Width", title: "Width", defaultVal: "84px", min: "0", callback: value => document.documentElement.style.setProperty("--cover-art-width", value ? value + "px" : "") }, { type: Input, inputType: "number", name: "Cover-Art-Height", title: "Height", defaultVal: "84px", min: "0", callback: value => document.documentElement.style.setProperty("--cover-art-height", value ? value + "px" : "") }, { type: Input, inputType: "number", name: "Cover-Art-Radius", title: "Border Radius", defaultVal: "8px", min: "0", callback: value => document.documentElement.style.setProperty("--cover-art-radius", value ? value + "px" : "") }, { type: Input, inputType: "number", name: "Cover-Art-Left", title: "Left Margin", defaultVal: "0px", desc: "Change the distance between the cover art and the left of the playbar", callback: value => document.documentElement.style.setProperty("--cover-art-left", value ? value + "px" : "") }, { type: Input, inputType: "number", name: "Cover-Art-Bottom", title: "Bottom Margin", defaultVal: "20px", tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("li", null, "Comfy default: 20px"), Spicetify.React.createElement("li", null, "Spotify default: 0px") ), desc: "Change the distance between the cover art and the bottom of the playbar", callback: value => document.documentElement.style.setProperty("--cover-art-bottom", value ? value + "px" : "") } ] } ]), Spicetify.React.createElement(Section, { name: "Banner Image", filter }, [ { type: SubSection, name: "Header-Background", title: "Header Background", desc: "Adds a translucent background behind header text and images", defaultVal: false, callback: value => { if (!value) { document.documentElement.style.setProperty("--header-opacity", ""); } }, items: [ { type: Input, inputType: "number", name: "Header-Background-Opacity", title: "Opacity", defaultVal: "0.6", callback: value => document.documentElement.style.setProperty("--header-opacity", value ? value : "") } ], collapseItems: false }, { type: SubSection, name: "Banner-Enabled", title: "Custom Banner Images", defaultVal: true, desc: "(all settings in this category will be ignored if disabled)", items: Object.keys(channels).map(channel => ({ type: Toggle, name: channel, title: `${channel.replace("-", " ")} Page`, defaultVal: channels[channel]["enabled"], callback: value => { if (value !== channels[channel]["enabled"]) { channels[channel]["enabled"] = value; updateBanner(); } } })), collapseItems: true }, { type: Toggle, name: "Replace-Existing-Banners", title: "Replace Existing Banners", defaultVal: false, desc: "Replace any existing banners with our own - e.g artist banners, playlist banners, etc.", callback: updateBanner }, { type: Toggle, name: "Prefer-Existing-Image", title: "Prefer Existing Image", defaultVal: false, desc: "If available, use existing images instead of the current playing song - e.g playlist image, album art, etc.", callback: updateBanner }, { type: SubSection, name: "Apple-Music-Gradient-Snippet", title: "Apple Music Gradient", defaultVal: false, callback: value => { if (!value) { document.documentElement.style.setProperty("--gradient-background-image", ""); document.documentElement.style.setProperty("--gradient-blend-mode", ""); document.documentElement.style.setProperty("--gradient-speed", ""); document.documentElement.style.setProperty("--gradient-width", ""); document.documentElement.style.setProperty("--gradient-radius", ""); } }, tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("h4", null, "MacOS Note:"), Spicetify.React.createElement("li", null, "Disable Reduced Motion in System Preferences"), Spicetify.React.createElement("h4", null, "Blur (10x Value):"), Spicetify.React.createElement("li", null, "Recommended: 4px") ), items: [ { type: Toggle, name: "AM-Gradient-Include-Existing-Snippet", title: "Existing Banners", defaultVal: false, desc: "Apply the gradient to existing banners on the page (e.g. artist banners)", callback: updateBanner }, { type: Input, inputType: "text", name: "Gradient-Noise", title: "Noise URL", defaultVal: "none", desc: "Overlays an image below the blur and over the art, can be used for noise", callback: value => document.documentElement.style.setProperty("--gradient-background-image", value ? `url('${value}')` : "") }, { type: Input, inputType: "text", name: "Gradient-Blend", title: "Blend Mode", defaultVal: "luminosity", desc: "'difference' works well with noise", callback: value => document.documentElement.style.setProperty("--gradient-blend-mode", value || "") }, { type: Input, inputType: "number", name: "Gradient-Speed", title: "Speed", defaultVal: "50", min: "0", tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("h4", null, "Seconds per full rotation (360°):"), Spicetify.React.createElement("li", null, "Comfy default: 50") ), callback: value => document.documentElement.style.setProperty("--gradient-speed", value ? value + "s" : "") }, { type: Input, inputType: "number", name: "Gradient-Size", title: "Size", defaultVal: "150", min: "0", tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("h4", null, "Width of circles in relation to viewport (in %)"), Spicetify.React.createElement("li", null, "Comfy default: 150") ), callback: value => document.documentElement.style.setProperty("--gradient-width", value ? value + "%" : "") }, { type: Input, inputType: "number", name: "Gradient-Radius", title: "Radius", desc: "Radius of circles (in %)", defaultVal: "50", min: "0", callback: value => document.documentElement.style.setProperty("--gradient-radius", value ? value + "%" : "") } ], collapseItems: true }, { type: SubSection, name: "Custom-Image", title: "Custom Image", defaultVal: false, callback: updateBanner, items: [ { type: Input, inputType: "text", name: "Custom-Image-URL", title: "URL", defaultVal: "Paste URL here!", tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("h4", null, "Network Images:"), Spicetify.React.createElement("li", null, "Enter any raw image url into text box, e.g. 'https://example.com/image.png'"), Spicetify.React.createElement("h4", null, "Local Images:"), Spicetify.React.createElement("li", null, "Place desired image in 'spotify/Apps/xpui/images'"), Spicetify.React.createElement("li", null, "Enter 'images/image.png' into text box") ), callback: updateBanner } ] }, { type: Input, inputType: "number", name: "Image-Blur", title: "Image Blur", defaultVal: "4", min: "0", tippy: Spicetify.React.createElement( Spicetify.React.Fragment, null, Spicetify.React.createElement("h4", null, "Amount of banner blur in pixels:"), Spicetify.React.createElement("li", null, "Comfy default: 4px") ), callback: value => document.documentElement.style.setProperty("--image-blur", value ? value + "px" : "") } ]), Spicetify.React.createElement(Section, { name: "Settings", filter }, [ { type: Toggle, name: "Version-Analytics", title: "Send Version Analytics", defaultVal: false, desc: "Help us improve by sharing your Spotify version anonymously", callback: async value => { waitForDeps("Spicetify.Platform.UserAPI", async () => { const endpoint = value ? "collect" : "purge"; const user = await Spicetify.Platform.UserAPI.getUser(); fetch(`https://included-exotic-javelin.ngrok-free.app/${endpoint}`, { method: "POST", headers: { "Content-Type": "application/json", "ngrok-skip-browser-warning": "true" }, body: JSON.stringify({ uri: await hashString(user.uri), spotify_version: value ? Spicetify.Platform.version : "" }) }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.warn("[Comfy-Warning]: Failed to send/purge analytics:", error)); }); } }, { type: Row, name: "setting-card setting-button-row", items: [ { type: Button, name: "Import", title: "Import", callback: async (state, setState) => { const paste = await Spicetify.Platform.ClipboardAPI.paste(); try { JSON.parse(paste); setState("Success!"); new Promise(resolve => setTimeout(resolve, 500)).then(() => { localStorage.setItem("comfy:config", paste); location.reload(); }); } catch (e) { setState("Invalid!"); new Promise(resolve => setTimeout(resolve, 2000)).then(() => { setState(state); }); } } }, { type: Button, name: "Export", title: "Export", callback: (state, setState) => { Spicetify.Platform.ClipboardAPI.copy(localStorage.getItem("comfy:config")); setState("Copied!"); new Promise(resolve => setTimeout(resolve, 2000)).then(() => { setState(state); }); } }, { type: Button, name: "Reset", title: "Reset", callback: () => { const settings = document.querySelector(".GenericModal__overlay:has(.comfy-settings)"); Spicetify.ReactDOM.render( Spicetify.React.createElement( Spicetify.ReactComponent.RemoteConfigProvider, { configuration: Spicetify.Platform.RemoteConfiguration }, Spicetify.React.createElement(Dialog, { titleText: "Are you sure?", descriptionText: "This will reset all settings to default!", cancelText: "Cancel", confirmText: "Reset", onOpen: () => { settings.style.zIndex = 0; }, onClose: () => { settings.style.zIndex = 100; }, onConfirm: () => { localStorage.removeItem("comfy:config"); location.reload(); } }) ), document.createElement("div") ); } } ] } ]) ); }; const headerButton = ({ label, link, svg, viewBox }) => { return Spicetify.React.createElement( Spicetify.ReactComponent.TooltipWrapper, { label: label, showDelay: 200 }, Spicetify.React.createElement( "button", { className: "main-trackCreditsModal-closeBtn", onClick: () => window.open(link) }, Spicetify.React.createElement("svg", { width: "18", height: "18", viewBox: viewBox, fill: "currentColor", dangerouslySetInnerHTML: { __html: svg } }) ) ); }; // Settings Button + Modal waitForDeps("Spicetify.Topbar.Button", () => { new Spicetify.Topbar.Button( "Comfy Settings", ``, () => { // reset startup preventions startup = false; preloadedScheme = false; // Trigger Modal + Modal Styling document.getElementById("main").classList.add("Settings-Open"); Spicetify.PopupModal.display({ title: "Comfy Settings", content: Spicetify.React.createElement(Content), isLarge: true }); document.querySelector(".main-trackCreditsModal-closeBtn[aria-label='Close']").addEventListener("click", function () { document.getElementById("main").classList.remove("Settings-Open"); }); document.querySelector("generic-modal").addEventListener("click", event => { if (event.target.className === "GenericModal__overlay") { event.preventDefault(); document.getElementById("main").classList.remove("Settings-Open"); } }); // Social Buttons const header = document.querySelector(".main-trackCreditsModal-header"); const closeButton = document.querySelector(".main-trackCreditsModal-closeBtn"); const container = document.createElement("div"); const socialButtons = [ Spicetify.React.createElement(headerButton, { label: "Join our Discord!", link: "https://discord.gg/rtBQX5D3bD", svg: ``, viewBox: "0 -28.5 256 256" }), Spicetify.React.createElement(headerButton, { label: "Visit our GitHub org!", link: "https://github.com/Comfy-Themes", svg: ``, viewBox: "0 0 16 16" }) ]; Spicetify.ReactDOM.render(socialButtons, container); container.appendChild(closeButton); header.appendChild(container); // Scroll Position const section = document.querySelector(".main-trackCreditsModal-mainSection"); const cache = sessionStorage.getItem("comfy-settings-scroll"); const scrollVal = cache ? cache * (section.scrollHeight - section.clientHeight) : 0; section.scrollTo(null, scrollVal); section.addEventListener("scroll", () => { const scrollTop = section.scrollTop; const scrollHeight = section.scrollHeight - section.clientHeight; const scrollPercentage = scrollTop / scrollHeight; sessionStorage.setItem("comfy-settings-scroll", scrollPercentage); }); }, false, true ); }); // Preloading settings console.debug("[Comfy-Event]: Settings Preload Started"); Spicetify.ReactDOM.render(Spicetify.React.createElement(Content), preloadContainer); Spicetify.ReactDOM.unmountComponentAtNode(preloadContainer); // Functions function getConfig(key) { return config[key] ?? null; } function setConfig(key, value, message, silent) { if (value !== getConfig(key)) { if (!silent) console.debug(`[Comfy-Config]: ${message ?? key + " ="}`, value); config[key] = value; localStorage.setItem("comfy:config", JSON.stringify(config)); } } function isPromise(p) { if (typeof p === "object" && typeof p.then === "function") { return true; } return false; } function isValidUrl(urlString) { try { return Boolean(new URL(urlString)); } catch (e) { return false; } } async function waitForDeps(dependencies, callback, element = false, elementType = "querySelector", timeout = 5000) { return new Promise(resolve => { let allDependenciesLoaded = false; let startTime = Date.now(); async function checkElements() { const check = () => Array.isArray(dependencies) ? dependencies.every(element => document[elementType](element)) : document[elementType](dependencies); if (check()) { callback?.(Array.isArray(dependencies) ? dependencies.map(d => document[elementType](d)) : document[elementType](dependencies)); resolve(); } else { const observer = new MutationObserver(() => { if (check()) { observer.disconnect(); callback?.(Array.isArray(dependencies) ? dependencies.map(d => document[elementType](d)) : document[elementType](dependencies)); resolve(); } }); observer.observe(document.documentElement, { childList: true, subtree: true }); } } async function checkDependencies() { for (const dependency of Array.isArray(dependencies) ? dependencies : [dependencies]) { if (!eval(dependency)) { if (Date.now() - startTime < timeout) { setTimeout(checkDependencies, 10); } else { console.error(`[Comfy-Error]: Dependency Timeout -`, dependencies); resolve(); } return; } } if (!allDependenciesLoaded) { allDependenciesLoaded = true; callback?.(Array.isArray(dependencies) ? dependencies.map(d => eval(d)) : eval(dependencies)); resolve(); } } element ? checkElements() : checkDependencies(); }); } async function updateBanner() { await waitForDeps(["Spicetify.Player.data", "Spicetify.Platform.History.location"]); const pathname = Spicetify.Platform.History.location.pathname; let source; if (getConfig("Apple-Music-Gradient-Snippet") && getConfig("AM-Gradient-Include-Existing-Snippet")) { const [isPlaylist, isArtist] = [Spicetify.URI.isPlaylistV1OrV2(pathname), Spicetify.URI.isArtist(pathname)]; if (isPlaylist || isArtist) { const id = pathname.match(/\/(?:playlist|artist)\/([^/]+)/)[1]; const uri = `spotify:${isPlaylist ? "playlist" : "artist"}:${id}`; const metadata = isPlaylist ? await Spicetify.Platform.PlaylistAPI.getMetadata(uri) : await Spicetify.GraphQL.Request( { name: "queryArtistOverview", operation: "query", sha256Hash: "35648a112beb1794e39ab931365f6ae4a8d45e65396d641eeda94e4003d41497", value: null }, { uri: uri, includePrerelease: true, locale: null } ); source = isPlaylist ? metadata.images[3]?.url : metadata.data.artistUnion.visuals.headerImage?.sources?.[0]?.url; } } if (!source && getConfig("Custom-Image")) { source = getConfig("Custom-Image-URL")?.replace(/"/g, ""); } if (!source && getConfig("Prefer-Existing-Image")) { if (Spicetify.URI.isPlaylistV1OrV2(pathname)) { const uri = `spotify:playlist:${pathname.split("/").pop()}`; const playlist = await Spicetify.Platform.PlaylistAPI.getMetadata(uri); source = playlist.images[0]?.url; } else if (Spicetify.URI.isAlbum(pathname)) { await waitForDeps("Spicetify.CosmosAsync"); const album = await Spicetify.CosmosAsync.get(`https://api.spotify.com/v1/albums/${pathname.split("/").pop()}`); source = album.images[0]?.url; } } source = source ?? Spicetify.Player.data.item?.metadata?.image_xlarge_url ?? Spicetify.Player.data.track.metadata.image_xlarge_url; const validChannel = Object.values(channels).some(channel => channel.enabled && channel.regex.test(pathname)); frame.style.display = validChannel ? "" : "none"; if (getConfig("Banner-Enabled")) { if (!validChannel) { document.getElementById("main").classList.remove("Banner-Enabled"); } else { document.getElementById("main").classList.add("Banner-Enabled"); } } if (document.documentElement.style.getPropertyValue("--image-url") !== `url(${source})`) { console.debug(`[Comfy-Event]: Banner Source = ${source}`); const preloadImage = new Image(); preloadImage.onload = function () { document.documentElement.style.setProperty("--image-url", `url(${source})`); }; preloadImage.src = source; } banner.forEach(image => { image.style.display = source ? "" : "none"; }); } function updateScheme(scheme, message) { const marketplace = document.querySelector("body > style.marketplaceCSS.marketplaceScheme"); const colorSchemes = getConfig("Color-Schemes"); const existingScheme = document.querySelector("style.comfyScheme"); existingScheme?.remove(); if (colorSchemes[scheme] && !marketplace && scheme !== configScheme) { console.debug(`[Comfy-Event]: Scheme ${message ? message : "applied"} - ${scheme}`); scheme = colorSchemes[scheme]; } else { return; } const schemeTag = document.createElement("style"); schemeTag.classList.add("comfyScheme"); let injectStr = ":root {"; const themeIniKeys = Object.keys(scheme); themeIniKeys.forEach(key => { injectStr += `--spice-${key}: #${scheme[key]};`; injectStr += `--spice-rgb-${key}: ${hexToRGB(scheme[key])};`; }); injectStr += "}"; schemeTag.innerHTML = injectStr; document.body.appendChild(schemeTag); } function parseIni(data) { const regex = { section: /^\s*\[\s*([^\]]*)\s*\]\s*$/, param: /^\s*([^=]+?)\s*=\s*(.*?)\s*$/, comment: /^\s*;.*$/ }; const value = {}; let section = null; const lines = data.split(/[\r\n]+/); lines.forEach(function (line) { if (regex.comment.test(line)) { return; } else if (regex.param.test(line)) { if (line.includes("xrdb")) { delete value[section || ""]; section = null; return; } const match = line.match(regex.param); if (match && match.length === 3) { if (section) { if (!value[section]) { value[section] = {}; } value[section][match[1]] = match[2].split(";")[0].trim(); } } } else if (regex.section.test(line)) { const match = line.match(regex.section); if (match) { value[match[1]] = {}; section = match[1]; } } else if (line.length === 0 && section) { section = null; } }); return value; } function hexToRGB(hex) { if (hex.length === 3) { hex = hex .split("") .map(char => char + char) .join(""); } else if (hex.length != 6) { throw "Only 3- or 6-digit hex colours are allowed"; } else if (hex.match(/[^0-9a-f]/i)) { throw "Only hex colours are allowed"; } const aRgbHex = hex.match(/.{1,2}/g); if (!aRgbHex || aRgbHex.length !== 3) { throw "Could not parse hex colour"; } const aRgb = [parseInt(aRgbHex[0], 16), parseInt(aRgbHex[1], 16), parseInt(aRgbHex[2], 16)]; return aRgb; } async function hashString(str) { const encoder = new TextEncoder(); const data = encoder.encode(str); const buffer = await crypto.subtle.digest("SHA-256", data); return Array.from(new Uint8Array(buffer)) .map(b => b.toString(16).padStart(2, "0")) .join(""); } })(); ================================================ FILE: Comfy/user.css ================================================ @import url("https://comfy-themes.github.io/Spicetify/Comfy/app.css"); ================================================ FILE: LICENCE ================================================ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2004 Sam Hocevar Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. ================================================ FILE: README.md ================================================
Preview
Logo

Comfy Spicetify

Stay comfy while listening to music

Report an issueJoin the support serverPreview images

✅ Recommended

  • 🔥 Spicetify: 2.38.5
  • 🟢 Spotify: 1.2.51

  • ### 📥 Automatic Installation --- Windows -> **PowerShell**: ```powershell iwr -useb https://raw.githubusercontent.com/NYRI4/Comfy-spicetify/main/install.ps1 | iex ``` macOS and Linux -> **Bash**: ```bash curl -fsSL https://raw.githubusercontent.com/NYRI4/Comfy-spicetify/main/install.sh | sh ``` ### 📥 Manual Installation --- ### Downloading Comfy. CD into your `Themes` folder in `.spicetify` and run : ```sh git clone https://github.com/Comfy-Themes/Spicetify ``` Rename the folder to `Comfy` and run these commands to apply : ```powershell spicetify config current_theme Comfy spicetify config color_scheme