feat(album): show all genres in album details, linkable to genre pages (#1186)

* feat(album): show all genres in album details, linkable to genre pages

The album header listed only a single genre. It now renders every genre
from the album's OpenSubsonic genres[] (falling back to splitting the
legacy genre string), each linking to its genre page via the existing
genre route.

* docs(changelog): multiple genres in album details (#1186)

* refactor(genres): extract genreColor into a shared util

* feat(album): union album and track genres behind a +N cursor menu

* feat(album): read album detail from the library index when ready

* docs(changelog): expand the album genres entry

* feat(album): genre pill row with keyboard-navigable popover

* test(offline): cover index-first resolveAlbum path with mocked libraryIsReady

* refactor(styles): move album-detail genre styles out of cover-lightbox.css
This commit is contained in:
Psychotoxical
2026-06-25 13:16:24 +02:00
committed by GitHub
parent 4aa6427727
commit 8b89596fcf
22 changed files with 517 additions and 24 deletions
+81
View File
@@ -1 +1,82 @@
/* ─ Album Detail ─ */
/* Shared Accent-Pill for the album-detail genre row (primary genre + "+N"). */
.album-detail-genre-pill {
appearance: none;
vertical-align: middle;
padding: 0.1em 0.45em;
border-radius: var(--radius-sm);
border: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
background: color-mix(in srgb, var(--accent) 8%, transparent);
color: var(--text-secondary);
font-size: 11px;
font-weight: 600;
font-family: inherit;
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.album-detail-genre-pill:hover {
background: color-mix(in srgb, var(--accent) 16%, transparent);
border-color: color-mix(in srgb, var(--accent) 45%, transparent);
color: var(--accent);
}
.album-detail-genre-pill:focus-visible {
outline: var(--focus-ring-width) solid var(--focus-ring-color);
outline-offset: var(--focus-ring-offset);
}
.album-detail-genre-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
margin: 2px 0 8px;
}
/* Cursor-anchored genre list (context-menu style) opened from the "+N" chip. */
.genre-menu {
position: fixed;
z-index: 9999;
display: flex;
flex-direction: column;
gap: 4px;
min-width: 130px;
max-width: 280px;
max-height: 60vh;
overflow-y: auto;
padding: 6px;
background: var(--bg-sidebar);
border: 1px solid var(--border);
border-radius: 10px;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}
/* Genre chips mirror the .genre-pill styling on the Genres page. */
.genre-menu-item {
appearance: none;
text-align: left;
padding: 0.12em 0.5em;
border-radius: var(--radius-sm);
border: 1px solid color-mix(in srgb, var(--genre-color, var(--accent)) 22%, transparent);
background: color-mix(in srgb, var(--genre-color, var(--accent)) 6%, transparent);
color: var(--text-primary);
font-size: 11px;
font-weight: 600;
font-family: inherit;
white-space: nowrap;
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.genre-menu-item:hover {
background: color-mix(in srgb, var(--genre-color, var(--accent)) 14%, transparent);
border-color: color-mix(in srgb, var(--genre-color, var(--accent)) 45%, transparent);
color: var(--genre-color, var(--accent));
}
.genre-menu-item:focus-visible {
outline: var(--focus-ring-width) solid var(--genre-color, var(--focus-ring-color));
outline-offset: var(--focus-ring-offset);
}