├── .editorconfig ├── .github └── CODEOWNERS ├── INSTALL.md ├── LICENSE.md ├── README.md ├── SpotifyNoControl.exe ├── assets └── glue-resources │ └── fonts │ ├── GoogleSansDisplayMedium.woff2 │ ├── GoogleSansDisplayRegular.woff2 │ ├── Roboto.woff2 │ └── RobotoMedium.woff2 ├── color.ini ├── omni.js ├── screenshot.png ├── user.css └── windows-shortcut-instruction.png /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Learn how to add code owners here: 2 | # https://help.github.com/en/articles/about-code-owners 3 | 4 | * @birobirobiro 5 | .github/* @jpedroschmitz 6 | *.md @jpedroschmitz 7 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | ### [Spicetify v2](https://github.com/khanhas/spicetify-cli) 2 | 3 | #### Linux and MacOS: 4 | 5 | In **Bash**: 6 | 7 | ```bash 8 | cd "$(dirname "$(spicetify -c)")/Themes" 9 | git clone https://github.com/getomni/spicetify.git omni 10 | cd omni 11 | cp omni.js ~/.config/spicetify/Extensions 12 | spicetify config extensions omni.js 13 | spicetify config current_theme omni color_scheme base 14 | spicetify config inject_css 1 replace_colors 1 overwrite_assets 1 15 | spicetify apply 16 | ``` 17 | 18 | #### Windows 19 | 20 | In **Powershell**: 21 | 22 | ```powershell 23 | cd "$(spicetify -c | Split-Path)\Themes" 24 | git clone https://github.com/getomni/spicetify.git omni 25 | cd omni 26 | Copy-Item omni.js %appdata%\spicetify\Extensions\ 27 | spicetify config extensions omni.js 28 | spicetify config current_theme omni color_scheme base 29 | spicetify config inject_css 1 replace_colors 1 overwrite_assets 1 30 | spicetify apply 31 | ``` 32 | 33 | From Spotify > v1.1.62, in sidebar, they use an adaptive render mechanic to actively show and hide items on scroll. It helps reducing number of items to render, hence there is significant performance boost if you have a large playlists collection. But the drawbacks is that item height is hard-coded, it messes up user interaction when we explicity change, in CSS, playlist item height bigger than original value. So you need to add these 2 lines in Patch section in config file: 34 | 35 | ```ini 36 | [Patch] 37 | xpui.js_find_8008 = ,(\w+=)32, 38 | xpui.js_repl_8008 = ,${1}56, 39 | ``` 40 | 41 | #### Hide Window Controls 42 | 43 | Windows user, please edit your Spotify shortcut and add flag `--transparent-window-controls` after the Spotify.exe: 44 | ![instruction1](./windows-shortcut-instruction.png) 45 | 46 | Alternatively, you can use `SpotifyNoControl.exe`, included in this theme package, to completely remove all windows controls and title menu (three dot at top left corner). Title menu still can be access via Alt key. Closing, minimizing can be done via right click menu at top window region. 47 | `SpotifyNoControl.exe` could be used as Spotify launcher, it opens Spotify and hides controls right after. So you should make a shortcut for it, change icon and add to desktop or start menu. 48 | Moreover, by default, Spotify adjusted sidebar items and profile menu icon to stay out of Windows native controls region. If you decided to use `SpotifyNoControl.exe` from now on, please open `user.css` file and change variable `--os-windows-icon-dodge` value to 0 as instruction to snap icons back to their original position. 49 | 50 | ![nocontrol](https://i.imgur.com/qdZyv1t.png) 51 | 52 | #### How to uninstall 53 | 54 | Remove the omni script with the following commands 55 | 56 | ``` 57 | spicetify config extensions omni.js- 58 | spicetify apply 59 | ``` 60 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Omni Theme 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |
3 | Omni Logo 4 |
5 | Omni for Spicetify v2 6 |
7 |

8 | 9 |

10 | Dark theme for Spicetify v2 11 |

12 | 13 |

14 | PRs welcome! 15 | 16 | License 17 |

18 | 19 |

20 | Info • 21 | Install • 22 | Team • 23 | License 24 |

25 | 26 |

27 | Omni screnshoot for Spicetify 28 |

29 | 30 | ## Info 31 | 32 | With the new versions of Spotify and Spicetify the main branch theme became outdated and doesn't work anymore. Using this version (v2), you can enjoy all Spotify functionalities from new releases using the Omni theme. 33 | 34 | ## Install 35 | 36 | All instructions can be found at [INSTALL.md](./INSTALL.md). 37 | 38 | ## Team 39 | 40 | This theme version (v2) is maintained by the following person(s) and a bunch of [awesome contributors](https://github.com/getomni/spicetify/graphs/contributors). 41 | 42 | | [![Ian Libânio](https://github.com/ianlibanio.png?size=100)](https://github.com/ianlibanio) | 43 | | ------------------------------------------------------------------------------------------- | 44 | | [Ian Libânio](https://github.com/ianlibanio) | 45 | 46 | ## License 47 | 48 | [MIT License](./LICENSE.md) 49 | 50 | --- 51 | 52 | Based on [Dribbblish v2](https://github.com/morpheusthewhite/spicetify-themes/tree/v2/Dribbblish) 53 | -------------------------------------------------------------------------------- /SpotifyNoControl.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getomni/spicetify/253ae45d2cac2dc3d92a43193ea8f6d9e7e1d3aa/SpotifyNoControl.exe -------------------------------------------------------------------------------- /assets/glue-resources/fonts/GoogleSansDisplayMedium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getomni/spicetify/253ae45d2cac2dc3d92a43193ea8f6d9e7e1d3aa/assets/glue-resources/fonts/GoogleSansDisplayMedium.woff2 -------------------------------------------------------------------------------- /assets/glue-resources/fonts/GoogleSansDisplayRegular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getomni/spicetify/253ae45d2cac2dc3d92a43193ea8f6d9e7e1d3aa/assets/glue-resources/fonts/GoogleSansDisplayRegular.woff2 -------------------------------------------------------------------------------- /assets/glue-resources/fonts/Roboto.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getomni/spicetify/253ae45d2cac2dc3d92a43193ea8f6d9e7e1d3aa/assets/glue-resources/fonts/Roboto.woff2 -------------------------------------------------------------------------------- /assets/glue-resources/fonts/RobotoMedium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getomni/spicetify/253ae45d2cac2dc3d92a43193ea8f6d9e7e1d3aa/assets/glue-resources/fonts/RobotoMedium.woff2 -------------------------------------------------------------------------------- /color.ini: -------------------------------------------------------------------------------- 1 | [base] 2 | text = E1E1E6 3 | subtext = E1E1E6 4 | sidebar-text = F7F7FB 5 | main = 191622 6 | sidebar = 191622 7 | player = 191622 8 | card = 191622 9 | shadow = 000000 10 | selected-row = 988BC7 11 | button = 5A4B81 12 | button-active = 988BC7 13 | button-disabled = 5A4B81 14 | tab-active = 5A4B81 15 | notification = 5A4B81 16 | notification-error = E96379 17 | misc = FFFFFF 18 | -------------------------------------------------------------------------------- /omni.js: -------------------------------------------------------------------------------- 1 | // Hide popover message 2 | // document.getElementById("popover-container").style.height = 0; 3 | const DribbblishShared = { 4 | configMenu: new Spicetify.Menu.SubMenu("Dribbblish", []), 5 | rightBigCover: localStorage.getItem("dribs-right-big-cover") === "true", 6 | setRightBigCover: () => { 7 | if (DribbblishShared.rightBigCover) { 8 | document.documentElement.classList.add("right-expanded-cover"); 9 | } else { 10 | document.documentElement.classList.remove("right-expanded-cover"); 11 | } 12 | } 13 | }; 14 | 15 | DribbblishShared.configMenu.register(); 16 | DribbblishShared.configMenu.addItem(new Spicetify.Menu.Item( 17 | "Right expanded cover", 18 | DribbblishShared.rightBigCover, 19 | (self) => { 20 | self.isEnabled = !self.isEnabled; 21 | DribbblishShared.rightBigCover = self.isEnabled; 22 | localStorage.setItem("dribs-right-big-cover", self.isEnabled); 23 | DribbblishShared.setRightBigCover(); 24 | } 25 | )); 26 | DribbblishShared.setRightBigCover(); 27 | 28 | function waitForElement(els, func, timeout = 100) { 29 | const queries = els.map(el => document.querySelector(el)); 30 | if (queries.every(a => a)) { 31 | func(queries); 32 | } else if (timeout > 0) { 33 | setTimeout(waitForElement, 300, els, func, --timeout); 34 | } 35 | } 36 | 37 | waitForElement([ 38 | `.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"]`, 39 | `.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"] li` 40 | ], ([root, firstItem]) => { 41 | const listElem = firstItem.parentElement; 42 | root.classList.add("dribs-playlist-list"); 43 | 44 | /** Replace Playlist name with their pictures */ 45 | function loadPlaylistImage() { 46 | for (const item of listElem.children) { 47 | let link = item.querySelector("a"); 48 | if (!link) continue; 49 | 50 | let [_, app, uid ] = link.pathname.split("/"); 51 | let uri; 52 | if (app === "playlist") { 53 | uri = Spicetify.URI.playlistV2URI(uid); 54 | } else if (app === "folder") { 55 | const base64 = localStorage.getItem("dribbblish:folder-image:" + uid); 56 | let img = link.querySelector("img"); 57 | if (!img) { 58 | img = document.createElement("img"); 59 | img.classList.add("playlist-picture"); 60 | link.prepend(img); 61 | } 62 | img.src = base64 || "/images/tracklist-row-song-fallback.svg"; 63 | continue; 64 | } 65 | 66 | Spicetify.CosmosAsync.get( 67 | `sp://core-playlist/v1/playlist/${uri.toURI()}/metadata`, 68 | { policy: { picture: true } } 69 | ).then(res => { 70 | const meta = res.metadata; 71 | let img = link.querySelector("img"); 72 | if (!img) { 73 | img = document.createElement("img"); 74 | img.classList.add("playlist-picture"); 75 | link.prepend(img); 76 | } 77 | img.src = meta.picture || "/images/tracklist-row-song-fallback.svg"; 78 | }); 79 | } 80 | } 81 | 82 | DribbblishShared.loadPlaylistImage = loadPlaylistImage; 83 | loadPlaylistImage(); 84 | 85 | new MutationObserver(loadPlaylistImage) 86 | .observe(listElem, {childList: true}); 87 | }); 88 | 89 | waitForElement([".Root__main-view"], ([mainView]) => { 90 | const shadow = document.createElement("div"); 91 | shadow.id = "dribbblish-back-shadow"; 92 | mainView.prepend(shadow); 93 | }); 94 | 95 | waitForElement([".main-rootlist-rootlistPlaylistsScrollNode"], (queries) => { 96 | const fade = document.createElement("div"); 97 | fade.id = "dribbblish-sidebar-fade-in"; 98 | queries[0].append(fade); 99 | }); 100 | 101 | waitForElement([ 102 | ".Root__nav-bar .LayoutResizer__input, .Root__nav-bar .LayoutResizer__resize-bar input" 103 | ], ([resizer]) => { 104 | const observer = new MutationObserver(updateVariable); 105 | observer.observe(resizer, { attributes: true, attributeFilter: ["value"]}); 106 | function updateVariable() { 107 | let value = resizer.value; 108 | if (value < 121) { 109 | value = 72; 110 | document.documentElement.classList.add("sidebar-hide-text"); 111 | } else { 112 | document.documentElement.classList.remove("sidebar-hide-text"); 113 | } 114 | document.documentElement.style.setProperty( 115 | "--sidebar-width", value + "px"); 116 | } 117 | updateVariable(); 118 | }); 119 | 120 | waitForElement([".Root__main-view .os-resize-observer-host"], ([resizeHost]) => { 121 | const observer = new ResizeObserver(updateVariable); 122 | observer.observe(resizeHost); 123 | function updateVariable([ event ]) { 124 | document.documentElement.style.setProperty( 125 | "--main-view-width", event.contentRect.width + "px"); 126 | document.documentElement.style.setProperty( 127 | "--main-view-height", event.contentRect.height + "px"); 128 | if (event.contentRect.width < 700) { 129 | document.documentElement.classList.add("minimal-player"); 130 | } else { 131 | document.documentElement.classList.remove("minimal-player"); 132 | } 133 | if (event.contentRect.width < 550) { 134 | document.documentElement.classList.add("extra-minimal-player"); 135 | } else { 136 | document.documentElement.classList.remove("extra-minimal-player"); 137 | } 138 | } 139 | }); 140 | 141 | (function Dribbblish() { 142 | const progBar = document.querySelector(".playback-bar"); 143 | 144 | if (!Spicetify.Player.origin || !progBar) { 145 | setTimeout(Dribbblish, 300); 146 | return; 147 | } 148 | 149 | const tooltip = document.createElement("div"); 150 | tooltip.className = "prog-tooltip"; 151 | progBar.append(tooltip); 152 | 153 | const progKnob = progBar.querySelector(".progress-bar__slider"); 154 | 155 | Spicetify.Player.addEventListener("onprogress", ({ data: e }) => { 156 | const offsetX = progKnob.offsetLeft + progKnob.offsetWidth / 2; 157 | const maxWidth = progBar.offsetWidth; 158 | const curWidth = Spicetify.Player.getProgressPercent() * maxWidth; 159 | const ttWidth = tooltip.offsetWidth / 2; 160 | if (curWidth < ttWidth) { 161 | tooltip.style.left = String(offsetX) + "px"; 162 | } else if (curWidth > maxWidth - ttWidth) { 163 | tooltip.style.left = String(offsetX - ttWidth * 2) + "px"; 164 | } else { 165 | tooltip.style.left = String(offsetX - ttWidth) + "px"; 166 | } 167 | tooltip.innerText = Spicetify.Player.formatTime(e) + " / " + 168 | Spicetify.Player.formatTime(Spicetify.Player.getDuration()); 169 | }); 170 | 171 | const filePickerForm = document.createElement("form"); 172 | filePickerForm.setAttribute("aria-hidden", true); 173 | filePickerForm.innerHTML = ''; 174 | document.body.appendChild(filePickerForm); 175 | /** @type {HTMLInputElement} */ 176 | const filePickerInput = filePickerForm.childNodes[0]; 177 | filePickerInput.accept = [ 178 | "image/jpeg", 179 | "image/apng", 180 | "image/avif", 181 | "image/gif", 182 | "image/png", 183 | "image/svg+xml", 184 | "image/webp" 185 | ].join(","); 186 | 187 | filePickerInput.onchange = () => { 188 | if (!filePickerInput.files.length) return; 189 | 190 | const file = filePickerInput.files[0]; 191 | const reader = new FileReader; 192 | reader.onload = (event) => { 193 | const result = event.target.result; 194 | const id = Spicetify.URI.from(filePickerInput.uri).id; 195 | try { 196 | localStorage.setItem( 197 | "dribbblish:folder-image:" + id, 198 | result 199 | ); 200 | } catch { 201 | Spicetify.showNotification("File too large"); 202 | } 203 | DribbblishShared.loadPlaylistImage?.call(); 204 | } 205 | reader.readAsDataURL(file); 206 | } 207 | 208 | new Spicetify.ContextMenu.Item("Remove folder image", 209 | ([uri]) => { 210 | const id = Spicetify.URI.from(uri).id; 211 | localStorage.removeItem("dribbblish:folder-image:" + id); 212 | DribbblishShared.loadPlaylistImage?.call(); 213 | }, 214 | ([uri]) => Spicetify.URI.isFolder(uri), 215 | "x", 216 | ).register(); 217 | new Spicetify.ContextMenu.Item("Choose folder image", 218 | ([uri]) => { 219 | filePickerInput.uri = uri; 220 | filePickerForm.reset(); 221 | filePickerInput.click(); 222 | }, 223 | ([uri]) => Spicetify.URI.isFolder(uri), 224 | "edit", 225 | ).register(); 226 | })(); 227 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getomni/spicetify/253ae45d2cac2dc3d92a43193ea8f6d9e7e1d3aa/screenshot.png -------------------------------------------------------------------------------- /user.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --bar-height: 70px; 3 | --bar-cover-art-size: 40px; 4 | --main-gap: 10px; 5 | --main-corner-radius: 10px; 6 | --scrollbar-vertical-size: 8px; 7 | --cover-border-radius: 8px; 8 | --os-windows-icon-dodge: 0; 9 | } 10 | 11 | @font-face { 12 | font-family: "Google Sans Display"; 13 | src: url("glue-resources/fonts/GoogleSansDisplayRegular.woff2") format("woff2"); 14 | font-style: normal; 15 | font-weight: 400; 16 | } 17 | 18 | @font-face { 19 | font-family: "Google Sans Display"; 20 | src: url("glue-resources/fonts/GoogleSansDisplayMedium.woff2") format("woff2"); 21 | font-style: normal; 22 | font-weight: 500; 23 | } 24 | 25 | @font-face { 26 | font-family: "Roboto"; 27 | src: url("glue-resources/fonts/Roboto.woff2") format("woff2"); 28 | font-style: normal; 29 | font-weight: 400; 30 | } 31 | 32 | @font-face { 33 | font-family: "Roboto"; 34 | src: url("glue-resources/fonts/RobotoMedium.woff2") format("woff2"); 35 | font-style: normal; 36 | font-weight: 500; 37 | } 38 | 39 | body { 40 | --glue-font-family: "Google Sans Display","Roboto",spotify-circular,spotify-circular-cyrillic,spotify-circular-arabic,spotify-circular-hebrew,Helvetica Neue,helvetica,arial,Hiragino Kaku Gothic Pro,Meiryo,MS Gothic,sans-serif; 41 | --info-font-family: "Roboto",spotify-circular,spotify-circular-cyrillic,spotify-circular-arabic,spotify-circular-hebrew,Helvetica Neue,helvetica,arial,Hiragino Kaku Gothic Pro,Meiryo,MS Gothic,sans-serif; 42 | font-family: var(--glue-font-family); 43 | letter-spacing: normal; 44 | } 45 | 46 | .main-type-mesto, 47 | .main-type-mestoBold, 48 | .main-type-ballad, 49 | .main-type-balladBold, 50 | .main-type-canon { 51 | font-family: var(--info-font-family); 52 | letter-spacing: normal; 53 | } 54 | 55 | .main-type-ballad { 56 | font-weight: 500; 57 | } 58 | 59 | .lyrics-lyricsContainer-LyricsContainer { 60 | --lyrics-color-background: var(--spice-main) !important; 61 | --lyrics-color-inactive: rgba(var(--spice-main), 0.9) !important; 62 | } 63 | 64 | .lyrics-lyricsContainer-LyricsLine { 65 | font-family: var(--glue-font-family); 66 | letter-spacing: -.03em !important; 67 | } 68 | 69 | .main-rootlist-rootlistDivider { 70 | display: none; 71 | } 72 | 73 | input { 74 | background-color: unset !important; 75 | border-bottom: solid 1px var(--spice-text) !important; 76 | border-radius: 0 !important; 77 | padding: 6px 10px 6px 48px; 78 | color: var(--spice-text) !important; 79 | } 80 | 81 | .x-searchInput-searchInputSearchIcon, 82 | .x-searchInput-searchInputClearButton { 83 | color: var(--spice-text) !important; 84 | } 85 | 86 | .main-home-homeHeader, 87 | .x-entityHeader-overlay, 88 | .x-actionBarBackground-background, 89 | .main-actionBarBackground-background, 90 | .main-entityHeader-overlay, 91 | .main-entityHeader-backgroundColor 92 | { 93 | background-color: unset !important; 94 | background-image: unset !important; 95 | } 96 | 97 | .main-playButton-PlayButton.main-playButton-primary { 98 | color: white; 99 | } 100 | 101 | .connect-title, .connect-header { 102 | display: none; 103 | } 104 | 105 | .connect-device-list { 106 | margin: 0px -5px; 107 | } 108 | 109 | /* Remove Topbar background colour */ 110 | .main-topBar-background { 111 | background-color: unset !important; 112 | } 113 | .main-topBar-overlay { 114 | background-color: var(--spice-main); 115 | } 116 | 117 | .main-entityHeader-shadow, 118 | .main-contextMenu-menu, 119 | .connect-device-list-container { 120 | box-shadow: 0 4px 20px #21212130; 121 | } 122 | 123 | .main-trackList-playingIcon { 124 | filter: grayscale(1); 125 | } 126 | 127 | span.artist-artistVerifiedBadge-badge svg > path:first-of-type { 128 | fill: var(--spice-button); 129 | } 130 | span.artist-artistVerifiedBadge-badge svg > path:last-of-type { 131 | fill: var(--spice-text); 132 | } 133 | 134 | /* Full window artist background */ 135 | .main-entityHeader-background.main-entityHeader-gradient { 136 | opacity: 0.3; 137 | } 138 | 139 | .main-entityHeader-container.main-entityHeader-withBackgroundImage, 140 | .main-entityHeader-background, 141 | .main-entityHeader-background.main-entityHeader-overlay:after { 142 | height: 100vh; 143 | } 144 | 145 | .main-entityHeader-withBackgroundImage .main-entityHeader-headerText { 146 | justify-content: center; 147 | } 148 | 149 | .main-entityHeader-container.main-entityHeader-nonWrapped.main-entityHeader-withBackgroundImage { 150 | padding-left: 9%; 151 | } 152 | 153 | .main-entityHeader-background.main-entityHeader-overlay:after { 154 | background-image: linear-gradient(transparent,transparent),linear-gradient(var(--spice-main), var(--spice-main)); 155 | } 156 | 157 | .artist-artistOverview-overview .main-entityHeader-withBackgroundImage h1 { 158 | font-size: 120px !important; 159 | line-height: 120px !important; 160 | } 161 | 162 | /** Hightlight selected playlist */ 163 | .main-rootlist-rootlistItemLink.main-rootlist-rootlistItemLinkActive { 164 | background: var(--spice-button); 165 | border-radius: 4px; 166 | } 167 | 168 | .main-navBar-navBarLinkActive { 169 | background: var(--spice-button); 170 | } 171 | 172 | .main-contextMenu-menu { 173 | background-color: var(--spice-button); 174 | } 175 | 176 | .main-contextMenu-menuHeading, 177 | .main-contextMenu-menuItemButton, 178 | .main-contextMenu-menuItemButton:not(.main-contextMenu-disabled):focus, 179 | .main-contextMenu-menuItemButton:not(.main-contextMenu-disabled):hover { 180 | color: var(--spice-main); 181 | } 182 | 183 | .main-playPauseButton-button { 184 | background-color: var(--spice-button); 185 | color: white; 186 | } 187 | 188 | /** Queue page header */ 189 | .queue-queue-title, 190 | .queue-playHistory-title { 191 | color: var(--spice-text) !important; 192 | } 193 | 194 | /** Artist page */ 195 | .artist-artistOverview-heading { 196 | color: var(--spice-text) !important; 197 | } 198 | .artist-artistAbout-content .artist-artistAbout-cityBlock div, 199 | .artist-artistAbout-content .artist-artistAbout-stats div { 200 | color: var(--spice-text) !important; 201 | } 202 | .artist-artistAbout-content div { 203 | color: var(--spice-text) !important; 204 | } 205 | 206 | /** Cards */ 207 | .main-cardImage-imageWrapper { 208 | background-color: transparent; 209 | box-shadow: unset; 210 | -webkit-box-shadow: unset; 211 | } 212 | 213 | .main-cardImage-imagePlaceholder, .main-cardImage-image { 214 | border-radius: var(--cover-border-radius); 215 | } 216 | 217 | .main-rootlist-rootlistDivider { 218 | background-color: unset; 219 | } 220 | 221 | .main-nowPlayingBar-nowPlayingBar { 222 | height: var(--bar-height); 223 | } 224 | 225 | .Root__top-bar { 226 | border-radius: var(--main-corner-radius) var(--main-corner-radius) 0 0; 227 | } 228 | 229 | .main-topBar-background { 230 | border-radius: var(--main-corner-radius) var(--main-corner-radius) 0 0; 231 | } 232 | 233 | .Root__main-view { 234 | background-color: var(--spice-main); 235 | border-radius: var(--main-corner-radius) var(--main-corner-radius) 0 0; 236 | overflow: hidden; 237 | } 238 | 239 | .main-buddyFeed-buddyFeed { 240 | box-shadow: unset; 241 | -webkit-box-shadow: unset; 242 | z-index: 0; 243 | } 244 | 245 | .main-buddyFeed-headerTitle, 246 | .main-buddyFeed-activityMetadata .main-buddyFeed-username a { 247 | color: var(--spice-sidebar-text); 248 | } 249 | 250 | .main-buddyFeed-activityMetadata .main-buddyFeed-artistAndTrackName a, 251 | .main-buddyFeed-activityMetadata .main-buddyFeed-playbackContextLink, 252 | .main-buddyFeed-activityMetadata .main-buddyFeed-timestamp { 253 | color: rgba(var(--spice-rgb-sidebar-text), 0.8); 254 | } 255 | 256 | .main-buddyFeed-buddyFeedRoot .main-avatar-avatar, 257 | .main-buddyFeed-buddyFeedRoot .main-buddyFeed-overlay { 258 | width: 32px !important; 259 | height: 32px !important; 260 | } 261 | 262 | .main-avatar-avatar.main-avatar-withBadge:after { 263 | box-shadow: 0 0 0 2px var(--spice-sidebar); 264 | background-color: var(--spice-notification); 265 | right: 0; 266 | } 267 | 268 | .Root__now-playing-bar { 269 | border-radius: 0 0 var(--main-corner-radius) var(--main-corner-radius); 270 | background-color: unset; 271 | } 272 | 273 | .main-nowPlayingBar-container { 274 | border-radius: 0 0 var(--main-corner-radius) var(--main-corner-radius); 275 | background-color: unset; 276 | background: radial-gradient(ellipse at right 50% bottom -80px, rgba(var(--spice-rgb-sidebar), 0.55), var(--spice-main) 60%); 277 | border-top: 0; 278 | min-width: 518px; 279 | } 280 | 281 | .main-connectBar-connectBar { 282 | border-radius: 0 0 var(--main-corner-radius) var(--main-corner-radius); 283 | border: 2px solid var(--spice-main); 284 | border-top: 0; 285 | color: var(--spice-sidebar-text); 286 | } 287 | 288 | .Root__nav-bar { 289 | height: 100%; 290 | z-index: 1; 291 | width: var(--sidebar-width) !important; 292 | } 293 | 294 | .main-buddyFeed-buddyFeedRoot { 295 | height: 100%; 296 | } 297 | 298 | .main-buddyFeed-buddyFeedRoot .os-content { 299 | padding-top: 0 !important; 300 | } 301 | 302 | html, 303 | .Root__nav-bar, 304 | .main-buddyFeed-buddyFeed { 305 | background-color: var(--spice-sidebar) !important; 306 | } 307 | 308 | html { 309 | background-position: center; 310 | background-repeat: no-repeat; 311 | } 312 | 313 | .Root__nav-bar .link-subtle, 314 | .main-rootlist-rootlistItemLink:link, 315 | .main-rootlist-rootlistItemLink:visited, 316 | .main-rootlist-rootlistContent span, 317 | .main-navBar-entryPoints span { 318 | color: var(--spice-sidebar-text) 319 | } 320 | 321 | .main-navBar-navBarItem svg { 322 | width: 24px !important; 323 | height: 24px !important; 324 | } 325 | 326 | .main-navBar-navBarItem { 327 | padding: 0 8px; 328 | } 329 | 330 | #spicetify-show-list >* { 331 | padding: 0 8px; 332 | } 333 | 334 | .main-rootlist-statusIcons { 335 | color: var(--spice-sidebar-text); 336 | padding-right: 16px; 337 | } 338 | 339 | .main-rootlist-statusIcons .main-playButton-button { 340 | color: var(--spice-sidebar-text); 341 | } 342 | 343 | .main-rootlist-expandArrow { 344 | position: absolute; 345 | top: 20px; 346 | right: 12px; 347 | width: 16px; 348 | height: 16px; 349 | color: var(--spice-sidebar-text) !important; 350 | background-color: var(--spice-button); 351 | border-radius: 50%; 352 | box-shadow: 0 0 0 2px var(--spice-sidebar); 353 | opacity: 0; 354 | } 355 | 356 | li.GlueDropTarget:hover .main-rootlist-expandArrow { 357 | opacity: 1; 358 | } 359 | 360 | html:not(.sidebar-hide-text) .main-rootlist-expandArrow { 361 | opacity: 1; 362 | } 363 | 364 | .main-rootlist-expandArrow::before { 365 | font-size: 10px; 366 | padding-bottom: 3px; 367 | } 368 | 369 | html.sidebar-hide-text .main-rootlist-expandArrow { 370 | right: 4px; 371 | } 372 | 373 | html.sidebar-hide-text .main-navBar-navBarItem span, 374 | html.sidebar-hide-text .main-rootlist-rootlistContent span, 375 | html.sidebar-hide-text .main-rootlist-rootlistItem span, 376 | html.sidebar-hide-text .main-rootlist-statusIcons, 377 | html.sidebar-hide-text .GlueDropTarget span { 378 | display: none; 379 | } 380 | 381 | .main-rootlist-rootlist { 382 | margin-top: 0; 383 | } 384 | 385 | .Root__nav-bar .os-scrollbar-vertical, 386 | .main-buddyFeed-buddyFeedRoot .os-scrollbar-vertical { 387 | display: none; 388 | } 389 | 390 | /** */ 391 | .main-topBar-historyButtons .main-topBar-button { 392 | background-color: unset; 393 | width: 24px; 394 | height: 24px; 395 | } 396 | 397 | .main-topBar-historyButtons svg { 398 | color: var(--spice-button); 399 | fill: var(--spice-button); 400 | } 401 | 402 | .playback-bar__progress-time, 403 | .main-playbackBarRemainingTime-container { 404 | display: none; 405 | } 406 | 407 | .playback-bar { 408 | position: absolute; 409 | width: var(--main-view-width); 410 | left: var(--sidebar-width); 411 | bottom: calc(var(--main-gap) + var(--bar-height) - 12px / 2); 412 | } 413 | 414 | .Root.is-connectBarVisible .playback-bar { 415 | bottom: calc(var(--main-gap) + var(--bar-height) + 24px - 12px / 2); 416 | } 417 | 418 | .main-nowPlayingWidget-coverArt .cover-art { 419 | width: var(--bar-cover-art-size) !important; 420 | height: var(--bar-cover-art-size) !important; 421 | } 422 | 423 | .player-controls__buttons { 424 | margin-bottom: 0; 425 | width: 192px; 426 | } 427 | 428 | .progress-bar { 429 | --progress-bar-height: 2px; 430 | --fg-color: var(--spice-button); 431 | --bg-color: rgba(var(--spice-rgb-text), .2); 432 | } 433 | 434 | .minimal-player .player-controls__buttons { 435 | width: 120px; 436 | gap: 0px; 437 | } 438 | 439 | .minimal-player .player-controls__left, 440 | .minimal-player .player-controls__right { 441 | --button-size: 16px !important; 442 | gap: 0px; 443 | } 444 | 445 | .minimal-player .volume-bar { 446 | flex: 0 1 70px; 447 | } 448 | .extra-minimal-player .player-controls__buttons { 449 | width: 64px; 450 | } 451 | .extra-minimal-player .main-shuffleButton-button, 452 | .extra-minimal-player .main-repeatButton-button, 453 | .extra-minimal-player .ExtraControls__connect-device-picker, 454 | .extra-minimal-player .volume-bar .progress-bar-wrapper { 455 | display: none; 456 | } 457 | .extra-minimal-player .volume-bar { 458 | flex: 0 0 32px; 459 | } 460 | 461 | .main-trackInfo-name { 462 | font-weight: 500; 463 | } 464 | 465 | .main-topBar-topbarContent .main-playButton-PlayButton { 466 | --size: 35px !important; 467 | } 468 | 469 | .main-entityHeader-image { 470 | border-radius: 5px; 471 | } 472 | 473 | .main-entityHeader-metaDataText, 474 | .main-duration-container { 475 | color: var(--spice-subtext); 476 | } 477 | 478 | /** Sidebar */ 479 | .main-rootlist-rootlist .os-content { 480 | padding: 0 0 8px 0 !important; 481 | } 482 | 483 | .main-rootlist-rootlistDividerContainer { 484 | display: none; 485 | } 486 | 487 | .main-rootlist-rootlistItem a { 488 | align-items: center; 489 | border-radius: 4px; 490 | display: flex; 491 | height: 56px; 492 | padding: 0 12px; 493 | } 494 | 495 | img.playlist-picture { 496 | width: 32px; 497 | height: 32px; 498 | flex: 0 0 32px; 499 | background-size: cover; 500 | background-position: center; 501 | border-radius: 50%; 502 | } 503 | 504 | .main-rootlist-rootlistItem a span { 505 | margin-left: 24px; 506 | } 507 | 508 | .main-rootlist-rootlistItem { 509 | padding-left: calc(var(--indentation)*var(--left-sidebar-item-indentation-width)); 510 | padding-right: 0; 511 | transition: padding-left .5s ease; 512 | } 513 | 514 | html.sidebar-hide-text .main-rootlist-rootlistItem { 515 | padding: 0; 516 | } 517 | 518 | .main-rootlist-dropIndicator { 519 | background: var(--spice-selected-row); 520 | height: 2px; 521 | } 522 | 523 | .main-navBar-navBarLink { 524 | height: 56px; 525 | } 526 | 527 | .main-navBar-navBarLink .icon, 528 | .main-collectionLinkButton-icon, 529 | .main-createPlaylistButton-icon, 530 | .main-collectionLinkButton-icon { 531 | margin-right: 24px; 532 | } 533 | 534 | li.GlueDropTarget { 535 | padding: 0 8px; 536 | } 537 | 538 | /** OS-specific window controls dodge */ 539 | .spotify__os--is-windows .main-navBar-navBar { 540 | padding-top: calc(var(--os-windows-icon-dodge) * 24px); 541 | } 542 | 543 | .spotify__container--is-desktop:not(.fullscreen).spotify__os--is-windows .main-navBar-entryPoints { 544 | padding-top: calc(var(--os-windows-icon-dodge) * 12px + 12px); 545 | } 546 | 547 | .spotify__os--is-windows .main-buddyFeed-header { 548 | padding-top: calc(var(--os-windows-icon-dodge) * 32px); 549 | } 550 | 551 | .spotify__container--is-desktop.spotify__os--is-windows[dir=ltr] .main-topBar-container { 552 | padding-right: calc(var(--os-windows-icon-dodge) * 135px + 32px); 553 | } 554 | 555 | .main-topBar-container { 556 | max-width: unset; 557 | } 558 | 559 | /** Custom elements */ 560 | #dribbblish-sidebar-fade-in { 561 | position: absolute; 562 | bottom: 0; 563 | width: 100%; 564 | height: 15%; 565 | background: linear-gradient(to top, var(--spice-sidebar) 10%, transparent); 566 | z-index: 3; 567 | pointer-events: none; 568 | } 569 | .dribs-playlist-list { 570 | padding-bottom: 56px; 571 | } 572 | #dribbblish-back-shadow { 573 | position: fixed; 574 | width: var(--main-view-width); 575 | height: calc(var(--main-view-height) + var(--bar-height)); 576 | box-shadow: 0 0 10px 3px #0000003b; 577 | border-radius: var(--main-corner-radius); 578 | z-index: 2; 579 | pointer-events: none; 580 | } 581 | 582 | .playback-bar .prog-tooltip { 583 | position: absolute; 584 | min-width: 100px; 585 | width: unset; 586 | height: 25px; 587 | top: -35px; 588 | padding: 0 5px; 589 | border-radius: 4px; 590 | text-align: center; 591 | color: var(--spice-text); 592 | background-color: var(--spice-button); 593 | opacity: 0; 594 | transition: opacity,left 0.2s ease; 595 | } 596 | 597 | .playback-bar:hover .prog-tooltip { 598 | opacity: 1; 599 | } 600 | 601 | /** Rearrange player bar */ 602 | .main-nowPlayingBar-left { 603 | order: 1; 604 | flex: 1; 605 | width: auto; 606 | min-width: 0 !important; 607 | } 608 | 609 | .main-nowPlayingBar-center { 610 | order: 0; 611 | flex: 1; 612 | width: auto; 613 | min-width: unset !important; 614 | } 615 | 616 | .main-nowPlayingBar-right { 617 | order: 2; 618 | flex: 1; 619 | width: auto; 620 | min-width: unset !important; 621 | } 622 | 623 | .main-nowPlayingWidget-nowPlaying { 624 | justify-content: center; 625 | } 626 | 627 | .player-controls { 628 | justify-content: flex-start; 629 | flex-direction: row; 630 | } 631 | 632 | .main-playPauseButton-button { 633 | background-color: transparent; 634 | } 635 | 636 | .main-playPauseButton-button svg { 637 | width: 32px !important; 638 | height: 32px !important; 639 | color: var(--spice-button); 640 | } 641 | 642 | /** Main container */ 643 | .contentSpacing, 644 | .artist-artistDiscography-headerContainer { 645 | padding-left: 64px; 646 | padding-right: 64px; 647 | } 648 | 649 | @media (min-width: 1024px) { 650 | .contentSpacing, 651 | .artist-artistDiscography-headerContainer { 652 | padding-left: 128px; 653 | padding-right: 128px; 654 | } 655 | } 656 | 657 | .main-collectionLinkButton-collectionLinkButton .main-collectionLinkButton-icon, 658 | .main-collectionLinkButton-collectionLinkButton .main-collectionLinkButton-collectionLinkText, 659 | .main-createPlaylistButton-button { 660 | opacity: 1; 661 | } 662 | 663 | .main-likedSongsButton-likedSongsIcon, 664 | .main-yourEpisodesButton-yourEpisodesIcon, 665 | .main-createPlaylistButton-createPlaylistIcon { 666 | background: unset !important; 667 | } 668 | 669 | .main-createPlaylistButton-icon, 670 | .main-collectionLinkButton-icon, 671 | .main-createPlaylistButton-icon { 672 | height: 40px; 673 | } 674 | 675 | .main-likedSongsButton-likedSongsIcon svg, 676 | .main-yourEpisodesButton-yourEpisodesIcon svg, 677 | .main-createPlaylistButton-createPlaylistIcon svg { 678 | fill: var(--spice-sidebar-text); 679 | width: 32px; 680 | height: 32px; 681 | } 682 | .main-yourEpisodesButton-yourEpisodesIcon svg path { 683 | fill: var(--spice-sidebar-text); 684 | } 685 | 686 | /** Grid */ 687 | .Root__top-container { 688 | grid-template-areas: 689 | "nav-bar main-view buddy-feed" 690 | "nav-bar now-playing-bar buddy-feed"; 691 | padding: var(--main-gap) 0; 692 | } 693 | 694 | html:not(.buddyfeed-visible) .Root__top-container { 695 | padding-right: var(--main-gap); 696 | } 697 | 698 | /** Minimal profile button */ 699 | span.main-userWidget-displayName, 700 | .main-userWidget-box svg { 701 | display: none; 702 | } 703 | 704 | /** Sidebar config */ 705 | #dribs-hidden-list { 706 | background-color: rgba(var(--spice-rgb-main), .3); 707 | } 708 | 709 | #dribs-sidebar-config { 710 | position: relative; 711 | width: 100%; 712 | height: 0; 713 | display: flex; 714 | justify-content: space-evenly; 715 | align-items: center; 716 | top: -30px; 717 | left: 0; 718 | } 719 | 720 | #dribs-sidebar-config button { 721 | min-width: 60px; 722 | border-radius: 3px; 723 | background-color: var(--spice-main); 724 | color: var(--spice-text); 725 | border: 1px solid var(--spice-text); 726 | } 727 | #dribs-sidebar-config button:disabled { 728 | color: var(--spice-button-disabled); 729 | } 730 | 731 | .main-navBar-entryPoints { 732 | --left-sidebar-padding-left: 24px; 733 | --left-sidebar-padding-right: 24px; 734 | } 735 | 736 | div.GlueDropTarget.personal-library { 737 | padding: 0 8px; 738 | } 739 | div.GlueDropTarget.personal-library >* { 740 | padding: 0 16px; 741 | height: 56px; 742 | border-radius: 4px; 743 | } 744 | 745 | div.GlueDropTarget.personal-library >*.active { 746 | background: var(--spice-button); 747 | } 748 | 749 | /** Big cover, small cover */ 750 | .main-coverSlotExpanded-container { 751 | position: fixed; 752 | z-index: 2; 753 | width: 250px; 754 | height: 250px; 755 | bottom: calc(var(--main-gap) + var(--bar-height) + 10px); 756 | left: calc(var(--sidebar-width) + 10px); 757 | } 758 | 759 | .Root.is-connectBarVisible .main-coverSlotExpanded-container { 760 | bottom: calc(var(--main-gap) + var(--bar-height) + 24px + 10px); 761 | } 762 | 763 | html.right-expanded-cover .main-coverSlotExpanded-container { 764 | right: calc(var(--main-gap) + 10px); 765 | left: unset; 766 | } 767 | 768 | html.right-expanded-cover.buddyfeed-visible .main-coverSlotExpanded-container { 769 | right: calc(var(--main-gap) + var(--buddy-feed-width) + 10px); 770 | left: unset; 771 | } 772 | 773 | .main-coverSlotExpanded-container img { 774 | border-radius: 4px; 775 | } 776 | 777 | .cover-art { 778 | border-radius: 4px; 779 | } 780 | 781 | .main-nowPlayingWidget-coverExpanded .main-coverSlotCollapsed-container { 782 | opacity: 0; 783 | } 784 | 785 | .main-nowPlayingWidget-coverExpanded { 786 | transform: translateX(-27px); 787 | } 788 | 789 | /** Mini dribbblish */ 790 | .x-categoryCard-CategoryCard > div { 791 | background-color: var(--spice-main); 792 | width: calc(100% - 14px); 793 | height: calc(100% - 6px); 794 | margin: 3px 10px; 795 | border-radius: 5px; 796 | } 797 | 798 | .x-categoryCard-CategoryCard { 799 | height: 100px; 800 | } 801 | 802 | .x-categoryCard-image { 803 | width: 50px !important; 804 | height: 50px !important; 805 | } 806 | 807 | .x-heroCategoryCard-HeroCategoryCard > div { 808 | background-color: var(--spice-main); 809 | width: calc(100% - 20px); 810 | height: calc(100% - 6px); 811 | margin: 3px 16px; 812 | border-radius: 5px; 813 | } 814 | 815 | .main-dropDown-dropDown, 816 | .x-sortBox-sortDropdown { 817 | background-color: rgba(var(--spice-rgb-selected-row), .1) !important; 818 | } 819 | 820 | .connect-device-list-item:focus, 821 | .connect-device-list-item:hover { 822 | background-color: rgba(var(--spice-rgb-selected-row), .3); 823 | } 824 | 825 | 826 | /* 1.1.56 */ 827 | .main-navBar-navBar { 828 | width: var(--sidebar-width) !important; 829 | } 830 | 831 | .main-entityHeader-container.main-entityHeader-nonWrapped { 832 | padding-left: 64px; 833 | padding-right: 64px; 834 | } 835 | 836 | @media (min-width: 1024px) { 837 | .main-entityHeader-container.main-entityHeader-nonWrapped { 838 | padding-left: 128px; 839 | padding-right: 128px; 840 | } 841 | } 842 | 843 | .main-userWidget-dropDownMenu > li > button { 844 | color: rgba(var(--spice-rgb-selected-row), .7); 845 | padding-left: 8px; 846 | text-decoration: none; 847 | } 848 | .main-userWidget-dropDownMenu > li > button:hover, 849 | .main-userWidget-dropDownMenu > li > button:focus { 850 | color: var(--spice-text); 851 | } 852 | 853 | .main-userWidget-dropDownMenu svg { 854 | position: unset; 855 | } 856 | .main-userWidget-dropDownMenu > li svg { 857 | position: absolute; 858 | } 859 | .main-buddyFeed-buddyFeed.main-buddyFeed-buddyFeed-expanded { 860 | z-index: 4; 861 | } 862 | -------------------------------------------------------------------------------- /windows-shortcut-instruction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getomni/spicetify/253ae45d2cac2dc3d92a43193ea8f6d9e7e1d3aa/windows-shortcut-instruction.png --------------------------------------------------------------------------------