/* ── Themes ── */
:root[data-theme="dark"] {
  --bg:            #0d0d10;
  --surface:       #16161c;
  --surface-hover: #1e1e28;
  --text:          #e2e2ea;
  --text-muted:    #9090a8;   /* 6:1 on surface — WCAG AA */
  --accent:        #7b68ee;
  --accent-dim:    #5548c8;
  --accent-glow:   rgba(123,104,238,0.15);
  --border:        #252530;
  --error:         #e05c5c;
  --success:       #5cb870;
  --range-track:   #35354a;   /* lifted so bar is visible at rest */
}
:root[data-theme="light"] {
  --bg:            #f5f5f7;
  --surface:       #ffffff;
  --surface-hover: #ededf5;
  --text:          #1a1a2e;
  --text-muted:    #656580;   /* 5.6:1 on white — WCAG AA */
  --accent:        #6c5ce7;
  --accent-dim:    #5048c0;
  --accent-glow:   rgba(108,92,231,0.12);
  --border:        #dedee8;
  --error:         #d63031;
  --success:       #00b894;
  --range-track:   #c0c0d0;
}
:root[data-theme="ocean"] {
  --bg:            #0a1628;
  --surface:       #0f2040;
  --surface-hover: #162a50;
  --text:          #c8e6f5;
  --text-muted:    #5d9ab8;   /* 5.3:1 on surface — WCAG AA */
  --accent:        #00cec9;
  --accent-dim:    #00a8a4;
  --accent-glow:   rgba(0,206,201,0.12);
  --border:        #1a3050;
  --error:         #ff7675;
  --success:       #55efc4;
  --range-track:   #2a4060;
}
:root[data-theme="sunset"] {
  --bg:            #1a0a10;
  --surface:       #26101a;
  --surface-hover: #321525;
  --text:          #f5e0d0;
  --text-muted:    #c09080;   /* 6.5:1 on surface — WCAG AA */
  --accent:        #fd7c6e;
  --accent-dim:    #e05a4e;
  --accent-glow:   rgba(253,124,110,0.12);
  --border:        #3a1820;
  --error:         #ff4757;
  --success:       #7bed9f;
  --range-track:   #4a2530;
}

:root {
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px;
  --space-4: 16px; --space-5: 24px; --space-6: 32px;
  --radius: 8px;
  --player-h: 84px;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

/* Access-denied / sign-in-required notice shown on privileged pages. */
.access-denied {
  max-width: 28rem;
  margin: var(--space-7, 4rem) auto;
  padding: var(--space-6, 2rem);
  text-align: center;
  display: grid;
  gap: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.access-denied h1 { margin: 0; font-size: 1.4rem; }
.access-denied p { margin: 0; color: var(--text-muted); }
.access-denied .btn { justify-self: center; text-decoration: none; }

body {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  padding-bottom: calc(var(--player-h) + var(--space-4));
}

/* ── Header ── */
header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.logo {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
}
.logo span { color: var(--accent); }   /* accent on "Mad" — the differentiator */

/* ── Site nav (shared between upload and library pages) ── */
.main-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  /* Push everything after the nav to the right so the logo + nav stay grouped
     on the left and the header-actions sit at the far right on every page —
     otherwise justify-content: space-between would drift the nav toward the
     centre. The header carries no search box now, so this is the layout on
     all pages. */
  margin-right: auto;
}

.nav-link {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
  padding: 4px 8px;
  border-bottom: 2px solid transparent;
  transition: color 150ms ease, border-color 150ms ease;
  line-height: 1;
  margin-bottom: -1px; /* align underline with header bottom border */
}
.nav-link:hover { color: var(--text); }
.nav-link--active {
  color: var(--text);
  border-bottom-color: var(--accent);
}
.nav-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ── About mini-menu (header) ── */
/* A flex container (not the default block) so the inline-flex button has no line
   box and centres against the sibling .nav-link anchors instead of sitting low. */
.about { position: relative; display: inline-flex; align-items: center; }

/* The trigger reuses .nav-link sizing/colour; reset the <button> chrome. */
.about__btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  font-family: inherit;
  cursor: pointer;
}
.about__caret { font-size: 9px; }

.about__menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 20;
  /* Hug the widest entry (e.g. "GitRepo") instead of a fixed width, so short
     items don't leave a big empty gap on the right. */
  width: max-content;
  display: flex;
  flex-direction: column;
  padding: var(--space-1);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
/* Beat the UA [hidden] rule, which our .about__menu display would otherwise win
   against (author > UA at equal specificity). */
.about__menu[hidden] { display: none; }

.about__item {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 6px 10px;
  font-family: inherit;
  font-size: 13px;
  color: var(--text-muted);
  text-align: left;
  text-decoration: none;
  background: none;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}
.about__item:hover { color: var(--text); background: var(--surface-hover); }
.about__item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ── About modal body (reuses .modal-backdrop / .modal / .btn-close) ── */
.about-card { text-align: center; }
.about-name {
  margin: 0 0 var(--space-4);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
}
.about-name span { color: var(--accent); }

.about-meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-4);
  margin: 0;
  text-align: left;
}
.about-meta dt { font-size: 13px; color: var(--text-muted); }
.about-meta dd { margin: 0; font-size: 13px; color: var(--text); }
.about-commit {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  word-break: break-all;
}

/* ── Library search ── */
/* #header-insert is a per-page header slot the shell swaps; today it's empty on
   every page (the library search moved into the Music page body so the header
   looks identical everywhere), but keep it transparent to layout so any future
   insert stays a direct header flex child. */
#header-insert { display: contents; }

/* The search box lives at the top of the Music page's <main>, above the view
   panels — a left-aligned row under the section tabs, not a header element. */
.library-search {
  position: relative;
  max-width: 360px;
  margin-bottom: var(--space-4);
}

.library-search__icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
}

.library-search__input {
  width: 100%;
  height: 36px;
  padding: 0 36px 0 36px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.library-search__input::placeholder { color: var(--text-muted); }
.library-search__input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
/* Hide the browser's native clear button — we render our own */
.library-search__input::-webkit-search-cancel-button { display: none; }

.library-search__clear {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 50%;
  transition: color 120ms ease, background 120ms ease;
}
.library-search__clear:hover { color: var(--text); background: var(--surface-hover); }
.library-search__clear:focus-visible { outline: 2px solid var(--accent); }

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

/* .theme-dot is the color swatch — formerly the header switcher dots, now reused
   as the swatches in the Settings page theme picker (settings.css). */
.theme-dot {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform 120ms ease, border-color 120ms ease;
}
.theme-dot:hover { transform: scale(1.15); }
.theme-dot[data-theme="dark"]   { background: linear-gradient(135deg, #0d0d10 50%, #7b68ee 50%); }
.theme-dot[data-theme="light"]  { background: linear-gradient(135deg, #f5f5f7 50%, #6c5ce7 50%); }
.theme-dot[data-theme="ocean"]  { background: linear-gradient(135deg, #0a1628 50%, #00cec9 50%); }
.theme-dot[data-theme="sunset"] { background: linear-gradient(135deg, #1a0a10 50%, #fd7c6e 50%); }
.theme-dot.active { border-color: var(--accent); }
.theme-dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Library ── */
main { padding: var(--space-5); max-width: 860px; margin: 0 auto; }

.section-title {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: var(--space-4);
}

.track-list { list-style: none; }

.track-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 120ms ease;
}
.track-row:hover  { background: var(--surface-hover); }
.track-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.track-row.playing { background: var(--surface-hover); }
.track-row.playing .track-title { color: var(--accent); }

/* Multi-disc subheading in an album's track list. */
.track-disc-header {
  padding: var(--space-4) var(--space-4) var(--space-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.track-num {
  flex-shrink: 0;
  width: 22px;
  text-align: right;
  font-size: 13px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.track-row.playing .track-num { display: none; }
.track-icon-playing {
  display: none;
  flex-shrink: 0;
  width: 22px;
  align-items: center;
  justify-content: center;
  color: var(--accent);
}
.track-row.playing .track-icon-playing { display: flex; }

.track-info { flex: 1; min-width: 0; }
.track-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
}
.track-meta {
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.track-dur {
  flex-shrink: 0;
  width: 40px;
  text-align: right;
  font-size: 12px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.track-row.playing .track-dur { color: var(--accent); }

.empty-state {
  text-align: center;
  padding: 48px var(--space-5);
  color: var(--text-muted);
}
.empty-state p { margin-top: var(--space-2); font-size: 14px; }
.btn-upload-empty {
  margin-top: var(--space-4);
  padding: var(--space-2) var(--space-5);
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 150ms ease;
}
.btn-upload-empty:hover { background: var(--accent-dim); }
.btn-upload-empty:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* The player bar (#player-bar, .progress-*, .player-*, .ctrl-btn, #volume-slider)
   lives in player.css now — it's shared with the admin Files page. The generic
   input[type=range] styling below stays here as it's used beyond the player. */

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  border-radius: 2px;
  background: var(--range-track);
  cursor: pointer;
  outline: none;
}
input[type="range"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
}
input[type="range"]::-moz-range-thumb {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
}

/* ── Upload modal ── */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.65);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal-backdrop.hidden { display: none; }

.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: var(--space-5);
  width: min(420px, calc(100vw - 2 * var(--space-5)));
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-5);
}
.modal-header h2 { font-size: 16px; font-weight: 600; }

.btn-close {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: var(--space-1);
  border-radius: 4px;
}
.btn-close:hover { color: var(--text); background: var(--surface-hover); }
.btn-close:focus-visible { outline: 2px solid var(--accent); }

.drop-zone {
  border: 2px dashed var(--border);
  border-radius: var(--radius);
  padding: 40px var(--space-5);
  text-align: center;
  color: var(--text-muted);
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease;
  position: relative;
}
.drop-zone.dragover {
  border-color: var(--accent);
  background: var(--accent-glow);
  color: var(--text);
}
.drop-zone input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
.drop-zone .drop-icon { font-size: 40px; margin-bottom: var(--space-3); }
.drop-zone p { font-size: 14px; pointer-events: none; color: var(--text); }
.drop-zone small { font-size: 12px; color: var(--text-muted); pointer-events: none; }

.upload-status {
  margin-top: var(--space-4);
  font-size: 13px;
  min-height: 20px;
}
.upload-status.error   { color: var(--error); }
.upload-status.success { color: var(--success); }

/* ── Library drill-down ── */
/* ── In-page subtab bar (.subtabs / .subtab) ──────────────────────────────── */
/* The underline tab strip used by every in-<main> subtab switcher: the library's
   section switcher (Music · Playlists · …, server-rendered <a>) and the upload
   page's Upload ⇄ My uploads bar (client-toggled <button>). One component so they
   look identical throughout; .subtab carries both the <a> and <button> resets so
   either element works. Active tab = .is-active. Extend by adding more .subtab. */
.subtabs {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
}
.subtab {
  appearance: none;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;            /* sit the active underline on the strip's border */
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease;
}
.subtab:hover { color: var(--text); }
.subtab.is-active { color: var(--text); border-bottom-color: var(--accent); }
.subtab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
/* Pill count badge (e.g. the upload page's My-uploads count). */
.subtab__count {
  display: inline-block;
  min-width: 1.6em;
  padding: 0 var(--space-1);
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  line-height: 1.6;
  text-align: center;
  vertical-align: text-bottom;
}

/* The breadcrumb row. No bottom border: the .subtabs strip above is the only
   divider, so a drilled view doesn't show two stacked lines. Hidden entirely at a
   section's top level (JS sets display:none) — there's nothing to show there. */
.library-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  min-width: 0;
}

.bc-item {
  font-size: 13px;
  white-space: nowrap;
}
.bc-link {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0;
  font-size: 13px;
  font-weight: 500;
  transition: color 100ms ease;
}
.bc-link:hover { color: var(--text); }
.bc-link:focus-visible { outline: 2px solid var(--accent); border-radius: 3px; }
.bc-current {
  color: var(--text);
  font-weight: 600;
}
.bc-sep {
  color: var(--text-muted);
  font-size: 13px;
  opacity: 0.5;
}

/* ── View panels (SPA) ── */
.view-panel--hidden { display: none; }
.view-panel--active { display: block; }

.library-panel { min-height: 120px; }

@keyframes panelFadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.panel-fade-in {
  animation: panelFadeIn 150ms ease-out both;
}

.panel-empty {
  padding: 40px var(--space-5);
  text-align: center;
  color: var(--text-muted);
  font-size: 14px;
}
.panel-empty a {
  color: var(--accent);
  text-decoration: none;
}
.panel-empty a:hover { text-decoration: underline; }

/* Artist and album rows share base */
.panel-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 120ms ease;
}
.panel-row:hover { background: var(--surface-hover); }
.panel-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.row-name {
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.row-meta {
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.row-chevron {
  margin-left: auto;
  flex-shrink: 0;
  color: var(--text-muted);
  font-size: 18px;
  opacity: 0.5;
}
.panel-row:hover .row-chevron { opacity: 1; }

/* Artist row: name fills space, meta right-aligned before chevron */
.artist-row { gap: var(--space-3); }
.artist-row .row-name { flex: 1; min-width: 0; }
.artist-row .row-meta { flex-shrink: 0; }

/* Album row: art + text block */
.album-row { gap: var(--space-4); }
.row-art {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 6px;
  background: var(--surface-hover);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  overflow: hidden;
}
.row-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}
.row-body { flex: 1; min-width: 0; }

.track-row.unavailable { opacity: 0.4; }
.track-row.unavailable .track-title { color: var(--text-muted); }
.track-row.unavailable .track-title::after {
  content: ' — not found';
  font-style: italic;
  font-weight: 400;
}

/* ── Search results ── */
#view-search { padding: 24px 32px; }

.search-section + .search-section { margin-top: 32px; }

.search-section__header {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 8px 0;
}

.search-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 120ms ease;
}
.search-row:hover { background: var(--surface-hover); }
.search-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Artist avatar — 32px circle with first letter */
.search-row__avatar {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 13px;
}

/* Album thumbnail — 40px square */
.search-row__thumb {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 4px;
  background: var(--surface-hover);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  overflow: hidden;
}
.search-row__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.search-row__body { flex: 1; min-width: 0; }

.search-row__title {
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-row__subtitle {
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-row__duration {
  flex-shrink: 0;
  font-size: 13px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* Search empty state */
.search-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 200px;
  gap: 8px;
  text-align: center;
}
.search-empty-state__query {
  font-size: 15px;
  color: var(--text);
}
.search-empty-state__hint {
  font-size: 13px;
  color: var(--text-muted);
}

/* Search loading shimmer bar */
.search-loading-bar {
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  background-size: 200% 100%;
  animation: search-shimmer 1.2s infinite;
  border-radius: 1px;
  margin-bottom: 16px;
}
@keyframes search-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── Button system ── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius);
  font-size: 14px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  border: 1px solid transparent;
  background: none;
  color: var(--text);
  transition: background 150ms ease, border-color 150ms ease, color 150ms ease;
}
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.btn:disabled { opacity: 0.6; cursor: default; }
.btn-neutral {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text);
}
.btn-neutral:hover:not(:disabled) { background: var(--surface-hover); }

/* ── Header auth area ── */
.user-area {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-right: var(--space-2);
}

/* ── Auth modals ── */
.modal-body { font-size: 14px; color: var(--text); margin-bottom: var(--space-5); }
.modal-actions { display: flex; justify-content: flex-end; gap: var(--space-3); margin-top: var(--space-3); }

/* ── Modal form fields (shared track-edit.js component + admin modals) ── */
.edit-form {
  display: grid;
  gap: var(--space-3);
}
.edit-form label {
  display: grid;
  gap: var(--space-1);
  font-size: 13px;
  color: var(--text-muted);
}
.edit-form input,
.edit-form select,
.edit-form textarea {
  padding: var(--space-2) var(--space-3);
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font: inherit;
}
.edit-form textarea { resize: vertical; min-height: 2.4em; }
.edit-form input:focus-visible,
.edit-form select:focus-visible,
.edit-form textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* "Extended edit" disclosure: a quiet text button that opens the wide modal. */
.edit-extended-toggle {
  justify-self: start;
  padding: 0;
  background: none;
  border: none;
  color: var(--accent);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.edit-extended-toggle:hover { text-decoration: underline; }
/* Wide secondary modal (the full "extended tags" editor), stacked above the
   regular edit modal. Two-column field grid; a .span-2 field spans both. */
.modal-wide { width: min(620px, calc(100vw - 2 * var(--space-5))); }
.modal-backdrop.is-stacked { z-index: 110; background: rgba(0,0,0,0.45); }
.edit-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.edit-grid-2 .span-2 { grid-column: 1 / -1; }
.login-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.login-form label {
  font-size: 0.85rem;
  color: var(--text-muted);
}
.login-form input {
  padding: var(--space-2) var(--space-3);
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font: inherit;
}
.login-form input:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-glow);
}
.login-error {
  color: var(--error);
  font-size: 0.9rem;
  margin: var(--space-1) 0 0;
}

/* ── Toasts ── */
.toast-stack {
  position: fixed;
  bottom: var(--space-5);
  right: var(--space-5);
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-width: min(360px, calc(100vw - 2 * var(--space-5)));
  pointer-events: none;
}
#toastAlert { bottom: auto; top: var(--space-5); }
/* On shell pages the fixed player bar (and the queue panel) own the bottom-right
   corner; lift the status stack clear of both so toasts never cover the player
   controls or the open queue (BUG-16). Errors (#toastAlert) stay top-anchored. */
#toastStatus { bottom: calc(var(--player-h) + var(--space-3)); }
body.queue-open #toastStatus {
  bottom: calc(var(--player-h) + min(60vh, 480px) + var(--space-4));
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: var(--space-3);
  font-size: 13px;
  color: var(--text);
  pointer-events: auto;
  box-shadow: 0 4px 16px rgba(0,0,0,0.25);
}
.toast.is-success { border-left-color: var(--success); }
.toast.is-error   { border-left-color: #e05c5c; }
.toast-icon { flex-shrink: 0; }
.toast.is-success .toast-icon { color: var(--success); }
.toast.is-error .toast-icon   { color: #e05c5c; }
.toast-msg { flex: 1; min-width: 0; }
.toast-close {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 0 2px;
  flex-shrink: 0;
}
.toast-close:hover { color: var(--text); }
.toast-close:focus-visible { outline: 2px solid var(--accent); }
.toast-action {
  flex-shrink: 0;
  background: none;
  border: none;
  color: var(--accent);
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  padding: 0 2px;
  text-decoration: underline;
}
.toast-action:hover { color: var(--accent-dim); }
.toast-action:focus-visible { outline: 2px solid var(--accent); }

/* ── Row hearts & quick-add menus (Phase 5: favorites + quick-add) ── */
.row-heart, .row-more {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  visibility: hidden;
}
.row-more { font-size: 16px; line-height: 1; font-weight: 700; }
.track-row:hover .row-heart,  .track-row:focus-within .row-heart,
.track-row:hover .row-more,   .track-row:focus-within .row-more,
.panel-row:hover .row-more,   .panel-row:focus-within .row-more,
.search-row:hover .row-heart, .search-row:focus-within .row-heart,
.row-heart.liked { visibility: visible; }
.row-heart:hover, .row-more:hover { color: var(--text); background: var(--surface-hover); }
.row-heart.liked { color: #e0526e; }
.row-heart.liked:hover { color: #e87b91; background: var(--surface-hover); }
.row-heart:focus-visible, .row-more:focus-visible {
  outline: 2px solid var(--accent);
  visibility: visible;
}

.row-menu {
  position: fixed;
  z-index: 300;
  min-width: 190px;
  max-width: 280px;
  padding: 4px 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}
.row-menu > button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 14px;
  background: none;
  border: none;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.row-menu > button:hover:not(:disabled) { background: var(--surface-hover); }
.row-menu > button:disabled { color: var(--text-muted); cursor: default; }
.row-menu > button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.row-menu-input {
  display: flex;
  gap: 6px;
  padding: 6px 10px;
}
.row-menu-input input {
  flex: 1;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: 13px;
  padding: 4px 8px;
}
.row-menu-input input:focus-visible { outline: 2px solid var(--accent); }
.row-menu-input button {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: 12px;
  padding: 4px 10px;
  cursor: pointer;
}
.row-menu-input button:hover { background: var(--surface-hover); }

/* ── Narrow viewport: in-page library search spans the content width ── */
@media (max-width: 599px) {
  .library-search { max-width: none; }
}
