/* 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);
}

/* a menu entry that is a button (the queue menu's "Keep a copy…"): drawn
   as the others — not Materialize's teal when focused */
.pop-list-btn {
  display: block;
  width: 100%;
  margin: 0;
  border: 0;
  background: transparent;
  text-align: left;
  font: inherit;
  font-size: 13px;
  line-height: inherit;
}
.pop-list-btn:focus { background-color: rgba(255,255,255,.1); outline: none; }
.pop-list-btn:focus-visible { outline: 2px solid #fa832b; outline-offset: -2px; }

.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; }
/* One source at a time (docs/designs/discover-panel, alternate A): the
   switch under the header names each source with its colour and count;
   the chosen source's view takes the whole slot. */
.discover-seg {
  display: flex;
  gap: 3px;
  margin: 0 14px 6px 14px;
  padding: 3px;
  background: #1a1e25;
  border-radius: 6px;
  flex-shrink: 0;
}
.discover-seg > a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 4px 6px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  color: #8a919e;
  white-space: nowrap;
}
.discover-seg > a:hover { color: #dfe3ea; }
.discover-seg > a > i { width: 7px; height: 7px; border-radius: 50%; background: #657ee4; flex-shrink: 0; }
.discover-seg > a.discover-seg-network > i { background: #4fb8a8; }
.discover-seg > a.discover-seg-peers > i { background: #d9a441; }
.discover-seg > a > small { font-weight: 400; font-size: 10.5px; color: #6f7683; }
.discover-seg > a.discover-seg-on { background: #262b33; color: #dfe3ea; box-shadow: inset 0 0 0 1px #444c56; }
.discover-seg > a.discover-seg-on > small { color: #8a919e; }
/* The similar-artists strip above the library list: no divider. */
.discover-artists-top { border-top: 0; margin-top: 0; padding-top: 0; }
/* A remote source's view: a line for who answered and the toggle, the
   list, the footer — laid out like the library's so the list scrolls. */
.discover-view { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.discover-listbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px 4px 14px;
  font-size: 11px;
  color: #6f7683;
  flex-shrink: 0;
}
/* "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-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; }
/* No hover on a touch screen: the add icons stay visible. */
@media (hover: none) {
  .discover-add { opacity: 1; }
}
/* ── Recommendation modal (docs/designs/discover-modal) ────────────────
   One window for a network or peer row. Same palette as the panel; the
   source colour (--src) follows the row: teal = network, gold = a
   connected server. Fixed overlay above the player and the nav bar (their
   z-indexes are 1000 / 2500); hystmodal windows sit at 5000+, and this
   never coexists with one. Top-anchored: a section that grows or a late
   answer moves only the window's bottom edge. */
.dmodal-shadow {
  position: fixed;
  inset: 0;
  /* One above the phone layout's floating menu button (.fixed-action-btn,
     4000), which otherwise sits on the window's form and close button. */
  z-index: 4001;
  background: rgba(0, 0, 0, .6);
  overflow-y: auto;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 12px;
}
/* The window's tokens: every colour inside it is one of these. --t4 is
   the one muted text colour (4.5:1 on every surface it sits on). */
.dmodal {
  --win: #2d333b; --card: #23282f; --well: #1a1e25; --btn: #363d47; --btn-h: #414957; --hover: #2c323c;
  --div: #3a4149; --bord: #444c56; --field: #6b7482;
  --t1: #f0f2f5; --t2: #dfe3ea; --t3: #b8bcc6; --t4: #a0a7b3;
  --ink: #0f1216; --ok: #4fc27a; --warn: #f5a05b; --err: #e0616a; --errt: #ec8a90; --other: #b8bcc6;
  --canon: #657ee4; --canon-t: #8ea0f0;
  --src: #4fb8a8; --src-2: #5ec9b9;
  position: relative;
  width: 520px;
  max-width: 100%;
  margin: 0;
  background: var(--win);
  border-radius: 6px;
  box-shadow: 0 16px 48px rgba(0, 0, 0, .6), 0 0 0 1px rgba(255, 255, 255, .04);
  color: var(--t2);
  font-size: 13px;
  line-height: 1.4;
  text-align: left;
}
.dmodal-peer { --src: #d9a441; --src-2: #e6b85c; }
/* The window itself takes focus only from a click on its body (so a key
   there is still the window's); it is not a control. */
.dmodal:focus { outline: none; }
/* One focus ring for every control in the window. */
.dmodal-shadow .dmodal :focus-visible { outline: 2px solid var(--t1); outline-offset: 2px; }
/* Materialize styles bare <button>s (and paints a focused one teal). */
.dmodal button { -webkit-appearance: none; appearance: none; margin: 0; font-family: inherit; }
.dmodal-close {
  position: absolute; top: 8px; right: 8px; width: 32px; height: 32px; border-radius: 4px; z-index: 2; padding: 0; border: 0;
  display: flex; align-items: center; justify-content: center; background: transparent; color: var(--t4); cursor: pointer;
}
.dmodal-close:focus { background: transparent; color: var(--t4); }
.dmodal-close:hover { background: var(--btn); color: var(--t1); }
.dmodal-head { display: flex; gap: 14px; padding: 18px 52px 14px 20px; }
.dmodal-art {
  width: 72px; height: 72px; border-radius: 4px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #2a3140, #1a1e25); color: rgba(255, 255, 255, .3); border: 1px solid var(--div);
  background-size: cover; background-position: center; box-sizing: border-box;
}
/* An artist's window: a person in a circle; a folder's: the file
   explorer's own folder on the well */
.dmodal-art.dmodal-art-artist { border-radius: 50%; }
.dmodal-art.dmodal-art-folder { background: var(--well); }
.dmodal-head-text { min-width: 0; flex: 1; padding-top: 1px; }
.dmodal .dmodal-title { margin: 0; font-size: 16px; font-weight: 600; color: var(--t1); line-height: 1.25; overflow-wrap: anywhere; }
.dmodal-artist { font-size: 13px; color: var(--t3); margin-top: 3px; overflow-wrap: anywhere; }
/* One meta line: the server's status, the format, the match — "·" between */
.dmodal-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; margin-top: 6px; font-size: 11.5px; line-height: 1.45; color: var(--t4); font-variant-numeric: tabular-nums; }
/* each part after the first carries its "·": a wrap takes it to the new line */
.dmodal-meta-part { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.dmodal-meta-part > span { min-width: 0; overflow-wrap: anywhere; }
.dmodal-isrc { font-family: ui-monospace, Consolas, monospace; font-size: 10.5px; background: var(--well); padding: 1px 5px; border-radius: 3px; }
.dmodal-status { display: inline-flex; align-items: center; gap: 6px; }
.dmodal-status i { width: 7px; height: 7px; border-radius: 50%; background: var(--t4); flex-shrink: 0; }
.dmodal-status i.dmodal-dot-ok { background: var(--ok); }
.dmodal-status i.dmodal-dot-off { background: var(--err); }
/* Sections */
.dmodal-section { border-top: 1px solid var(--div); padding: 12px 20px 14px; }
.dmodal-section-h { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.dmodal .dmodal-label { margin: 0; font-size: 10.5px; line-height: 1.4; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--t4); white-space: nowrap; }
.dmodal-hint { font-size: 11px; line-height: 1.4; color: var(--t4); font-style: italic; text-align: right; }
.dmodal-note { font-size: 11.5px; font-style: italic; color: var(--t4); margin-right: 4px; }
.dmodal-note-plain { font-style: normal; }
/* Option rows */
.dm-opt { display: flex; align-items: center; gap: 10px; padding: 7px 10px; background: var(--card); border-radius: 4px; }
.dm-opt + .dm-opt { margin-top: 6px; }
.dm-opt-ic { width: 28px; height: 28px; border-radius: 6px; background: var(--well); display: flex; align-items: center; justify-content: center; color: var(--t3); flex-shrink: 0; }
.dm-opt-ic-on { background: var(--src); color: var(--ink); }
.dm-opt-ic-ok { color: var(--ok); }
.dm-opt-ic-err { color: var(--errt); }
.dm-opt-body { flex: 1; min-width: 0; }
.dm-opt-title { font-size: 12.5px; color: var(--t2); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.dm-opt-sub { font-size: 11px; color: var(--t4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dm-opt-act { display: flex; gap: 6px; flex-shrink: 0; align-items: center; }
.dm-opt-muted .dm-opt-title, .dm-opt-muted .dm-opt-sub { color: var(--t4); }
/* A row whose buttons sit on their own line under the text (three never fit beside it). */
.dm-opt-wrap { flex-wrap: wrap; }
.dm-opt-wrap > .dm-opt-act, .dm-opt-wrap > .dm-form { flex-basis: 100%; padding-left: 38px; justify-content: flex-start; margin-top: 2px; flex-wrap: wrap; }
.dm-attrib { font-size: 10.5px; color: var(--t4); margin-top: 3px; }
/* Preview tiles: two up; the whole tile is the play / stop button */
.dm-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
.dm-tiles > .dm-opt { margin-top: 0; }
.dm-opt-btn { cursor: pointer; user-select: none; transition: background .12s; }
.dm-opt-btn:hover, .dm-opt-btn:focus-visible { background: var(--hover); outline: none; }
.dm-opt-btn:focus-visible, .dm-opt-playing, .dm-opt-playing:hover { box-shadow: inset 0 0 0 1px var(--src); }
/* Buttons: real <button>s (an <a href> for a URL), one height. Kinds:
   .dm-btn (secondary) · -primary (one gold fill per state) · -ghost ·
   -quiet · -icon (square); .dm-link is a Listen link. The kind rules name
   :focus too: Materialize paints a focused <button> teal. Disabled =
   aria-disabled="true" (still focusable, the handler a no-op — never
   pointer-events: none); in flight adds .is-busy. */
.dm-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 32px; padding: 0 12px; margin: 0;
  box-sizing: border-box; border: 0; border-radius: 4px; cursor: pointer; text-decoration: none;
  font-size: 12.5px; font-weight: 600; line-height: 1; background: var(--btn); color: var(--t2); white-space: nowrap;
}
.dm-btn:focus { background: var(--btn); color: var(--t2); }
.dm-btn:hover { background: var(--btn-h); color: var(--t1); }
.dm-btn.dm-btn-primary, .dm-btn.dm-btn-primary:focus { background: var(--src); color: var(--ink); }
.dm-btn.dm-btn-primary:hover { background: var(--src-2); color: var(--ink); }
.dm-btn.dm-btn-ghost, .dm-btn.dm-btn-ghost:focus { background: transparent; border: 1px solid var(--bord); color: var(--t2); }
.dm-btn.dm-btn-ghost:hover { background: transparent; border-color: var(--src); color: var(--t1); }
.dm-btn.dm-btn-quiet, .dm-btn.dm-btn-quiet:focus { background: transparent; padding: 0 8px; color: var(--t3); }
.dm-btn.dm-btn-quiet:hover { background: var(--hover); color: var(--t1); }
.dm-btn.dm-btn-icon { width: 32px; padding: 0; }
.dm-btn[aria-disabled="true"] { opacity: .45; cursor: default; }
.dm-btn[aria-disabled="true"].is-busy { opacity: .6; cursor: progress; }
.dm-btn svg { flex-shrink: 0; }
/* A Listen link: a button that reads as a gold word */
.dm-link, .dm-link:focus {
  display: inline-flex; align-items: center; height: 32px; padding: 0 8px; margin: 0; box-sizing: border-box; border: 0; border-radius: 4px;
  background: transparent; color: var(--src); font-size: 12px; font-weight: 600; line-height: 1; white-space: nowrap; cursor: pointer;
}
.dm-link:hover { background: transparent; color: var(--src-2); text-decoration: underline; }
/* Invite form (inline, one line) */
.dm-form { display: flex; gap: 6px; align-items: center; }
.dm-input, .dm-input[type="text"] {
  flex: 1; min-width: 0; height: 28px; margin: 0; padding: 0 8px; box-sizing: border-box;
  font-size: 12px; color: #dfe3ea; background: #1a1e25; border: 1px solid #444c56; border-radius: 4px; box-shadow: none;
}
.dm-input[type="text"]:focus { border-color: var(--src); box-shadow: none; }
/* Find elsewhere: "Search", then ghost chips (links out, and Copy title);
   a canonical page leads, in the blue outline */
.dm-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.dm-chips-lead { font-size: 12px; color: var(--t4); margin-right: 2px; }
.dm-chip, .dm-chip:focus {
  display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px; margin: 0; box-sizing: border-box;
  border: 1px solid var(--bord); border-radius: 4px; background: transparent; color: var(--t2);
  font-size: 12px; line-height: 1; text-decoration: none; white-space: nowrap; cursor: pointer;
}
.dm-chip:hover { background: transparent; border-color: var(--t4); color: var(--t1); }
.dm-chip.dm-chip-canon, .dm-chip.dm-chip-canon:focus { border-color: var(--canon); color: var(--canon-t); }
.dm-chip.dm-chip-canon:hover { background: rgba(101, 126, 228, .12); color: var(--canon-t); }
.dm-tag {
  display: inline-flex; align-items: center; font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 8px; background: var(--well); color: var(--t4); white-space: nowrap; vertical-align: middle;
}
.dm-tag-ok { color: var(--ok); }
.dm-tag-src { color: var(--src); }
/* error text is --errt: --err (#e0616a) is never text (4.29:1 on a row) */
.dm-tag-err { color: var(--errt); }
/* Get it's job rows: the row is its job */
.dm-opt-sub-err { color: var(--errt); }
/* The lookup card: the upload "Get it" would fetch, and the others to pick from */
.dm-thumb { width: 52px; height: 29px; border-radius: 4px; background: var(--well) center / cover no-repeat; flex-shrink: 0; }
.dm-thumb-sm { width: 40px; height: 23px; }
.dm-others { flex-basis: 100%; padding-left: 38px; margin-top: 4px; display: grid; gap: 2px; }
.dm-other { display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: 4px; cursor: pointer; }
.dm-other:hover, .dm-other:focus-visible { background: var(--hover); outline: none; }
.dm-other-t { min-width: 0; line-height: 1.3; }
.dm-other-t b { display: block; font-size: 12px; font-weight: 400; color: var(--t2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dm-other-t small { display: block; font-size: 10.5px; color: var(--t4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dm-progress { height: 4px; background: #1a1e25; border-radius: 2px; overflow: hidden; margin-top: 6px; }
.dm-progress i { display: block; height: 100%; background: var(--src); border-radius: 2px; transition: width .4s ease; }
.dm-progress-indet i { width: 35%; animation: dm-indet 1.4s ease-in-out infinite; }
@keyframes dm-indet { 0% { margin-left: -35%; } 100% { margin-left: 100%; } }
/* Where files land (dm-dest): the path bar in the section whose copy or
   download uses it — where a copy of the chosen scope lands, a song's
   file, whose choice it is, Change… — and the editor that replaces it in
   place. A path is never cut short: it wraps, each "›" travelling with the
   folder after it, so it breaks between folders first, then inside one. */
.dm-dest { display: grid; gap: 2px; margin: 0; padding: 9px 10px 4px 12px; background: var(--well); border-radius: 6px; }
.dm-dest-line { display: flex; gap: 8px; align-items: flex-start; min-width: 0; }
.dm-dest-line > svg { color: var(--src); flex-shrink: 0; margin-top: 1px; }
.dm-dest-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 0 6px; min-height: 32px; padding-left: 22px; }
.dm-dest-source { font-size: 11.5px; line-height: 1.4; color: var(--t4); }
.dm-dest-acts { display: flex; gap: 6px; align-items: center; margin-left: auto; }
.dm-opt + .dm-dest, .dm-opt + .dm-dest-ed, .dm-dest + .dm-opt, .dm-dest-ed + .dm-opt { margin-top: 6px; }
/* A path (dm-dest-path): the bar's, a copy's Into / In line, the preview */
.dm-dest-path { flex: 1 1 auto; min-width: 0; }
.dm-dest-crumbs { font-size: 12px; line-height: 1.45; overflow-wrap: anywhere; }
.dm-dest-crumbs b { font-weight: 600; }
.dm-dest-crumb { display: inline-block; max-width: 100%; }
.dm-dest-crumb > i { font-style: normal; margin: 0 5px; color: var(--t4); }
.dm-dest-crumb-note { color: var(--t3); }
/* A slot ("‹artist›": each song's own tag) drawn as the note is, inside its
   folder's text — in the preview's bold source colour too — and the one
   line under the path that says why */
.dm-dest-slot { color: var(--t3); font-weight: 400; }
.dm-dest-file { margin-top: 2px; font: 11.5px/1.45 ui-monospace, Consolas, monospace; color: var(--t3); overflow-wrap: anywhere; }
.dm-dest-slots { margin-top: 2px; font-size: 11px; line-height: 1.4; color: var(--t4); }
.dm-dest-path-bar .dm-dest-crumbs, .dm-dest-path-preview .dm-dest-crumbs { color: var(--t2); }
.dm-dest-path-bar .dm-dest-pre { color: var(--t3); }
.dm-dest-path-bar b, .dm-dest-path-preview b { color: var(--t1); }
.dm-dest-path-preview .dm-dest-crumb-rendered { color: var(--src); font-weight: 600; }
.dm-dest-path-state { margin-top: 8px; }
.dm-dest-path-state + .dm-dest-path-state { margin-top: 2px; }
.dm-dest-path-state .dm-dest-crumbs { font-size: 11.5px; color: var(--t3); }
.dm-dest-path-state .dm-dest-pre { color: var(--t4); }
.dm-dest-path-state b { color: var(--t2); }
/* The editor ("Where copies land": the phone's destination sheet in the
   window's look): a header — the title, whose choice is in force, what it
   is for, Cancel — then where this item would land, the library chips,
   the layouts as one radio group (the folder list, then Custom's field and
   its variables under it), Use the library default and Save */
.dm-dest-ed { display: grid; gap: 14px; margin: 0; padding: 12px; border: 1px solid var(--bord); border-radius: 6px; }
.dm-dest-ed-h { display: flex; align-items: flex-start; gap: 8px; }
.dm-dest-ed-titles { flex: 1 1 auto; min-width: 0; }
.dm-dest-ed-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.dm-dest-ed-title { font-size: 13px; line-height: 1.3; font-weight: 600; color: var(--t1); }
.dm-dest-tag { display: inline-flex; align-items: center; gap: 4px; padding: 0 7px; border: 1px solid var(--bord); border-radius: 10px; font-size: 11px; line-height: 16px; color: var(--t3); white-space: nowrap; }
.dm-dest-tag > svg { flex-shrink: 0; }
.dm-dest-ed-sub { margin-top: 2px; font-size: 12px; line-height: 1.4; color: var(--t3); }
.dm-dest-ed-h > .dm-btn { flex: none; margin: -6px -6px 0 0; }
/* Where this item would land: the bar's well, its folder icon; the file
   the path's last crumb */
.dm-dest-preview { display: flex; gap: 8px; align-items: flex-start; padding: 9px 10px 9px 12px; background: var(--well); border-radius: 6px; }
.dm-dest-preview > svg { flex-shrink: 0; margin-top: 1px; color: var(--src); }
.dm-dest-preview > .dm-c-warn { color: var(--warn); }
.dm-dest-preview-body { flex: 1 1 auto; min-width: 0; }
.dm-dest-preview-note { flex: 1 1 auto; min-width: 0; font-size: 12px; line-height: 1.45; color: var(--t3); }
.dm-dest-lands { margin-bottom: 1px; font-size: 11.5px; line-height: 1.4; color: var(--t3); overflow-wrap: anywhere; }
.dm-dest-path-preview .dm-dest-slot { font-style: italic; }
.dm-dest-crumb-file { color: var(--t2); }
.dm-dest-field { display: grid; gap: 6px; min-width: 0; }
.dm-dest-label { font-size: 10.5px; line-height: 1.4; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--t4); }
/* The libraries: real buttons; the chosen one as the chosen segment is
   (the source edge), with a check. A long name ends in "…" inside the
   window, whole in its title */
.dm-dest-chips { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.dm-dest-chip, .dm-dest-chip:focus {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 88px; max-width: 100%; height: 32px; padding: 0 12px; margin: 0; box-sizing: border-box;
  border: 1px solid var(--bord); border-radius: 6px; background: transparent; color: var(--t2); font-size: 12.5px; font-weight: 600; line-height: 1; white-space: nowrap; cursor: pointer;
}
.dm-dest-chip > svg { flex-shrink: 0; }
.dm-dest-chip-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.dm-dest-chip:hover { background: transparent; border-color: var(--t4); color: var(--t1); }
.dm-dest-chip.dm-on, .dm-dest-chip.dm-on:focus, .dm-dest-chip.dm-on:hover { background: var(--btn); border-color: var(--src); color: var(--t1); }
.dm-dest-chip.dm-on > svg { color: var(--src); }
.dm-dest-chip[aria-disabled="true"] { opacity: .6; cursor: default; }
/* The layouts: one radio group, each row its native radio (back from
   under Materialize's own drawing), its name and its template (spans: a
   label holds phrasing content). The radio is last in its label, drawn
   first: Materialize draws a radio of its own from a "+ span" */
.dm-dest-opts { display: grid; gap: 2px; }
.dm-dest-opt { display: flex; align-items: center; gap: 10px; min-height: 40px; margin: 0; padding: 4px 8px; box-sizing: border-box; border-radius: 4px; cursor: pointer; }
.dm-dest-opt:hover { background: var(--hover); }
.dmodal .dm-dest-opt .dm-dest-radio { order: -1; position: static; flex: none; width: 16px; height: 16px; margin: 0; opacity: 1; pointer-events: auto; accent-color: var(--src); cursor: pointer; }
.dm-dest-opt-text { display: block; min-width: 0; }
.dm-dest-opt-label { display: block; font-size: 12.5px; line-height: 1.35; color: var(--t2); }
.dm-dest-opt.dm-on .dm-dest-opt-label { font-weight: 600; color: var(--t1); }
.dm-dest-opt-sub { display: block; font-size: 11px; line-height: 1.4; color: var(--t4); overflow-wrap: anywhere; }
.dm-dest-mono { font-family: ui-monospace, Consolas, monospace; }
/* "Start from an existing folder…" and its list under the layouts, then
   Custom's field under its row's name: the variables, how a layout reads */
.dm-dest-custom { display: grid; gap: 6px; min-width: 0; padding-left: 34px; }
.dm-dest-folders { display: grid; justify-items: start; gap: 6px; min-width: 0; padding-left: 26px; }
.dm-dest-folders > .dm-dest-tree { justify-self: stretch; }
.dm-dest-ed .dm-input, .dm-dest-ed .dm-input[type="text"] {
  height: 32px; padding: 0 10px; font-size: 12.5px; color: var(--t1); background: var(--well); border-color: var(--field);
}
.dm-dest-ed .dm-input::placeholder { color: var(--t4); }
.dm-dest-ed .dm-input[type="text"]:focus { border-color: var(--src); }
.dm-dest-ed .dm-input.is-warn, .dm-dest-ed .dm-input[type="text"].is-warn { border-color: var(--warn); }
.dm-dest-ed .dm-input.is-err, .dm-dest-ed .dm-input[type="text"].is-err { border-color: var(--err); }
.dm-dest-ed .dm-dest-mono[type="text"] { flex: none; width: 100%; font-size: 12px; }
/* Empty, Custom's field and its example ("e.g. From friends or
   {{ARTIST}}/{{ALBUM}}") take the window's font: narrower than monospace,
   so the example is not cut on a phone */
.dm-dest-ed .dm-dest-mono[type="text"]:placeholder-shown { font-family: inherit; }
.dm-dest-hint { font-size: 11px; line-height: 1.4; color: var(--t4); }
.dm-dest-err, .dm-dest-warn { display: flex; gap: 6px; align-items: flex-start; font-size: 11.5px; line-height: 1.4; color: var(--errt); }
.dm-dest-warn { color: var(--warn); }
.dm-dest-err > svg, .dm-dest-warn > svg { flex-shrink: 0; margin-top: 2px; }
.dm-dest-missing { font-size: 11.5px; line-height: 1.4; color: var(--t3); }
/* The layout's variables: real buttons, all alike */
.dm-dest-vars { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.dm-dest-var, .dm-dest-var:focus {
  display: inline-flex; align-items: center; height: 32px; padding: 0 9px; margin: 0; box-sizing: border-box; border: 0; border-radius: 4px;
  background: var(--btn); color: var(--t2); font: 500 11.5px/1 ui-monospace, Consolas, monospace; white-space: nowrap; cursor: pointer;
}
.dm-dest-var:hover { background: var(--btn-h); color: var(--t1); }
.dm-dest-var[aria-disabled="true"] { opacity: .45; cursor: default; }
/* "Start from an existing folder…": one level of folders, each row a
   button, the folder the layout starts in pressed */
.dm-dest-tree { background: var(--well); border: 1px solid var(--bord); border-radius: 4px; max-height: 224px; overflow-y: auto; }
.dm-dest-tree-h {
  display: flex; flex-wrap: wrap; align-items: center; min-height: 32px; padding: 0 10px; box-sizing: border-box;
  font-size: 11.5px; line-height: 1.4; color: var(--t3); border-bottom: 1px solid var(--div); overflow-wrap: anywhere;
}
.dm-dest-tree-h b { color: var(--t2); font-weight: 600; }
.dm-dest-tree-h > i { font-style: normal; margin: 0 5px; color: var(--t4); }
.dm-dest-node, .dm-dest-node:focus {
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: 32px; padding: 6px 10px; margin: 0; box-sizing: border-box;
  border: 0; border-radius: 0; background: transparent; color: var(--t2); font-family: inherit; font-size: 12px; line-height: 1.3;
  text-align: left; overflow-wrap: anywhere; cursor: pointer;
}
.dm-dest-node > svg { flex-shrink: 0; color: var(--t3); }
.dm-dest-node:hover, .dm-dest-node[aria-pressed="true"] { background: var(--btn); }
.dm-dest-node[aria-pressed="true"] > svg { color: var(--src); }
.dm-dest-node[aria-disabled="true"] { opacity: .6; cursor: default; }
.dm-dest-node.dm-dest-node-new { border-top: 1px solid var(--div); color: var(--src); }
.dm-dest-node-new > svg { color: var(--src); }
.dmodal-shadow .dmodal .dm-dest-node:focus-visible { outline-offset: -2px; }
.dm-dest-naming { display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 10px; border-top: 1px solid var(--div); color: var(--src); }
.dm-dest-naming > svg { flex-shrink: 0; }
.dm-dest-tree-note { padding: 8px 10px; font-size: 11.5px; font-style: italic; color: var(--t4); }
.dm-dest-tree-warn { border-top: 1px solid var(--div); font-style: normal; color: var(--warn); }
/* Use the library default at the start, Save at the end */
.dm-dest-ed-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; padding-top: 12px; border-top: 1px solid var(--div); }
.dm-dest-ed-foot > .dm-btn-quiet { margin-right: auto; }
/* Phones: every target 44 px tall; Use the library default and Save share
   their row */
@media (max-width: 600px) {
  .dm-dest { padding: 8px 10px 4px 10px; }
  .dm-dest-foot { min-height: 44px; }
  .dm-dest-chip, .dm-dest-chip:focus { height: 44px; }
  .dm-dest-opt { min-height: 44px; }
  .dm-dest-custom { padding-left: 8px; }
  .dm-dest-var, .dm-dest-var:focus { height: 44px; }
  .dm-dest-node, .dm-dest-node:focus { min-height: 44px; }
  .dm-dest-tree { max-height: 308px; }
  .dm-dest-ed .dm-input, .dm-dest-ed .dm-input[type="text"] { height: 44px; }
  .dm-dest-ed-foot > .dm-btn { flex: 1 1 0; }
  .dm-dest-ed-foot > .dm-btn-quiet { margin-right: 0; }
}
/* Phones: a bottom sheet, every target 44 px tall. The sheet sits on the
   bottom edge by its auto top margin, not by flex-end: a window taller than
   the screen would overflow above the overlay's top, where no scroll can
   reach its title and Close. The auto margin is 0 then, and the overlay
   scrolls from the top. */
@media (max-width: 600px) {
  .dmodal-shadow { padding: 24px 0 0; align-items: flex-start; }
  .dmodal { width: 100%; margin: auto 0 0; border-radius: 14px 14px 0 0; }
  .dmodal-close { top: 6px; right: 6px; width: 44px; height: 44px; }
  .dmodal-head { padding: 12px 52px 10px 16px; }
  .dmodal-art { width: 56px; height: 56px; }
  .dmodal-section { padding: 10px 16px 12px; }
  .dmodal-section-h { flex-direction: column; align-items: flex-start; gap: 2px; }
  .dmodal-hint { text-align: left; }
  .dm-btn, .dm-link, .dm-link:focus, .dm-chip, .dm-chip:focus { height: 44px; }
  .dm-btn.dm-btn-icon { width: 44px; }
}
@media (max-width: 480px) {
  .dm-tiles { grid-template-columns: minmax(0, 1fr); }
}
/* Downloads strip: plug-in jobs that outlive the window that started them */
.discover-tray { border-top: 1px solid #21252d; margin-top: 4px; padding-bottom: 6px; }
.discover-tray-h {
  display: flex; align-items: center; gap: 8px; padding: 6px 14px 4px; font-size: 10px; font-weight: 700;
  letter-spacing: 1.2px; text-transform: uppercase; color: #6f7683;
}
.discover-tray-h > svg { flex-shrink: 0; }
.discover-tray-count { font-weight: 600; letter-spacing: 0; text-transform: none; color: #8a919e; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.discover-job { display: flex; align-items: center; gap: 10px; padding: 4px 14px 4px 12px; }
.discover-job:hover { background: #1e222a; }
.discover-job-ic {
  width: 22px; height: 22px; border-radius: 5px; background: #1a1e25; display: flex; align-items: center;
  justify-content: center; color: #b8bcc6; flex-shrink: 0;
}
.discover-job-ic-on { background: #4fb8a8; color: #0f1216; }
.discover-job-ic-peer { background: #d9a441; color: #0f1216; }
.discover-job-ic-ok { color: #4fc27a; }
.discover-job-ic-err { color: #e0616a; }
.discover-job-t { flex: 1; min-width: 0; line-height: 1.3; }
.discover-job-t b { display: block; font-size: 12px; color: #dfe3ea; font-weight: 400; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.discover-job-t small { display: block; font-size: 10.5px; color: #8a919e; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.discover-job .dm-progress { --src: #4fb8a8; margin-top: 3px; height: 3px; background: #262b33; }
.discover-job .dm-progress-peer { --src: #d9a441; }
.discover-job-act { display: flex; gap: 4px; flex-shrink: 0; }
.discover-job-act a { display: flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 4px; color: #8a919e; }
.discover-job-act a:hover { background: #262b33; color: #dfe3ea; }
/* Downloads panel (m.js discoverDownloadsPanel): the usual file rows with
   the song's provenance under its name. */
.dl-panel { padding-bottom: 4px; }
.dl-lead { margin: 0 0 8px; color: #b8bcc6; font-size: 14px; }
.dl-bar { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.dl-totals { font-size: 13px; color: #8a919e; }
.dl-toggle { font-size: 13px; }
.dl-toggle span { padding-left: 28px; }
.dl-empty { color: #8a919e; }
.dl-item .dl-ic { color: #8bb7f0; flex-shrink: 0; }
.dl-item .dl-facts { display: block; font-size: 12px; color: #8a919e; }
.dl-item .dl-where { display: block; font-size: 11.5px; color: #6f7683; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.dl-item-muted .dl-ic, .dl-item-muted b, .dl-item-muted .dl-facts { color: #6f7683; }
.dl-dead { cursor: default; }
.dl-remove { cursor: pointer; color: #e0616a; font-size: 12px; padding: 0 6px; }
.dl-remove:hover { text-decoration: underline; }
.discover-tray-f { display: flex; align-items: center; padding: 4px 14px 0 12px; font-size: 11px; color: #657ee4; font-weight: 600; min-height: 16px; }
.discover-tray-f a { color: #657ee4; }
.discover-tray-f a:hover { color: #8ea0f0; }
/* "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;
}

/* ── Keep a copy, from browsing a connected server (m.js browseKeep*) ────
   The page header above the list (#browse-head: an album, an artist, a
   folder below the library root), the row ⋯ in the ▾ / ↓ slot, the card ⋯
   (Discover's .dpage-album-more), and the marks a copy's state leaves on
   the page — in the window's words and colours. Focus outside the window
   is the house ring, #fa832b. */
/* the header: tile · title and sub · the action row under them; in a
   column under 420 px the action row takes the column's full width */
#browse-head { flex-shrink: 0; container-type: inline-size; }
.browse-head { position: relative; display: grid; grid-template-columns: 72px minmax(0, 1fr); column-gap: 14px; align-items: start; padding: 12px 12px 12px 6px; }
.browse-head-tile { grid-row: 1 / span 2; position: relative; width: 72px; height: 72px; box-sizing: border-box; border-radius: 4px; border: 1px solid #3a4149; background: #2d333b; color: #b8bcc6; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.browse-head-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.browse-head-tile-artist { border-radius: 50%; }
.browse-head-text { min-width: 0; }
.browse-head-title { margin: 0; font-size: 20px; line-height: 1.2; font-weight: 600; color: #f0f2f5; overflow-wrap: anywhere; }
.browse-head-sub { margin-top: 3px; font-size: 13px; line-height: 1.45; color: #b8bcc6; overflow-wrap: anywhere; }
.browse-head-acts { grid-column: 2; min-width: 0; margin-top: 10px; }
.browse-head-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; min-height: 32px; }
.browse-head-line { flex: 1 1 200px; min-width: 0; font-size: 12.5px; line-height: 1.35; color: #a0a7b3; overflow-wrap: anywhere; }
.browse-head-live { margin-top: 6px; font-size: 12px; line-height: 1.4; color: #a0a7b3; overflow-wrap: anywhere; }
.browse-head-live:empty { display: none; }
/* the bar's holder takes no cell of the grid (no row, no row gap): the bar
   sits on the header's foot */
.browse-head > [data-head="bar"] { display: contents; }
.browse-head-bar { position: absolute; left: 6px; right: 12px; bottom: 0; height: 3px; border-radius: 2px; background: #363d47; overflow: hidden; }
.browse-head-bar i { display: block; height: 100%; border-radius: 2px; background: #d9a441; }
@container (max-width: 419px) {
  .browse-head { grid-template-columns: 56px minmax(0, 1fr); row-gap: 10px; }
  .browse-head-tile { grid-row: auto; width: 56px; height: 56px; }
  .browse-head-title { font-size: 18px; }
  .browse-head-acts { grid-column: 1 / -1; margin-top: 0; }
}
/* "Keep a copy…": gold-outlined; once a copy has a state the box stays
   and the words change (the same states as the window's) */
.browse-keep { position: relative; display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; margin: 0; box-sizing: border-box; border-radius: 4px; border: 1px solid rgba(217, 164, 65, .6); background: transparent; color: #e6b85c; font-family: inherit; font-size: 13px; font-weight: 600; line-height: 1; white-space: nowrap; cursor: pointer; flex: none; }
.browse-keep .browse-keep-ic { flex: none; display: block; color: #d9a441; }
.browse-keep:focus { background-color: transparent; outline: none; }
.browse-keep:hover { background-color: rgba(217, 164, 65, .12); border-color: #d9a441; }
.browse-keep:focus-visible { outline: 2px solid #fa832b; outline-offset: 2px; }
.browse-keep-on { color: #dfe3ea; }
.browse-keep-on.bk-other, .browse-keep-on.bk-kept, .browse-keep-on.bk-yours, .browse-keep-on.bk-skipped,
.browse-keep-on.bk-stopped, .browse-keep-on.bk-refused, .browse-keep-on.bk-failed { border-color: #444c56; }
.browse-keep-pct { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; color: #e6b85c; }
.browse-keep-plain { display: inline-flex; align-items: center; min-height: 32px; font-size: 13px; font-weight: 600; }
/* never past the column (a long server's name in "Copying from …", at a
   phone's width): the words shrink to an ellipsis — the full words are in
   the name and the tooltip — the glyph and the figure keep their size */
.browse-keep, .browse-keep-plain { max-width: 100%; min-width: 0; }
.browse-keep-plain .browse-keep-st { max-width: 100%; min-width: 0; }
.browse-keep .browse-keep-w, .browse-keep-plain .browse-keep-w { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* a state's words and glyph: a gold dot while it copies (grey for another
   server's), a clock while it waits, a check once in, a warning otherwise */
.browse-keep-st { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.browse-keep-dot { width: 7px; height: 7px; flex: none; border-radius: 50%; background: #d9a441; }
.bk-other .browse-keep-dot { background: #b8bcc6; }
.bk-queued, .bk-copying, .bk-stopping, .bk-other, .bk-yours { color: #dfe3ea; }
.bk-kept { color: #4fc27a; }
.bk-skipped, .bk-stopped, .bk-refused { color: #f5a05b; }
.bk-failed { color: #ec8a90; }
.bk-queued .browse-keep-ic, .bk-yours .browse-keep-ic { color: #b8bcc6; }
/* the header button's glyph follows its state (gold is the idle one's) */
.browse-keep.bk-kept .browse-keep-ic { color: #4fc27a; }
.browse-keep.bk-queued .browse-keep-ic, .browse-keep.bk-yours .browse-keep-ic { color: #b8bcc6; }
.browse-keep.bk-skipped .browse-keep-ic, .browse-keep.bk-stopped .browse-keep-ic, .browse-keep.bk-refused .browse-keep-ic { color: #f5a05b; }
.browse-keep.bk-failed .browse-keep-ic { color: #ec8a90; }
/* the marks: after an album page's song's artist, on an album card's line
   (under the year, a fixed height: a state that arrives never grows the
   card), after a folder row's name */
.browse-keep-row { white-space: nowrap; font-size: 13px; }
.browse-keep-row .browse-keep-st { gap: 4px; vertical-align: -1px; line-height: 1; }
.browse-keep-sep { color: #a0a7b3; }
.browse-keep-card { height: 16px; margin-top: 2px; font-size: 11px; line-height: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.browse-keep-card .browse-keep-st { gap: 4px; max-width: 100%; vertical-align: top; }
.browse-keep-card .browse-keep-w { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.browse-keep-card .browse-keep-dot, .browse-keep-folder .browse-keep-dot { width: 7px; height: 7px; margin: 0 1.5px; }
.browse-keep-card .bk-copying { color: #d9a441; }
.browse-keep-folder { margin-left: 10px; font-size: 13px; white-space: nowrap; vertical-align: top; }
.browse-keep-folder:empty { display: none; }
.browse-keep-folder .browse-keep-st { gap: 4px; }
.browse-keep-folder .bk-copying { color: #d9a441; }
/* the row ⋯: the tab it replaces (▾ Add To Playlist, ↓ Download Directory),
   at the same metrics, so a connected server's rows look like this one's */
.browse-keep-tab { float: right; min-width: 28px; height: 14px; padding: 0 3px; margin: 0; box-sizing: border-box; border: 0; border-right: 1px solid rgba(255, 255, 255, .1); border-bottom-left-radius: 3px; background-color: rgba(255, 255, 255, .08); color: #bbb; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.song-button-box .browse-keep-tab svg { display: block; padding-top: 0; }
.browse-keep-tab:focus { background-color: rgba(255, 255, 255, .08); outline: none; }
.browse-keep-tab:hover { background-color: rgba(255, 255, 255, .15); color: #fff; }
.browse-keep-tab:focus-visible { outline: 2px solid #fa832b; outline-offset: 2px; position: relative; z-index: 101; }
/* no hover (a touch screen, any width): every browse row's controls — this
   server's rows too, so a mixed search stays one system — come into the
   row's flow at 44 px, and the card ⋯ stays up with a 44 px target */
@media (hover: none) {
  #filelist .collection-item { align-items: center; min-height: 54px; box-sizing: border-box; }
  #filelist .collection-item > .dirz, #filelist .collection-item > .filez, #filelist .collection-item > .playlistz,
  #filelist .collection-item > .fileplaylistz { flex: 1 1 auto; min-width: 0; }
  #filelist .collection-item > .song-button-box { position: static; display: flex; align-self: center; flex: none; gap: 0; padding-right: 4px; }
  #filelist .song-button-box > .songDropdown, #filelist .song-button-box > .fileAddToPlaylist, #filelist .song-button-box > .downloadDir,
  #filelist .song-button-box > .addFileplaylist, #filelist .song-button-box > .downloadFileplaylist, #filelist .song-button-box > .browse-keep-tab {
    float: none; width: 44px; min-width: 44px !important; height: 44px; padding: 0 !important; display: flex; align-items: center; justify-content: center;
    background-color: transparent; border: 0; border-radius: 0; color: #c9ccd1;
  }
  #filelist .song-button-box > * > svg { width: 18px; height: 18px; padding-top: 0; vertical-align: middle !important; fill: #c9ccd1; }
  #filelist .song-button-box > .browse-keep-tab > svg { height: 6px; }
  #filelist .song-button-box > .renamePlaylist, #filelist .song-button-box > .deletePlaylist, #filelist .song-button-box > .removePlaylistSong {
    float: none; height: 44px; display: flex; align-items: center;
  }
  .browse-keep { height: 44px; }
  .browse-head-row { min-height: 44px; }
  .browse-keep-more::before { content: ''; position: absolute; inset: -4px; border-radius: 50%; }
}

/* 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;
}
/* A connected server's window: Listen (the play row, then the album and
   the artist as fact rows: a label column, the name and its facts, the
   links), then Keep a copy (one card: a choice of scope, where the copy
   lands, one Add — the card is the job) */
.dm-play { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* The play disc, in every window: a gold glyph on a grey disc (teal in a
   network window) — never a second gold fill beside Keep's primary */
.dm-play-btn, .dm-play-btn:focus {
  width: 40px; height: 40px; padding: 0; border: 0; border-radius: 50%; background: var(--btn); color: var(--src);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0; cursor: pointer;
}
.dm-play-btn:hover { background: var(--btn-h); color: var(--src); }
/* a folder's, until it is counted: dimmed, still focusable */
.dm-play-btn[aria-disabled="true"] { opacity: .45; cursor: default; }
.dm-play-body { flex: 1 1 160px; min-width: 0; }
.dm-play-title { font-size: 13px; font-weight: 600; color: var(--t1); }
.dm-play-sub { font-size: 11.5px; color: var(--t4); overflow-wrap: anywhere; }
.dm-play-act { display: flex; gap: 6px; flex-shrink: 0; }
.dm-facts { margin-top: 8px; }
.dm-fact { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; column-gap: 10px; align-items: center; min-height: 36px; }
.dm-fact-label { font-size: 11.5px; color: var(--t4); }
.dm-fact-body { min-width: 0; line-height: 1.45; overflow-wrap: anywhere; }
.dm-fact-name { font-size: 12px; font-weight: 600; color: var(--t2); margin-right: 8px; }
.dm-fact-more { font-size: 11.5px; color: var(--t4); }
.dm-fact-links { display: flex; flex-wrap: nowrap; margin-right: -8px; }
/* Keep a copy: one card — the choice strip, under Artist the only-missing
   checkbox, then the path bar or the copy's state (dm-keep-body), then its
   actions, the primary last */
.dm-keep { background: var(--card); border-radius: 6px; padding: 12px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
.dm-keep > *, .dm-keep-body > * { min-width: 0; }
.dm-keep-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
/* What to copy: a radio group drawn as segments, equal columns, every one
   as tall as the tallest; the radio itself out of sight but focusable, its
   ring drawn on the segment. A segment with a state of its own (not the
   chosen one) leads with a marker, its state word in the sub's place. */
.dm-segs { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); align-items: stretch; gap: 3px; padding: 3px; background: var(--well); border-radius: 6px; }
.dm-seg {
  position: relative; display: flex; flex-direction: column; justify-content: center; min-width: 0; min-height: 40px; margin: 0;
  padding: 5px 9px; box-sizing: border-box; border-radius: 4px; background: transparent; cursor: pointer; font-size: 13px; color: var(--t3);
}
.dm-seg:hover { background: var(--hover); }
.dm-seg.dm-on { background: var(--btn); box-shadow: inset 0 0 0 1px var(--src); }
.dm-seg-text { display: flex; flex-direction: column; min-width: 0; }
.dm-seg-label { display: flex; align-items: center; gap: 5px; font-size: 12.5px; line-height: 1.3; font-weight: 600; color: var(--t3); }
.dm-seg.dm-on .dm-seg-label { color: var(--t1); }
.dm-seg-sub { font-size: 11px; line-height: 1.3; color: var(--t4); overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.dm-seg.dm-on .dm-seg-sub { color: var(--t3); }
.dm-seg-mark { display: flex; flex: none; }
.dm-seg-mark > i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
/* Materialize hides radios with (0,2,0) and draws its own from a "+ span" */
.dmodal .dm-seg .dm-seg-input { position: absolute; left: 0; top: 0; width: 1px; height: 1px; margin: 0; padding: 0; opacity: 0; pointer-events: none; }
.dmodal-shadow .dmodal .dm-seg:has(.dm-seg-input:focus-visible) { outline: 2px solid var(--t1); outline-offset: 1px; }
.dm-c-t3 { color: var(--t3); }
.dm-c-src { color: var(--src); }
.dm-c-other { color: var(--other); }
.dm-c-ok { color: var(--ok); }
.dm-c-warn { color: var(--warn); }
.dm-c-errt { color: var(--errt); }
/* "Only the albums you don't have": the native box, back from under
   Materialize's own drawing ((0,2,0) hides it) */
.dm-check { display: flex; align-items: center; gap: 8px; min-height: 32px; margin: 0; font-size: 12.5px; line-height: 1.35; color: var(--t2); cursor: pointer; }
.dmodal .dm-check input[type="checkbox"] { position: static; flex: none; width: 16px; height: 16px; margin: 0; opacity: 1; pointer-events: auto; accent-color: var(--src); }
/* The outcome block, on the card itself: a tile tinted by what happened,
   the headline in its colour with the % beside it, the server's line, at
   most one muted line, the bar, where the files go or went */
.dm-out { display: flex; gap: 12px; align-items: flex-start; }
.dm-out-tile { width: 32px; height: 32px; flex: none; border-radius: 6px; display: flex; align-items: center; justify-content: center; }
.dm-out-tile-gold { background: rgba(217, 164, 65, .16); color: #d9a441; }
.dm-out-tile-ok { background: rgba(79, 194, 122, .14); color: var(--ok); }
.dm-out-tile-warn { background: rgba(245, 160, 91, .14); color: var(--warn); }
.dm-out-tile-err { background: rgba(224, 97, 106, .16); color: var(--errt); }
.dm-out-tile-grey { background: rgba(184, 188, 198, .12); color: var(--t3); }
.dm-out-text { flex: 1 1 auto; min-width: 0; }
.dm-out-head { display: flex; align-items: baseline; gap: 8px; }
.dm-out-headline { flex: 1 1 auto; min-width: 0; font-size: 14px; line-height: 1.3; font-weight: 600; color: var(--t1); overflow-wrap: anywhere; }
.dm-out-headline.dm-tone-ok { color: var(--ok); }
.dm-out-headline.dm-tone-warn { color: var(--warn); }
.dm-out-headline.dm-tone-err { color: var(--errt); }
.dm-out-pct { flex: none; font-size: 13px; line-height: 1.3; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--src); }
.dm-out-pct.dm-out-pct-other { color: var(--other); }
.dm-out-sub, .dm-out-muted { margin-top: 2px; font-size: 12px; line-height: 1.45; color: var(--t3); overflow-wrap: anywhere; }
.dm-out-muted { color: var(--t4); }
.dm-out .dm-progress { margin-top: 8px; background: var(--btn); }
.dm-out .dm-progress-other i { background: var(--other); }
@media (prefers-reduced-motion: reduce) {
  .dm-out .dm-progress-indet i { width: 100%; margin: 0; opacity: .35; animation: none; }
}
/* What only a screen reader hears: the finished headline's sub */
.dm-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* A start the server did not take: why, above the actions */
.dm-keep-line { display: flex; gap: 8px; align-items: flex-start; font-size: 12.5px; line-height: 1.45; color: var(--t2); }
.dm-keep-line > svg { flex: none; margin-top: 2px; color: var(--warn); }
/* A right lost while the window was open: the card holds this line alone */
.dm-keep-plain { display: flex; gap: 10px; align-items: center; min-height: 32px; font-size: 12.5px; line-height: 1.45; color: var(--t3); }
.dm-keep-plain > svg { flex: none; color: var(--t4); }
.dm-keep-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
/* Under Artist, what an artist copy leaves out */
.dm-keep-out { display: flex; gap: 8px; align-items: flex-start; margin-top: -2px; font-size: 12px; line-height: 1.45; color: var(--t4); overflow-wrap: anywhere; }
.dm-keep-out > svg { flex: none; margin-top: 2px; }
/* A folder past the songs one copy takes here: the card holds this alone */
.dm-keep-cap { display: flex; gap: 10px; align-items: flex-start; min-height: 32px; font-size: 12.5px; line-height: 1.45; color: var(--t2); overflow-wrap: anywhere; }
.dm-keep-cap > svg { flex: none; margin-top: 1px; color: var(--warn); }
/* a name with no space in it (a folder's, an album's) breaks anywhere,
   never past the card */
.dm-keep-out > span, .dm-keep-cap > span, .dm-land-note > span { min-width: 0; }
/* Where a folder lands: one radio group, each row its native radio (back
   from under Materialize's own drawing, last in its label, drawn first),
   its name and what it means; the chosen row as the chosen segment is.
   Under it the chosen landing's place: as on the peer in the bar's well
   (its files under the path, the peer's path in the foot), into a folder
   in its own box — the libraries, this server's folders, where the files
   go, that nothing is saved */
.dm-land-label { margin-bottom: 6px; font-size: 12px; line-height: 1.4; font-weight: 600; color: var(--t2); }
.dm-land { display: grid; gap: 2px; }
.dm-land-opt {
  display: grid; grid-template-columns: 16px minmax(0, 1fr); column-gap: 10px; align-items: center; min-height: 40px; margin: 0;
  padding: 6px 10px; box-sizing: border-box; border-radius: 4px; cursor: pointer;
}
.dm-land-opt:hover { background: var(--hover); }
.dm-land-opt.dm-on { background: var(--btn); box-shadow: inset 0 0 0 1px var(--src); }
.dmodal .dm-land-opt .dm-land-radio { grid-column: 1; grid-row: 1; position: static; width: 16px; height: 16px; margin: 0; opacity: 1; pointer-events: auto; accent-color: var(--src); cursor: pointer; }
/* the row draws the keyboard's ring, as the stacked segments do */
.dmodal-shadow .dmodal .dm-land-opt:has(.dm-land-radio:focus-visible) { outline: 2px solid var(--t1); outline-offset: 1px; }
.dmodal-shadow .dmodal .dm-land-opt .dm-land-radio:focus-visible { outline: none; }
.dm-land-text { grid-column: 2; grid-row: 1; display: block; min-width: 0; }
.dm-land-name { display: block; font-size: 12.5px; line-height: 1.35; font-weight: 600; color: var(--t2); overflow-wrap: anywhere; }
.dm-land-opt.dm-on .dm-land-name { color: var(--t1); }
.dm-land-sub { display: block; font-size: 11px; line-height: 1.4; color: var(--t4); }
.dm-land-files { display: grid; gap: 1px; margin-top: 4px; padding-left: 22px; min-width: 0; }
.dm-land-file { font: 11.5px/1.45 ui-monospace, Consolas, monospace; color: var(--t3); overflow-wrap: anywhere; }
.dm-land-more { font-size: 11.5px; line-height: 1.45; color: var(--t4); }
.dm-land-into { display: grid; gap: 12px; padding: 12px; min-width: 0; border: 1px solid var(--bord); border-radius: 6px; }
.dm-land-into > * { min-width: 0; }
.dm-land-field { display: grid; gap: 6px; min-width: 0; }
.dm-land-field > .dm-land-label { margin-bottom: 0; }
.dm-land-into .dm-input, .dm-land-into .dm-input[type="text"] {
  height: 32px; padding: 0 10px; font-size: 12.5px; color: var(--t1); background: var(--well); border-color: var(--field);
}
.dm-land-into .dm-input::placeholder { color: var(--t4); }
.dm-land-into .dm-input[type="text"]:focus { border-color: var(--src); }
.dm-land-preview { display: flex; gap: 8px; align-items: flex-start; padding: 8px 10px; background: var(--well); border-radius: 4px; }
.dm-land-preview > svg { flex-shrink: 0; margin-top: 1px; color: var(--src); }
.dm-land-preview-body { flex: 1 1 auto; min-width: 0; }
.dm-land-preview .dm-land-files { padding-left: 0; }
.dm-land-note { display: flex; gap: 6px; align-items: flex-start; font-size: 11.5px; line-height: 1.4; color: var(--t4); overflow-wrap: anywhere; }
.dm-land-note > svg { flex: none; margin-top: 2px; }
.dm-land-foot { font-size: 11.5px; line-height: 1.4; color: var(--t4); overflow-wrap: anywhere; }
@media (max-width: 600px) {
  .dm-play-btn, .dm-play-btn:focus { width: 44px; height: 44px; }
  /* every target 44 px tall; the actions share their row, a lone one the
     card's width, the primary still last */
  .dm-keep { padding: 10px; }
  .dm-seg { min-height: 44px; }
  .dm-check { min-height: 44px; }
  .dm-keep-acts > .dm-btn { flex: 1 1 0; }
  .dm-land-opt { min-height: 44px; }
  .dm-land-into { padding: 10px; }
  .dm-land-into .dm-input, .dm-land-into .dm-input[type="text"] { height: 44px; }
}
/* Phones: the queue buttons under the play row's title; a fact row's
   links under its facts, never alone on a line of their own; the choice
   strip as stacked rows, each with its radio in sight */
@media (max-width: 480px) {
  .dm-play { row-gap: 6px; }
  .dm-play-act { flex-basis: 100%; padding-left: 56px; flex-wrap: wrap; }
  .dm-fact { grid-template-columns: 44px minmax(0, 1fr); align-items: baseline; padding-top: 6px; }
  .dm-fact-links { grid-column: 2; flex-wrap: wrap; margin: 0 0 0 -8px; }
  .dm-segs { grid-auto-flow: row; grid-template-columns: minmax(0, 1fr); }
  .dm-seg { display: grid; grid-template-columns: 16px minmax(0, 1fr); column-gap: 10px; align-items: center; min-height: 44px; padding: 8px 10px; }
  .dmodal .dm-seg .dm-seg-input { position: static; grid-column: 1; grid-row: 1; width: 16px; height: 16px; opacity: 1; pointer-events: auto; accent-color: var(--src); }
  .dmodal-shadow .dmodal .dm-seg .dm-seg-input:focus-visible { outline: none; }   /* the row draws the ring */
  .dm-seg-text { grid-column: 2; grid-row: 1; }
  .dm-seg-label { font-size: 13px; }
  .dm-seg-sub { font-size: 11.5px; line-height: 1.35; }
}

/* ── The Discover page (m.js discoveryPanel) ─────────────────────────────
   The history-seeded page in #browser: a gray configuration bar (the
   window, "More options" → the seed chips; on Explore its one checkbox).
   Discover (play now): small labels with their source's dot — library
   #657ee4, connected servers #d9a441 — over album strips, then the songs
   in two columns where the page's content box is ≥ 560 px (a 1440 window with the Now Playing panel open) (the @container
   rule below, so the sidenav and the queue panel count), stacked under
   it. With no connected server the library's songs flow column-major over
   both columns. Explore (the network, #4fb8a8) keeps its section look. */
.dpage { padding: 0 0 16px 0; color: #dfe3ea; font-size: 13px; line-height: 1.4; container-type: inline-size; container-name: dpage; }
.dpage .grow { flex-grow: 1; }
.dpage-busy .dpage-sec, .dpage-busy .dpage-seeds, .dpage-busy .dpage-strip, .dpage-busy .dpage-songs { opacity: .6; transition: opacity .15s; }
/* The bar's host: #dpage-head, in the #browser column's chrome above the
   #filelist scroller (as #directory_bar is for the other panels), so the bar
   never scrolls. Its own .dpage (.dpage-chrome) carries the page's type and
   colour without the page's bottom padding. The host carries the one line
   under it: the last child drops its own. The open picker is capped, so a
   long seed list never eats the scroll box. */
#dpage-head { flex-shrink: 0; background: #262a33; border-bottom: 1px solid #2c313a; }
#dpage-head .dpage-chrome { padding: 0; }
#dpage-head .dpage-chrome > :last-child { border-bottom: 0; }
#dpage-head .dpage-options { max-height: 45vh; overflow-y: auto; }
/* the configuration bar: one quiet gray row (the sidenav's surface) */
.dpage-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; padding: 6px 10px 6px 14px; background: #262a33; border-bottom: 1px solid #2c313a; font-size: 12px; }
.dpage-bar-r { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; }
.dpage-bar-opt { height: 28px; padding: 0 4px; display: inline-flex; align-items: center; gap: 5px; background: transparent; border: 0; border-radius: 4px; color: #8ea0f0; font-size: 12px; cursor: pointer; white-space: nowrap; }
.dpage-bar-opt:hover { color: #dfe3ea; }
.dpage-bar-opt[aria-expanded="true"] { color: #dfe3ea; }
.dpage-bar-caret { font-size: 10px; }
/* the drawer under the bar: (Explore) its one checkbox, then the seed picker */
.dpage-options { background: #23282f; border-bottom: 1px solid #2c313a; }
.dpage-options > .dpage-hint { padding-left: 14px; }
.dpage-opt-row { padding: 10px 14px 0 14px; }
.dpage-window { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: #8a919e; }
/* Its fill is the global select rule's (#2d333b, !important): a step up from the bar. */
.dpage-window select.browser-default { height: 28px; padding: 0 8px; border: 1px solid #444c56; border-radius: 4px; color: #F5F7FA; font-size: 13px; width: auto; }
.dpage-icon-btn { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 0; border-radius: 4px; color: #dfe3ea; cursor: pointer; }
.dpage-icon-btn:hover { background: rgba(255, 255, 255, .08); }
/* dim, but AA on the page (a column's only line in some states) */
.dpage-hint { padding: 6px 16px 10px 16px; font-size: 12px; font-style: italic; color: #8a919e; }
.dpage-hint b { color: #dfe3ea; font-style: normal; }
.dpage-hint a { color: #8ea0f0; font-style: normal; }
.dpage-hint-btn { margin-left: 8px; font-style: normal; vertical-align: middle; }
.dpage-off .dpage-hint { padding: 18px 14px; font-size: 13px; }

/* seeds */
.dpage-seeds { padding: 10px 14px; }
.dpage-seeds-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; margin-bottom: 8px; }
.dpage-cap { font-size: 11px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: #8a919e; }
.dpage-sub { font-size: 11.5px; font-style: italic; color: #6f7683; min-width: 0; }
.dpage-chips { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.dpage-dropped { margin-top: 8px; }
.dpage-chip { height: 36px; max-width: 100%; display: inline-flex; align-items: center; gap: 8px; padding: 0 10px 0 4px; border: 1px solid #444c56; border-radius: 18px; background: #262b33; color: #dfe3ea; font-size: 12.5px; cursor: pointer; white-space: nowrap; }
.dpage-chip:hover { border-color: #657ee4; }
.dpage-chip-pin { border-color: #657ee4; }
.dpage-chip-dim { opacity: .6; }
.dpage-chip-art { width: 28px; height: 28px; border-radius: 4px; background: #2d333b; color: #6f7683; display: flex; align-items: center; justify-content: center; flex-shrink: 0; overflow: hidden; }
.dpage-chip-art img { width: 100%; height: 100%; object-fit: cover; }
.dpage-chip-label { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.dpage-chip-tag { font-size: 10.5px; color: #657ee4; }
.dpage-chip-x { color: #6f7683; margin-left: 2px; }
.dpage-chip:hover .dpage-chip-x { color: #e0616a; }
.dpage-dropped .dpage-chip:hover .dpage-chip-x { color: #4fc27a; }
.dpage-chip-more { padding-left: 10px; color: #8a919e; }
.dpage-chip-add { padding-left: 10px; color: #8ea0f0; border-style: dashed; }

/* the states' card */
.dpage-card { margin: 10px 14px; padding: 14px 16px; border: 1px solid #444c56; border-radius: 6px; background: #23282f; }
.dpage-card-t { font-size: 14px; color: #f0f2f5; margin-bottom: 4px; }
.dpage-card-s { font-size: 12px; color: #b8bcc6; }
.dpage-card-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.dpage-card-note { margin-top: 8px; font-size: 11px; font-style: italic; color: #6f7683; }
.dpage-btn { height: 30px; padding: 0 12px; border-radius: 4px; border: 1px solid #444c56; background: #1a1e25; color: #dfe3ea; font-size: 12px; cursor: pointer; }
.dpage-btn:hover { border-color: #8ea0f0; color: #f0f2f5; }
.dpage-btn.pri { background: #657ee4; border-color: #657ee4; color: #0f1216; font-weight: 600; }
.dpage-btn.pri:hover { background: #8ea0f0; border-color: #8ea0f0; }

/* the Explore page's one checkbox ("new artists only"): a button with
   role=checkbox, its box drawn here */
.dpage-tog { height: 28px; padding: 0 2px; border: 0; border-radius: 4px; background: transparent; color: #dfe3ea; font-size: 12.5px; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.dpage-check i { width: 14px; height: 14px; border: 1px solid #444c56; border-radius: 3px; background: #1a1e25; flex-shrink: 0; position: relative; }
.dpage-check.on i { background: #4fb8a8; border-color: #4fb8a8; }
.dpage-check.on i::after { content: ''; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px; border: solid #0f1216; border-width: 0 2px 2px 0; transform: rotate(45deg); }

/* the play page's labels: small letter-spaced caps after the source dot */
.dpage-label { display: flex; align-items: center; gap: 10px; margin: 0; padding: 16px 16px 10px 16px; font-size: 12px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase; color: #8a919e; line-height: 1.4; }
.dpage-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: #657ee4; }
.dpage-src-peers .dpage-dot { background: #d9a441; }
.dpage-sec-network .dpage-dot { background: #4fb8a8; }

/* album strips: the grid's cards, one row that scrolls sideways */
.album-grid.dpage-albums { display: grid; grid-auto-flow: column; grid-auto-columns: 150px; grid-template-columns: none; overflow-x: auto; gap: 16px; padding: 0 16px 6px 16px; scroll-snap-type: x mandatory; scroll-padding-inline: 16px; }
.dpage-album { position: relative; min-width: 0; scroll-snap-align: start; }
/* the strips' play button: the source's accent; shown on hover, on keyboard
   focus inside the card, and always where there is no hover */
.dpage-src-library .album-grid-play { background: #657ee4; }
.dpage-src-library .album-grid-play:hover, .dpage-src-library .album-grid-play:focus { background: #8ea0f0; }
.dpage-src-peers .album-grid-play { background: #d9a441; }
.dpage-src-peers .album-grid-play:hover, .dpage-src-peers .album-grid-play:focus { background: #e6b85c; }
.dpage .album-grid-play svg { fill: #0f1216; }
/* keyboard focus only (:focus-visible): a mouse click focuses the button
   too, and focus comes back to it when the menu or window it opened
   closes — :focus-within would keep the controls up until the next click */
.dpage .album-grid-card:has(:focus-visible) .album-grid-play { opacity: 1; transform: translateY(0); }
.dpage .album-grid-play:focus { outline: none; }
.dpage .album-grid-play:focus-visible, .dpage-peer-card:focus-visible { outline: 2px solid #fa832b; outline-offset: 2px; }
.dpage-peer-card:focus { outline: none; }
.dpage-peer-card:focus-visible { border-radius: 8px; }
/* a connected album's ⋯ (its recommendation window): the art's top-right
   corner, shown as the play button is — on hover, on keyboard focus inside
   the card, and always where there is no hover. The same ⋯ on a connected
   server's browse cards (m.js browseKeepCard), so not under .dpage */
.dpage-album-more { position: absolute; top: 6px; right: 6px; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; background: rgba(15, 18, 22, .72); color: #dfe3ea; font-size: 16px; line-height: 1; display: flex; align-items: center; justify-content: center; cursor: pointer; opacity: 0; transition: opacity .2s, background .15s; }
.album-grid-card:hover .dpage-album-more, .album-grid-card:has(:focus-visible) .dpage-album-more { opacity: 1; }
/* so is the card's play button, which Tab reaches first: keyboard focus
   inside any card shows it, with the house ring — never a press on a
   button no one can see */
.album-grid-card:has(:focus-visible) .album-grid-play { opacity: 1; transform: translateY(0); }
.album-grid-play:focus { outline: none; background-color: rgba(30, 215, 96, .9); }
.album-grid-play:focus-visible { outline: 2px solid #fa832b; outline-offset: 2px; }
.dpage-album-more:hover, .dpage-album-more:focus { background: rgba(15, 18, 22, .9); color: #f0f2f5; outline: none; }
.dpage-album-more:focus-visible { outline: 2px solid #fa832b; outline-offset: 2px; }
.dpage-skel-card i { display: block; aspect-ratio: 1; border-radius: 8px; background: #262b33; }
.dpage-skel-card b { display: block; height: 10px; width: 70%; margin-top: 8px; border-radius: 3px; background: #262b33; }
.dpage-skel-card b + b { width: 45%; }

/* the songs: library | connected servers */
.dpage-songs { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 32px; padding-top: 4px; }
.dpage-col { min-width: 0; }
.dpage-rows { padding: 0 8px; }
.dpage-row { min-height: 52px; gap: 12px; padding: 6px 6px 6px 8px; border-radius: 4px; }
.dpage-songs .discover-row-title { font-size: 13px; color: #F5F7FA; }
.dpage-songs .discover-row-sub { font-size: 12px; }
.dpage-art { width: 40px; height: 40px; border-radius: 3px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; overflow: hidden; background: #2d333b; }
.dpage-art img { width: 100%; height: 100%; object-fit: cover; }
.dpage-art-ph { background: #262a33; border: 1px solid #444c56; box-sizing: border-box; color: #8a919e; }
.dpage-skel-row { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 6px 8px; }
.dpage-skel-row i { width: 40px; height: 40px; border-radius: 3px; background: #262b33; flex-shrink: 0; }
.dpage-skel-row span { flex-grow: 1; }
.dpage-skel-row b { display: block; height: 10px; width: 46%; margin: 4px 0; border-radius: 3px; background: #262b33; }
.dpage-skel-row b + b { width: 30%; }
.dpage-more { display: inline-block; margin: 6px 0 0 16px; padding: 4px 0; background: transparent; border: 0; color: #8ea0f0; font-size: 12px; cursor: pointer; }
.dpage-more:hover { color: #dfe3ea; }
.dpage-more:focus { background-color: transparent; outline: none; }
@container dpage (min-width: 560px) {
  .dpage-songs:not(.dpage-songs-solo) { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  /* no connected server: rows 1–8 left, 9–16 right (m.js columnBlocks) */
  .dpage-flow { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: repeat(var(--dpage-per, 8), auto); grid-auto-flow: column; column-gap: 32px; }
}
/* In the two-column range on a pointer device the hidden verbs would
   otherwise reserve their width inside a ~300 px column and clip every
   title: they float over the row's right end on hover instead (the row
   and the verbs share the hover ground). Touch keeps them inline and
   always visible (the hover: none rule below). */
@container dpage (min-width: 560px) and (max-width: 899px) {
  @media (hover: hover) {
    .dpage-row { position: relative; }
    .dpage-verbs { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); padding-left: 10px; background: #1e222a; pointer-events: none; }
    .dpage-row:hover .dpage-verbs, .dpage-row:has(:focus-visible) .dpage-verbs { pointer-events: auto; }
  }
}

/* rows' hover verbs */
.dpage-tag { font-size: 11px; color: #6f7683; white-space: nowrap; flex-shrink: 0; }
.dpage-new { color: #4fb8a8; }
/* a row's badge and bar slots (patched in place on a job poll): no box */
.dpage-slot { display: contents; }
.dpage-verbs { display: flex; align-items: center; gap: 6px; flex-shrink: 0; opacity: 0; transition: opacity .12s; }
.dpage-row:hover .dpage-verbs, .dpage-row:has(:focus-visible) .dpage-verbs { opacity: 1; }
/* a browser without :has() keeps the old rule, so the keyboard still
   reaches the controls */
@supports not selector(:has(*)) {
  .album-grid-card:focus-within .album-grid-play { opacity: 1; transform: translateY(0); }
  .album-grid-card:focus-within .dpage-album-more, .dpage-row:focus-within .dpage-verbs { opacity: 1; pointer-events: auto; }
}
.dpage-vb { height: 26px; min-width: 26px; padding: 0 8px; border-radius: 4px; border: 1px solid #444c56; background: #1a1e25; color: #dfe3ea; font-size: 11.5px; display: inline-flex; align-items: center; justify-content: center; gap: 5px; cursor: pointer; white-space: nowrap; }
.dpage-vb:hover { border-color: #8ea0f0; color: #f0f2f5; }
/* keyboard focus: the house outline (a mouse click draws none) */
.dpage-tog:focus, .dpage-chip:focus, .dpage-btn:focus, .dpage-vb:focus, .dpage-icon-btn:focus,
.dpage-bar-opt:focus, .dpage a:focus { outline: none; }
/* materialize paints every focused button teal (button:focus); a control
   that was re-focused after a re-render, or tabbed to, keeps its own face. */
.dpage-tog:focus, .dpage-icon-btn:focus, .dpage-bar-opt:focus { background-color: transparent; }
.dpage-icon-btn:focus:hover { background-color: rgba(255, 255, 255, .08); }
.dpage-chip:focus { background-color: #262b33; }
.dpage-btn:not(.pri):focus { background-color: #1a1e25; }
.dpage-vb:focus { background-color: #1a1e25; }
.dpage-tog:focus-visible, .dpage-chip:focus-visible, .dpage-btn:focus-visible, .dpage-vb:focus-visible,
.dpage-icon-btn:focus-visible, .dpage-bar-opt:focus-visible, .dpage-more:focus-visible, .dpage a:focus-visible { outline: 2px solid #fa832b; outline-offset: 2px; }
.dpage-badge { font-size: 11px; white-space: nowrap; flex-shrink: 0; max-width: 45%; overflow: hidden; text-overflow: ellipsis; }
.dpage-badge-src { color: #4fb8a8; }
.dpage-badge-ok { color: #4fc27a; }
.dpage-badge-err { color: #e0616a; }
.dpage-badge-dim { color: #8a919e; }
.dpage-prog { height: 3px; background: #262b33; border-radius: 2px; margin-top: 4px; overflow: hidden; }
.dpage-prog i { display: block; height: 100%; background: #4fb8a8; border-radius: 2px; }
/* the play page's copies (connected-server rows and album cards): the word
   and what it acts on, never a number; the bar is drawn by a scale */
.dpage-prog-thin i { width: 100%; transform-origin: left center; }
/* a connected row's badge shares the subtitle line ("Artist · Album" gives
   way first) and its bar is pinned to the row's bottom edge: neither adds a
   line, so a badge arriving on the poll never changes the row's height */
.dpage-songs .dpage-row { position: relative; }
.dpage-subline { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.dpage-subtext { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dpage-subline .dpage-badge { flex-shrink: 0; max-width: 60%; }
.dpage-songs .dpage-row .dpage-prog-thin { position: absolute; left: 8px; right: 6px; bottom: 1px; margin: 0; height: 2px; }
/* a connected album card's state line: kept on every card, a fixed line
   box the badge fills — a badge that appears on the poll's beat never
   grows the card, so the strip never changes height under the user */
.dpage-strip .dpage-cstate { display: block; height: 16px; margin-top: 2px; overflow: hidden; }
.dpage-strip .dpage-cstate .dpage-badge { display: block; max-width: 100%; margin: 0; line-height: 16px; }
.dpage-src-peers .album-grid-art .dpage-prog { position: absolute; left: 0; right: 0; bottom: 0; margin: 0; border-radius: 0; background: rgba(15, 18, 22, .6); }
.dpage-src-peers .album-grid-art .dpage-prog i { border-radius: 0; }
/* the columns' footers: dim links */
.dpage-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; padding: 6px 16px 4px 16px; font-size: 12px; }
/* the whole-list verbs, under a column's header and ahead of its rows */
.dpage-acts { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; padding: 0 16px 8px 16px; font-size: 12px; }
.dpage-acts a { color: #8a919e; }
.dpage-acts a:hover { color: #dfe3ea; }
.dpage-acts a.dpage-acts-pri { color: #657ee4; }
.dpage-acts a.dpage-acts-pri:hover { color: #8ea0f0; }
.dpage-src-peers .dpage-acts a.dpage-acts-pri { color: #d9a441; }
.dpage-foot a { color: #8a919e; }
.dpage-foot a:hover { color: #dfe3ea; }
.dpage-foot a.dpage-foot-pri { color: #657ee4; }
.dpage-foot a.dpage-foot-pri:hover { color: #8ea0f0; }
.dpage-src-peers .dpage-foot a.dpage-foot-pri { color: #d9a441; }
.dpage-sep { color: #6f7683; }
.dpage-foot-note { margin-left: auto; font-weight: 400; font-style: italic; color: #6f7683; }

/* Explore: the network section */
.dpage-sec { border-top: 1px solid #2c313a; }
.dpage > .dpage-sec:first-child { border-top: 0; }
.dpage-sec-h { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; padding: 14px 14px 8px 14px; }
.dpage-sec-h h3 { margin: 0; font-size: 11px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: #dfe3ea; line-height: 1.4; }
.dpage-plugins { display: flex; flex-wrap: wrap; gap: 4px 12px; padding: 0 16px 6px 16px; font-size: 11px; color: #6f7683; }
.dpage-plugin b { color: #b8bcc6; font-weight: 600; }

/* the now-playing panel's "Discover page →": where the ping has the page */
.discover-page-footer { display: none; }
body.has-discover-page .discover-page-footer { display: flex; }
body.on-federated-server .discover-page-footer { display: none; }
.discover-page-link { font-size: 11.5px; font-weight: 600; color: #8ea0f0; }
.discover-page-link:hover { color: #dfe3ea; }

/* no hover (a touch screen, any width): the verbs stay, with room to tap */
@media (hover: none) {
  .dpage-verbs { opacity: 1; }
  .dpage .album-grid-play { opacity: 1; transform: translateY(0); }
  .dpage-vb { min-width: 40px; height: 40px; }
  .dpage-album-more { opacity: 1; width: 36px; height: 36px; }
}

@media (max-width: 600px) {
  .dpage-bar { padding: 6px 16px; }
  .dpage-bar .grow { display: none; }
  .dpage-bar-r { flex: 1 0 100%; justify-content: flex-end; }
  .dpage-seeds, .dpage-opt-row { padding-left: 16px; padding-right: 16px; }
  .dpage-options > .dpage-hint { padding-left: 16px; }
  .dpage-chip { height: 30px; font-size: 12px; }
  .dpage-chip-art { width: 22px; height: 22px; }
  /* no hover on a phone: the verbs stay; the row's own tap queues */
  .dpage-verbs { opacity: 1; }
  .dpage-foot-note { margin-left: 0; width: 100%; }
}
/* a narrow content box (a phone, or the sidenav and queue open on a tablet):
   smaller cards and art */
@container dpage (max-width: 600px) {
  .album-grid.dpage-albums { grid-auto-columns: 120px; gap: 12px; }
  .dpage-art, .dpage-skel-row i { width: 36px; height: 36px; }
}
