/* ── Search ── */
.search-container {
  display: flex; flex-direction: column; gap: 14px; margin-bottom: 28px;
  position: sticky; top: calc(var(--nav-height) + env(safe-area-inset-top, 0px)); z-index: 90;
  background: var(--bg); padding-top: 8px; padding-bottom: 8px;
}
.search-row {
  display: flex; gap: 12px; align-items: center;
}
.search-input-wrap {
  flex: 1; position: relative;
}
.search-logo {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px; pointer-events: none; opacity: 0.7;
}
.search-input {
  width: 100%; padding: 16px 48px 16px 50px; font-size: 16px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius); color: var(--text); outline: none;
  font-family: inherit; transition: all var(--transition);
  box-shadow: inset 0 1px 3px rgba(0,0,0,.2);
}
.search-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim), inset 0 1px 3px rgba(0,0,0,.2); }
.search-input::placeholder { color: var(--text-dim); }

#searchClear {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  background: none; border: none; color: var(--red, #ef4444); font-size: 20px;
  cursor: pointer; padding: 4px 8px; display: none; transition: opacity var(--transition);
  opacity: 0.7;
}
#searchClear:hover { opacity: 1; }

.btn-mic {
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--bg-card); border: 2px solid var(--border);
  color: var(--text-muted); cursor: pointer; display: flex;
  align-items: center; justify-content: center; transition: all .3s;
  flex-shrink: 0;
}
.btn-mic:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-dim); }
.btn-mic.recording {
  border-color: var(--red); color: var(--red);
  animation: pulse 1.5s ease infinite;
  box-shadow: 0 0 24px rgba(239, 68, 68, 0.3);
}
.btn-mic.identifying { border-color: var(--accent); color: var(--accent); animation: pulse 1s ease infinite; }

.mic-status {
  font-size: 12px; color: var(--text-muted);
  text-align: center; width: 100%;
}
.mic-status:empty { display: none; }

/* Live input-level meter shown only while recording (Fix 4). Hidden by
   default; JS toggles .active so it doesn't reserve layout space when idle. */
.mic-level {
  display: none; width: 100%; height: 4px; margin-top: 6px;
  border-radius: 2px; background: var(--bg-card); border: 1px solid var(--border);
  overflow: hidden;
}
.mic-level.active { display: block; }
.mic-level-fill {
  height: 100%; width: 0%; background: var(--accent);
  transition: width .1s linear;
}
.mic-level-fill.quiet { background: var(--red); }

.type-toggle {
  display: flex; gap: 6px; flex-wrap: wrap;
}
.type-btn {
  background: var(--bg-card); border: 1px solid var(--border); color: var(--text-muted);
  padding: 8px 18px; cursor: pointer; font-size: 13px; transition: all var(--transition);
  font-family: inherit; font-weight: 500; border-radius: 20px;
}
.type-btn:hover { border-color: var(--border-hover); color: var(--text); }
.type-btn.active { background: var(--accent); color: #000; font-weight: 600; border-color: var(--accent); }

/* ── Recognize Result ── */
.recognize-result {
  background: var(--bg-card); border: 1px solid var(--accent); border-radius: var(--radius);
  padding: 20px; margin-bottom: 24px; display: none;
  animation: slideUp .3s ease;
  box-shadow: 0 0 20px rgba(162,230,64,.1);
}
.recognize-result .rr-header { display: flex; gap: 16px; align-items: center; }
.recognize-result .rr-img { width: 64px; height: 64px; border-radius: var(--radius-sm); object-fit: cover; }
.recognize-result .rr-info { flex: 1; min-width: 0; }
.recognize-result .rr-title { font-size: 16px; font-weight: 700; }
.recognize-result .rr-artist { font-size: 14px; color: var(--text-muted); margin-top: 2px; }
.recognize-result .rr-label { font-size: 11px; color: var(--accent); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 6px; font-weight: 600; }
.recognize-result .rr-actions { display: flex; gap: 8px; margin-left: auto; }
.recognize-result .rr-btn {
  padding: 8px 16px; border-radius: 20px; border: none;
  font-size: 13px; font-weight: 600; cursor: pointer; font-family: inherit;
  transition: all var(--transition);
}
.rr-btn-download { background: var(--accent); color: #000; }
.rr-btn-download:hover { box-shadow: var(--shadow-glow); }
.rr-btn-search { background: var(--bg-elevated); color: var(--text); border: 1px solid var(--border) !important; }
.rr-btn-search:hover { border-color: var(--accent) !important; }
.rr-btn-close { background: none; color: var(--text-muted); font-size: 18px; cursor: pointer; border: none; padding: 4px 8px; }

/* ── All-mode aggregated search (Spotify-style sections) ── */
.search-section { margin-top: 28px; }

.search-section-header {
  display: flex; align-items: baseline; justify-content: space-between;
  margin: 0 0 12px;
}
.search-section-header h3 {
  font-size: 20px; font-weight: 700; color: var(--text); margin: 0;
}
.section-showall {
  background: none; border: none; cursor: pointer; font-family: inherit;
  font-size: 12px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase;
  color: var(--text-dim); padding: 4px 2px; transition: color .15s;
}
.section-showall:hover { color: var(--text); }

/* ── Top-result hero row (top card + songs panel) ── */
.top-result-row {
  display: grid; grid-template-columns: minmax(0, 340px) 1fr; gap: 20px;
  margin-top: 8px;
}

.top-result-card {
  background: var(--bg-card); border-radius: 16px; padding: 20px;
  position: relative; display: flex; flex-direction: column; gap: 4px;
  overflow: visible;
}
/* .card-play-btn's shared cards.css rule anchors to `100cqw` (the artwork's
   height, since .card-img is width:100%;aspect-ratio:1) — that doesn't hold
   here: .top-result-img is a FIXED 180px square (140px below the 640px
   breakpoint), unrelated to the hero card's own (much wider, up to 340px)
   inline size. Fall back to a fixed px offset instead: 20px card padding-top
   + 180px artwork - 8px inset - 36px button height = 156px (116px at the
   140px mobile artwork size, kept in sync with the breakpoint below). This
   selector's specificity (2 classes) already wins over the shared rule, so
   no !important is needed. */
.top-result-card .card-play-btn,
.top-result-card .card-radio-btn,
.top-result-card .card-addpl-btn { top: 156px; bottom: auto; }
/* Horizontal placement of the radio/add buttons is set in JS (buildTopResultCard),
   because it depends on whether a play button exists for this item type; only the
   artwork-relative `top` is static, so it lives here with the play button. */
.top-result-img {
  width: 180px; height: 180px; max-width: 100%; border-radius: 8px;
  object-fit: cover; background: var(--bg-elevated); margin-bottom: 12px;
}
.top-result-card.artist-card .top-result-img { border-radius: 50%; }
.top-result-name {
  font-size: 26px; font-weight: 800; line-height: 1.15; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.top-result-type {
  font-size: 13px; color: var(--text-dim); text-transform: capitalize;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.top-songs-panel { min-width: 0; }

/* ── Song rows (compact list; each row carries .card for play delegation) ── */
/* The album/playlist track list lives inside #albumTracks, which is a CSS grid
   (styled for card layouts). Span all columns + full width so the flat list
   doesn't collapse into a single ~150px grid cell (which zeroed out titles). */
.song-list { display: flex; flex-direction: column; gap: 2px; width: 100%; grid-column: 1 / -1; }
.song-list .song-row {
  display: flex; align-items: center; gap: 12px; padding: 8px;
  border-radius: 8px; cursor: pointer; background: transparent;
  overflow: visible; border: 1px solid transparent;
}
.song-list .song-row:hover { background: var(--bg-elevated); transform: none; box-shadow: none; }
.song-list .song-row:active { transform: none; }
.song-row .song-thumb {
  width: 44px; height: 44px; border-radius: 4px; object-fit: cover;
  background: var(--bg-elevated); flex-shrink: 0;
}
/* Numbered album list: track position replaces the repeated cover thumbnail. */
.song-num {
  width: 28px; flex-shrink: 0; text-align: center;
  font-size: 14px; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.song-info { min-width: 0; flex: 1; }
.song-title {
  font-size: 14px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.3;
}
.song-artist {
  font-size: 12px; color: var(--text-muted); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.song-duration { color: var(--text-dim); font-size: 12px; flex-shrink: 0; }
/* Reset the card-absolute buttons back to inline flow inside a row. */
.song-list .song-row .card-play-btn {
  position: static; width: 32px; height: 32px; box-shadow: none;
  opacity: 0; transform: none; flex-shrink: 0;
}
.song-list .song-row:hover .card-play-btn { opacity: 1; transform: none; }
.song-list .song-row .kebab-btn {
  position: static; width: 32px; height: 32px; background: none; flex-shrink: 0;
}
.song-list .song-row .kebab-btn:hover { background: var(--bg-elevated); }
.song-list .song-row .like-btn { position: static; width: 32px; height: 32px; flex-shrink: 0; }
/* Quick add-to-playlist: same inline-flow reset as the play button above. */
.song-list .song-row .card-addpl-btn {
  position: static; width: 32px; height: 32px; background: none; border: none;
  box-shadow: none; opacity: 0; transform: none; flex-shrink: 0;
}
.song-list .song-row:hover .card-addpl-btn { opacity: 1; transform: none; }
.song-list .song-row .card-addpl-btn:hover { background: var(--bg-elevated); }
/* The card overlay "In Library" badge is position:absolute (built for cover art)
   and would float over the track title on a flat row. Drop it and instead tint
   the track number of in-library rows — clean and non-overlapping. */
.song-list .song-row .in-library-badge { display: none; }
.song-list .song-row.in-library .song-num { color: var(--accent); }

/* Circular artist thumbnails on result cards. */
.card.artist-card .card-img { border-radius: 50%; }

/* Aligned to the app's single mobile breakpoint (640px — see responsive.css,
   which switches the card grids, nav, modal, etc. at max-width:640px). This
   used to be 760px, so the 641–760px range rendered the hero row collapsed
   to mobile layout while the card grids below it were still on desktop
   sizing ("mobile on top, desktop below"). Picked 640 over bumping the rest
   of the app to 760 since 640 is already the established convention
   everywhere else and responsive.css is out of this fix's scope. */
@media (max-width: 640px) {
  .top-result-row { grid-template-columns: 1fr; gap: 16px; }
  .top-result-img { width: 140px; height: 140px; }
  .top-result-name { font-size: 22px; }
  /* Keep in sync with .top-result-img's shrink above: 20px padding-top +
     140px artwork - 8px inset - 36px button height = 116px. */
  .top-result-card .card-play-btn,
  .top-result-card .card-radio-btn,
  .top-result-card .card-addpl-btn { top: 116px; }
  .song-list .song-row .card-play-btn,
  .song-list .song-row .card-addpl-btn { opacity: 1; }
  /* Universal-search rows now carry play + add + kebab + heart; at this width the
     title already truncates, so drop the heart here the same way the numbered
     album/playlist list below does (still reachable from the ⋮ menu). */
  .song-list:not(.song-list-numbered) .song-row .like-btn { display: none; }
  /* Album/playlist track list: maximise room for the title on narrow screens by
     dropping the per-row heart + BPM badge (both still reachable — the ⋮ menu and
     the tempo-filter bar respectively) and tightening the gaps. */
  .song-list-numbered .song-row { gap: 8px; }
  .song-list-numbered .song-row .like-btn,
  .song-list-numbered .song-row .bpm-badge { display: none; }
}
