/* Responsive layout */
html {
  overflow: hidden; /* removes all scroll bars */
}

body {
  min-height: 100vh;
  width: 100vw;
  position: fixed; /* Prevents nav-bar from being hidden on chrome mobile*/

  margin: 0;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-content: start;

  flex: 1;
}

#nav-bar {
  border-bottom: 1px solid #444c56;
  flex-basis: 100%;
  height: 48px;
  background-color: #1a1a1a;

  color: #F5F7FA;

  display: flex;
  align-items: center;
  padding: 0 12px;
  gap: 12px;

  /* Must be higher than #mstream-player's z-index (1000) because both are
     flex items in related stacking contexts and source order would otherwise
     paint the player above our dropdown. */
  position: relative;
  z-index: 2500;
}

/* mStream logo inside the top bar (left-aligned). Sized to fit the 48px bar. */
.nav-bar-logo {
  display: flex;
  align-items: center;
  height: 100%;
  flex-shrink: 0;
  /* Override #nav-bar div's padding-left: 4px so the logo sits flush */
  padding: 0 !important;
}

.nav-bar-logo svg {
  height: 32px;
  width: auto;
  display: block;
}

.nav-bar-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
}

/* ── "Hide top bar" layout state ──────────────────────────────────────────
   When the user disables the top bar in the Layout panel:
   - #nav-bar is hidden entirely
   - The sidenav logo returns to its original spot (shown again)
   - The sidenav-spacer-bottom expands to push later sidenav children down
   - #content / #sidenav reclaim the 48px the nav bar occupied
   The corresponding rules that show the sidenav-bottom language picker
   live in lang-dropdown.css alongside the dropdown styles themselves.

   The `.side-nav-header.sidenav-logo` selector is used instead of plain
   `.sidenav-logo` because the sidenav logo div has both classes and
   `.side-nav-header { display: flex }` (defined later in this file) would
   otherwise win the specificity tie. */
.side-nav-header.sidenav-logo,
.sidenav-spacer-bottom {
  display: none;
}

body.top-bar-hidden #nav-bar {
  display: none;
}

body.top-bar-hidden .side-nav-header.sidenav-logo {
  display: flex;
}

body.top-bar-hidden .sidenav-spacer-bottom {
  display: block;
  flex-grow: 1;
}

body.top-bar-hidden #content {
  height: calc(var(--vh, 1vh) * 100);
}

@media screen and (min-width: 768px) {
  body.top-bar-hidden #sidenav {
    height: calc(var(--vh, 1vh) * 100);
  }
}

/* Shared style for icon links in the top nav-bar (GitHub, Discord, etc.) */
.nav-icon-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 4px;
  color: #F5F7FA;
  opacity: 0.75;
  transition: opacity 0.15s, background-color 0.15s;
}

.nav-icon-link:hover {
  opacity: 1;
  background-color: rgba(255, 255, 255, 0.08);
}

.nav-icon-link svg {
  fill: currentColor;
  display: block;
}

#media-player-spacer {
  flex: 0 0 10px;
}

.progress {
  padding-top: 10px;
  background-color: #CCC !important;
}

.determinate {
  background-color: #fa832b !important;
}

/* Waveform canvas — overlays the progress bar */
.waveform-canvas {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 2;
  display: none;
}
.progress.wf-active .waveform-canvas { display: block; }
.progress.wf-active .determinate { visibility: hidden; }
.progress.wf-active {
  background-color: transparent !important;
  padding-top: 28px;
  margin-top: 12px;
}
/* Keep time indicators above the waveform */
.progress-wrapper .left,
.progress-wrapper .right {
  position: relative;
  z-index: 3;
}

#media-player-button-bar {
  flex: 0 0 50px;

  display: flex;
  flex-direction: row;
}

#sidenav {
  background-color: #262a33;
  /* background-color: #22272e; */
  border-right: 1px solid #444c56;

  overflow-y: auto;
  user-select: none;
  color: #F5F7FA;
  
  display: flex;
  flex-direction: column;

  font-family: 'Jura', sans-serif;
}

#sidenav-cover {
  background-color: black;
  opacity: 0;
  position: fixed;
  width: 100vw;
  height: 100vh;
  cursor: pointer;
}

#content {
  background-color: #1e2228;
  color: #FFF;
  height: calc(calc(var(--vh, 1vh) * 100) - 48px);

  overflow-y: hidden;
  overflow-x: hidden;
  flex-grow: 1;     /* do not grow   - initial value: 0 */
  flex-shrink: 0;   /* do not shrink - initial value: 1 */
  flex-basis: inherit; /* width/height  - initial value: auto */
}

#content-header {
  display: none;
  width: 100%;
  height: 0px;

  flex-direction: row;
}

#content-header-spacer {
  height:100%;
  display: flex;
  flex-grow: 1;
}

.click-through {
  pointer-events: none;
}

.fade-in {
  animation: fadeIn ease 400ms forwards;
}

.fade-out {
  animation: fadeOut ease 400ms forwards;
}

.menu-in {
  animation: menuOut ease 400ms forwards;
}

.menu-out {
  animation: menuIn ease 400ms forwards;
}

/* On screens that are 600px wide or less, the background color is olive */
@media screen and (max-width: 768px) {
  #sidenav {
    position: fixed;
    height: calc(var(--vh, 1vh) * 100);
    width: 220px;
    z-index: 100000;

    left: -220px;
  }

  #sidenav-cover {
    z-index: 50000;
  }

  #content {
    width: 100%;
    flex-basis: auto;
  }

  #content-header {
    display: flex;
    height: 60px;
  }
}

@keyframes fadeIn {
  0% {
    opacity:0;
  }
  100% {
    opacity:.3;
  }
}

@keyframes fadeOut {
  0% {
    opacity:0.3;
  }
  100% {
    opacity:0;
  }
}

@keyframes menuIn {
  0% {
    left: -220px;
  }
  100% {
    left: 0px;
  }
}

@keyframes menuOut {
  0% {
    left: 0px;
  }
  100% {
    left: -220px;
  }
}

@media screen and (min-width: 768px) {
  #sidenav {
    height: calc(calc(var(--vh, 1vh) * 100) - 48px);
    overflow-y: auto;
    flex-grow: 0;     /* do not grow   - initial value: 0 */
    flex-shrink: 0;   /* do not shrink - initial value: 1 */
    flex-basis: 240px; /* width/height  - initial value: auto */
  }

  #sidenav-cover {
    visibility: hidden;
  }

  .responsive-hide {
    display: none;
  }

  .col-rev {
    flex-direction: column-reverse !important;
  }
}

/* Animated menu button */
/* Shamelessly stolen from: https://codepen.io/ainalem/pen/LJYRxz*/
.ham {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 400ms;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.hamRotate.active {
  transform: rotate(45deg);
}
.hamRotate180.active {
  transform: rotate(180deg);
}
.line {
  fill:none;
  transition: stroke-dasharray 400ms, stroke-dashoffset 400ms;
  stroke:#fff;
  stroke-width:5.5;
  stroke-linecap:round;
}
.ham5 .top {
  stroke-dasharray: 40 82;
}
.ham5 .bottom {
  stroke-dasharray: 40 82;
}
.ham5.active .top {
  stroke-dasharray: 14 82;
  stroke-dashoffset: -72px;
}
.ham5.active .bottom {
  stroke-dasharray: 14 82;
  stroke-dashoffset: -72px;
}


/* Sidenav Stuff */
#sidenav svg {
  fill: #fff;
  height: 100%;
  margin-right: 10px;
  margin-left: 10px;
}

.side-nav-header {
  width: 100%;
  min-height: 40px;
  display: flex;
  align-items: center;
  font-weight: bold;
}

.side-nav-header button {
  background-color: rgb(101, 126, 228);
  border-radius: 3px;
  border: none;
  font-weight: bold;
  font-size: 14px;
  text-align: center;
  color: #FFF;

  width: 100%;
  height: 40px;
  margin: 10px;

  cursor: pointer;
}

.side-nav-header button:hover {
  filter: brightness(105%);
}

.side-nav-item {
  cursor: pointer;
  width: 100%;
  min-height: 35px;

  display: flex;
  align-items: center;
}

.side-nav-item:not(.select):hover {
  background-color: #31353d;
}

.side-nav-spacer {
  width: 100%;
  display: flex;
  flex-grow: 1;
}

.select {
  color: #ffffff;
  background-color: #31353d;
  font-weight: bold;
}

@media screen and (min-width: 600px) {
  .h100-res {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}

@media screen and (max-width: 600px) {
  .container {
    width: 100% !important;
  }

  .col-y {
    padding-left: 0px !important;
  }

  .col-x {
    padding-right: 0px !important;
  }
}

.pointer {
  cursor: pointer;
}

/* Note: maybe move things below this line elsewhere */

.collection-item {
  /* background-color: #22272e !important; */
  background-color: #2d333b !important;
  border-bottom: 1px solid #444c56 !important;
  color: #FFF;

  padding: 0 !important;
  position: relative;
  border-left: 1px solid #444c56 !important;
  border-right: 1px solid #444c56 !important;
}

.collection {
  border: none !important;
  margin: 0 !important;
}

.collection-item:last-child {
  border-bottom: 1px solid #444c56 !important;
}

.collection-item:first-child {
  border-top: 1px solid #444c56 !important;
}

#filelist {
  overflow-y: auto !important;
  margin: 0 !important;
  flex-grow: 1;
  /* background-color: #1a1a1a; */
}

.flex-x {
  display: flex;
  flex-flow: column;
}

.flex2 {
  display: flex;
}

.h1 {
  height: 100%;
}

.row-x {
  margin-bottom: 0px !important;
  min-height: 0;
  width: 100%;
}

.col-x {
  padding-left: 0px !important;
}

.col-y {
  padding-right: 1px !important;
}

.col-z {
  width: 100%;
  max-height: 45px;
  overflow-y: hidden;
  flex-shrink: 0;
}

.row-y {
  margin-bottom: 6px !important;
  width: 100%;
}

.aa-card {
  margin-left: auto !important;
  margin-right: auto !important;
  max-width: 180px !important;
  margin-bottom: 0 !important;
}

.card-image {
  max-height: 180px !important;
}

.data-card {
  margin-right: 20px;
}

.card {
  background-color: #2d333b !important;
}

.row-mod {
  margin-bottom: 0px !important;
}

.pointer {
  cursor: pointer;
}

/* Legacy playing highlight */
.playing {
  background-color: #4a463e !important;
}

/* ── Now Playing Queue ───────────────────────────────────────────────────── */

.np-queue-item {
  display: flex;
  align-items: center;
  padding: 6px 8px;
  gap: 10px;
  border-bottom: 1px solid rgba(255,255,255,.06);
  cursor: pointer;
  transition: background .12s;
}

.np-queue-item:hover {
  background: rgba(255,255,255,.04);
}

.np-queue-active {
  background: rgba(100,126,228,.15) !important;
  border-left: 3px solid #657ee4;
  padding-left: 5px;
}

.np-queue-art {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  object-fit: cover;
  flex-shrink: 0;
}

.np-queue-art-placeholder {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  background: rgba(255,255,255,.05);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.np-queue-info {
  flex: 1;
  min-width: 0;
}

.np-queue-title {
  font-size: 13px;
  font-weight: 500;
  color: #eee;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.3;
}

.np-queue-artist {
  font-size: 11px;
  color: #888;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.3;
  margin-top: 1px;
}

.np-queue-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}

.np-queue-action {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  cursor: pointer;
  transition: background .12s;
}

.np-queue-action:hover {
  background: rgba(255,255,255,.1);
}

.np-queue-remove svg {
  fill: #888;
}

.np-queue-remove:hover svg {
  fill: #e57373;
}

.np-queue-action.popperMenu {
  background-color: transparent;
  border: none;
  float: none;
  min-width: unset !important;
  height: 28px;
  padding: 0;
  font-size: unset;
  border-radius: 50%;
}

.np-queue-action.popperMenu:hover {
  background-color: rgba(255,255,255,.1);
}

.np-queue-action.popperMenu svg path {
  fill: #aaa;
}

.np-queue-action.popperMenu:hover svg path {
  fill: #fff;
}

.aa-card {
  max-width: 220px;
  margin-left: auto;
  margin-right: auto;
}

.playError {
  background-color: lightcoral !important;
}

.aux-button-active{
  fill:rgb(102, 132, 178) !important;
  color: rgb(102, 132, 178) !important;
}

.playlist-text {
  width: calc(100% - 25px);
  display: inline-block;
}

.secondary-content {
  height: 100%;
}

.progress {
  margin-top: 30px;
  padding-top: 11px
}

.no-margin {
  margin: 0;
}

.button-block {
  margin-top: 8px;
  display: flex;
  margin-right: 10px;
}

.button-block-2 {
  margin-top: 4px;
  display: flex;
  margin-right: 10px;
}

.button-block-1 {
  margin-top: 8px;
  width: 180px;
  display: flex;
  margin-left: 10px;
  justify-content: right;
}

.volume {
  width: 100px;
  margin-bottom: 0px;
  margin-top: 7px;
  margin-right: 6px;
}

.margin-lr {
  margin-left: 2px;
  margin-right: 2px;
}

.margin-lr2 {
  margin-left: 6px;
  margin-right: 6px;
}

.progress-wrapper {
  padding-top: 10px;
}

.fixed-action-btn {
  bottom: auto !important;
}

#mstream-player {
  max-width: 1800px;
}

#mstream-player svg {
  fill:#FFF;
  color: #FFF;
}

.flex {
  display: flex;
  flex-wrap: wrap;
}

.dirz, .filez, .playlist-item, .playlistz, .albumz, .artistz {
  width: 100%;
  padding-top: 12px;
  padding-bottom: 12px;
  padding-left: 10px;
  padding-right: 10px;
  cursor: pointer;
}

.song-button-box{
  position: absolute;
  right: 0;
  z-index: 100;
  top: 0;
}

.folder-image{
  height: 20px;
  margin-right: 5px;
}

.music-image{
  min-height: 20px;
  min-width: 20px;
  margin-right: 5px;
}

.item-text {
  vertical-align: top;
}

.songDropdown:hover, .downloadPlaylistSong:hover, .recursiveAddDir:hover, .addFileplaylist:hover {
  background-color: #9E9E9E;
}

.songDropdown, .downloadPlaylistSong, .recursiveAddDir, .addFileplaylist {
  height: 14px;
  background-color: #B5B5B5;
  float: right;
  text-align: center;
  font-size: 12px;
  font-family: "Arial Black", Gadget, sans-serif;
  padding-left: 3px;
  padding-right: 3px;
  cursor: pointer;
}

.songDropdown {
  min-width: 42px !important;
  line-height: 100% !important;
}

#pop-d, #pop-f {
  min-width: 50px;
  background-color: #2a2a2e;
  border-radius: 6px;
  border: 1px solid #444;
  color: #ddd;
  z-index: 100;
  box-shadow: 0 4px 16px rgba(0,0,0,.5);
  overflow: hidden;
}

.pop-playlist {
  padding: 5px 10px;
  border-bottom: 1px solid #444;
  font-size: 11px;
  color: #888;
  text-transform: uppercase;
  letter-spacing: .5px;
}

.pop-list-item {
  padding: 6px 10px;
  cursor: pointer;
  font-size: 13px;
  color: #ddd;
  transition: background .12s;
}

.pop-list-item:hover {
  background-color: rgba(255,255,255,.1);
}

.popperMenu:hover, .downloadDir:hover, .downloadFileplaylist:hover, .fileAddToPlaylist:hover {
  background-color: rgba(255,255,255,.15);
}

.popperMenu, .downloadDir, .downloadFileplaylist, .fileAddToPlaylist {
  min-width: 28px !important;
  height: 14px;
  background-color: rgba(255,255,255,.08);
  float: right;
  text-align: center;
  font-size: 12px;
  font-family: "Arial Black", Gadget, sans-serif;
  border-bottom-left-radius: 3px;
  padding-left: 3px;
  padding-right: 3px;
  border-right: 1px solid rgba(255,255,255,.1);
  cursor: pointer;
  color: #bbb;
}

.song-button-box svg {
  vertical-align: top !important;
  padding-top: 1px;
}

.drag-handle{
  cursor: move;
  float: left;
  padding-right: 6px;
}

.removeSong, .deletePlaylist, .removePlaylistSong{
  cursor: pointer;
  min-width: 28px !important;
  height: 14px;
  background-color: 	rgba(255,0,0, .7);
  float: right;
  text-align: center;
  font-size: 12px;
  font-family: "Arial Black", Gadget, sans-serif;
  opacity: 0.9;
}

.removeSong:hover, .deletePlaylist:hover, .removePlaylistSong:hover{
  opacity: 1;
  background-color: 	rgba(255,0,0, .85);
}

.deletePlaylist, .removePlaylistSong {
  line-height: 100% !important;
  padding-left: 7px;
  padding-right: 7px;
  border-bottom-left-radius: 3px;
}

.downloadPlaylistSong, .recursiveAddDir, .addFileplaylist {
  min-width: 28px;
  border-right: 1px solid #9E9E9E;
}

#pop {
  background: #1a1a1a;
  padding: 3px;
  border-radius: 3px;
  border: 1px solid #262a33;
  z-index: 1000;
}

#mstream-player {
  z-index: 1000;
  background-color: #1e2228;
}

.header-tab{
  z-index: 1000;
  display: flex;
  padding-left: 6px;
}

.grow {
  flex-grow: 1;
}

#playlist-buttons a {
  padding:6px;
  cursor: pointer;
}

#playlist-buttons {
  margin-top: 8px;
}


#playlist-buttons svg {
  fill: #fff;
  opacity: .7;
}

#playlist-buttons svg:hover {
  opacity: 1;
}

.fixed-action-btn {
  z-index: 4000 !important;
}

#rg-pregain-info {
  font-weight: 800;
  font-size: 16px;
  font-family: 'Jura', sans-serif;
  width: 34px;
  transition: opacity 0.25s;
  text-align: right;
}

#rg-status {
  transition: opacity 0.25s;
}

.rpg {
  margin-right: 10px;
  cursor: pointer;
}

.auto-dj {
  cursor: pointer;
  margin-left: 10px;
}

svg {
  fill: #FFF;
}

#directoryName, #search_folders {
  flex: 1 1 auto;
  min-width: 0;
}

#search_folders {
  padding-right: 5px;
  padding-left: 5px;
}

.super-hide {
  display: none !important;
}

#localSearchBar {
  max-height: 20px;
  color: #FFF;
}

.album-art-box{
  height: 50px;
  min-width: 50px;
  margin-right: 10px;
}

.collection-item {
  display: flex;
}

.main-overlay{
  position: absolute;

  padding:0;
  margin:0;

  top:0;
  left:0;

  width: 100%;
  height: 100%;
  background:rgba(0,0,0,1);
  z-index:99999;
  cursor: pointer;
}

.show-fade {
  opacity: 1;
  transition: opacity 400ms;
}

.hide-fade {
  pointer-events: none;
  opacity: 0;
  transition: opacity 400ms;
}

#viz-canvas {
  width: 100%;
  height: 100%;
}

.trans-input {
  max-width: 200px;
}

.browser-panel {
  margin: 12px;
}

.collection .collection-item {
  line-height: normal !important;
}

.flex-center {
  display: flex;
  justify-content: center;
}

.scroll-auto {
  overflow-y: auto !important;
}

#directory_bar {
  min-height: 40px;
  align-items: center;
  justify-content: center;
  flex-wrap: nowrap;
}

#directory_bar > svg {
  flex-shrink: 0;
}

#directory_bar > svg path:not([fill="none"]) {
  fill: #fff;
  transition: fill .15s;
}

#directory_bar > svg:hover path:not([fill="none"]) {
  fill: #999;
}

#directoryName{
  padding-bottom: 3px;
  padding-left: 5px;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  max-height: 100%;
}

.newPlaylistButton {
  margin: 0 auto;
  display: table !important;
  line-height: inherit !important;
}

.recently-added-input {
  max-width: 80px;
  color: #FFF;
}

.hystmodal__window {
  background-color: #2d333b;
  color: #FFF;
}

#new_playlist_name, #share_time, #playlist_name, #search-term {
  color: #FFF;
}

#new_playlist, #save_playlist {
  margin-top: 20px;
}

#share-textarea {
  margin-top: 20px;
  min-height: 60px;
  color: #FFF;
}

.switch label .lever {
  height: 18px !important;
  width: 46px !important;
}

.switch label input[type="checkbox"]:not(:checked) + .lever {
  background-color: #888 !important;
}

.switch label input[type="checkbox"]:checked + .lever::after {
  background-color: #26a69a !important;
}

.switch label .lever::before, .switch label .lever::after {
  width: 24px !important;
  height: 24px !important;
}

.switch label input[type="checkbox"]:checked + .lever::before, .switch label input[type="checkbox"]:checked + .lever::after {
  left: 24px !important;
}

.switch label {
  font-size: 1.2rem;
}

.column-reverse {
  flex-direction: column-reverse;
}

.song-button-box svg {
  fill: #000;
}


.fileplaylistz {
  padding: 10px; }

.upload-progress-bar {
  background-color: rgba(0,0,0,0);
  height: 1px;
}

.upload-progress-inner {
  background-color: skyblue;
  box-shadow: 0px 0px 4px 2px rgba(135, 206, 235,0.91);
  height: 100%;
  position: relative;
  z-index:1000;
}

.m-tab {
  font-size: 22px;
  width:50%;
  cursor: pointer;
  height: 40px;
  background-color: #111;
  margin-top: 5px;
}

.selected-tab {
  border-bottom: 1px solid #FFF;
}

#nav-bar div {
  padding-left: 4px;
}

#autodj-ratings{
  max-width: 120px;
}

select {
  background-color: #2d333b !important;
  color: #FFF;
  cursor: pointer;
}

#ytdl_codec {
  display: block !important;
  width: auto;
  margin-left: auto;
  padding: 4px 8px;
  height: auto;
}

.custom-card-img img {
  max-height: 140px;
}

.card-mod {
  margin-top: 0 !important;
  margin-bottom: 0 !important;
}

.card-mod .card-content {
  padding: 6px !important;
}

.card-meta {
  padding-left: 12px;
}

.flex-end {
  justify-content: flex-end;
}

.block {
  display: block;
}

#flip-me {
  overflow: hidden;
}

.pad-6 {
  padding-left: 6px;
  padding-right: 6px;
}

.mobile-links {
  display: flex;
  justify-content: space-between;
}

.mobile-links a {
  width: 100%;
  max-width: 380px;
}

.mobile-links img {
  width: 100%;
}

.no-margin p {
  margin: 0;
}

/* ── Album Grid ──────────────────────────────────────────────────────────── */

.album-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 16px;
  padding: 16px;
}

.album-grid-card {
  cursor: pointer;
  border-radius: 8px;
  overflow: hidden;
  background: rgba(255,255,255,.04);
  transition: background .15s, transform .1s;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.album-grid-card:hover {
  background: rgba(255,255,255,.08);
}

.album-grid-card:active {
  transform: scale(.97);
}

.album-grid-art {
  width: 100%;
  aspect-ratio: 1;
  background: rgba(255,255,255,.03);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  position: relative;
}

.album-grid-play {
  position: absolute;
  bottom: 6px;
  right: 6px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: rgba(30,215,96,.9);
  color: #000;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .2s, transform .2s, background .15s;
  box-shadow: 0 4px 12px rgba(0,0,0,.4);
  padding: 0;
}

.album-grid-play svg {
  width: 20px;
  height: 20px;
  fill: #000;
  opacity: 1;
}

.album-grid-card:hover .album-grid-play {
  opacity: 1;
  transform: translateY(0);
}

.album-grid-play:hover {
  background: rgba(30,215,96,1);
  transform: scale(1.08);
}

.album-grid-play:active {
  transform: scale(.95);
}

.album-grid-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.album-grid-art svg {
  width: 40%;
  height: 40%;
  opacity: .4;
}

.album-grid-info {
  padding: 8px 10px 10px;
}

.album-grid-name {
  font-size: 13px;
  font-weight: 600;
  color: #eee;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.album-grid-artist {
  font-size: 11px;
  color: #aaa;
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.album-grid-year {
  font-size: 11px;
  color: #888;
  margin-top: 2px;
}

@media (max-width: 480px) {
  .album-grid {
    grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    gap: 10px;
    padding: 10px;
  }
}

.make-white {
  color: #FFF;
}

/* ── Compact progress cards (nav bar — scan + sync) ─────────────────────── */
/* Adapted from webapp/velvet/style.css .spc-* rules with concrete colors
   matching the main UI palette (velvet's CSS variables aren't defined here). */
.spc-wrap {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.spc-card {
  display: flex;
  align-items: center;
  gap: 7px;
  background: #262a33;
  border: 1px solid #444c56;
  border-left: 2px solid #2ecc71;
  border-radius: 4px;
  padding: 4px 10px;
  cursor: default;
  min-width: 180px;
  max-width: 320px;
}
.spc-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #2ecc71;
  flex-shrink: 0;
  animation: spc-pulse 1.4s ease-in-out infinite;
}
@keyframes spc-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
.spc-vpath {
  font-size: 12px;
  font-weight: 700;
  color: #F5F7FA;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 0;
  max-width: 80px;
}
.spc-track {
  flex: 1;
  position: relative;
  height: 4px;
  background: #444c56;
  border-radius: 99px;
  overflow: hidden;
  min-width: 40px;
}
.spc-fill {
  height: 100%;
  background: #2ecc71;
  border-radius: 99px;
  transition: width .8s ease-out;
}
.spc-fill-ind {
  position: absolute;
  inset: 0;
  width: 40%;
  background: linear-gradient(90deg, transparent, rgb(101, 126, 228), transparent);
  animation: spc-shimmer 1.8s ease-in-out infinite;
}
@keyframes spc-shimmer { 0% { transform: translateX(-250%); } 100% { transform: translateX(350%); } }
.spc-pct {
  font-size: 11px;
  font-weight: 700;
  color: #2ecc71;
  white-space: nowrap;
  flex-shrink: 0;
}
.spc-count {
  font-size: 10px;
  color: #F5F7FA;
  white-space: nowrap;
  flex-shrink: 0;
}
/* Enrichment-pass variant: blue accent (vs the scan cards' green) so a
   background pass reads as "working, not scanning". Same blue as the
   indeterminate shimmer above. */
.spc-enrich {
  border-left-color: #657ee4;
}
.spc-enrich .spc-dot {
  background: #657ee4;
}
.spc-enrich .spc-fill {
  background: #657ee4;
}

/* ── Auto-DJ panel ─────────────────────────────────────────────────
   PR-E2: replaces the legacy folder-checkbox layout with a velvet-
   style toggle panel. Sourced from velvet/webapp/style.css with
   colours retuned to alpha's palette (#fa832b accent, dark base).
   ────────────────────────────────────────────────────────────────── */

.autodj-root {
  max-width: 560px;
  margin: 0 auto;
  /* Generous bottom padding: #filelist is the scroller and the panel
     is its only child, so this is the sole source of clearance at the
     scroll end. 32px left the last row grazing the bottom edge once
     the Filters section grew. */
  padding: 16px 12px 56px;
  color: #F5F7FA;
}

.autodj-hero {
  text-align: center;
  margin-bottom: 24px;
}
.autodj-hero .autodj-icon {
  font-size: 40px;
  line-height: 1;
  margin-bottom: 8px;
}
.autodj-hero h2 {
  font-size: 22px;
  font-weight: 600;
  margin: 0 0 4px;
}
.autodj-hero-desc {
  font-size: 13px;
  color: #b8bcc6;
  margin: 0;
}

/* Big primary toggle button. On = orange filled, Off = outlined.
   Reuses Materialize's `.btn` resets but overrides the colour/size
   to make it the clear primary action of the panel. */
.autodj-toggle {
  display: block;
  width: 100%;
  margin: 16px 0 8px;
  padding: 14px 20px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .4px;
  text-transform: uppercase;
  background: transparent;
  border: 2px solid #fa832b;
  border-radius: 8px;
  color: #fa832b;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.autodj-toggle:hover,
.autodj-toggle.on {
  background: #fa832b;
  color: #111;
}

.autodj-status {
  text-align: center;
  font-size: 12px;
  color: #b8bcc6;
  margin-bottom: 24px;
  min-height: 16px;
}
.autodj-status.on { color: #fa832b; }

/* Settings card */
.autodj-opts {
  background: #262a33;
  border: 1px solid #444c56;
  border-radius: 8px;
  /* Extra bottom padding so the last row's controls aren't flush
     against the card border — the top gets its air from the first
     section heading's own margin. */
  padding: 4px 16px 12px;
}
.autodj-section-heading {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: #b8bcc6;
  margin: 16px 0 8px;
  padding-top: 12px;
  border-top: 1px solid #444c56;
}
.autodj-section-heading:first-of-type {
  border-top: none;
  padding-top: 0;
}

.autodj-opt-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid #383c47;
  gap: 16px;
}
.autodj-opt-row:last-child { border-bottom: none; }

.autodj-opt-row.autodj-opt-col {
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
}

.autodj-opt-row.autodj-opt-disabled .autodj-opt-label,
.autodj-opt-row.autodj-opt-disabled .autodj-opt-hint {
  opacity: 0.45;
}

.autodj-opt-label {
  font-size: 14px;
  font-weight: 500;
  color: #F5F7FA;
}
.autodj-opt-hint {
  font-size: 12px;
  color: #8c919a;
  margin-top: 2px;
  line-height: 1.4;
}
.autodj-opt-hint em {
  font-style: italic;
  color: #b8bcc6;
}

/* Native select restyled to fit the dark card */
.autodj-select {
  background: #1a1d23;
  color: #F5F7FA;
  border: 1px solid #444c56;
  border-radius: 4px;
  padding: 6px 10px;
  font-size: 14px;
  cursor: pointer;
  min-width: 100px;
}
.autodj-select:focus {
  outline: none;
  border-color: #fa832b;
}

/* Vpath pills — pill-shaped buttons, click to toggle inclusion. */
.dj-vpath-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.dj-vpath-pill {
  appearance: none;
  background: #1a1d23;
  color: #b8bcc6;
  border: 1px solid #444c56;
  border-radius: 14px;
  padding: 5px 12px;
  font-size: 12px;
  cursor: pointer;
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}
.dj-vpath-pill:hover {
  background: #2a2e38;
  color: #F5F7FA;
}
.dj-vpath-pill.on {
  background: #fa832b;
  border-color: #fa832b;
  color: #111;
}

/* Toggle switch — lifted from velvet/webapp/style.css:1369-1374,
   recoloured for alpha's orange accent.
   Markup: <label class="toggle-sw"><input type="checkbox"><span class="toggle-sw-track"><span class="toggle-sw-thumb"></span></span></label> */
.toggle-sw {
  position: relative;
  display: inline-flex;
  cursor: pointer;
  flex-shrink: 0;
}
.toggle-sw input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
/* Specificity bumped from `.toggle-sw-track` (single class) to
   `.toggle-sw input[type="checkbox"] + .toggle-sw-track` (two
   classes + one attribute) to beat Materialize's
   `[type="checkbox"] + span:not(.lever)` rule (two attributes +
   one type). materialize.css loads AFTER spa.css in the document
   head, so a tied-specificity contest goes to Materialize by
   source order — without the bump our height/padding/font-size
   get overridden by Materialize defaults intended for plain
   checkbox-and-label markup. */
.toggle-sw input[type="checkbox"] + .toggle-sw-track {
  width: 40px;
  height: 22px;
  border-radius: 11px;
  background: #444c56;
  transition: background-color .18s;
  position: relative;
  padding: 0;
  line-height: normal;
  font-size: 0;
  display: inline-block;
  cursor: pointer;
}
.toggle-sw input:checked ~ .toggle-sw-track {
  background: #fa832b;
}
.toggle-sw input:disabled ~ .toggle-sw-track {
  opacity: 0.4;
  cursor: not-allowed;
}
/* Suppress Materialize's checkbox decorations bleeding onto the
   .toggle-sw-track <span>:
   • `[type="checkbox"]:not(.filled-in) + span:not(.lever)::after`
     is an 18×18 grey border box (hidden via scale(0), but still
     allocates a stacking context).
   • `[type="checkbox"]:checked + span:not(.lever)::before` is a
     rotated-border "tick" mark drawn in teal #26a69a — visible as
     a diagonal slash crossing the orange pill in the ON state.
   We kill both pseudo-elements via `content: none`. The track's
   own visual (background + .toggle-sw-thumb child) is unchanged. */
.toggle-sw input[type="checkbox"] + .toggle-sw-track::before,
.toggle-sw input[type="checkbox"] + .toggle-sw-track::after {
  content: none;
}
.toggle-sw-thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  transition: transform .18s;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
.toggle-sw input:checked ~ .toggle-sw-track .toggle-sw-thumb {
  transform: translateX(18px);
}
/* The native input is opacity:0 (the visible affordance is the track
   sibling), so keyboard focus would otherwise have NO indicator.
   Mirror the focus ring onto the track instead. */
.toggle-sw input:focus-visible ~ .toggle-sw-track {
  outline: 2px solid #fa832b;
  outline-offset: 2px;
}
/* Same treatment for the vpath pills + slider — give keyboard
   users a visible focus indicator without changing mouse-hover UX. */
.dj-vpath-pill:focus-visible,
.autodj-slider:focus-visible,
.autodj-toggle:focus-visible {
  outline: 2px solid #fa832b;
  outline-offset: 2px;
}

/* BPM tolerance slider — native range input restyled to fit the card. */
.autodj-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 140px;
  height: 4px;
  background: #444c56;
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}
.autodj-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fa832b;
  border: none;
  cursor: pointer;
}
.autodj-slider::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fa832b;
  border: none;
  cursor: pointer;
}

/* Keyword filter — toggle row sits across the top, tag chips and
   the text input stack below it (the parent `.autodj-opt-col`
   already gives us the column layout). Chips reuse the vpath-pill
   shape but with a built-in × button. */
.dj-filter-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
}
.dj-filter-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
  min-height: 0; /* collapses cleanly when empty so spacing isn't weird */
}
.dj-filter-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: #1a1d23;
  border: 1px solid #444c56;
  border-radius: 14px;
  padding: 4px 4px 4px 12px;
  font-size: 12px;
  color: #b8bcc6;
}
.dj-filter-tag-rm {
  appearance: none;
  background: transparent;
  border: none;
  color: #b8bcc6;
  cursor: pointer;
  padding: 0 6px;
  font-size: 14px;
  line-height: 1;
  border-radius: 50%;
  transition: background-color .12s ease, color .12s ease;
}
.dj-filter-tag-rm:hover {
  background: #fa832b;
  color: #111;
}
.dj-filter-tag-rm:focus-visible {
  outline: 2px solid #fa832b;
  outline-offset: 1px;
}
.dj-filter-input {
  width: 100%;
  margin-top: 8px;
  background: #1a1d23;
  color: #F5F7FA;
  border: 1px solid #444c56;
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 13px;
  box-sizing: border-box;
}
.dj-filter-input:focus-visible {
  outline: 2px solid #fa832b;
  outline-offset: 0;
  border-color: #fa832b;
}
.dj-filter-input:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Genre filter — segmented mode toggle (whitelist/blacklist) and
   suggestion dropdown wrapper. Reuses .dj-filter-* for the chip
   list + outer input field; the additions below are limited to
   the two new pieces. */

.dj-genre-mode {
  display: inline-flex;
  margin-top: 6px;
  border: 1px solid #444c56;
  border-radius: 6px;
  overflow: hidden;
  background: #1a1d23;
  align-self: flex-start;  /* don't stretch full width on the column flex */
}
.dj-genre-mode-btn {
  appearance: none;
  background: transparent;
  border: none;
  color: #b8bcc6;
  cursor: pointer;
  font-size: 12px;
  padding: 4px 12px;
  line-height: 1.4;
  transition: background-color .12s ease, color .12s ease;
}
.dj-genre-mode-btn + .dj-genre-mode-btn {
  border-left: 1px solid #444c56;
}
.dj-genre-mode-btn[aria-pressed="true"] {
  background: #fa832b;
  color: #111;
}
.dj-genre-mode-btn:hover:not([aria-pressed="true"]):not(:disabled) {
  background: #2a2f37;
}
.dj-genre-mode-btn:focus-visible {
  outline: 2px solid #fa832b;
  outline-offset: -2px;
}
.dj-genre-mode-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Anchor for the suggestion dropdown — keep it relative so the
   absolutely-positioned panel sticks to the input. */
.dj-genre-combo {
  position: relative;
}
.dj-genre-suggest {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 2px;
  max-height: 240px;
  overflow-y: auto;
  z-index: 5;
  background: #1a1d23;
  border: 1px solid #444c56;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.4);
}
.dj-genre-suggest[hidden] { display: none; }
.dj-genre-suggest-row {
  padding: 6px 10px;
  font-size: 13px;
  color: #b8bcc6;
  cursor: pointer;
}
.dj-genre-suggest-row:hover,
.dj-genre-suggest-row[aria-selected="true"] {
  background: #fa832b;
  color: #111;
}
.dj-genre-suggest-empty,
.dj-genre-suggest-more {
  padding: 6px 10px;
  font-size: 12px;
  color: #8a8f99;
  font-style: italic;
}

/* Track-length window — two minute fields side by side plus an
   "include unknown length" checkbox. Reuses .dj-filter-input for the
   field chrome; the additions below are the two-up layout, the
   per-field caption, and the checkbox row. */
.dj-duration-inputs {
  display: flex;
  gap: 12px;
  width: 100%;
}
.dj-duration-field {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-width: 0;
}
.dj-duration-field-label {
  font-size: 12px;
  color: #8c919a;
}
/* .dj-filter-input carries margin-top for the stacked keyword/genre
   layout; here the caption above already provides the gap. */
.dj-duration-num {
  margin-top: 4px;
}
/* Hide the spinner arrows — cramped at this width, and with
   step="any" they'd step by a meaningless 1-minute default. */
.dj-duration-num::-webkit-inner-spin-button,
.dj-duration-num::-webkit-outer-spin-button {
  appearance: none;
  margin: 0;
}
.dj-duration-num {
  -moz-appearance: textfield;
}

/* Songs-per-fetch — a short numeric field on the right of its row,
   dressed as .autodj-select so the two "how much" controls at the top
   of the panel match. Native spinners stay: step=1 is meaningful here. */
.dj-limit-num {
  width: 5.5em;
  min-width: 0;
  text-align: center;
  cursor: text;
}
/* Unknown-length row — same shape as .dj-filter-head (caption left,
   .toggle-sw switch right) so it reads as one of the panel's toggles
   rather than a stray control. The switch itself needs no rules here;
   .toggle-sw already handles sizing and the Materialize suppression. */
.dj-duration-unknown {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-top: 12px;
  width: 100%;
}
.dj-duration-unknown-label {
  font-size: 14px;
  font-weight: 500;
  color: #F5F7FA;
}

/* Now-playing BPM/key pills — sit alongside the existing metadata
   card "Year:" line. Compact pill row that only renders when at
   least one of bpm / musical-key is non-null (controlled by
   v-if in the template). */
.np-bpm-key-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
  flex-wrap: wrap;
}
.np-bpm-pill,
.np-key-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  background: #1a1d23;
  border: 1px solid #444c56;
  color: #b8bcc6;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .2px;
  white-space: nowrap;
}
.np-bpm-pill { color: #fa832b; }
.np-key-pill { color: #b8bcc6; }


/* ── Discover panel ──────────────────────────────────────────────────────
   Model-powered "sounds like" suggestions anchored to the bottom of the
   Now Playing column. Design intent: reads as a natural continuation of
   the queue ("what could come next"), not a separate app — same dark
   card palette as the queue rows (#1a1d23 / #444c56 / #b8bcc6), player
   blue (#657ee4) as the single accent. The vertical match bar on each
   row is a level-meter metaphor: fuller = closer match. */
.discover-panel {
  flex-shrink: 0;
  border-top: 1px solid #2c313a;
  background: #15171c;
  /* 60% (was 45%): the "From the network" section shares this budget with
     the local list; content-sized below the cap, so short panels are
     unaffected. */
  max-height: 60%;
  display: flex;
  flex-direction: column;
}
.discover-header {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px 7px 14px;
  color: #b8bcc6;
  flex-shrink: 0;
}
.discover-header:hover { background: #1a1d23; }
.discover-icon { color: #657ee4; flex-shrink: 0; }
.discover-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: #dfe3ea;
}
.discover-sub {
  font-size: 11.5px;
  font-style: italic;
  color: #6f7683;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.discover-chevron {
  color: #6f7683;
  transition: transform .18s;
  flex-shrink: 0;
}
.discover-chevron-open { transform: rotate(180deg); }
/* The body never scrolls as a whole — the artists strip and footer stay
   pinned and visible; only the song list (.discover-rows) scrolls. */
.discover-body {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 0 0 6px 0;
  /* Backstop only: when the panel cap is smaller than the sections'
     minimums (tiny viewports), scroll the whole body rather than paint
     rows over the footer/player bar. Invisible when content fits. */
  overflow-y: auto;
}
.discover-rows {
  overflow-y: auto;
  /* Never let pinned siblings (artists strip, network section, footer)
     crush the song list to nothing — always keep ~1.5 rows visible. */
  min-height: 58px;
  flex: 1 1 auto;
}
.discover-hint {
  padding: 6px 14px 10px 14px;
  font-size: 12px;
  font-style: italic;
  color: #6f7683;
}
.discover-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 14px 4px 12px;
  line-height: 1.3;
}
.discover-row:hover { background: #1e222a; }
.discover-match {
  width: 4px;
  height: 26px;
  border-radius: 2px;
  background: #262b33;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  flex-shrink: 0;
  overflow: hidden;
}
.discover-match-fill {
  width: 100%;
  border-radius: 2px;
  background: linear-gradient(to top, #657ee4, #8ea0f0);
}
.discover-row-info { min-width: 0; flex-grow: 1; }
.discover-row-title {
  font-size: 12.5px;
  color: #dfe3ea;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.discover-row-sub {
  font-size: 11px;
  color: #8a919e;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.discover-row-tags { color: #6f7683; }
.discover-add {
  color: #657ee4;
  opacity: 0;
  transition: opacity .12s;
  flex-shrink: 0;
  display: flex;
  align-items: center;
}
.discover-row:hover .discover-add { opacity: 1; }
.discover-footer {
  display: flex;
  align-items: center;
  padding: 3px 14px 2px 26px;
  flex-shrink: 0;
}
.discover-queue-all {
  font-size: 11.5px;
  font-weight: 600;
  color: #657ee4;
}
.discover-queue-all:hover { color: #8ea0f0; }
.discover-powered {
  font-size: 10px;
  font-style: italic;
  color: #4d535e;
  letter-spacing: .3px;
}
.discover-artists {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  flex-shrink: 0;
  padding: 6px 14px 4px 14px;
  border-top: 1px solid #21252d;
  margin-top: 4px;
}
.discover-artists-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: #6f7683;
  margin-right: 2px;
}
.discover-artist-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border-radius: 11px;
  background: #1a1d23;
  border: 1px solid #444c56;
  font-size: 11.5px;
  color: #dfe3ea;
}
.discover-artist-chip:hover { border-color: #657ee4; }
.discover-artist-name:hover { color: #8ea0f0; }
.discover-artist-tag {
  font-size: 10px;
  color: #6f7683;
  border-left: 1px solid #444c56;
  padding-left: 6px;
}
.discover-artist-play { color: #657ee4; }
.discover-artist-play:hover { color: #8ea0f0; }
/* "From the network" — same row anatomy as local results, but visually
   marked as leads (teal match bar + peer name where genre tags would be)
   since these tracks aren't in the library and can't be queued. */
.discover-network {
  /* Deterministically bounded: at most ~3 lead rows visible (the inner
     list scrolls for the rest), so it can never starve the local song
     list of panel height — local results are playable, these are leads. */
  flex-shrink: 0;
  border-top: 1px solid #21252d;
  margin-top: 4px;
}
.discover-network .discover-rows { min-height: 0; max-height: 116px; }
.discover-network-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 14px 2px 14px;
}
.discover-network-toggle {
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: none;
  font-weight: 600;
  color: #6f7683;
  padding: 1px 8px;
  border-radius: 9px;
  border: 1px solid #444c56;
}
.discover-network-toggle:hover { border-color: #4fb8a8; color: #dfe3ea; }
.discover-network-toggle-on {
  color: #0f1216;
  background: #4fb8a8;
  border-color: #4fb8a8;
}
.discover-match-fill-p2p { background: #4fb8a8; }
.discover-mb-link { color: #6f7683; }
.discover-mb-link:hover { color: #4fb8a8; }
/* "From your peers" — federation leads. Same anatomy as the network
   section; the amber match bar + peer name mark rows as coming from a
   PAIRED server (playable once the federation stream proxy lands). */
.discover-match-fill-fed { background: #d9a441; }
.discover-peers .discover-network-toggle:hover { border-color: #d9a441; }
.discover-peers .discover-network-toggle-on { background: #d9a441; border-color: #d9a441; color: #0f1216; }
.discover-peers .discover-mb-link:hover { color: #d9a441; }
/* Slim scrollbar for the song list (matches the app's dark chrome
   instead of the OS default). */
.discover-rows::-webkit-scrollbar { width: 6px; }
.discover-rows::-webkit-scrollbar-track { background: transparent; }
.discover-rows::-webkit-scrollbar-thumb { background: #444c56; border-radius: 3px; }
/* "Flip player" layout: col-rev reverses #flip-me (desktop-only, matching
   the media query that defines .col-rev), which would throw the panel to
   the TOP of the queue column. In column-reverse the first-ordered item
   renders at the bottom, so pin the panel there — and keep the moveMeta
   metadata card below it, hugging the player bar like it was designed to. */
@media screen and (min-width: 768px) {
  #flip-me.col-rev .discover-panel { order: -1; }
  #flip-me.col-rev .data-card { order: -2; }
}
.discover-footer { border-top: 1px solid #21252d; margin-top: 4px; padding-top: 5px; }

/* ── Sonic Path panel (side-nav view) ───────────────────────────────── */
.spath-panel { max-width: 640px; padding: 14px 16px; }
.spath-hint { font-size: 12.5px; opacity: 0.6; margin-bottom: 16px; }
.spath-context { font-size: 14px; font-weight: 600; color: #9ad; margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spath-arrow-inline { opacity: 0.5; font-weight: 400; }
/* Compound selector: .spath-btn (defined later in this sheet) sets the
   generic button color, so the reset tint needs the extra specificity. */
.spath-btn.spath-startover { margin-left: auto; color: #f28b82; border-color: rgba(242,139,130,0.45); }
.spath-btn.spath-startover:hover { background: rgba(242,139,130,0.12); color: #ffa39b; }
/* Stacked start-over-end with a downward arrow between — reads like the
   journey it builds. */
.spath-fields { display: flex; flex-direction: column; align-items: stretch; gap: 8px; max-width: 420px; }
.spath-arrow { align-self: center; font-size: 20px; line-height: 1; opacity: 0.45; }
.spath-field { min-width: 0; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.09); border-radius: 6px; padding: 10px 12px; }
.spath-song { min-height: 34px; display: flex; flex-direction: column; justify-content: center; margin: 6px 0 8px; }
.spath-song-title { font-size: 13.5px; font-weight: 600; color: #9ad; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spath-song-artist { font-size: 11.5px; opacity: 0.65; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spath-notset { font-size: 12.5px; opacity: 0.4; font-style: italic; }
.spath-chosen { display: flex; align-items: center; gap: 10px; min-height: 52px; }
.spath-art { width: 44px; height: 44px; border-radius: 4px; object-fit: cover; flex: 0 0 auto; }
.spath-art-placeholder { display: flex; align-items: center; justify-content: center; background: rgba(255,255,255,0.07); }
.spath-row-art { width: 34px; height: 34px; border-radius: 4px; object-fit: cover; flex: 0 0 auto; align-self: center; }
.spath-chosen-info { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.spath-clear { flex: 0 0 auto; font-size: 13px; opacity: 0.55; padding: 4px 6px; }
.spath-clear:hover { opacity: 1; }
.spath-field-buttons { display: flex; gap: 6px; flex-wrap: wrap; }
.spath-btn { font-size: 12px; padding: 5px 10px; color: #ddd; background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.14); border-radius: 4px; cursor: pointer; }
.spath-btn:hover { background: rgba(255,255,255,0.12); }
.spath-btn:disabled { opacity: 0.35; cursor: default; }
.spath-btn-primary { background: #33507a; border-color: #46679a; }
.spath-btn-primary:hover:not(:disabled) { background: #3e619c; }
.spath-length-row { display: flex; align-items: center; gap: 10px; margin: 16px 0 4px; }
.spath-length-row input[type="range"] { flex: 1 1 0; max-width: 280px; }
.spath-length-value { font-size: 13px; font-weight: 700; color: #9ad; min-width: 2ch; text-align: center; }
.spath-build { margin: 10px 0 14px; padding: 7px 18px; }
.spath-rows { max-width: 560px; }
.discover-path-seed .discover-row-title { color: #9ad; font-weight: 600; }
/* Actions lead the results view (above the length row), so they're
   visible the moment a build lands — no sticky/scroll plumbing needed. */
.spath-actions { display: flex; gap: 10px; margin: 10px 0 4px; }
/* Bright green + a restrained entrance: slide in, two gentle pulses,
   then hold — enough to catch the eye the first time without nagging. */
#spath-banner { position: fixed; top: 0; left: 0; right: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; gap: 14px; padding: 9px 14px; font-size: 13px; font-weight: 600; color: #06280f; background: #22c55e; box-shadow: 0 2px 10px rgba(0,0,0,0.45); animation: spath-banner-in 0.28s ease-out, spath-banner-pulse 1.3s ease-in-out 0.4s 2; }
@keyframes spath-banner-in { from { transform: translateY(-100%); } to { transform: translateY(0); } }
@keyframes spath-banner-pulse { 0%, 100% { background: #22c55e; } 50% { background: #4ade80; } }
.spath-banner-cancel { text-decoration: underline; color: #06280f; opacity: 0.8; }
.spath-banner-cancel:hover { opacity: 1; }

/* Keyboard Shortcuts modal (Layout > Keyboard Shortcuts) */
.hotkeys-modal-window { max-width: 560px; }
.hotkey-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
.hotkey-label { flex: 1 1 0; }
.hotkey-keycap { font-family: monospace; font-size: 13px; background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.25); border-radius: 4px; padding: 2px 10px; min-width: 72px; text-align: center; white-space: nowrap; }
.hotkey-keycap.unbound { opacity: 0.5; }
.hotkey-keycap.capturing { border-color: #22c55e; color: #22c55e; }
.hotkey-btn { cursor: pointer; font-size: 12px; text-transform: uppercase; opacity: 0.7; min-width: 52px; text-align: right; }
.hotkey-btn:hover { opacity: 1; }
.hotkeys-disabled { opacity: 0.4; pointer-events: none; }

/* ── Federation: the server picker + read-only chrome ──────────────────────
   The app points at one server at a time. `body.on-federated-server` is the
   single switch: it hides every nav entry a federated server cannot serve
   and reveals the read-only note. Driven by a BODY class rather than by
   toggling .super-hide on each item, so it composes with the flag gates
   that already hide some entries (Sonic Path) instead of fighting them. */
.nav-server-wrap {
  display: flex;
  align-items: center;
  margin-right: 12px;
}

.nav-server-select {
  padding: 6px 10px;
  background-color: #262a33;
  color: #F5F7FA;
  border: 1px solid #444c56;
  border-radius: 4px;
  font-family: 'Jura', sans-serif;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  min-width: 150px;
  display: block;
  height: auto;
}

.nav-server-select:hover,
.nav-server-select:focus {
  border-color: #657ee4;
  outline: none;
}

body.on-federated-server .side-nav-item.local-only {
  display: none !important;
}

.side-nav-note {
  display: none;
  padding: 8px 14px;
  margin: 4px 0;
  font-size: 12px;
  line-height: 1.4;
  color: #d6b45f;
  background-color: rgba(214, 180, 95, 0.1);
  border-left: 3px solid #d6b45f;
}

body.on-federated-server .side-nav-note {
  display: block;
}

/* The escape hatch back to this server, shown inside the read-only note. It
   lives in the side-nav so it survives top-bar-hidden (which hides the top-bar
   switcher), the one state where a federated search hit could otherwise strand
   you on a peer with no visible way home. */
.nav-note-back {
  display: inline-block;
  margin-top: 6px;
  color: #657ee4;
  font-weight: bold;
  cursor: pointer;
  text-decoration: underline;
}

/* Header above each server's block in a multi-server search result. */
.search-server-header {
  padding: 12px 12px 2px;
  font-size: 13px;
  font-weight: 600;
  color: #8bb7f0;
}

.search-server-note {
  color: #999;
  font-weight: 400;
}
