diff --git a/webui/index.html b/webui/index.html
index 9c462bbe..b40a19f6 100644
--- a/webui/index.html
+++ b/webui/index.html
@@ -1628,12 +1628,25 @@
+
+
+
+
+
FEATURED ARTIST
Loading...
Discover new music tailored to your taste
+
+
+
+
diff --git a/webui/static/script.js b/webui/static/script.js
index ce7fae39..ce6a0480 100644
--- a/webui/static/script.js
+++ b/webui/static/script.js
@@ -24478,8 +24478,10 @@ function displayDiscoverHeroArtist(artist) {
bgEl.style.backgroundPosition = 'center';
}
- // Store artist ID for watchlist button and update its state
+ // Store artist ID for both buttons and update watchlist state
const addBtn = document.getElementById('discover-hero-add');
+ const discographyBtn = document.getElementById('discover-hero-discography');
+
if (addBtn && artist.spotify_artist_id) {
addBtn.setAttribute('data-artist-id', artist.spotify_artist_id);
addBtn.setAttribute('data-artist-name', artist.artist_name);
@@ -24487,6 +24489,14 @@ function displayDiscoverHeroArtist(artist) {
// Check if this artist is already in watchlist and update button appearance
checkAndUpdateDiscoverHeroWatchlistButton(artist.spotify_artist_id);
}
+
+ if (discographyBtn && artist.spotify_artist_id) {
+ discographyBtn.setAttribute('data-artist-id', artist.spotify_artist_id);
+ discographyBtn.setAttribute('data-artist-name', artist.artist_name);
+ }
+
+ // Update slideshow indicators
+ updateDiscoverHeroIndicators();
}
async function checkAndUpdateDiscoverHeroWatchlistButton(artistId) {
@@ -24540,6 +24550,72 @@ function toggleDiscoverHeroWatchlist(event) {
toggleWatchlist(event, artistId, artistName);
}
+function navigateDiscoverHero(direction) {
+ if (!discoverHeroArtists || discoverHeroArtists.length === 0) return;
+
+ // Update index with wrapping
+ discoverHeroIndex = (discoverHeroIndex + direction + discoverHeroArtists.length) % discoverHeroArtists.length;
+
+ // Display the artist
+ displayDiscoverHeroArtist(discoverHeroArtists[discoverHeroIndex]);
+
+ // Update indicators
+ updateDiscoverHeroIndicators();
+}
+
+function updateDiscoverHeroIndicators() {
+ const indicatorsContainer = document.getElementById('discover-hero-indicators');
+ if (!indicatorsContainer || !discoverHeroArtists || discoverHeroArtists.length === 0) return;
+
+ // Create indicator dots
+ indicatorsContainer.innerHTML = discoverHeroArtists.map((_, index) => `
+
+ `).join('');
+}
+
+function jumpToDiscoverHeroSlide(index) {
+ if (!discoverHeroArtists || index < 0 || index >= discoverHeroArtists.length) return;
+
+ discoverHeroIndex = index;
+ displayDiscoverHeroArtist(discoverHeroArtists[discoverHeroIndex]);
+ updateDiscoverHeroIndicators();
+}
+
+async function viewDiscoverHeroDiscography() {
+ const button = document.getElementById('discover-hero-discography');
+ if (!button) return;
+
+ const artistId = button.getAttribute('data-artist-id');
+ const artistName = button.getAttribute('data-artist-name');
+
+ if (!artistId || !artistName) {
+ console.error('No artist data found for discography view');
+ return;
+ }
+
+ // Create artist object matching the expected format
+ const artist = {
+ id: artistId,
+ name: artistName,
+ image_url: discoverHeroArtists[discoverHeroIndex]?.image_url || '',
+ genres: discoverHeroArtists[discoverHeroIndex]?.genres || [],
+ popularity: discoverHeroArtists[discoverHeroIndex]?.popularity || 0
+ };
+
+ console.log(`🎵 Navigating to artist detail for: ${artistName}`);
+
+ // Navigate to Artists page
+ navigateToPage('artists');
+
+ // Small delay to let the page load
+ await new Promise(resolve => setTimeout(resolve, 100));
+
+ // Load the artist details
+ await selectArtistForDetail(artist);
+}
+
function showDiscoverHeroEmpty() {
const titleEl = document.getElementById('discover-hero-title');
const subtitleEl = document.getElementById('discover-hero-subtitle');
diff --git a/webui/static/style.css b/webui/static/style.css
index d2dabf05..79a4c615 100644
--- a/webui/static/style.css
+++ b/webui/static/style.css
@@ -16116,10 +16116,11 @@ body {
.discover-hero {
position: relative;
width: 100%;
- height: 500px;
- border-radius: 12px;
+ height: 550px;
+ border-radius: 16px;
overflow: hidden;
margin-bottom: 40px;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.discover-hero-background {
@@ -16160,76 +16161,165 @@ body {
}
.discover-hero-label {
- font-size: 12px;
+ font-size: 13px;
font-weight: 700;
- letter-spacing: 2px;
+ letter-spacing: 3px;
color: #1db954;
- margin-bottom: 12px;
+ margin-bottom: 16px;
text-transform: uppercase;
+ display: inline-block;
+ padding: 6px 16px;
+ background: rgba(29, 185, 84, 0.15);
+ border-radius: 20px;
+ border: 1px solid rgba(29, 185, 84, 0.3);
}
.discover-hero-title {
- font-size: 56px;
- font-weight: 800;
+ font-size: 64px;
+ font-weight: 900;
color: #fff;
- margin: 0 0 16px 0;
- line-height: 1.1;
- text-shadow: 0 4px 12px rgba(0,0,0,0.4);
+ margin: 0 0 20px 0;
+ line-height: 1.05;
+ text-shadow: 0 4px 16px rgba(0,0,0,0.5);
+ letter-spacing: -1px;
}
.discover-hero-subtitle {
- font-size: 18px;
- color: rgba(255, 255, 255, 0.85);
- margin-bottom: 32px;
- line-height: 1.6;
+ font-size: 19px;
+ color: rgba(255, 255, 255, 0.9);
+ margin-bottom: 36px;
+ line-height: 1.7;
+ font-weight: 400;
}
.discover-hero-actions {
display: flex;
gap: 16px;
+ align-items: center;
+ flex-wrap: wrap;
}
.discover-hero-button {
display: flex;
align-items: center;
- gap: 8px;
- padding: 14px 32px;
+ gap: 10px;
+ padding: 16px 36px;
border: none;
border-radius: 50px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ position: relative;
+ overflow: hidden;
+ z-index: 1;
}
-.discover-hero-button.primary {
+.discover-hero-button::before {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 0;
+ height: 0;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.2);
+ transform: translate(-50%, -50%);
+ transition: width 0.6s, height 0.6s;
+}
+
+.discover-hero-button:hover::before {
+ width: 300px;
+ height: 300px;
+}
+
+/* Discography button - prominent and large */
+.discover-hero-button.secondary {
+ background-color: rgba(255, 255, 255, 0.12);
+ color: #fff;
+ border: 2px solid rgba(255, 255, 255, 0.25);
+ backdrop-filter: blur(10px);
+ padding: 18px 48px !important;
+ font-size: 17px !important;
+ font-weight: 700 !important;
+ gap: 12px !important;
+}
+
+.discover-hero-button.secondary .button-icon {
+ font-size: 20px !important;
+}
+
+.discover-hero-button.secondary .button-text {
+ font-size: 17px !important;
+ font-weight: 700 !important;
+}
+
+/* Watchlist button - smaller and subtle */
+.discover-hero-button.primary.watchlist-toggle-btn {
background-color: #1db954;
color: #fff;
+ padding: 9px 16px !important;
+ font-size: 13px !important;
+ font-weight: 600 !important;
+ gap: 6px !important;
}
-.discover-hero-button.primary:hover {
+.discover-hero-button.primary.watchlist-toggle-btn .watchlist-icon {
+ font-size: 13px !important;
+}
+
+.discover-hero-button.primary.watchlist-toggle-btn .watchlist-text {
+ flex: none !important;
+ text-align: left !important;
+ font-size: 13px !important;
+}
+
+.discover-hero-button.primary.watchlist-toggle-btn:hover {
background-color: #1ed760;
- transform: scale(1.05);
+ transform: translateY(-2px);
+ box-shadow: 0 8px 20px rgba(29, 185, 84, 0.4);
}
-.discover-hero-button.secondary {
- background-color: rgba(255, 255, 255, 0.1);
- color: #fff;
- border: 2px solid rgba(255, 255, 255, 0.3);
+.discover-hero-button.primary.watchlist-toggle-btn:active {
+ transform: translateY(0);
}
.discover-hero-button.secondary:hover {
background-color: rgba(255, 255, 255, 0.2);
- border-color: rgba(255, 255, 255, 0.5);
+ border-color: rgba(255, 255, 255, 0.4);
+ transform: translateY(-2px);
+ box-shadow: 0 8px 20px rgba(255, 255, 255, 0.15);
+}
+
+.discover-hero-button.secondary:active {
+ transform: translateY(0);
+}
+
+.discover-hero-button.primary.watchlist-toggle-btn.watching {
+ background-color: rgba(29, 185, 84, 0.2) !important;
+ border: 2px solid rgba(29, 185, 84, 0.5) !important;
+ color: #1db954 !important;
+}
+
+.discover-hero-button.primary.watchlist-toggle-btn.watching:hover {
+ background-color: rgba(29, 185, 84, 0.3) !important;
+ border-color: rgba(29, 185, 84, 0.7) !important;
}
.discover-hero-image {
flex-shrink: 0;
- width: 320px;
- height: 320px;
- border-radius: 12px;
+ width: 360px;
+ height: 360px;
+ border-radius: 16px;
overflow: hidden;
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6);
+ border: 3px solid rgba(255, 255, 255, 0.1);
+ transition: transform 0.3s ease;
+}
+
+.discover-hero-image:hover {
+ transform: scale(1.02);
}
.hero-image-placeholder {
@@ -16248,6 +16338,92 @@ body {
object-fit: cover;
}
+/* Hero Navigation Arrows - Hidden by default, show on hover */
+.discover-hero-nav {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ z-index: 10;
+ background: rgba(0, 0, 0, 0.5);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ color: #fff;
+ width: 50px;
+ height: 50px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ font-size: 28px;
+ line-height: 1;
+ padding: 0;
+ opacity: 0;
+ pointer-events: none;
+}
+
+.discover-hero:hover .discover-hero-nav {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+.discover-hero-nav:hover {
+ background: rgba(0, 0, 0, 0.7);
+ border-color: rgba(255, 255, 255, 0.3);
+ transform: translateY(-50%) scale(1.1);
+}
+
+.discover-hero-nav:active {
+ transform: translateY(-50%) scale(0.95);
+}
+
+.discover-hero-nav-prev {
+ left: 20px;
+}
+
+.discover-hero-nav-next {
+ right: 20px;
+}
+
+/* Hero Slideshow Indicators */
+.discover-hero-indicators {
+ position: absolute;
+ bottom: 24px;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 10;
+ display: flex;
+ gap: 10px;
+ padding: 12px 20px;
+ background: rgba(0, 0, 0, 0.3);
+ backdrop-filter: blur(10px);
+ border-radius: 20px;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.hero-indicator {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.4);
+ border: none;
+ padding: 0;
+ cursor: pointer;
+ transition: all 0.3s ease;
+}
+
+.hero-indicator:hover {
+ background: rgba(255, 255, 255, 0.7);
+ transform: scale(1.2);
+}
+
+.hero-indicator.active {
+ background: #1db954;
+ width: 24px;
+ border-radius: 4px;
+}
+
/* Discover Sections */
.discover-section {
margin-bottom: 50px;