/* ═══════════════════════════════════════════════════════
   VARIABLES & RESET
═══════════════════════════════════════════════════════ */
:root {
  --green: #1DB954;
  --green-dim: #1aa34a;
  --bg: #0a0a0a;
  --surface: #121212;
  --surface2: #181818;
  --surface3: #242424;
  --surface4: #2a2a2a;
  --text: #ffffff;
  --text-muted: #b3b3b3;
  --text-dim: #6a6a6a;
  --border: rgba(255,255,255,0.07);
  --player-h: 90px;
  --sidebar-w: 72px;
  /* Task 660 — width of the expanded sidebar. Applied via .app.sidebar-expanded
     inside a desktop-only media query so the mobile override of --sidebar-w
     (0px, sidebar hidden) can never be shadowed by it. */
  --sidebar-w-expanded: 220px;
  --nav-h: 60px;
  --radius: 10px;
  --transition: 0.2s ease;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
body {
  font-family: 'DM Sans', sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  user-select: none;
}
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--surface4); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #555; }
button { cursor: pointer; border: none; background: none; color: inherit; font-family: inherit; }
a { color: inherit; text-decoration: none; }
img { display: block; }

/* ═══════════════════════════════════════════════════════
   LAYOUT
═══════════════════════════════════════════════════════ */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: 1fr var(--player-h);
  height: 100vh;
  transition: grid-template-columns 0.15s ease;
}
.sidebar {
  /* Task 660 — spans both rows: the player no longer runs underneath it, so
     the sidebar has to reach the bottom of the window itself. */
  grid-row: 1 / -1;
  grid-column: 1;
  background: #000;
  display: flex;
  flex-direction: column;
  /* Task 660 — stretch + fixed padding in BOTH states: the icon column sits at
     a constant x, so collapsing and expanding animate width only. Centring the
     items when collapsed and left-aligning them when expanded made the icons
     jump the moment the class flipped, while the width was still animating. */
  align-items: stretch;
  padding: 16px 12px;
  gap: 8px;
  border-right: 1px solid var(--border);
  /* Above the player (z-index: 20). A grid item with z-index creates its own
     stacking context, so the avatar popup — which lives inside the sidebar and
     opens over the content area — was being covered by the player bar despite
     its own z-index: 999 (task 660). */
  z-index: 30;
}
.main {
  grid-row: 1;
  grid-column: 2;
  overflow-y: auto;
  background: linear-gradient(180deg, #1a1a1a 0%, var(--bg) 300px);
  position: relative;
}
.player-bar {
  grid-row: 2;
  /* Task 660 — starts after the sidebar and follows its width. */
  grid-column: 2;
  background: #0d0d0d;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 0 20px;
  gap: 20px;
  z-index: 20;
}

/* ═══════════════════════════════════════════════════════
   SIDEBAR
═══════════════════════════════════════════════════════ */
/* Task 660 — sidebar header: logo, wordmark (expanded only), collapse toggle. */
.sidebar-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 6px;              /* 12 (sidebar) + 6 = logo centred in 72px */
  margin-bottom: 8px;
  flex-shrink: 0;
}
.sidebar-wordmark {
  display: none;
  font-size: 17px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  cursor: pointer;
  flex: 1;
}
.sidebar-toggle {
  height: 40px;
  flex-shrink: 0;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: flex-start;
  padding-left: 13.5px;        /* 12 + 13.5 + 10.5 = icon centre at 36px */
  color: var(--text-muted);
  background: none; border: none; cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.sidebar-toggle:hover { background: var(--surface3); color: var(--text); }
.sidebar-toggle svg { width: 21px; height: 21px; flex-shrink: 0; }

.logo-mark {
  width: 36px; height: 36px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.logo-mark img {
  width: 36px; height: 36px;
  object-fit: contain;
}
.sidebar-btn {
  height: 48px;
  flex-shrink: 0;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: flex-start;
  gap: 14px;
  padding-left: 13px;          /* 12 + 13 + 11 = icon centre at 36px */
  color: var(--text-muted);
  transition: background var(--transition), color var(--transition);
  position: relative;
}
.sidebar-btn:hover { background: var(--surface3); color: var(--text); }
.sidebar-btn.active { background: var(--surface3); color: var(--green); }
.sidebar-btn svg { width: 22px; height: 22px; flex-shrink: 0; }
.sidebar-btn .tip {
  position: absolute;
  left: calc(100% + 8px);
  background: #333;
  color: #fff;
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 6px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translateX(-4px);
  transition: 0.15s;
  z-index: 100;
}
.sidebar-btn:hover .tip { opacity: 1; transform: translateX(0); }
.sidebar-spacer { flex: 1; }

/* Task 660 — user block at the bottom: avatar alone when collapsed,
   avatar + name when expanded. */
.sidebar-user-wrap { position: relative; display: flex; }
.sidebar-user {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1;
  border-radius: 12px;
  padding: 6px;                /* 12 + 6 = avatar centred in 72px */
  cursor: pointer;
  transition: background var(--transition);
  min-width: 0;
}
.sidebar-user:hover { background: var(--surface3); }
.sidebar-username {
  display: none;
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-avatar {
  width: 36px; height: 36px;
  flex-shrink: 0;
  background: var(--green);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 14px; color: #000;
  cursor: pointer;
  position: relative;
}
/* ═══════════════════════════════════════════════════════
   SIDEBAR — EXPANDED STATE (task 660)

   Desktop only. Below 769px the sidebar is hidden entirely and .mobile-nav
   takes over, so scoping this to min-width keeps the collapse state from
   leaking into the mobile layout.
═══════════════════════════════════════════════════════ */
@media (min-width: 769px) {
  .app.sidebar-expanded { --sidebar-w: var(--sidebar-w-expanded); }

  /* Only the labels differ between the two states — the icon column, the
     paddings and the row geometry are identical, so nothing moves while the
     width animates.

     Labels fade in AFTER the width transition (delay = its duration): shown
     immediately, they would stick out past a sidebar that is still 72px wide.
     Collapsing drops the rule outright, so they vanish at once and never
     overflow. */
  .app.sidebar-expanded .sidebar-wordmark,
  .app.sidebar-expanded .sidebar-username { display: block; }

  /* The same <span class="tip"> that is a hover tooltip when collapsed becomes
     an inline label here — no duplicate markup to keep in sync. */
  .app.sidebar-expanded .sidebar-btn .tip {
    position: static;
    transform: none;
    background: none;
    color: inherit;
    font-size: 14px;
    font-weight: 500;
    padding: 0;
    border-radius: 0;
    z-index: auto;
    white-space: nowrap;
    min-width: 0;
    overflow: hidden;
  }

  .app.sidebar-expanded .sidebar-wordmark,
  .app.sidebar-expanded .sidebar-username,
  .app.sidebar-expanded .sidebar-btn .tip {
    animation: sv-sidebar-label-in 0.12s ease 0.15s both;
  }
}

@keyframes sv-sidebar-label-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ═══════════════════════════════════════════════════════
   SEARCH VIEW
═══════════════════════════════════════════════════════ */
.search-panel {
  padding: 24px 24px 40px;
  width: 100%;
  box-sizing: border-box;
}
.search-bar {
  display: flex;
  gap: 0;
  background: var(--surface3);
  border: 1.5px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  transition: border-color 0.15s;
  margin-bottom: 20px;
  width: 100%;
  box-sizing: border-box;
}
.search-bar:focus-within { border-color: var(--accent); }
.search-input {
  flex: 1;
  background: none;
  border: none;
  outline: none;
  color: var(--text);
  font-size: 16px;
  padding: 14px 18px;
  font-family: inherit;
}
.search-input::placeholder { color: var(--text-dim); }
.search-go-btn {
  background: var(--accent);
  border: none;
  color: #000;
  width: 56px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s;
  flex-shrink: 0;
}
.search-go-btn:hover { background: #1ed760; }
.search-go-btn svg { width: 22px; height: 22px; }
.search-status {
  font-size: 13px;
  color: var(--text-muted);
  margin-bottom: 10px;
  min-height: 18px;
  padding: 0 4px;
}

/* Results table header */
.sr-table-head {
  display: grid;
  grid-template-columns: 48px 48px 2fr 1.5fr 80px 64px 1fr 34px;
  gap: 0 12px;
  align-items: center;
  padding: 6px 12px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
/* Unified header grid (follow-up: «формат с шапкой» for all lists). Matches
   .track-row.tr-unified columns so header cells line up with row cells. */
.sr-table-head.tr-unified-header {
  grid-template-columns: 32px 48px 1fr 1fr 56px 60px 72px 40px 28px;
  gap: 8px;
  padding: 8px 24px;
}
.sr-th {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-dim);
}
.search-results { display: flex; flex-direction: column; gap: 1px; width: 100%; }

/* Result row: № | cover | title+sub | album | format | duration | path */
.sr-item {
  display: grid;
  grid-template-columns: 48px 48px 2fr 1.5fr 80px 64px 1fr 34px;
  align-items: center;
  gap: 0 12px;
  padding: 7px 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s;
}
/* ── Search result rows ── */
.sr-item:hover { background: var(--surface3); }

/* Default: number visible, arrow+bars hidden */
.sr-num {
  font-size: 13px;
  color: var(--text-dim);
  text-align: center;
  position: relative;
  width: 36px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.sr-num-label { transition: opacity 0.15s; }

/* Arrow — always green, hidden by default */
.sr-play {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  transition: opacity 0.15s;
  color: #1db954;
}
/* Bars — hidden by default */
.sr-bars {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
}

/* HOVER (non-playing): hide number, show green arrow */
.sr-item:not(.sr-playing):hover .sr-num-label { opacity: 0; }
.sr-item:not(.sr-playing):hover .sr-play    { opacity: 1; }

/* PLAYING (not paused): hide number+arrow, show bars */
.sr-item.sr-playing:not(.paused) .sr-num-label { opacity: 0; }
.sr-item.sr-playing:not(.paused) .sr-play      { opacity: 0; }
.sr-item.sr-playing:not(.paused) .sr-bars      { opacity: 1; }

/* PLAYING + PAUSED: green number, no bars, no arrow */
.sr-item.sr-playing.paused .sr-num-label { opacity: 1; color: #1db954; }
.sr-item.sr-playing.paused .sr-bars      { opacity: 0; }
.sr-item.sr-playing.paused .sr-play      { opacity: 0; }

/* PLAYING hover: never show arrow */
.sr-item.sr-playing:hover .sr-play { opacity: 0; }

/* Title green when playing */
.sr-item.sr-playing .sr-title      { color: #1db954; }
.sr-item.sr-playing .sr-sub        { color: #1db954; }
.sr-item.sr-playing .sr-album-cell { color: #1db954; }
.sr-item.sr-playing .sr-format     { color: #1db954; background: rgba(29,185,84,0.12); }
.sr-item.sr-playing .sr-duration   { color: #1db954; }
.sr-item.sr-playing .sr-path       { color: #1db954; opacity: 0.7; }

/* Cover thumbnail */
.sr-cover {
  width: 40px; height: 40px;
  border-radius: 5px;
  object-fit: cover;
  background: var(--surface4);
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.sr-cover img { width: 100%; height: 100%; object-fit: cover; border-radius: 5px; }
.sr-cover-none {
  width: 40px; height: 40px;
  border-radius: 5px;
  background: var(--surface4);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-dim);
  flex-shrink: 0;
}

.sr-info { min-width: 0; }
.sr-title {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sr-sub {
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-top: 2px;
}
.sr-sub em, .sr-title em {
  font-style: normal;
  color: var(--accent);
  font-weight: 600;
}
.sr-album-cell {
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sr-album-cell em {
  font-style: normal;
  color: var(--accent);
  font-weight: 600;
}
.sr-format {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--text-dim);
  background: var(--surface4);
  border-radius: 4px;
  padding: 2px 7px;
  text-transform: uppercase;
  width: fit-content;
}
.sr-duration {
  font-size: 13px;
  color: var(--text-dim);
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.sr-path {
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: monospace;
  opacity: 0.7;
}

/* ═══════════════════════════════════════════════════════
   ABOUT MODAL
═══════════════════════════════════════════════════════ */
.about-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.65);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s;
}
.about-overlay.open { opacity: 1; pointer-events: all; }
.about-box {
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 40px 48px;
  text-align: center;
  max-width: 360px;
  width: 90%;
  transform: translateY(12px);
  transition: transform 0.25s cubic-bezier(.34,1.56,.64,1);
  position: relative;
}
.about-overlay.open .about-box { transform: translateY(0); }
.about-close {
  position: absolute; top: 14px; right: 14px;
  background: none; border: none;
  color: var(--text-muted); cursor: pointer;
  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s, color 0.15s;
}
.about-close:hover { background: var(--surface4); color: var(--text); }

/* Action bar at the bottom of the About modal (Web UI 1.0.76 — download APK).
   Left-aligned so it doesn't compete visually with the close button. */
.about-actions {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-start;
}
.about-action-btn {
  display: inline-flex;
  align-items: center;
  padding: 8px 14px;
  background: var(--surface3);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}
.about-action-btn:hover {
  background: var(--surface4);
  border-color: var(--accent);
}
.about-logo {
  width: 100%;
  max-width: min(60vw, 288px);
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  margin: 0 auto 20px;
  display: block;
  filter: drop-shadow(0 4px 18px rgba(29,185,84,0.35));
}
.about-title {
  font-size: 26px; font-weight: 700;
  color: var(--text);
  letter-spacing: -0.5px;
  margin-bottom: 6px;
}
.about-subtitle {
  font-size: 13px; color: var(--accent);
  font-weight: 600; letter-spacing: 1.5px;
  text-transform: uppercase;
  margin-bottom: 24px;
}
.about-sep {
  height: 1px; background: var(--border);
  margin: 20px 0;
}
.about-row {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 13px;
  padding: 4px 0;
}
.about-row-label { color: var(--text-muted); }
.about-row-value { color: var(--text); font-weight: 500; }
.about-author-badge {
  display: inline-flex; align-items: center; gap: 6px;
  background: linear-gradient(135deg, var(--accent) 0%, #1ed760 100%);
  color: #000;
  font-size: 12px; font-weight: 700;
  padding: 4px 12px; border-radius: 20px;
  letter-spacing: 0.3px;
}

.user-menu {
  position: absolute;
  bottom: 50px; left: 8px;
  background: var(--surface3);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px;
  min-width: 180px;
  z-index: 999;
  display: none;
}
.user-menu.open { display: block; }
.user-menu-item {
  padding: 10px 12px;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  color: var(--text-muted);
  transition: background 0.15s, color 0.15s;
}
.user-menu-item:hover { background: var(--surface4); color: var(--text); }
.user-menu-sep { height: 1px; background: var(--border); margin: 6px 0; }

/* ═══════════════════════════════════════════════════════
   TOP NAV
═══════════════════════════════════════════════════════ */
.topbar {
  position: sticky; top: 0;
  display: flex; flex-direction: column; align-items: stretch;
  z-index: 5;
  background: rgba(10,10,10,0.8);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
/* #635: row 1 of the sticky topbar — back button, breadcrumbs, actions.
   Carries the padding that used to sit on .topbar itself. */
.topbar-row {
  display: flex; align-items: center;
  padding: 14px 24px;
  gap: 12px;
}
.breadcrumb {
  display: flex; align-items: center; gap: 6px;
  flex: 1;
  font-size: 15px;
  overflow: hidden;
}
.breadcrumb-item {
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: color 0.15s;
}
.breadcrumb-item:hover { color: var(--text); }
.breadcrumb-item.current { color: var(--text); font-weight: 600; cursor: default; }
.breadcrumb-sep { color: var(--text-dim); font-size: 12px; flex-shrink: 0; }
.topbar-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

/* ═════════════════════════════════════════════════════════════════
   LIBRARY FILTER + SORT BUTTONS (task 122)
   Two round icon buttons in the top bar, modelled on .back-btn.
   When the filter is active (≠ 'all') the filter button paints itself
   green so the user notices the library view is restricted.
═════════════════════════════════════════════════════════════════ */
.lib-icon-btn {
  width: 36px; height: 36px;
  background: var(--surface3);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted);
  transition: background 0.15s, color 0.15s;
  flex-shrink: 0;
  cursor: pointer;
  border: none;
}
.lib-icon-btn:hover { background: var(--surface4); color: var(--text); }
.lib-icon-btn svg { width: 18px; height: 18px; }
.lib-icon-btn.has-filter { background: var(--green); color: #000; }
.lib-icon-btn.has-filter:hover { background: var(--green-dim); }

/* ═════════════════════════════════════════════════════════════════
   LIBRARY PREFERENCES MODALS (filter + sort)
   Compact overlay-centered dialogs with radio options. Click outside
   closes the dialog (onclick handler on overlay).
═════════════════════════════════════════════════════════════════ */
.lib-pref-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 1000;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.lib-pref-overlay.open { display: flex; }
.lib-pref-box {
  background: var(--surface2);
  border-radius: 12px;
  padding: 20px 24px;
  min-width: 280px;
  max-width: 360px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
.lib-pref-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 14px;
}
.lib-pref-option {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 8px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text-muted);
  transition: background 0.1s, color 0.1s;
}
.lib-pref-option:hover { background: var(--surface3); color: var(--text); }
.lib-pref-option input[type="radio"] {
  accent-color: var(--green);
  width: 16px; height: 16px;
  margin: 0;
  cursor: pointer;
}
.lib-pref-option input[type="radio"]:checked + span { color: var(--text); font-weight: 500; }
.lib-pref-divider {
  height: 1px;
  background: var(--border);
  margin: 10px 0;
}
.lib-pref-dir-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 10px 12px;
  background: var(--surface3);
  border: none;
  border-radius: 6px;
  color: var(--text-muted);
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
}
.lib-pref-dir-btn:hover { background: var(--surface4); color: var(--text); }
.lib-pref-dir-btn svg { width: 16px; height: 16px; transition: transform 0.2s; }
.lib-pref-dir-btn.desc svg { transform: rotate(180deg); }

.back-btn {
  width: 36px; height: 36px;
  background: var(--surface3);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted);
  transition: background 0.15s, color 0.15s;
  flex-shrink: 0;
}
.back-btn:hover { background: var(--surface4); color: var(--text); }
.back-btn svg { width: 18px; height: 18px; }
.back-btn:disabled { opacity: 0.3; pointer-events: none; }

/* ═════════════════════════════════════════════════════════════════
   PROFILE MODAL (task 121)
   Shape mirrors .lib-pref-overlay/box for visual consistency, but
   wider since the form has labelled inputs + avatar row.
═════════════════════════════════════════════════════════════════ */
.profile-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 1000;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.profile-overlay.open { display: flex; }
.profile-box {
  background: var(--surface2);
  border-radius: 12px;
  padding: 24px 28px;
  width: 420px;
  max-width: 100%;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
/* ═══════════════════════════════════════════════════════
   SHARE LINKS MODAL (task 644)
═══════════════════════════════════════════════════════ */
.shares-box { width: 520px; }
.shares-hint {
  font-size: 13px;
  color: var(--text-muted);
  margin-bottom: 14px;
}
.shares-list {
  max-height: 420px;
  overflow-y: auto;
  margin-bottom: 8px;
}
.shares-empty {
  padding: 28px 0;
  text-align: center;
  font-size: 14px;
  color: var(--text-muted);
}
.share-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 4px;
  border-bottom: 1px solid var(--border);
}
.share-row:last-child { border-bottom: none; }
.share-info { flex: 1; min-width: 0; }
.share-title {
  font-size: 14px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.share-sub {
  font-size: 12px; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.share-meta { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.share-warn { color: var(--red, #e05555); }
/* A link the creator can no longer reach: still listed, visibly inert. */
.share-row-unavailable .share-title,
.share-row-unavailable .share-sub { opacity: 0.55; }
.share-actions { display: flex; gap: 6px; flex-shrink: 0; }
.share-btn {
  width: 34px; height: 34px;
  border: none; border-radius: 8px;
  background: var(--surface3);
  color: var(--text-muted);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.share-btn svg { width: 17px; height: 17px; }
.share-btn:hover { background: var(--surface4); color: var(--text); }
.share-btn-danger:hover { background: rgba(224,85,85,0.85); color: #fff; }

@media (max-width: 768px) {
  .shares-box { width: 100%; }
  .shares-list { max-height: 60vh; }
}

.profile-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 18px;
}
.profile-avatar-row {
  display: flex; align-items: center; gap: 18px;
  margin-bottom: 22px;
}
.profile-avatar-wrap {
  width: 80px; height: 80px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--surface3);
  flex-shrink: 0;
}
.profile-avatar-wrap img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.profile-avatar-actions {
  display: flex; flex-direction: column; gap: 8px;
}
.profile-field { margin-bottom: 14px; }
.profile-label {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.profile-readonly {
  color: var(--text);
  font-size: 14px;
  padding: 8px 0;
}
.profile-input {
  width: 100%;
  background: var(--surface3);
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text);
  font-size: 14px;
  padding: 10px 12px;
  outline: none;
  font-family: inherit;
  transition: border-color 0.15s;
  box-sizing: border-box;
}
.profile-input:focus { border-color: var(--green); }
.profile-input::placeholder { color: var(--text-dim); }
.profile-error {
  color: #ff6464;
  font-size: 12px;
  margin-top: 6px;
}
.profile-actions {
  display: flex; justify-content: flex-end; gap: 10px;
  margin-top: 8px;
}
.profile-btn-primary, .profile-btn-secondary {
  padding: 9px 18px;
  border-radius: 6px;
  font-size: 14px;
  font-family: inherit;
  border: none;
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
}
.profile-btn-primary {
  background: var(--green);
  color: #000;
  font-weight: 600;
}
.profile-btn-primary:hover { background: var(--green-dim); }
.profile-btn-secondary {
  background: var(--surface3);
  color: var(--text);
}
.profile-btn-secondary:hover { background: var(--surface4); }
.profile-btn-danger { color: #ff8a8a; }

/* User-avatar image (right of topbar). When the <img> loads it's shown
   and the letter fallback is hidden. We keep the circular shape from the
   existing .user-avatar rule (defined elsewhere) — only sizing here. */
#user-avatar-img {
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

/* ═════════════════════════════════════════════════════════════
   PROFILE MODAL — REDESIGN (Task 6, Web UI 1.0.96)
   Two-column layout: 80px avatar left, fields right.
   Avatar is clickable → popup menu (Upload / Delete).
   ═════════════════════════════════════════════════════════════ */

.profile-grid {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 20px;
  align-items: start;
  margin-bottom: 8px;
}

.profile-avatar-col {
  display: flex; flex-direction: column; align-items: center;
}

/* Click target for the avatar menu — pointer cursor + subtle ring on hover.
   Reuses the existing .profile-avatar-wrap circular shape. */
.profile-avatar-clickable {
  cursor: pointer;
  transition: box-shadow 0.15s;
}
.profile-avatar-clickable:hover {
  box-shadow: 0 0 0 2px var(--green-dim);
}

.profile-fields-col {
  min-width: 0;  /* enables ellipsis on overflowing username */
}

/* Inline username — «Имя пользователя: test» on one line */
.profile-username-line {
  font-size: 14px;
  color: var(--text);
  margin-bottom: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.profile-username-label {
  color: var(--text-muted);
  margin-right: 6px;
}
.profile-username-value {
  color: var(--text);
  font-weight: 600;
}

/* «Сменить пароль» — right-aligned red button under E-mail */
.profile-change-pwd-row {
  display: flex; justify-content: flex-end;
  margin-top: 10px;
}

/* Spacer between Change-Password row and the bottom Close/Save row —
   ~one input-element high (≈ 40px). */
.profile-actions-spacer {
  height: 40px;
}

/* Bottom actions — right-aligned, button size by text (not stretched) */
.profile-actions-compact {
  display: flex; justify-content: flex-end; gap: 8px;
  border-top: none;
  padding-top: 0;
}
.profile-actions-compact .profile-btn-secondary,
.profile-actions-compact .profile-btn-primary {
  /* Override any inherited width:100% that would stretch the buttons */
  width: auto;
  min-width: 0;
  padding: 8px 18px;
}

/* Avatar context menu — popup positioned at the avatar */
.avatar-menu {
  position: fixed;
  display: none;
  background: var(--surface3);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  z-index: 2000;
  min-width: 180px;
  padding: 4px 0;
}
.avatar-menu.open { display: block; }
.avatar-menu-item {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  color: var(--text);
  font-size: 14px;
  cursor: pointer;
}
.avatar-menu-item:hover { background: var(--surface4); }
.avatar-menu-item svg { width: 16px; height: 16px; flex-shrink: 0; }
.avatar-menu-item-danger { color: #ff8a8a; }
.avatar-menu-item-danger:hover { background: rgba(255, 138, 138, 0.12); }
.avatar-menu-item.disabled {
  opacity: 0.4;
  pointer-events: none;
}

/* Red solid button — reused from Task 6 «Сменить пароль» */
.profile-btn-danger-solid {
  background: #d93636;
  color: #fff;
  border: none;
  padding: 8px 18px;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.1s;
}
.profile-btn-danger-solid:hover { background: #b82e2e; }
.profile-btn-danger-solid:active { background: #a02828; }

/* Password-change rule checkers (task 120). Grey row → green-tinted text
   + filled check when the rule passes. Subtle animation makes the live
   feedback feel responsive without screaming. */
.pwd-rules {
  margin-top: 8px;
  display: flex; flex-direction: column; gap: 4px;
}
.pwd-rule {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px;
  color: var(--text-dim);
  transition: color 0.15s;
}
.pwd-rule.met { color: var(--green); }
.pwd-rule-mark {
  display: inline-block;
  width: 14px; text-align: center;
  font-family: 'DM Mono', monospace;
}
.pwd-rule.met .pwd-rule-mark { color: var(--green); }

/* ═══════════════════════════════════════════════════════
   GRID VIEW
═══════════════════════════════════════════════════════ */
#grid-view {
  padding: 24px;
}
.section-header {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 20px;
}
.section-title { font-size: 22px; font-weight: 700; letter-spacing: -0.3px; }
.section-count { font-size: 13px; color: var(--text-muted); }
.folder-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 16px;
}
.folder-card {
  background: var(--surface2);
  border-radius: var(--radius);
  overflow: hidden;
  cursor: pointer;
  transition: background 0.2s, transform 0.2s;
  position: relative;
}
.folder-card:hover { background: var(--surface3); transform: translateY(-2px); }
.folder-card:active { transform: scale(0.98); }
.folder-cover {
  aspect-ratio: 1;
  background: var(--surface3);
  overflow: hidden;
  position: relative;
}
.folder-cover img { width: 100%; height: 100%; object-fit: cover; }
.folder-cover .no-cover {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--surface3) 0%, var(--surface4) 100%);
}
.folder-cover .no-cover svg { width: 40%; height: 40%; opacity: 0.35; }
.folder-cover .play-overlay {
  position: absolute; bottom: 8px; right: 8px;
  width: 40px; height: 40px;
  background: var(--green);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.2s, transform 0.2s;
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
}
.folder-cover .play-overlay svg { width: 18px; height: 18px; margin-left: 2px; }
.folder-card:hover .play-overlay { opacity: 1; transform: translateY(0); }
.folder-meta {
  padding: 12px;
}
.folder-name {
  font-size: 14px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-bottom: 4px;
}
.folder-sub { font-size: 12px; color: var(--text-muted); }
.folder-card.subfolder .folder-sub::before { content: '📁 '; }
.folder-card.playing .folder-cover::after {
  content: '';
  position: absolute; inset: 0;
  background: rgba(29,185,84,0.2);
}

/* ═══════════════════════════════════════════════════════
   TRACK LIST VIEW
═══════════════════════════════════════════════════════ */
#track-view { padding: 0 0 24px; }
.album-header {
  display: flex; align-items: flex-end;
  gap: 24px;
  padding: 24px;
  background: linear-gradient(180deg, rgba(29,185,84,0.2) 0%, transparent 100%);
  margin-bottom: 8px;
}
.album-cover-lg {
  width: 180px; height: 180px;
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;
  box-shadow: 0 16px 48px rgba(0,0,0,0.6);
}
.album-cover-lg img { width: 100%; height: 100%; object-fit: cover; }
.album-cover-lg .no-cover-lg {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface3);
}
.album-cover-lg .no-cover-lg svg { width: 72px; height: 72px; opacity: 0.55; color: var(--text-muted); }
.album-info { flex: 1; min-width: 0; }
.album-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 1.5px; color: var(--text-muted); margin-bottom: 8px; }
.album-title { font-size: 28px; font-weight: 800; letter-spacing: -0.5px; margin-bottom: 8px; line-height: 1.1; }
.album-meta-line { font-size: 13px; color: var(--text-muted); }
.album-play-btn {
  display: flex; align-items: center; gap: 8px;
  background: var(--green);
  color: #000;
  border-radius: 50px;
  padding: 12px 28px;
  font-weight: 700; font-size: 14px;
  transition: background 0.2s, transform 0.1s;
}
.album-play-btn:hover { background: #1ed760; }
.album-play-btn:active { transform: scale(0.97); }
.album-play-btn svg { width: 18px; height: 18px; }

/* Track list header */
.track-list-header {
  display: grid;
  grid-template-columns: 28px 40px 1fr 1fr 54px 52px 68px 28px;
  gap: 8px;
  padding: 8px 24px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 1px;
}
.track-list-header.tr-unified-header {
  grid-template-columns: 32px 48px 1fr 1fr 56px 60px 72px 40px 28px;
}
.track-list { padding: 8px 0; }
/* #631 П4: the compact sticky album panel is a mobile-only affordance — hidden
   everywhere by default; the mobile media query turns it on via .visible. */
.album-sticky { display: none; }
.track-row {
  display: grid;
  grid-template-columns: 28px 40px 1fr 1fr 54px 52px 68px 28px;
  gap: 8px;
  padding: 8px 24px;
  border-radius: 6px;
  align-items: center;
  cursor: pointer;
  transition: background 0.15s;
  position: relative;
}
/* Unified track row (follow-up 2): № · cover · info · album · fmt · time ·
   size · heart · menu. One grid for library, playlist, favourites, search,
   «Недавно слушали», history. */
.track-row.tr-unified {
  grid-template-columns: 32px 48px 1fr 1fr 56px 60px 72px 40px 28px;
}
/* Playlist edit rows start with a drag handle and end with ×, which shifted
   every cell one column left (cover landed in a 1fr, album in 56px). Give that
   variant its own track list. */
.track-row.tr-unified.tr-edit {
  grid-template-columns: 32px 32px 48px 1fr 1fr 56px 60px 72px 28px;
}
.track-row:hover { background: var(--surface3); }
.track-row.playing:hover { background: rgba(29,185,84,0.13); }
.track-row.playing { color: var(--green); background: rgba(29,185,84,0.08); }
.track-num {
  position: relative;
  font-size: 14px; color: var(--text-dim);
  text-align: center;
  font-family: 'DM Mono', monospace;
  display: flex; align-items: center; justify-content: center;
  height: 100%;
}
.track-num-label { transition: opacity 0.15s; }
/* playing + not paused: hide number, show animated bars */
.track-row.playing:not(.paused) .track-num-label { opacity: 0; }
.track-playing-icon {
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
}
/* playing + not paused: show bars */
.track-row.playing:not(.paused) .track-playing-icon { opacity: 1; }
/* playing + paused: number visible again, bars hidden */
.track-row.playing.paused .track-num-label { opacity: 1; color: var(--green); }
.track-row.playing.paused .track-playing-icon { opacity: 0; }
.playing-bars {
  display: flex; align-items: flex-end; gap: 2px; height: 16px;
}
.playing-bars span {
  width: 3px; background: var(--green); border-radius: 2px;
  animation: bars 0.8s ease infinite;
}
.playing-bars span:nth-child(2) { animation-delay: 0.2s; }
.playing-bars span:nth-child(3) { animation-delay: 0.4s; }
@keyframes bars {
  0%, 100% { height: 4px; }
  50% { height: 14px; }
}
.track-info { min-width: 0; }
.track-title { font-size: 15px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.track-artist { font-size: 12px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.track-artist-col { font-size: 13px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.track-album-col { font-size: 13px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.track-fmt-col { font-size: 11px; color: var(--text-dim); font-family: 'DM Mono', monospace; min-width: 0; overflow: hidden; }
.track-size { font-size: 12px; color: var(--text-dim); font-family: 'DM Mono', monospace; text-align: right; min-width: 0; overflow: hidden; }
.track-dur { font-size: 12px; color: var(--text-dim); font-family: 'DM Mono', monospace; text-align: right; min-width: 0; overflow: hidden; }
/* .track-sort-bar / .track-sort-btn removed in Web UI 1.0.90 — track sort
   moved into the topbar dialog opened from the sort icon (task 122) */

/* ── Playlist info bar (replaces sort bar for CUE/M3U) ── */
.playlist-info-bar {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 24px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  flex-wrap: nowrap;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
}
.playlist-info-bar::-webkit-scrollbar { display: none; }
.playlist-info-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px;
  color: var(--text-muted);
  background: var(--surface3);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 4px 12px;
  flex-shrink: 0;
}
.playlist-info-chip svg {
  width: 13px; height: 13px;
  flex-shrink: 0;
  color: var(--accent);
}
.playlist-info-chip strong {
  color: var(--text);
  font-weight: 500;
}

/* ═══════════════════════════════════════════════════════
   PLAYER BAR
═══════════════════════════════════════════════════════ */
.player-left {
  display: flex; align-items: center; gap: 12px;
  width: 312px; min-width: 0; flex-shrink: 0;
}
.player-thumb {
  width: 70px; height: 70px;
  border-radius: 8px; overflow: hidden;
  background: var(--surface3); flex-shrink: 0;
}
.player-thumb img { width: 100%; height: 100%; object-fit: cover; }
.player-track-info { min-width: 0; }
.player-title { font-size: 17px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.player-artist { font-size: 15px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.player-fmt { font-size: 12px; color: var(--text-dim); font-family: 'DM Mono', monospace; margin-top: 2px; }

.player-center {
  flex: 1;
  display: flex; flex-direction: column;
  align-items: center;
  gap: 10px;
  max-width: 625px;
  margin: 0 auto;
}
.player-controls {
  display: flex; align-items: center; gap: 20px;
}
.ctrl-btn {
  color: var(--text-muted);
  transition: color 0.15s, transform 0.1s;
  display: flex; align-items: center; justify-content: center;
}
.ctrl-btn:hover { color: var(--text); }
.ctrl-btn:active { transform: scale(0.9); }
.ctrl-btn.active { color: var(--green); }
.ctrl-btn svg { width: 25px; height: 25px; }
.play-pause-btn {
  width: 50px; height: 50px;
  background: var(--green);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #000;
  transition: transform 0.1s, background 0.15s;
}
.play-pause-btn:hover { transform: scale(1.05); background: #1ed760; }
.play-pause-btn svg { width: 22px; height: 22px; }
.progress-row {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
}
.time-label { font-size: 13px; color: var(--text-dim); font-family: 'DM Mono', monospace; width: 36px; flex-shrink: 0; }
.time-label.right { text-align: right; }
.progress-bar {
  flex: 1; height: 4px;
  background: var(--surface4);
  border-radius: 2px;
  cursor: pointer;
  position: relative;
}
/* Расширяем зону клика/тача невидимым псевдоэлементом, не меняя высоту полосы */
.progress-bar::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: -10px; bottom: -10px;
}
.progress-fill {
  height: 100%;
  background: var(--text-muted);
  border-radius: 2px;
  transition: background 0.15s;
  pointer-events: none;
}
.progress-bar:hover .progress-fill,
.progress-bar.dragging .progress-fill { background: var(--green); }

.progress-thumb {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 12px; height: 12px;
  background: var(--green);
  border-radius: 50%;
  opacity: 0;
  transition: opacity 0.15s;
  pointer-events: none;
  z-index: 2;
}
.progress-bar:hover .progress-thumb,
.progress-bar.dragging .progress-thumb { opacity: 1; }

/* Всплывающее время над шариком */
.seek-preview {
  position: absolute;
  bottom: calc(100% + 10px);
  transform: translateX(-50%);
  background: var(--surface3);
  color: var(--text);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  padding: 2px 7px;
  border-radius: 4px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.1s;
  z-index: 10;
}
.progress-bar:hover .seek-preview,
.progress-bar.dragging .seek-preview { opacity: 1; }

.player-right {
  display: flex; align-items: center; gap: 8px;
  width: 250px; justify-content: flex-end; flex-shrink: 0;
}
.volume-bar {
  display: flex; align-items: center; gap: 8px;
}
.vol-slider {
  width: 150px; height: 4px;
  background: var(--surface4);
  border-radius: 2px;
  cursor: pointer;
  position: relative;
}
.vol-slider::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: -10px; bottom: -10px;
}
.vol-fill {
  height: 100%;
  background: var(--text-muted);
  border-radius: 2px;
  pointer-events: none;
  transition: background 0.15s;
}
.vol-slider:hover .vol-fill,
.vol-slider.dragging .vol-fill { background: var(--green); }
.vol-thumb {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 12px; height: 12px;
  background: var(--green);
  border-radius: 50%;
  opacity: 0;
  transition: opacity 0.15s;
  pointer-events: none;
  z-index: 2;
}
.vol-slider:hover .vol-thumb,
.vol-slider.dragging .vol-thumb { opacity: 1; }
.vol-preview {
  position: absolute;
  bottom: calc(100% + 10px);
  transform: translateX(-50%);
  background: var(--surface3);
  color: var(--text);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  padding: 2px 7px;
  border-radius: 4px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.1s;
  z-index: 10;
}
.vol-slider:hover .vol-preview,
.vol-slider.dragging .vol-preview { opacity: 1; }

/* ═══════════════════════════════════════════════════════
   ADMIN PANEL (modal)
═══════════════════════════════════════════════════════ */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.7);
  backdrop-filter: blur(4px);
  z-index: 200;
  display: none; align-items: center; justify-content: center;
  padding: 20px;
}
.modal-overlay.open { display: flex; }
.modal {
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 16px;
  width: 100%; max-width: 860px;
  max-height: 90vh;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 24px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.modal-header h2 { font-size: 18px; font-weight: 700; }
.modal-close {
  width: 32px; height: 32px;
  border-radius: 8px;
  background: var(--surface3);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted);
  transition: 0.15s;
}
.modal-close:hover { background: var(--surface4); color: var(--text); }
.modal-close svg { width: 16px; height: 16px; }
.modal-tabs {
  display: flex; gap: 0;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.modal-tab {
  padding: 14px 20px;
  font-size: 14px; font-weight: 500;
  color: var(--text-muted);
  border-bottom: 2px solid transparent;
  transition: 0.15s;
  cursor: pointer;
}
.modal-tab:hover { color: var(--text); }
.modal-tab.active { color: var(--green); border-bottom-color: var(--green); }
.modal-body { flex: 1; overflow-y: auto; padding: 20px 24px; }
.admin-section { margin-bottom: 28px; }
.admin-section h3 { font-size: 15px; font-weight: 600; margin-bottom: 14px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; font-size: 12px; }
.input-row { display: flex; gap: 8px; margin-bottom: 12px; }
.form-input {
  background: var(--surface3);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 14px;
  color: var(--text);
  font-family: inherit; font-size: 14px;
  outline: none;
  flex: 1;
  transition: border-color 0.15s;
}
.form-input:focus { border-color: var(--green); }
.btn-primary {
  background: var(--green);
  color: #000;
  font-weight: 700; font-size: 14px;
  padding: 10px 18px;
  border-radius: 8px;
  transition: 0.15s;
  white-space: nowrap;
}
.btn-primary:hover { background: #1ed760; }
.btn-danger {
  background: rgba(220,38,38,0.15);
  color: #ff6b6b;
  font-size: 13px;
  padding: 6px 12px;
  border-radius: 6px;
  border: 1px solid rgba(220,38,38,0.3);
  transition: 0.15s;
}
.btn-danger:hover { background: rgba(220,38,38,0.25); }
.btn-secondary {
  background: var(--surface3);
  color: var(--text-muted);
  font-size: 13px;
  padding: 6px 12px;
  border-radius: 6px;
  border: 1px solid var(--surface4);
  transition: 0.15s;
}
.btn-secondary:hover { background: var(--surface4); color: var(--text); }
.user-list { display: flex; flex-direction: column; gap: 8px; }
.user-row {
  display: flex; align-items: center;
  background: var(--surface3);
  border-radius: 10px;
  padding: 12px 14px;
  gap: 12px;
  cursor: pointer;
  transition: background 0.15s;
}
.user-row:hover { background: var(--surface4); }
.user-row.selected { background: rgba(29,185,84,0.1); border: 1px solid rgba(29,185,84,0.3); }
.user-avatar-sm {
  width: 36px; height: 36px;
  background: var(--surface4);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 14px; color: var(--text-muted);
  flex-shrink: 0;
}
.user-info { flex: 1; min-width: 0; }
.user-name { font-size: 14px; font-weight: 600; }
/* Task 681 — nickname shown beside the login in the admin user list,
   de-emphasised so the login stays the primary identifier. */
.user-nick { font-weight: 400; opacity: .65; margin-left: 6px; }
.user-badge { font-size: 11px; color: var(--text-dim); }
.admin-badge { color: var(--green); font-size: 11px; font-weight: 600; margin-left: 6px; }
.access-tree { font-size: 13px; }
.folder-access-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  transition: background 0.15s;
}
.folder-access-row:hover { background: var(--surface3); }
.folder-access-row label { cursor: pointer; flex: 1; color: var(--text-muted); min-width: 0; }
.folder-access-row.has-audio label { color: var(--text); }
.folder-access-row input[type="checkbox"] { accent-color: var(--green); width: 15px; height: 15px; cursor: pointer; flex-shrink: 0; }
/* Task 640 — access inherited from a parent folder, not granted on this row. */
.folder-access-row.inherited input[type="checkbox"] { opacity: .55; }
.fa-inherited { color: var(--text-dim); font-size: 10px; flex-shrink: 0; }
.dt-toggle {
  width: 18px; height: 18px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; color: var(--text-dim);
  border-radius: 3px; transition: background 0.15s;
}
.dt-toggle:hover { background: var(--surface4); }
.dt-toggle-gap { width: 18px; flex-shrink: 0; }
.dt-children { border-left: 2px solid var(--surface4); margin-left: 8px; }
.scan-result {
  background: var(--surface3); border-radius: 8px;
  padding: 12px 16px; font-size: 13px;
  font-family: 'DM Mono', monospace;
  color: var(--green);
  display: none; margin-top: 12px;
}
.scan-result.visible { display: block; }

/* Task 46: scan progress and history */
.scan-progress {
  display: none;
  margin-top: 16px;
  padding: 14px 16px;
  background: var(--surface3);
  border-radius: 8px;
}
.scan-progress.visible { display: block; }
.scan-prog-row {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 8px;
}
.scan-prog-bar-wrap {
  flex: 1; height: 8px;
  background: var(--surface4);
  border-radius: 4px; overflow: hidden;
}
.scan-prog-bar {
  height: 100%;
  background: var(--green);
  transition: width 0.3s ease;
}
.scan-prog-pct {
  font-family: 'DM Mono', monospace;
  font-size: 13px;
  color: var(--green);
  min-width: 40px; text-align: right;
}
.scan-prog-meta {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  font-size: 12px; color: var(--text-muted);
  font-family: 'DM Mono', monospace;
}
.scan-prog-meta button {
  margin-left: auto;
  padding: 4px 12px; font-size: 12px;
}

.scan-history {
  margin-top: 20px;
}
.scan-history-title {
  font-size: 12px; font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.5px;
  margin-bottom: 8px;
}
.scan-history-row {
  display: grid;
  grid-template-columns: 24px 170px 80px 60px 1fr;
  gap: 12px; align-items: center;
  padding: 6px 10px;
  font-size: 12px; font-family: 'DM Mono', monospace;
  color: var(--text-muted);
  border-radius: 4px;
}
.scan-history-row:hover { background: var(--surface3); }
.scan-h-icon { font-size: 14px; text-align: center; }
.scan-history-row.ok   .scan-h-icon { color: var(--green); }
.scan-history-row.err  .scan-h-icon { color: #e22134; }
.scan-history-row.warn .scan-h-icon { color: #f59e0b; }
.scan-history-row.run  .scan-h-icon { color: var(--green); }
.scan-h-time { color: var(--text); }
.scan-h-scope { }
.scan-h-scope-admin {
  color: var(--green);
  font-size: 11px;
}
.scan-h-scope-user {
  color: var(--text-muted);
  font-size: 11px;
}
.scan-h-summary { color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.btn-secondary {
  background: var(--surface4); color: var(--text);
  border: none; border-radius: 4px; padding: 6px 14px;
  font-size: 13px; cursor: pointer;
}
.btn-secondary:hover { background: var(--surface5, #404040); }
.muted { color: var(--text-muted); font-size: 13px; font-family: 'DM Mono', monospace; }
.checkbox-row { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.checkbox-row label { font-size: 14px; cursor: pointer; }
.checkbox-row input { accent-color: var(--green); width: 16px; height: 16px; }

/* ═══════════════════════════════════════════════════════
   PLAYER VIEW (mobile tab)
═══════════════════════════════════════════════════════ */
#player-view {
  display: none;
  padding: 20px 20px 24px;
  flex-direction: column;
  align-items: stretch;
  gap: 20px;
}
.pv-cover {
  /* #612 П2: cover fills the window width (was min(280px,80vw) centered). */
  width: 100%;
  max-width: 92vw;
  align-self: center;
  aspect-ratio: 1;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 24px 64px rgba(0,0,0,0.6);
  background: var(--surface3);
  flex-shrink: 0;
}
.pv-cover img { width: 100%; height: 100%; object-fit: cover; }
.pv-no-cover { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }
.pv-no-cover svg { width: 30%; height: 30%; opacity: 0.3; }
/* #612 П2/П3: title/artist left-aligned like the Android big player, with the
   queue button on the right of the info row. */
.pv-info { text-align: left; width: 100%; display: flex; align-items: center; gap: 12px; }
.pv-info-text { flex: 1; min-width: 0; }
.pv-queue-btn {
  position: relative; flex-shrink: 0;
  width: 40px; height: 40px; padding: 0;
  background: none; border: none; color: var(--text-muted);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.pv-queue-btn:hover { color: var(--text); }
.pv-queue-btn svg { width: 24px; height: 24px; }
.pv-queue-badge {
  position: absolute; top: 0; right: 0;
  min-width: 15px; height: 15px; padding: 0 3px;
  background: var(--green); color: var(--bg);
  font-size: 10px; font-weight: 700; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
}
.pv-title { font-size: 20px; font-weight: 700; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pv-artist { font-size: 14px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* #629 П1: format line under the artist (FLAC · 1000 kbps · 44.1 kHz), same
   content as the player bar — mirrors the Android big player. */
.pv-fmt {
  font-size: 11px; color: var(--text-dim);
  font-family: 'DM Mono', monospace;
  margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pv-controls { width: 100%; display: flex; flex-direction: column; gap: 12px; align-items: center; }
.pv-progress { width: 100%; display: flex; align-items: center; gap: 10px; }
.pv-btns { display: flex; align-items: center; gap: 24px; }
.pv-btns .ctrl-btn svg { width: 24px; height: 24px; }
.pv-btns .play-pause-btn { width: 56px; height: 56px; }
.pv-btns .play-pause-btn svg { width: 24px; height: 24px; }

/* ═══════════════════════════════════════════════════════
   MOBILE BOTTOM NAV
═══════════════════════════════════════════════════════ */
.mobile-nav {
  display: none;
  position: fixed; bottom: 0; left: 0; right: 0;
  background: #000;
  border-top: 1px solid var(--border);
  z-index: 30;
  height: 60px;
}
.mobile-nav-inner {
  display: flex; height: 100%; width: 100%;
  justify-content: space-around;
  align-items: center;
  padding: 0 8px;
  gap: 4px;
}
.mobile-nav-btn {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  color: var(--text-muted);
  transition: color 0.15s;
  flex: none;
}
.mobile-nav-btn.active { color: var(--green); }
.mobile-nav-btn svg { width: 24px; height: 24px; }

/* ═══════════════════════════════════════════════════════
   NOTIFICATIONS
═══════════════════════════════════════════════════════ */
.toast {
  position: fixed; top: 20px; right: 20px;
  background: var(--surface3);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
  font-size: 14px;
  z-index: 999;
  transform: translateY(-10px);
  opacity: 0;
  transition: 0.3s;
  max-width: 320px;
}
.toast.show { transform: translateY(0); opacity: 1; }
.toast.success { border-color: rgba(29,185,84,0.5); color: var(--green); }
.toast.error { border-color: rgba(220,38,38,0.4); color: #ff6b6b; }

/* Loading */
.loading {
  display: flex; align-items: center; justify-content: center;
  padding: 60px; color: var(--text-dim);
  flex-direction: column; gap: 16px;
}
.spin {
  width: 32px; height: 32px;
  border: 2px solid var(--surface4);
  border-top-color: var(--green);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Empty state */
.empty-state {
  text-align: center; padding: 80px 24px;
  color: var(--text-dim);
}
.empty-state svg { width: 64px; height: 64px; opacity: 0.2; margin: 0 auto 16px; }
.empty-state h3 { font-size: 18px; font-weight: 600; color: var(--text-muted); margin-bottom: 8px; }
.empty-state p { font-size: 14px; }

/* ═══════════════════════════════════════════════════════
   RESPONSIVE
═══════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  :root { --player-h: 0px; --sidebar-w: 0px; }
  .app { grid-template-columns: 1fr; grid-template-rows: calc(100vh - 60px) 60px; height: 100vh; }
  .sidebar { display: none; }
  .player-bar { display: none; }
  .mobile-nav { display: flex; position: fixed; bottom: 0; left: 0; right: 0; }
  body { padding-bottom: 0; }
  .main { grid-row: 1; grid-column: 1; max-height: calc(100vh - 60px); height: calc(100vh - 60px); overflow-y: auto; overflow-x: hidden; }
  /* #630 П1: on mobile browsers 100vh is the LARGE viewport (address bar
     hidden), so with the bar visible the container is taller than the screen
     and the player's controls fall below the fold. dvh tracks the actually
     visible height; browsers without dvh ignore this and keep the vh values. */
  .main { max-height: calc(100dvh - 60px); height: calc(100dvh - 60px); }
  .folder-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
  .album-header { flex-direction: column; align-items: center; text-align: center; }
  .album-info { display: flex; flex-direction: column; align-items: center; }
  .album-cover-lg { width: 140px; height: 140px; }
  .track-list-header { grid-template-columns: 32px 1fr 52px; }
  .track-list-header .th-album, .track-list-header .th-fmt, .track-list-header .th-size { display: none; }
  .track-row { grid-template-columns: 32px 1fr 52px; }
  .track-album-col, .track-fmt-col, .track-size { display: none; }
  /* #612 П0: the unified row/header carry higher specificity (.track-row
     .tr-unified), so a bare .track-row override never wins on mobile — the row
     kept the desktop 9-column grid and looked cramped. Re-declare at matching
     specificity: № · cover · title/artist · time · ❤ · ⋮ (album/format/size
     hidden). */
  /* #629 П2 (mobile only): list format is № · cover · title/artist · ❤ · ⋮.
     No column header, no duration — album/format/size stay hidden as before. */
  .track-row.tr-unified {
    grid-template-columns: 28px 48px 1fr 34px 28px;
    gap: 8px;
    padding: 8px 12px;
  }
  /* Edit rows keep the drag handle and × : handle · № · cover · info · × */
  .track-row.tr-unified.tr-edit {
    grid-template-columns: 28px 22px 48px 1fr 28px;
  }
  .track-row.tr-unified .track-album-col,
  .track-row.tr-unified .track-fmt-col,
  .track-row.tr-unified .track-dur,
  .track-row.tr-unified .track-size { display: none; }
  /* Column headers are noise on a phone — hide them in every list. */
  .track-list-header,
  .track-list-header.tr-unified-header,
  .sr-table-head,
  .sr-table-head.tr-unified-header { display: none !important; }
  .track-row.tr-unified .track-fav-btn svg { width: 22px; height: 22px; }
  /* #629 П3: filter / sort dialogs become bottom sheets on a phone, matching
     the track menu (.tm-sheet) instead of a centred modal box. */
  .lib-pref-overlay {
    align-items: flex-end;
    justify-content: stretch;
    padding: 0;
  }
  .lib-pref-box {
    width: 100%;
    min-width: 0;
    max-width: none;
    border-radius: 16px 16px 0 0;
    padding: 18px 18px calc(18px + env(safe-area-inset-bottom));
    max-height: 80vh;
    overflow-y: auto;
    animation: libSheetUp 0.18s ease;
  }
  @keyframes libSheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
  .folder-cover .play-overlay { display: none !important; }
  .player-left { width: auto; }
  .player-right { width: auto; }
  #grid-view { padding: 16px 16px 100px !important; }
  #favorites-view { padding: 16px 16px 100px !important; }
  #track-view { padding-bottom: 0 !important; }
  .track-list { padding-bottom: 100px !important; }
  .album-title { font-size: 20px; }
  /* #629 П1: Android-like layout — the player fills the viewport, the cover
     takes all the slack, and the controls sit at the bottom instead of being
     bunched up under the cover with dead space below. */
  #player-view {
    display: flex;
    height: 100%;
    min-height: 0;
    padding: 12px 16px 16px;
    gap: 14px;
  }
  #player-view .pv-cover {
    /* #631 П2: the cover box takes whatever vertical space is left after the
       labels and controls, and the artwork is scaled to FIT inside it
       (object-fit: contain) — so non-square art keeps its proportions instead
       of being cropped or stretched, mirroring the Android big player. */
    flex: 1 1 auto;
    min-height: 0;
    align-self: stretch;
    width: 100%;
    height: auto;
    aspect-ratio: auto;
    background: transparent;
    box-shadow: none;
  }
  #player-view .pv-cover img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
  }
  #player-view .pv-info { flex: 0 0 auto; }
  /* Anchors the progress+buttons block to the bottom regardless of how much
     the cover managed to grow (aspect-ratio can cap its height). */
  #player-view .pv-controls { flex: 0 0 auto; margin-top: auto; }
  /* #612 П2: hide the breadcrumb top bar while the big player is open. */
  body.mob-player-open .topbar { display: none; }
  /* #612 П6: smaller breadcrumbs, sized to the toolbar buttons with a little
     padding, so they don't dominate the narrow top bar. */
  .breadcrumb { font-size: 13px; gap: 4px; padding: 2px 2px; }
  .breadcrumb-sep { font-size: 10px; }
  /* #630 П2: «Популярное» becomes a horizontal carousel with small tiles,
     mirroring the Android rv_popular (horizontal list, 104dp tiles). */
  .popular-grid {
    display: flex;
    grid-template-columns: none;
    overflow-x: auto;
    overflow-y: hidden;
    flex-wrap: nowrap;
    gap: 8px;
    padding-bottom: 6px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .popular-grid::-webkit-scrollbar { display: none; }
  .popular-grid .folder-card {
    flex: 0 0 104px;
    width: 104px;
  }
  .popular-grid .folder-meta { padding: 6px 4px 4px; }
  .popular-grid .folder-name { font-size: 12px; }
  .popular-grid .folder-sub { font-size: 10px; }
  /* #630 П3: the search view added 24px side padding on top of each row's own
     12px, so «Недавно слушали» sat noticeably further from the edges than the
     library lists. Drop the panel's horizontal padding and give it back only to
     the chrome (search bar, status, section headers) — rows then line up with
     the library. */
  .search-panel { padding: 12px 0 40px; }
  .search-panel .search-bar,
  .search-panel .search-status,
  .search-panel .search-recent-head { padding-left: 12px; padding-right: 12px; }
  /* #631 П4: compact sticky album panel — shown only after the big header
     scrolls out (JS toggles .visible). Android track_header parity. */
  .album-sticky {
    /* #635: second row of the sticky topbar — no position, no z-index, no
       coordinates. It sits directly under the breadcrumb row by construction,
       so it can neither cover it nor leave a gap. */
    display: none;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    background: var(--surface);
    border-top: 1px solid var(--border);
    box-sizing: border-box;
  }
  .album-sticky.visible { display: flex; }
  .album-sticky-cover {
    width: 48px; height: 48px;
    min-width: 48px; max-width: 48px;
    border-radius: 4px; overflow: hidden;
    background: var(--surface3);
    display: flex; align-items: center; justify-content: center;
    color: var(--text-dim);
  }
  .album-sticky-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .album-sticky-cover svg { width: 22px; height: 22px; opacity: 0.5; }
  .album-sticky-info { flex: 1; min-width: 0; }
  .album-sticky-title {
    font-size: 14px; font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .album-sticky-meta {
    font-size: 11px; color: var(--text-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
}
@media (min-width: 769px) {
  /* #player-view visibility on desktop is controlled by JS, not CSS */
  #player-view { display: none; /* default hidden, JS overrides */ }
}

/* ═══════════════════════════════════════════════════════
   MOBILE USER BOTTOM SHEET
═══════════════════════════════════════════════════════ */
.mob-sheet-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.6);
  z-index: 200;
}
.mob-sheet-overlay.open { display: block; }

.mob-sheet {
  position: fixed; bottom: 0; left: 0; right: 0;
  background: var(--surface2);
  border-radius: 20px 20px 0 0;
  border-top: 1px solid var(--border);
  z-index: 201;
  padding: 0 0 40px;
  transform: translateY(100%);
  transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
  max-height: 85vh;
  overflow-y: auto;
}
.mob-sheet.open { transform: translateY(0); }

.mob-sheet-handle {
  width: 36px; height: 4px;
  background: var(--surface4);
  border-radius: 2px;
  margin: 12px auto 8px;
}
.mob-sheet-header {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 20px 12px;
}
.mob-sheet-avatar {
  width: 44px; height: 44px;
  background: var(--green);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 18px; color: #000;
  flex-shrink: 0;
}
.mob-sheet-username {
  font-size: 17px; font-weight: 600; color: var(--text);
}
.mob-sheet-sep {
  height: 1px; background: var(--border);
  margin: 4px 0;
}
.mob-sheet-section-title {
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--text-dim);
  padding: 12px 20px 4px;
}
.mob-sheet-item {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 20px;
  font-size: 16px; color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.mob-sheet-item:active { background: var(--surface3); }
.mob-sheet-item svg { width: 22px; height: 22px; flex-shrink: 0; }

@media (min-width: 769px) {
  .mob-sheet, .mob-sheet-overlay { display: none !important; }
}

/* ═══════════════════════════════════════════════════════
   MOBILE ADMIN PANELS
═══════════════════════════════════════════════════════ */
.mob-admin-panel {
  display: none;
  position: fixed; inset: 0;
  background: var(--bg);
  z-index: 300;
  flex-direction: column;
  overflow: hidden;
}
.mob-admin-panel.open { display: flex; }

.mob-admin-header {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font-size: 17px; font-weight: 600; color: var(--text);
  flex-shrink: 0;
}
.mob-admin-back {
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  color: var(--green);
  border-radius: 50%;
  transition: background 0.15s;
}
.mob-admin-back:active { background: var(--surface3); }
.mob-admin-back svg { width: 22px; height: 22px; }

.mob-admin-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 16px 80px;
  display: flex; flex-direction: column; gap: 24px;
}
.mob-admin-desc {
  font-size: 14px; color: var(--text-muted); line-height: 1.5;
  margin-bottom: 16px;
}
.mob-admin-desc code {
  font-family: 'DM Mono', monospace;
  color: var(--green);
}
.mob-admin-section {
  display: flex; flex-direction: column; gap: 0;
}
.mob-admin-section-title {
  font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 1px;
  color: var(--text-dim);
  margin-bottom: 12px;
}

@media (min-width: 769px) {
  .mob-admin-panel { display: none !important; }
}

/* ═══════════════════════════════════════════════════════
   MOBILE FOLDER TREE
═══════════════════════════════════════════════════════ */
.tree-node {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-top: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
  min-height: 40px;
}
.tree-toggle {
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: var(--text-dim);
  flex-shrink: 0;
  border-radius: 4px;
  transition: background 0.15s;
}
.tree-toggle:active { background: var(--surface3); }
.tree-toggle-gap { width: 22px; flex-shrink: 0; }
.tree-node input[type="checkbox"] {
  width: 18px; height: 18px;
  accent-color: var(--green);
  flex-shrink: 0;
  cursor: pointer;
}
.tree-label {
  display: flex; align-items: center; gap: 6px;
  font-size: 14px; color: var(--text-muted);
  cursor: pointer;
  flex: 1;
  min-width: 0;
}
.tree-icon { font-size: 15px; flex-shrink: 0; }
.tree-label span:not(.tree-badge):not(.tree-icon) {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tree-badge {
  font-size: 10px; font-weight: 600;
  padding: 2px 5px; border-radius: 4px;
  flex-shrink: 0;
  margin-left: auto;
}
.tree-badge-audio { background: rgba(29,185,84,0.15); color: var(--green); }
.tree-badge-folder { background: var(--surface4); color: var(--text-dim); }
.tree-children { border-left: 2px solid var(--surface4); margin-left: 10px; }

/* ── Playlist: unavailable track ── */
.track-row.track-unavailable {
  opacity: 0.45;
  cursor: default;
  pointer-events: none;
}
.track-row.track-unavailable:hover {
  background: transparent;
}
.track-unavailable-badge {
  display: inline-block;
  margin-left: 8px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(255, 80, 80, 0.12);
  color: #e05555;
  vertical-align: middle;
  line-height: 1.4;
}

/* ── Cover modal ── */
.cover-modal-box {
  padding: 40px 36px 32px;
  max-width: 420px;
}
.cover-modal-img-wrap {
  width: 320px; height: 320px;
  margin: 0 auto 20px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--surface3);
  display: flex; align-items: center; justify-content: center;
}
.cover-modal-img-wrap img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.cover-modal-img-wrap svg {
  width: 64px; height: 64px;
  color: var(--surface4);
}
.cover-modal-title {
  font-size: 17px; font-weight: 600;
  color: var(--text);
  margin-bottom: 4px;
  text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cover-modal-artist {
  font-size: 13px; color: var(--text-muted);
  text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── Favorites ── */
/* Sidebar heart button — red when active */
#sb-favorites.active svg { color: #e05555; }
#sb-favorites.active { color: #e05555; }
#mob-favorites.active svg { color: #e05555; }

/* Heart button in track row */
.track-fav-btn {
  background: none; border: none; padding: 0;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  color: var(--text-dim);
  opacity: 0;
  transition: opacity 0.15s, color 0.15s;
  flex-shrink: 0;
}
.track-fav-btn svg { width: 15px; height: 15px; }
.track-fav-btn.fav-active { color: #e05555; opacity: 1; }
.track-row:hover .track-fav-btn { opacity: 1; }
.track-fav-btn:hover { color: #e05555; }
.track-row.track-unavailable .track-fav-btn { display: none; }

/* Mobile: always visible if favorited */
@media (max-width: 768px) {
  .track-fav-btn.fav-active { opacity: 1; }
}

/* Heart button on folder card */
.folder-fav-btn {
  position: absolute; top: 8px; right: 8px;
  width: 30px; height: 30px;
  background: rgba(0,0,0,0.45);
  border: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s, background 0.15s;
  z-index: 2;
}
.folder-fav-btn svg { width: 15px; height: 15px; color: #fff; }
.folder-fav-btn.fav-active { opacity: 1; background: rgba(224,85,85,0.85); }
.folder-fav-btn.fav-active svg { color: #fff; }
.folder-card:hover .folder-fav-btn { opacity: 1; }
.folder-fav-btn:hover { background: rgba(224,85,85,0.85); }

/* Favorites view */
#favorites-view { padding: 24px; display: none; }
.fav-section-title {
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 1.5px;
  color: var(--text-dim);
  margin: 24px 0 12px;
}

/* Virtual "Любимые треки" card */
.fav-tracks-card {
  display: flex; align-items: center; gap: 16px;
  padding: 16px;
  background: var(--surface2);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.2s, transform 0.2s;
  margin-bottom: 20px;
}
.fav-tracks-card:hover { background: var(--surface3); transform: translateY(-1px); }
.fav-tracks-cover {
  width: 72px; height: 72px; flex-shrink: 0;
  border-radius: 8px;
  background: linear-gradient(135deg, #c0392b 0%, #e74c3c 100%);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 16px rgba(224,85,85,0.4);
}
.fav-tracks-cover svg { width: 36px; height: 36px; color: #fff; }
.fav-tracks-info { flex: 1; min-width: 0; }
.fav-tracks-name { font-size: 17px; font-weight: 700; margin-bottom: 4px; }
.fav-tracks-meta { font-size: 13px; color: var(--text-muted); }

/* Mobile: adjust grid for heart column */
@media (max-width: 768px) {
  /* #612 П0: obsolete pre-unification row grids removed — the unified overrides
     live in the main max-width:768 block above. */
}

/* ── Favorite tracks card cover — grey bg + red heart ── */
.fav-heart-cover {
  background: linear-gradient(135deg, var(--surface3) 0%, var(--surface4) 100%) !important;
}
.fav-heart-cover svg {
  width: 45% !important; height: 45% !important;
  opacity: 1 !important;
  color: #e05555 !important;
}

/* ── Favorites heart cover for alb-cover-lg ── */
.fav-heart-cover-lg {
  background: linear-gradient(135deg, var(--surface3) 0%, var(--surface4) 100%) !important;
}
.fav-heart-cover-lg svg {
  width: 52px !important; height: 52px !important;
  color: #e05555 !important;
  opacity: 1 !important;
}

/* ── Public folder markers ───────────────────────────────────────────────── */
/* Tile outlines say where a folder comes from, at a glance and without
   reading: green = public (curated by the admin, everyone's), blue = shared
   with me by another user, none = my own. Personal folders are the common
   case, so they carry no decoration at all. */
.folder-card.folder-public .folder-cover {
  outline: 2px solid #1db95455;
  outline-offset: -2px;
}
.folder-card.folder-shared .folder-cover {
  outline: 2px solid #4a9eff55;
  outline-offset: -2px;
}

/* ── Edit-user modal ─────────────────────────────────────────────────────── */
.edit-modal-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.65);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.15s ease;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.modal-box {
  background: var(--surface2);
  border-radius: 12px;
  padding: 28px 32px;
  width: 420px;
  max-width: calc(100vw - 32px);
  box-shadow: 0 8px 40px rgba(0,0,0,0.5);
  animation: slideUp 0.18s ease;
}
@keyframes slideUp {
  from { transform: translateY(16px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

.modal-box h3 {
  margin: 0 0 20px;
  font-size: 17px;
  font-weight: 700;
}

.modal-field {
  margin-bottom: 14px;
}
.modal-field label {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.modal-field input[type="text"],
.modal-field input[type="password"],
.modal-field input[type="number"] {
  width: 100%;
  box-sizing: border-box;
  background: var(--surface3);
  border: 1px solid var(--surface4);
  border-radius: 6px;
  color: var(--text);
  padding: 9px 12px;
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s;
}
.modal-field input:focus {
  border-color: var(--accent);
}
.modal-field .hint {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 4px;
}
.modal-checkbox-row {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 20px;
  font-size: 14px;
}
.modal-checkbox-row input[type="checkbox"] {
  width: 16px; height: 16px; accent-color: var(--accent);
}

.modal-actions {
  display: flex; justify-content: flex-end; gap: 10px;
  margin-top: 6px;
}
.modal-btn {
  padding: 9px 20px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  border: none;
  transition: opacity 0.15s;
}
.modal-btn:hover { opacity: 0.85; }
.modal-btn-cancel {
  background: var(--surface3);
  color: var(--text-muted);
}
.modal-btn-save {
  background: var(--accent);
  color: #fff;
}
.modal-error {
  color: #e05555;
  font-size: 13px;
  margin-bottom: 10px;
  display: none;
}

/* ═══════════════════════════════════════════════════════
   USER MENU — icons
═══════════════════════════════════════════════════════ */
.user-menu-item { display: flex; align-items: center; gap: 9px; }
.user-menu-username { font-weight: 600; color: var(--text); pointer-events: none; }
.umicon { width: 15px; height: 15px; flex-shrink: 0; opacity: 0.7; }

/* ═══════════════════════════════════════════════════════
   MY FILES MODAL
═══════════════════════════════════════════════════════ */
.mf-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.7);
  backdrop-filter: blur(4px);
  z-index: 500;
  display: none; align-items: center; justify-content: center;
  padding: 16px;
}
.mf-overlay.open { display: flex; }
.mf-box {
  background: var(--surface2);
  border-radius: 14px;
  /* Task 668: was min(900px, 100%) / min(620px, 90vh) — the caps were the
     complaint, the window was too small on a desktop. Raised by 30% (900→1170,
     620→806) and expressed as a share of the viewport so the dialog scales
     with the main window instead of stopping at a fixed number.
     30% rather than 50%: +50% would put the height at 930px, above the 90vh
     cap on a 1366×768 laptop, so the stated size and the real one would
     silently disagree. 1170×806 fits there and leaves room on 1080p. */
  width: min(1170px, 92vw);
  height: min(806px, 88vh);
  display: flex; flex-direction: column;
  box-shadow: 0 12px 48px rgba(0,0,0,0.6);
  overflow: hidden;
}

/* Header */
.mf-header {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.mf-title {
  display: flex; align-items: center; gap: 8px;
  font-size: 15px; font-weight: 700;
  flex: 1;
}
.mf-quota {
  font-size: 12px; color: var(--text-muted);
  background: var(--surface3);
  padding: 3px 10px; border-radius: 20px;
}
.mf-quota { color: var(--green); }
.mf-quota.over { color: #ff6b6b; background: rgba(220,38,38,0.15); }
.mf-close {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); padding: 4px;
  border-radius: 6px; transition: 0.15s;
  display: flex; align-items: center;
}
.mf-close:hover { background: var(--surface4); color: var(--text); }

/* Body */
.mf-body {
  display: flex; flex: 1; overflow: hidden;
}

/* Tree panel */
.mf-tree-panel {
  width: 50%; flex: 0 0 50%; min-width: 180px; max-width: calc(100% - 220px);
  overflow-y: auto;
  padding: 8px 0;
  position: relative;
}

/* Resizer */
.mf-resizer {
  width: 5px; flex-shrink: 0;
  background: var(--border);
  cursor: col-resize;
  transition: background 0.15s;
  position: relative; z-index: 1;
}
.mf-resizer:hover, .mf-resizer.dragging {
  background: var(--green);
}
.mf-tree { font-size: 13px; }
.mf-tree-node { user-select: none; }
.mf-tree-row {
  display: flex; align-items: center; gap: 4px;
  padding: 5px 8px; cursor: pointer;
  border-radius: 6px; margin: 1px 4px;
  color: var(--text-muted);
  transition: background 0.1s;
  white-space: nowrap; overflow: hidden;
}
.mf-tree-row:hover { background: var(--surface3); color: var(--text); }
.mf-tree-row.active { background: rgba(29,185,84,.12); color: var(--green); font-weight: 600; }
.mf-tree-toggle {
  width: 16px; flex-shrink: 0;
  font-size: 10px; color: var(--text-dim);
  background: none; border: none; cursor: pointer; padding: 0;
  display: flex; align-items: center; justify-content: center;
}
.mf-tree-icon { flex-shrink: 0; opacity: 0.6; }
.mf-tree-name { overflow: hidden; text-overflow: ellipsis; }
.mf-tree-editing input {
  font-size: 13px; padding: 1px 6px;
  background: var(--surface4);
  border: 1px solid var(--accent);
  border-radius: 4px; color: var(--text);
  outline: none; width: 120px;
}
.mf-tree-children { padding-left: 16px; }

/* Tree DnD */
.mf-tree-row.drag-src { opacity: 0.4; }
.mf-tree-row.drag-over-target {
  background: rgba(29,185,84,0.2) !important;
  outline: 1px solid var(--green);
  border-radius: 6px;
}

/* Files panel */
.mf-files-panel {
  flex: 1 1 50%; display: flex; flex-direction: column;
  overflow: hidden; position: relative;
}
.mf-files-panel.drag-over { background: rgba(29,185,84,0.06); }
.mf-files-panel.drag-over .mf-drop-hint { opacity: 1; }
.mf-files-list {
  flex: 1; overflow-y: auto; padding: 8px;
  padding-bottom: 48px;
}
.mf-file-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 6px;
  cursor: pointer; font-size: 13px;
  transition: background 0.1s;
  user-select: none;
}
.mf-file-row:hover { background: var(--surface3); }
.mf-file-row.selected { background: rgba(29,185,84,0.15); color: var(--accent); }
.mf-file-icon { flex-shrink: 0; opacity: 0.55; }
.mf-file-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mf-file-size { font-size: 11px; color: var(--text-muted); white-space: nowrap; }
/* Task 668: modification date, fixed width so names above each other line up. */
.mf-file-date {
  font-size: 11px; color: var(--text-muted); white-space: nowrap;
  width: 116px; text-align: right; flex-shrink: 0;
}
/* Folder rows in the right pane read as folders, not as odd files. */
.mf-file-row.is-dir .mf-file-icon { opacity: 0.8; color: var(--accent); }
.mf-file-row.is-dir .mf-file-name { font-weight: 500; }
/* Drop target while dragging onto a folder row. */
.mf-file-row.drag-over-target {
  background: rgba(29,185,84,0.22);
  outline: 1px solid var(--accent);
}
.mf-file-row.drag-src { opacity: 0.45; }
.mf-drop-hint {
  position: absolute; bottom: 0; left: 0; right: 0;
  padding: 10px 16px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 12px; color: var(--text-dim);
  border-top: 1px dashed var(--border);
  opacity: 0.5; pointer-events: none;
  transition: opacity 0.2s;
  background: var(--surface2);
}
.mf-files-empty {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 8px;
  height: 100%; color: var(--text-dim); font-size: 13px;
}

/* Toolbar */
.mf-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px;
  border-top: 1px solid var(--border);
  flex-shrink: 0; gap: 8px;
}
.mf-toolbar-left, .mf-toolbar-right { display: flex; align-items: center; gap: 6px; }

.mf-conflict-wrap {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text-dim);
  margin-right: 4px;
}
.mf-conflict-select {
  height: 30px;
  background: var(--surface3);
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 12px;
  padding: 0 8px;
  outline: none;
}
.mf-conflict-select:focus { border-color: var(--green); color: var(--text); }
.mf-btn {
  display: flex; align-items: center; gap: 5px;
  padding: 7px 12px; border-radius: 7px;
  font-size: 12px; font-weight: 600; border: none;
  cursor: pointer; transition: 0.15s;
  background: var(--surface3); color: var(--text-muted);
  white-space: nowrap;
}
.mf-btn:hover { background: var(--surface4); color: var(--text); }
.mf-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.mf-btn-danger { color: #ff6b6b; }
.mf-btn-danger:hover { background: rgba(220,38,38,0.2); color: #ff6b6b; }
.mf-btn-upload { background: rgba(29,185,84,0.15); color: var(--green); }
.mf-btn-upload:hover { background: rgba(29,185,84,0.25); }
.mf-btn-scan { background: var(--surface3); }

/* Upload progress */
.mf-upload-progress {
  padding: 8px 16px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

/* Task 46b: user scan progress + history in MyFiles */
.mf-scan-progress {
  display: none;
  margin: 12px 16px 0 16px;
  padding: 10px 14px;
  background: var(--surface3);
  border-radius: 6px;
}
.mf-scan-progress.visible { display: block; }
.mf-scan-prog-row {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 6px;
}
.mf-scan-prog-bar-wrap {
  flex: 1; height: 6px;
  background: var(--surface4);
  border-radius: 3px; overflow: hidden;
}
.mf-scan-prog-bar {
  height: 100%; background: var(--green);
  transition: width 0.3s ease;
}
.mf-scan-prog-pct {
  font-family: 'DM Mono', monospace;
  font-size: 12px; color: var(--green);
  min-width: 36px; text-align: right;
}
.mf-scan-prog-meta {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  font-size: 11px; color: var(--text-muted);
  font-family: 'DM Mono', monospace;
}
.mf-scan-prog-meta button {
  margin-left: auto; padding: 3px 10px; font-size: 11px;
}
.mf-scan-history {
  margin: 8px 16px 0 16px;
}
.mf-scan-history-title {
  font-size: 11px; font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.5px;
  margin-bottom: 4px;
}
.mf-scan-history-row {
  display: grid;
  grid-template-columns: 18px 150px 50px 1fr;
  gap: 10px; align-items: center;
  padding: 4px 8px;
  font-size: 11px; font-family: 'DM Mono', monospace;
  color: var(--text-muted);
  border-radius: 3px;
}
.mf-scan-history-row.ok  > :first-child { color: var(--green); }
.mf-scan-history-row.err > :first-child { color: #e22134; }
.mf-scan-history-row.warn > :first-child { color: #f59e0b; }

.mf-progress-info {
  display: flex; justify-content: space-between;
  font-size: 12px; color: var(--text-muted); margin-bottom: 5px;
}
.mf-progress-bar-wrap {
  height: 4px; background: var(--surface4); border-radius: 2px; overflow: hidden;
}
.mf-progress-bar {
  height: 100%; background: var(--green);
  border-radius: 2px; transition: width 0.2s;
  width: 0%;
}

/* Status */
.mf-status {
  padding: 8px 16px; font-size: 12px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
  display: flex; align-items: center; gap: 6px;
}
.mf-status.ok    { color: var(--green); border-top-color: rgba(29,185,84,0.3); }
.mf-status.error { color: #ff6b6b; border-top-color: rgba(220,38,38,0.3); }
.mf-status.warn  { color: #f59e0b; border-top-color: rgba(245,158,11,0.3); }

/* Scan spinner inside toolbar */
.mf-scan-spin {
  display: inline-block; width: 14px; height: 14px;
  border: 2px solid var(--surface4);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  vertical-align: middle;
}


.mf-upload-details {
  padding: 10px 16px 12px;
  border-top: 1px solid var(--border);
  background: rgba(255,255,255,0.02);
  flex-shrink: 0;
  max-height: 150px;
  overflow: auto;
  font-size: 12px;
}
.mf-upload-details-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  color: var(--text-muted);
  margin-bottom: 8px;
}
.mf-upload-details-toggle {
  background: var(--surface3);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 10px;
  font-size: 11px;
  font-weight: 600;
}
.mf-upload-details-toggle:hover {
  color: var(--text);
  background: var(--surface4);
}
.mf-upload-details-list {
  display: none;
  flex-direction: column;
  gap: 5px;
}
.mf-upload-details.open .mf-upload-details-list {
  display: flex;
}
.mf-upload-detail-item {
  color: var(--text-muted);
  line-height: 1.35;
  word-break: break-word;
}
.mf-upload-detail-code {
  color: #f59e0b;
  font-weight: 700;
  margin-right: 6px;
}
.mf-upload-detail-file {
  color: var(--text);
}


.mf-busy .mf-body,
.mf-busy .mf-toolbar {
  opacity: 0.62;
  pointer-events: none;
}
.mf-status-busy {
  display: flex !important;
  align-items: center;
  gap: 8px;
}
.mf-status-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(245,158,11,0.25);
  border-top-color: #f59e0b;
  border-radius: 50%;
  display: inline-block;
  animation: mfSpin 0.8s linear infinite;
  flex-shrink: 0;
}
@keyframes mfSpin {
  to { transform: rotate(360deg); }
}

/* ── «Моё» umbrella section (task 59) ── */
.my-subheader {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.2px;
  margin: 26px 2px 12px;
}
.my-subheader:first-of-type { margin-top: 8px; }
.new-playlist-card .folder-cover {
  border: 1px dashed var(--surface4);
  background: var(--surface2);
}
.new-playlist-plus {
  display: flex; align-items: center; justify-content: center;
}
.new-playlist-plus svg {
  width: 38% !important; height: 38% !important;
  opacity: 0.6; color: var(--text-muted);
}
.new-playlist-card:hover .new-playlist-plus svg { opacity: 1; color: var(--accent); }

/* ═══ Track ⋮ button + context menu (task 59, stage 3) ═══ */
.track-menu-btn {
  background: none; border: none; padding: 0;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  color: var(--text-dim);
  opacity: 0;
  transition: opacity 0.15s, color 0.15s, background 0.15s;
  border-radius: 50%;
  flex-shrink: 0;
}
.track-menu-btn svg { width: 18px; height: 18px; }
.track-row:hover .track-menu-btn { opacity: 1; }
.sr-item:hover .track-menu-btn { opacity: 1; }
.track-menu-btn:hover { color: var(--text); background: var(--surface4); }
.track-row.track-unavailable .track-menu-btn { display: none; }
@media (max-width: 768px) {
  .track-menu-btn { opacity: 1; }   /* no hover on touch → always visible */
}

.tm-overlay {
  position: fixed; inset: 0; z-index: 4000;
  background: transparent;
}
.tm-menu {
  position: fixed;
  min-width: 220px; max-width: 280px;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 12px 32px rgba(0,0,0,0.5);
  padding: 6px;
  z-index: 4001;
  animation: tmFade 0.12s ease;
}
@keyframes tmFade { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }

.tm-item {
  width: 100%;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  background: none; border: none; border-radius: 7px;
  color: var(--text); font-size: 14px; text-align: left;
  cursor: pointer;
  transition: background 0.12s;
}
.tm-item:hover { background: var(--surface4); }
.tm-item svg { width: 18px; height: 18px; color: var(--text-muted); flex-shrink: 0; }
.tm-item .tm-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tm-item .tm-trailing { color: var(--text-dim); font-size: 12px; font-variant-numeric: tabular-nums; }

.tm-head {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px 8px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.tm-head-title { font-size: 13px; font-weight: 600; color: var(--text-muted); }
.tm-back {
  background: none; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  color: var(--text-muted);
}
.tm-back:hover { background: var(--surface4); color: var(--text); }
.tm-back svg { width: 20px; height: 20px; }

/* ── Track menu header (task 88) — mirrors Android's TrackMenuSheet ── */
.tm-track-head {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 6px 10px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
}
.tm-th-cover {
  width: 48px; height: 48px; flex-shrink: 0;
  border-radius: 4px; overflow: hidden;
  background: var(--surface3);
  display: flex; align-items: center; justify-content: center;
  color: var(--surface4);
}
.tm-th-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tm-th-cover svg { width: 24px; height: 24px; }
.tm-th-info { flex: 1; min-width: 0; }
.tm-th-title {
  font-size: 14px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tm-th-artist {
  font-size: 12px; color: var(--text-muted); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tm-th-meta {
  display: flex; align-items: center; gap: 6px; margin-top: 4px;
  min-width: 0;
}
.tm-th-fmt {
  flex-shrink: 0;
  font-size: 10px; font-weight: 700; letter-spacing: 0.4px;
  color: var(--text-muted); background: var(--surface3);
  padding: 1px 5px; border-radius: 3px;
}
.tm-th-metatext {
  font-size: 11px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.tm-list { max-height: 240px; overflow-y: auto; }
.tm-empty { padding: 12px; color: var(--text-dim); font-size: 13px; text-align: center; }
.tm-loading { padding: 16px; color: var(--text-muted); font-size: 13px; text-align: center; }

/* Narrow screens: bottom action-sheet */
@media (max-width: 768px) {
  .tm-overlay { background: rgba(0,0,0,0.45); }
  .tm-menu.tm-sheet {
    position: fixed;
    left: 0; right: 0; bottom: 0; top: auto !important;
    min-width: 0; max-width: none;
    border-radius: 16px 16px 0 0;
    padding: 10px 10px calc(10px + env(safe-area-inset-bottom));
    animation: tmSheetUp 0.18s ease;
  }
  @keyframes tmSheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
  .tm-item { padding: 14px 14px; font-size: 15px; }
  .tm-list { max-height: 50vh; }
  .tm-track-head { padding: 4px 8px 12px; gap: 12px; }
  .tm-th-cover { width: 56px; height: 56px; }
  .tm-th-title { font-size: 15px; }
}

/* ═══ Playlist editing + header actions (task 59, stage 4) ═══ */
.album-actions-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 20px; }
.pl-actions { display: flex; align-items: center; gap: 10px; }
.pl-action-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 28px;
  background: var(--surface3); border: 1px solid var(--border);
  border-radius: 50px; color: var(--text);
  font-size: 14px; font-weight: 700; cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.pl-action-btn svg { width: 18px; height: 18px; }
.pl-action-btn:hover { background: var(--surface4); }
.pl-action-btn.active { background: var(--green); border-color: var(--green); color: #07210f; }
.pl-action-btn.active svg { color: #07210f; }
/* Destructive «Удалить» — red outline, fills on hover */
.pl-action-danger {
  color: #e05555; border-color: rgba(224, 85, 85, 0.5); background: transparent;
}
.pl-action-danger svg { color: #e05555; }
.pl-action-danger:hover { background: #e05555; border-color: #e05555; color: #fff; }
.pl-action-danger:hover svg { color: #fff; }

/* Edit-mode rows: drag handle (replaces ♥ col) + × (replaces ⋮ col) */
.track-list.editing .track-row { cursor: default; }
.track-list.editing .track-row:hover { background: var(--surface3); }
.pl-drag-handle {
  background: none; border: none; padding: 0;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  color: var(--text-dim); cursor: grab;
  touch-action: none;   /* let pointer drag work on touch */
}
.pl-drag-handle:active { cursor: grabbing; }
.pl-drag-handle svg { width: 16px; height: 16px; }
.pl-remove-btn {
  background: none; border: none; padding: 0;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  color: var(--text-dim); cursor: pointer;
  transition: color 0.12s, background 0.12s;
}
.pl-remove-btn svg { width: 18px; height: 18px; }
.pl-remove-btn:hover { color: #e05555; background: var(--surface4); }
.track-row.pl-dragging {
  background: var(--surface4);
  box-shadow: 0 6px 18px rgba(0,0,0,0.4);
  opacity: 0.95;
}

/* Settings modal — square cover */
.pl-cover-wrap { border-radius: 8px !important; overflow: hidden; }
.pl-cover-wrap img { border-radius: 8px !important; width: 100%; height: 100%; object-fit: cover; }
.pl-cover-reset {
  display: block; margin: 10px auto 0;
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 12px; text-decoration: underline;
}
.pl-cover-reset:hover { color: var(--text); }

/* ═══ Inline playlist rename + clickable cover (task 59, stage 4 visual) ═══ */
.pl-title-editable { cursor: pointer; border-radius: 6px; }
.pl-title-editable:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.pl-title-edit { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pl-title-input {
  font-size: 28px; font-weight: 800; letter-spacing: -0.5px; line-height: 1.1;
  background: var(--surface2); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 2px 10px; max-width: min(70vw, 520px);
}
.pl-title-input:focus { outline: none; border-color: var(--green); }
.pl-title-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--surface3);
  cursor: pointer; color: var(--text-muted); flex-shrink: 0;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.pl-title-btn svg { width: 20px; height: 20px; }
.pl-title-save { color: var(--green); }
.pl-title-save:hover { background: var(--green); color: #07210f; border-color: var(--green); }
.pl-title-cancel:hover { background: var(--surface4); color: var(--text); }
@media (max-width: 768px) { .pl-title-input { font-size: 20px; } }

.pl-cover-clickable { cursor: pointer; position: relative; }
.pl-cover-clickable::after {
  content: 'Сменить обложку'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; text-align: center;
  background: rgba(0,0,0,0.5); color: #fff; font-size: 13px; font-weight: 600;
  opacity: 0; transition: opacity 0.15s; border-radius: inherit; padding: 8px;
}
.pl-cover-clickable:hover::after { opacity: 1; }

/* «В плейлист»: track already in this playlist → green check, non-actionable */
.tm-item-added { cursor: default; }
.tm-item-added .tm-label { color: var(--text-muted); }
.tm-item-added .tm-trailing { color: var(--green); font-weight: 700; font-size: 15px; }
.tm-item-added:hover { background: transparent; }

/* Recently played block in search empty state (task 49) */
.search-recent { margin-top: 6px; }
.search-recent-head {
  font-size: 12px;
  color: var(--text-muted);
  letter-spacing: 0.3px;
  padding: 10px 12px 6px;
}

/* Search query history chips (task 49) */
.search-recent-head-row { display: flex; align-items: center; justify-content: space-between; }
.search-clear-history { color: var(--green); font-size: 12px; cursor: pointer; }
.search-clear-history:hover { text-decoration: underline; }
.search-chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 12px 6px; }
.search-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface3); font-size: 13px;
  padding: 6px 10px; border-radius: 18px; cursor: pointer;
  transition: background 0.12s;
}
.search-chip:hover { background: var(--surface4); }
.search-chip .chip-ic { color: var(--text-dim); flex-shrink: 0; }
.search-chip .chip-text { color: var(--text); }
.search-chip .chip-x { color: var(--text-dim); font-size: 16px; line-height: 1; padding: 0 2px; }
.search-chip .chip-x:hover { color: var(--text); }

/* Listening history view (task 597) */
.history-day-head {
  font-size: 13px; font-weight: 700; color: var(--text);
  padding: 16px 24px 6px; letter-spacing: 0.2px;
}
.history-empty, .history-more {
  color: var(--text-muted); font-size: 13px; text-align: center; padding: 22px 16px;
}
.history-row {
  display: grid;
  grid-template-columns: 36px 40px 1fr 1fr 54px 52px 68px 28px;
  gap: 8px;
  padding: 8px 24px;
  border-radius: 6px;
  align-items: center;
  cursor: pointer;
  transition: background 0.15s;
}
.history-row:hover { background: var(--surface3); }
.history-cover {
  width: 40px; height: 40px; border-radius: 4px; overflow: hidden;
  background: var(--surface3); flex-shrink: 0;
}
.history-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (max-width: 768px) {
  .history-row { grid-template-columns: 28px 40px 1fr 28px; }
  .history-row .track-album-col,
  .history-row .track-fmt-col,
  .history-row .track-dur,
  .history-row .track-size { display: none; }
}

/* History view padding to match Library content indent (task 597) */
#history-view { padding: 0 0 100px; }
#history-view .section-header { padding: 24px 24px 0; }

/* ── Queue panel (task 57) ── */
.queue-badge {
  position: absolute;
  top: -4px; right: -4px;
  min-width: 15px; height: 15px;
  padding: 0 3px;
  background: var(--green); color: var(--bg);
  font-size: 10px; font-weight: 700;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
}
.queue-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.45);
  opacity: 0; visibility: hidden;
  transition: opacity var(--transition), visibility var(--transition);
  z-index: 200;
}
.queue-overlay.open { opacity: 1; visibility: visible; }
.queue-panel {
  position: absolute;
  top: 0; right: 0; bottom: var(--player-h);
  width: 360px;
  background: var(--surface);
  border-left: 1px solid var(--border);
  transform: translateX(100%);
  transition: transform var(--transition);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.queue-overlay.open .queue-panel { transform: translateX(0); }
.queue-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px; flex-shrink: 0;
  border-bottom: 1px solid var(--border);
}
.queue-title { font-size: 16px; font-weight: 700; }
.queue-close {
  background: none; border: none; color: var(--text-muted);
  cursor: pointer; padding: 4px; display: flex;
}
.queue-close:hover { color: var(--text); }
.queue-body { flex: 1; overflow-y: auto; padding: 8px 0 16px; }
.qp-section-label {
  font-size: 11px; color: var(--text-dim); letter-spacing: 0.3px;
  padding: 12px 16px 4px;
}
.qp-section-head {
  display: flex; align-items: center; justify-content: space-between;
  padding-right: 16px;
}
.qp-section-head .qp-section-label { flex: 1; }
.qp-clear { font-size: 13px; color: var(--green); cursor: pointer; padding: 4px; }
.qp-ctx-label { border-top: 1px solid var(--border); margin-top: 4px; }
.qp-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 16px;
}
.qp-cover {
  width: 38px; height: 38px; flex-shrink: 0;
  border-radius: 4px; overflow: hidden; background: var(--surface3);
}
.qp-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.qp-info { flex: 1; min-width: 0; }
.qp-title {
  font-size: 14px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qp-accent { color: var(--green); }
.qp-sub, .qp-src {
  font-size: 12px; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qp-src { color: var(--text-dim); font-size: 11px; }
.qp-ctx-row { opacity: 0.72; cursor: pointer; }
.qp-ctx-row:hover { opacity: 1; background: var(--surface2); }
.qp-queue-row { cursor: default; }
.qp-queue-row:hover { background: var(--surface2); }
.qp-queue-row.qp-dragging { opacity: 0.4; }
.qp-remove, .qp-drag {
  color: var(--text-dim); cursor: pointer; padding: 2px; display: flex; flex-shrink: 0;
}
.qp-remove:hover { color: var(--text); }
.qp-drag { cursor: grab; }

@media (max-width: 768px) {
  .queue-panel {
    top: auto; left: 0; right: 0; bottom: 0;
    width: 100%; max-height: 70vh;
    border-left: none; border-top: 1px solid var(--border);
    border-radius: 12px 12px 0 0;
    transform: translateY(100%);
  }
  .queue-overlay.open .queue-panel { transform: translateY(0); }
}

/* ── Unified track-row component (follow-up 2–5) ── */
/* Number cell with hover→play and playing bars (mirrors old .sr-num). */
.tr-num {
  position: relative;
  font-size: 14px; color: var(--text-dim);
  text-align: center; font-family: 'DM Mono', monospace;
  display: flex; align-items: center; justify-content: center;
  height: 100%;
}
.tr-num-label, .tr-play, .tr-bars {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  transition: opacity 0.15s;
}
.tr-play, .tr-bars { opacity: 0; pointer-events: none; }
/* hover (not playing): number → play glyph */
.track-row.tr-unified:not(.playing):hover .tr-num-label { opacity: 0; }
.track-row.tr-unified:not(.playing):hover .tr-play      { opacity: 1; }
/* playing + not paused: only bars */
.track-row.tr-unified.playing:not(.paused) .tr-num-label { opacity: 0; }
.track-row.tr-unified.playing:not(.paused) .tr-play      { opacity: 0; }
.track-row.tr-unified.playing:not(.paused) .tr-bars      { opacity: 1; }
/* playing + paused: green number, no bars, no play glyph */
.track-row.tr-unified.playing.paused .tr-num-label { opacity: 1; color: var(--green); }
.track-row.tr-unified.playing.paused .tr-play { opacity: 0; }
.track-row.tr-unified.playing.paused .tr-bars { opacity: 0; }

/* Cover cell. */
.tr-cover {
  /* Plain block box with hard geometry: no flex, so the <img> can't be
     re-laid-out by flex sizing rules. The image fills it and is centre-cropped
     via object-fit/object-position (non-square embedded art keeps its centre
     rather than drifting to one side). */
  display: block;
  position: relative;
  width: 40px; height: 40px;
  min-width: 40px; max-width: 40px;
  min-height: 40px; max-height: 40px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--surface3);
  justify-self: start; align-self: center;
  color: var(--text-dim);
}
.tr-cover-none {
  display: flex; align-items: center; justify-content: center;
}
.tr-cover img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center center;
}

/* Heart in the unified row — 75% larger than the legacy in-row heart
   (was 15px → ~26px), placed before the ⋮ menu. */
.track-row.tr-unified .track-fav-btn svg { width: 26px; height: 26px; }
.track-row.tr-unified .track-fav-btn { opacity: 0.55; }
.track-row.tr-unified:hover .track-fav-btn { opacity: 1; }
.track-row.tr-unified .track-fav-btn.fav-active { opacity: 1; }

/* ── Upload collision dialog (follow-up 6) ── */
.mf-collision-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.6);
  display: none; align-items: center; justify-content: center;
  z-index: 500;
}
.mf-collision-overlay.open { display: flex; }
.mf-collision-box {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; width: 420px; max-width: 92vw;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
  overflow: hidden;
}
.mf-collision-head {
  padding: 16px 20px; font-size: 16px; font-weight: 700;
  border-bottom: 1px solid var(--border);
}
.mf-collision-body { padding: 16px 20px; }
.mf-collision-fname {
  font-family: 'DM Mono', monospace; font-size: 13px;
  color: var(--green); word-break: break-all;
  background: var(--surface2); border-radius: 6px; padding: 8px 10px;
}
.mf-collision-q { color: var(--text-muted); font-size: 14px; margin: 12px 0 8px; }
.mf-collision-all-wrap {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-muted); cursor: pointer;
  user-select: none;
}
.mf-collision-actions {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 12px 20px 20px;
}
.mf-collision-btn { flex: 1 1 auto; min-width: 120px; justify-content: center; }
.mf-collision-cancel { color: var(--text-dim); }
.mf-collision-cancel:hover { color: #e05555; }

/* Player-bar track-action buttons (follow-up). */
#pb-fav-btn.pb-fav-active svg { color: #e05555; }

/* «Популярное» tiles — half the size of album tiles (follow-up). */
.popular-grid {
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 10px;
}
.popular-grid .folder-meta { padding: 8px; }
.popular-grid .folder-name { font-size: 13px; margin-bottom: 3px; }
.popular-grid .folder-sub { font-size: 11px; }
.popular-grid .folder-cover .play-overlay svg { width: 36px; height: 36px; }

/* ── Internal sharing (task 683) ──────────────────────────────────────────
   Dialog reuses .modal-box; these are only the parts it adds. The avatar
   badge sits where the public globe would, but on the cover rather than in
   the title line: a face reads as a picture, not as an icon before text. */
.share-album-name {
  font-size: 13px; opacity: .7; margin: -8px 0 16px 0;
  word-break: break-word;
}
.share-list-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  opacity: .55; margin: 18px 0 8px 0;
}
.share-list { max-height: 210px; overflow-y: auto; }
.share-row {
  display: flex; align-items: center;
  gap: 10px; padding: 7px 0;
  border-bottom: 1px solid var(--border);
}
.share-row:last-child { border-bottom: none; }
/* Nickname takes the slack so the delete button stays hard right. */
.share-row-nick { font-size: 14px; word-break: break-word; flex: 1; min-width: 0; }

/* Same circle as the origin badge on a library tile, at text scale. */
.share-avatar {
  width: 26px; height: 26px; border-radius: 50%;
  overflow: hidden; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface3, #2a2a2a);
}
.share-avatar img { width: 100%; height: 100%; object-fit: cover; }
.share-avatar-letter {
  background: #4a9eff; color: #fff;
  font-size: 12px; font-weight: 700; line-height: 1;
}

/* Icon + label buttons: the icon carries the meaning at a glance, the word
   removes any doubt about which one deletes. */
.share-add-row .btn-primary,
.share-row .btn-danger {
  display: inline-flex; align-items: center; gap: 6px;
}
.share-add-row .btn-primary svg,
.share-row .btn-danger svg { flex-shrink: 0; }
.share-empty { font-size: 13px; opacity: .55; padding: 6px 0; }
.btn-small { padding: 4px 10px; font-size: 12px; }

/* Input and its submit button on one line: the dialog previously offered no
   way to commit a typed nickname except Enter, which is not discoverable. */
.share-add-row { display: flex; gap: 8px; align-items: stretch; }
.share-add-row input { flex: 1; min-width: 0; }
.share-add-row .btn-primary { flex-shrink: 0; white-space: nowrap; }

.share-suggest {
  margin-top: 6px; max-height: 200px; overflow-y: auto;
}
.share-suggest-item {
  padding: 6px 10px; font-size: 14px; cursor: pointer;
  border-radius: 6px;
  display: flex; align-items: center; gap: 10px;
}
.share-suggest-nick { flex: 1; min-width: 0; word-break: break-word; }
.share-suggest-item:hover,
.share-suggest-item.is-active { background: var(--surface3, rgba(255,255,255,.07)); }
/* Already a recipient: shown so the name does not look missing, but not
   offered — no pointer, no hover, and a reason on the right. */
.share-suggest-item.is-shared { opacity: .45; cursor: default; }
.share-suggest-item.is-shared:hover { background: none; }
.share-suggest-note {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  opacity: .8; margin-left: 10px; flex-shrink: 0;
}

/* Sharer's avatar on a shared album tile — replaces the globe a public
   folder would show. Bottom-left so it never collides with the favourite
   heart (top-right) or the play overlay (centre). */
/* Origin badge on the cover — the sharer's avatar for a shared album, the
   SoundVault mark for a public one. One shape for both so the tiles read as
   variations of one idea rather than two unrelated decorations.

   Bottom-left: the favourite heart owns the top-right and the play overlay
   owns the centre. */
.folder-badge {
  position: absolute; left: 8px; bottom: 8px;
  width: 28px; height: 28px; border-radius: 50%;
  overflow: hidden; z-index: 2;
  border: 2px solid var(--surface2, #1e1e1e);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 6px rgba(0,0,0,.45);
}
.folder-badge img { width: 100%; height: 100%; object-fit: cover; }
.folder-badge span {
  font-size: 13px; font-weight: 700; color: #fff; line-height: 1;
}
/* Avatar fallback is a letter on a solid fill, so the circle needs a colour;
   a real avatar covers it entirely. */
.folder-badge-shared { background: #4a9eff; }
/* The logo is not a photo — it needs padding and a dark disc behind it, or
   it reads as a cropped smudge at 28px. contain, not cover. */
.folder-badge-public { background: var(--surface1, #121212); }
.folder-badge-public img {
  width: 78%; height: 78%; object-fit: contain;
}

/* Task 692 — separates «Скрытые» from the additive filters above it: that
   option replaces the selection instead of joining it, and the gap says so
   before the user finds out by clicking. */
.lib-pref-sep {
  height: 1px; margin: 8px 0;
  background: var(--border, rgba(255,255,255,.1));
}
/* Under «Все» the three parts are ticked because they are true, not because
   the user picked them. Dimming says "implied"; they stay clickable, because
   clicking one is how you narrow down from «Все». */
.lib-pref-option.is-implied span { opacity: .55; }

/* ── Federation peers (task 614) ──────────────────────────────────────────── */
.peer-hint { font-size: 13px; color: var(--text-muted); margin: 6px 0 14px; line-height: 1.5; }
.peer-actions { display: flex; gap: 10px; margin-bottom: 16px; }
.peer-box {
  background: var(--surface3); border-radius: 10px;
  padding: 16px; margin-bottom: 18px;
}
.peer-box-title { font-size: 14px; font-weight: 600; margin-bottom: 8px; }
.peer-code {
  width: 100%; box-sizing: border-box;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12px; line-height: 1.45;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 10px; resize: vertical; margin-bottom: 10px;
  word-break: break-all;
}
.peer-list { display: flex; flex-direction: column; gap: 12px; }
.peer-empty { font-size: 13px; color: var(--text-muted); padding: 10px 0; }
.peer-card {
  background: var(--surface3); border-radius: 10px; padding: 14px 16px;
}
.peer-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.peer-name { font-size: 15px; font-weight: 600; }
.peer-url { font-size: 12px; color: var(--text-muted); margin-top: 2px; word-break: break-all; }
.peer-status { font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
               padding: 3px 8px; border-radius: 20px; white-space: nowrap; }
.peer-active    { background: rgba(29,185,84,.18);  color: #1DB954; }
.peer-attention { background: rgba(229,160,13,.18); color: #E5A00D; }
.peer-pending   { background: rgba(255,255,255,.08); color: var(--text-muted); }
.peer-revoked   { background: rgba(229,72,77,.15);  color: #E5484D; }

/* The fingerprint is the only thing in this screen a human must actually
   read, so it gets size, spacing and a monospaced face — mistaking 0 for O
   here is the failure mode the whole handshake guards against. */
.peer-fp-row { margin-top: 12px; }
.peer-fp-label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
                 color: var(--text-dim); margin-bottom: 3px; }
.peer-fp {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 15px; letter-spacing: .06em; word-spacing: .3em;
  color: var(--text);
}
.peer-fp-own { color: var(--text-muted); }

.peer-warn {
  margin-top: 12px; padding: 10px 12px; border-radius: 8px;
  background: rgba(229,160,13,.12); border-left: 3px solid #E5A00D;
  font-size: 13px; line-height: 1.45;
}
.peer-warn-soft { background: rgba(255,255,255,.05); border-left-color: var(--text-dim); }
.peer-card-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.peer-result { margin-top: 10px; font-size: 13px; }
.peer-ok  { color: #1DB954; }
.peer-bad { color: #E5484D; }

/* ── Federation, task 697 ──────────────────────────────────────────────────── */
.peer-name-row { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; }
.peer-name-row .form-input { flex: 1; min-width: 0; }
.peer-sync-row { margin-top: 12px; }
.peer-switch {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; cursor: pointer; margin-bottom: 4px;
}
.peer-switch input { accent-color: var(--green, #1DB954); }
/* Group headings in the access list: users and servers answer the same
   question but are not the same kind of thing, and an unlabelled mixed list
   would make a server look like a person. */
.access-group-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-dim); margin: 10px 0 4px;
}
.access-group-title:first-child { margin-top: 0; }
.peer-avatar-sm {
  background: var(--surface4, #2A2A2A) !important;
  color: var(--text-muted);
  display: flex; align-items: center; justify-content: center;
}
