From bf8e8beeb79fba7fb7327adc6eff08edeb6bfece Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Mon, 29 Jun 2026 14:32:16 -0700 Subject: [PATCH] discover: convert the two artist sections to the .ya-card grid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based On Your Listening + Recommended For You now use the same .ya-card as the rest (square cover, name overlaid, recommendation reason as the subtitle) in wrapping grids with the Show-all clamp, replacing the bespoke recommended-artist-card layout. The watchlist toggle and live image enrichment are preserved by keeping their hooks on the new markup — .recommended-artist-card[data-artist-id], .recommended-card-image, and .recommended-card-watchlist-btn (restyled as a hover-reveal corner pill that stays lit when watching). _clampGrid wired into both onRendered callbacks. 64 script-integrity tests green. --- webui/index.html | 4 ++-- webui/static/discover.js | 30 ++++++++++++++++-------------- webui/static/style.css | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/webui/index.html b/webui/index.html index 1d56249d..6d72c777 100644 --- a/webui/index.html +++ b/webui/index.html @@ -3155,7 +3155,7 @@

Artists you'd love — ranked from who you actually play the most

- @@ -3219,7 +3219,7 @@ - diff --git a/webui/static/discover.js b/webui/static/discover.js index 5440e55c..92752f4c 100644 --- a/webui/static/discover.js +++ b/webui/static/discover.js @@ -701,32 +701,32 @@ function _renderRecommendedMini(artist, source, opts) { const artistSource = artist.source || source || ''; const reason = reasonFn(artist); const reasonTitle = titleFn(artist); - const genreTags = (artist.genres || []).slice(0, 2).map(g => - `${escapeHtml(g)}` - ).join(''); const img = artist.image_url ? `${escapeHtml(artist.artist_name)}` : ``; + // .ya-card visual (matches Your Artists / albums) while keeping the class + data hooks the + // watchlist handler (.recommended-card-watchlist-btn) and image enrichment + // (.recommended-artist-card[data-artist-id] → .recommended-card-image) rely on. #discover redesign. return ` - `; } @@ -790,6 +790,7 @@ async function loadRecommendedArtistsSection() { } const source = (data && data.source) || 'spotify'; _enrichRecommendedCarouselCards((data && data.artists || []).slice(0, 18), source); + _clampGrid(carousel); }, loadingMessage: 'Finding recommendations...', emptyMessage: 'No recommendations yet — let the Similar Artists worker run', @@ -832,6 +833,7 @@ async function loadListeningRecommendations() { } const source = (data && data.source) || 'spotify'; _enrichRecommendedCarouselCards((data && data.artists || []).slice(0, 18), source, 'listening-recs-carousel'); + _clampGrid(carousel); }, loadingMessage: 'Reading your listening...', emptyMessage: 'Play more music and run a watchlist scan to see picks based on your listening', diff --git a/webui/static/style.css b/webui/static/style.css index 9b290b33..3738002d 100644 --- a/webui/static/style.css +++ b/webui/static/style.css @@ -35144,6 +35144,25 @@ div.artist-hero-badge { border-color: rgba(var(--accent-rgb),0.4); color: #fff; } +/* Watchlist toggle on recommended-artist .ya-cards — corner pill, appears on hover, + stays lit when already watching. Keeps the .recommended-card-watchlist-btn hook. */ +.recommended-artist-card .recommended-card-watchlist-btn { + position: absolute; top: 8px; right: 8px; z-index: 3; + background: rgba(0,0,0,0.72); color: #fff; + border: 1px solid rgba(255,255,255,0.25); + border-radius: 14px; padding: 4px 10px; + font-size: 10px; font-weight: 600; cursor: pointer; + opacity: 0; transform: translateY(-4px); + transition: opacity 0.2s, transform 0.2s, background 0.2s, border-color 0.2s; +} +.recommended-artist-card:hover .recommended-card-watchlist-btn { opacity: 1; transform: none; } +.recommended-artist-card .recommended-card-watchlist-btn:hover { + background: var(--accent); color: #000; border-color: transparent; +} +.recommended-artist-card .recommended-card-watchlist-btn.watching { + opacity: 1; transform: none; + background: var(--accent); color: #000; border-color: transparent; +} /* ── Artist Info Modal ── */ .ya-info-modal {