/* ==================== CSS Variables ==================== */ :root { /* Colors - Dark theme (default) */ --bg-primary: #0a0a0f; --bg-secondary: #12121a; --bg-tertiary: #1a1a25; --bg-elevated: #22222f; --text-primary: #ffffff; --text-secondary: #a0a0b0; --text-tertiary: #606070; --accent: #6366f1; --accent-light: #818cf8; --accent-dark: #4f46e5; --accent-glow: rgba(99, 102, 241, 0.3); --success: #22c55e; --error: #ef4444; /* Spacing */ --spacing-xs: 4px; --spacing-sm: 8px; --spacing-md: 16px; --spacing-lg: 24px; --spacing-xl: 32px; /* Border radius */ --radius-sm: 8px; --radius-md: 12px; --radius-lg: 16px; --radius-full: 9999px; /* Safe areas for notched phones */ --safe-top: env(safe-area-inset-top, 0px); --safe-bottom: env(safe-area-inset-bottom, 0px); --safe-left: env(safe-area-inset-left, 0px); --safe-right: env(safe-area-inset-right, 0px); /* Player height */ --player-height: 180px; } /* ==================== Theme Variants ==================== */ .theme-purple { --accent: #a855f7; --accent-light: #c084fc; --accent-dark: #9333ea; --accent-glow: rgba(168, 85, 247, 0.3); } .theme-blue { --accent: #3b82f6; --accent-light: #60a5fa; --accent-dark: #2563eb; --accent-glow: rgba(59, 130, 246, 0.3); } .theme-green { --accent: #22c55e; --accent-light: #4ade80; --accent-dark: #16a34a; --accent-glow: rgba(34, 197, 94, 0.3); } .theme-pink { --accent: #ec4899; --accent-light: #f472b6; --accent-dark: #db2777; --accent-glow: rgba(236, 72, 153, 0.3); } .theme-orange { --accent: #f97316; --accent-light: #fb923c; --accent-dark: #ea580c; --accent-glow: rgba(249, 115, 22, 0.3); } /* ==================== Reset & Base ==================== */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; } html { font-size: 16px; -webkit-text-size-adjust: 100%; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background: var(--bg-primary); color: var(--text-primary); line-height: 1.5; min-height: 100vh; min-height: 100dvh; overflow: hidden; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* ==================== App Container ==================== */ .app-container { display: flex; flex-direction: column; height: 100vh; height: 100dvh; padding-top: var(--safe-top); padding-left: var(--safe-left); padding-right: var(--safe-right); } /* ==================== Header ==================== */ .header { flex-shrink: 0; padding: var(--spacing-md); background: linear-gradient(180deg, var(--bg-secondary) 0%, transparent 100%); } .header-content { display: flex; align-items: center; justify-content: center; } .logo { display: flex; align-items: center; gap: var(--spacing-sm); font-size: 1.5rem; font-weight: 700; } .logo-icon { font-size: 1.75rem; } .logo-text { background: linear-gradient(135deg, var(--accent-light), var(--accent)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } /* ==================== Search Section ==================== */ .search-section { flex-shrink: 0; padding: 0 var(--spacing-md) var(--spacing-md); } .search-container { max-width: 600px; margin: 0 auto; } .search-input-wrapper { position: relative; display: flex; align-items: center; } .search-icon { position: absolute; left: var(--spacing-md); width: 20px; height: 20px; color: var(--text-tertiary); pointer-events: none; } .search-input { width: 100%; padding: var(--spacing-md) var(--spacing-md) var(--spacing-md) 48px; background: var(--bg-tertiary); border: 2px solid transparent; border-radius: var(--radius-full); color: var(--text-primary); font-size: 1rem; outline: none; transition: all 0.2s ease; } .search-input::placeholder { color: var(--text-tertiary); } .search-input:focus { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-glow); } .clear-btn { position: absolute; right: var(--spacing-sm); width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-tertiary); cursor: pointer; border-radius: var(--radius-full); opacity: 0; transition: all 0.2s ease; } .search-input:not(:placeholder-shown) + .clear-btn { opacity: 1; } .clear-btn:hover { background: var(--bg-elevated); color: var(--text-primary); } .clear-btn svg { width: 18px; height: 18px; } /* ==================== Results Section ==================== */ .results-section { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 0 var(--spacing-md); padding-bottom: calc(var(--player-height) + var(--safe-bottom) + var(--spacing-md)); -webkit-overflow-scrolling: touch; } /* States */ .welcome-state, .loading-state, .error-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--spacing-xl); text-align: center; min-height: 300px; } .welcome-icon, .error-icon { font-size: 4rem; margin-bottom: var(--spacing-md); } .welcome-state h2, .error-state h2 { font-size: 1.25rem; margin-bottom: var(--spacing-sm); } .welcome-state p, .error-state p, .loading-state p { color: var(--text-secondary); } .hidden { display: none !important; } /* Loader */ .loader { width: 40px; height: 40px; border: 3px solid var(--bg-elevated); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; margin-bottom: var(--spacing-md); } .loader.large { width: 60px; height: 60px; border-width: 4px; } @keyframes spin { to { transform: rotate(360deg); } } .retry-btn { margin-top: var(--spacing-md); padding: var(--spacing-sm) var(--spacing-lg); background: var(--accent); color: white; border: none; border-radius: var(--radius-full); font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; } .retry-btn:hover { background: var(--accent-dark); } /* ==================== Track List ==================== */ .track-list { list-style: none; max-width: 600px; margin: 0 auto; } .track-item { display: flex; align-items: center; gap: var(--spacing-md); padding: var(--spacing-md); background: var(--bg-secondary); border-radius: var(--radius-md); margin-bottom: var(--spacing-sm); cursor: pointer; transition: all 0.2s ease; position: relative; overflow: hidden; } .track-item::before { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, var(--accent-glow), transparent); opacity: 0; transition: opacity 0.2s ease; } .track-item:hover::before, .track-item:active::before { opacity: 1; } .track-item.playing { background: var(--bg-tertiary); border: 1px solid var(--accent); } .track-item.playing::before { opacity: 1; } .track-album-art { width: 56px; height: 56px; border-radius: var(--radius-sm); object-fit: cover; flex-shrink: 0; background: var(--bg-tertiary); } .track-info { flex: 1; min-width: 0; position: relative; z-index: 1; } .track-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 2px; } .track-artist { color: var(--text-secondary); font-size: 0.875rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .track-duration { color: var(--text-tertiary); font-size: 0.875rem; flex-shrink: 0; position: relative; z-index: 1; min-width: 40px; text-align: right; } .track-play-indicator { position: absolute; left: var(--spacing-md); display: flex; gap: 3px; } .track-play-indicator span { width: 3px; height: 16px; background: var(--accent); border-radius: 2px; animation: equalizer 0.5s ease-in-out infinite alternate; } .track-play-indicator span:nth-child(2) { animation-delay: 0.1s; } .track-play-indicator span:nth-child(3) { animation-delay: 0.2s; } @keyframes equalizer { from { transform: scaleY(0.3); } to { transform: scaleY(1); } } /* ==================== Queue Section ==================== */ /* Queue styles moved to end of file */ .queue-header h3 { font-size: 1rem; font-weight: 600; } .queue-close-btn { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-secondary); cursor: pointer; border-radius: var(--radius-full); } .queue-close-btn:hover { background: var(--bg-tertiary); color: var(--text-primary); } .queue-close-btn svg { width: 20px; height: 20px; } .queue-list { flex: 1; overflow-y: auto; padding: var(--spacing-sm); list-style: none; } .queue-item { display: flex; align-items: center; gap: var(--spacing-sm); padding: var(--spacing-sm); border-radius: var(--radius-sm); cursor: pointer; } .queue-item:hover { background: var(--bg-tertiary); } .queue-item-art { width: 40px; height: 40px; border-radius: var(--radius-sm); object-fit: cover; } .queue-item-info { flex: 1; min-width: 0; } .queue-item-name { font-size: 0.875rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .queue-item-artist { font-size: 0.75rem; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* ==================== Player Section ==================== */ .player-section { position: fixed; bottom: 0; left: 0; right: 0; background: linear-gradient(180deg, var(--bg-secondary) 0%, var(--bg-primary) 100%); border-top: 1px solid var(--bg-tertiary); z-index: 200; padding-bottom: var(--safe-bottom); } .player-container { max-width: 600px; margin: 0 auto; padding: var(--spacing-md); } /* Track Info */ .player-track-info { display: flex; align-items: center; gap: var(--spacing-md); margin-bottom: var(--spacing-md); } .player-album-art { width: 56px; height: 56px; border-radius: var(--radius-sm); object-fit: cover; background: var(--bg-tertiary); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); } .player-track-details { flex: 1; min-width: 0; } .player-track-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .player-artist { color: var(--text-secondary); font-size: 0.875rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .player-artist.clickable, .player-album.clickable { cursor: pointer; transition: color 0.2s; } .player-artist.clickable:hover, .player-album.clickable:hover { color: var(--accent-color); text-decoration: underline; } .player-album { color: var(--text-tertiary); font-size: 0.8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 150px; } .player-separator { color: var(--text-tertiary); font-size: 0.7rem; flex-shrink: 0; } .player-year { color: var(--text-tertiary); font-size: 0.75rem; flex-shrink: 0; } .player-meta-row { display: flex; align-items: center; gap: 6px; } .audio-format-badge { font-size: 0.65rem; font-weight: 700; padding: 2px 6px; border-radius: 4px; text-transform: uppercase; letter-spacing: 0.5px; flex-shrink: 0; } .audio-format-badge.flac { background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: white; } .audio-format-badge.hi-res { background: linear-gradient(135deg, #06b6d4 0%, #0ea5e9 100%); color: white; box-shadow: 0 0 8px rgba(6, 182, 212, 0.4); } .audio-format-badge.mp3 { background: var(--bg-tertiary); color: var(--text-tertiary); } /* Progress Bar */ .player-progress-container { display: flex; align-items: center; gap: var(--spacing-sm); margin-bottom: var(--spacing-md); } .player-time { font-size: 0.75rem; color: var(--text-tertiary); min-width: 36px; text-align: center; } .player-progress { flex: 1; height: 6px; background: var(--bg-tertiary); border-radius: var(--radius-full); cursor: pointer; position: relative; overflow: hidden; } .player-progress-buffer { position: absolute; top: 0; left: 0; height: 100%; background: var(--bg-elevated); border-radius: var(--radius-full); transition: width 0.1s ease; } .player-progress-fill { position: absolute; top: 0; left: 0; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-light)); border-radius: var(--radius-full); transition: width 0.1s ease; z-index: 1; } /* Controls */ .player-controls { display: flex; align-items: center; justify-content: center; gap: var(--spacing-md); } .control-btn { width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-primary); cursor: pointer; border-radius: var(--radius-full); transition: all 0.2s ease; } .control-btn:hover { background: var(--bg-tertiary); } .control-btn:active { transform: scale(0.95); } .control-btn svg { width: 24px; height: 24px; } .control-btn.play-btn { width: 64px; height: 64px; background: var(--accent); box-shadow: 0 4px 16px var(--accent-glow); } .control-btn.play-btn:hover { background: var(--accent-dark); } .control-btn.play-btn svg { width: 32px; height: 32px; } .queue-btn { position: absolute; right: var(--spacing-md); } .queue-btn.active { color: var(--accent); } /* ==================== Loading Overlay ==================== */ .loading-overlay { position: fixed; inset: 0; background: rgba(10, 10, 15, 0.9); backdrop-filter: blur(8px); display: flex; align-items: center; justify-content: center; z-index: 500; } .loading-content { text-align: center; } .loading-content p { color: var(--text-secondary); margin-top: var(--spacing-md); } /* ==================== Responsive ==================== */ @media (max-width: 400px) { .track-album-art { width: 48px; height: 48px; } .player-album-art { width: 48px; height: 48px; } .control-btn.play-btn { width: 56px; height: 56px; } } /* Desktop adjustments */ @media (min-width: 768px) { .player-progress { height: 8px; } :root { --player-height: 160px; } } /* ==================== Animations ==================== */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .track-item { animation: fadeIn 0.3s ease forwards; } .track-item:nth-child(1) { animation-delay: 0.0s; } .track-item:nth-child(2) { animation-delay: 0.05s; } .track-item:nth-child(3) { animation-delay: 0.1s; } .track-item:nth-child(4) { animation-delay: 0.15s; } .track-item:nth-child(5) { animation-delay: 0.2s; } .track-item:nth-child(6) { animation-delay: 0.25s; } .track-item:nth-child(7) { animation-delay: 0.3s; } .track-item:nth-child(8) { animation-delay: 0.35s; } .track-item:nth-child(9) { animation-delay: 0.4s; } .track-item:nth-child(10) { animation-delay: 0.45s; } /* ==================== Search Type Selector ==================== */ .search-type-selector { display: flex; justify-content: center; gap: var(--spacing-sm); margin-top: var(--spacing-md); max-width: 600px; margin-left: auto; margin-right: auto; } .type-btn { padding: 6px 10px; background: var(--bg-tertiary); border: 1px solid transparent; border-radius: var(--radius-full); color: var(--text-secondary); font-size: 0.75rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; white-space: nowrap; } .type-btn.active { background: var(--text-primary); color: var(--bg-primary); } .type-btn:hover:not(.active) { background: var(--bg-elevated); color: var(--text-primary); } /* Search More Menu */ .search-more-menu { position: absolute; top: 140px; /* Adjust based on header */ right: 50%; transform: translateX(50%); background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 12px; padding: 8px; display: flex; flex-direction: column; gap: 4px; box-shadow: 0 4px 12px rgba(0,0,0,0.4); z-index: 1000; min-width: 180px; margin-right: -100px; /* Offset to align better with button */ } .menu-divider { height: 1px; background: rgba(255, 255, 255, 0.1); margin: 4px 0; } .search-more-menu.hidden { display: none; } .menu-item { text-align: left; padding: 8px 16px; background: transparent; border: none; color: var(--text-primary); font-size: 0.9rem; cursor: pointer; border-radius: 8px; transition: background 0.2s; display: flex; align-items: center; gap: 8px; } .menu-item:hover { background: var(--bg-elevated); } .menu-item.active { color: var(--accent); background: rgba(var(--accent-rgb), 0.1); } .type-btn:hover { background: var(--bg-elevated); color: var(--text-primary); } .type-btn.active { background: var(--accent); color: white; border-color: var(--accent); } .load-more-btn { display: block; width: 100%; max-width: 300px; margin: var(--spacing-lg) auto; padding: var(--spacing-md) var(--spacing-lg); background: var(--bg-tertiary); color: var(--text-primary); border: 1px solid var(--accent); border-radius: var(--radius-full); font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; } .load-more-btn:hover { background: var(--accent); color: white; } /* ==================== Detail View (Albums/Playlists) ==================== */ .detail-view { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--bg-primary); z-index: 50; display: flex; flex-direction: column; padding-top: var(--safe-top); } .detail-header { display: flex; justify-content: space-between; align-items: center; padding: var(--spacing-md); background: var(--bg-secondary); border-bottom: 1px solid var(--bg-tertiary); } .back-btn { background: none; border: none; color: var(--accent); font-size: 1rem; font-weight: 500; cursor: pointer; padding: var(--spacing-sm); } .queue-all-btn { background: var(--accent); border: none; color: white; font-size: 0.875rem; font-weight: 600; padding: var(--spacing-sm) var(--spacing-md); border-radius: var(--radius-full); cursor: pointer; transition: all 0.2s ease; } .queue-all-btn:hover { background: var(--accent-dark); } .detail-info { display: flex; align-items: center; gap: var(--spacing-md); padding: var(--spacing-lg); background: var(--bg-secondary); } .detail-art { width: 120px; height: 120px; border-radius: var(--radius-md); object-fit: cover; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); } .detail-meta { flex: 1; min-width: 0; } .detail-name { font-size: 1.25rem; font-weight: 700; margin-bottom: var(--spacing-xs); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; width: 100%; box-sizing: border-box; } .detail-artist { color: var(--text-secondary); margin-bottom: var(--spacing-xs); text-align: center; } .detail-stats { color: var(--text-tertiary); font-size: 0.875rem; } .detail-tracks { flex: 1; overflow-y: auto; padding: var(--spacing-md); padding-bottom: calc(var(--player-height) + var(--safe-bottom) + var(--spacing-md)); } /* ==================== Album/Artist Cards ==================== */ .album-item, .artist-item { display: flex; align-items: center; gap: var(--spacing-md); padding: var(--spacing-md); background: var(--bg-secondary); border-radius: var(--radius-md); margin-bottom: var(--spacing-sm); cursor: pointer; transition: all 0.2s ease; } .album-item:hover, .artist-item:hover { background: var(--bg-tertiary); } .album-art, .artist-art { width: 64px; height: 64px; border-radius: var(--radius-sm); object-fit: cover; background: var(--bg-tertiary); } .artist-art { border-radius: 50%; } .album-info, .artist-info { flex: 1; min-width: 0; } .album-name, .artist-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 2px; } .album-artist, .artist-genres { color: var(--text-secondary); font-size: 0.875rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .album-tracks-count, .artist-followers { color: var(--text-tertiary); font-size: 0.875rem; } /* ==================== Results Grid (Card Layout) ==================== */ .results-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: var(--spacing-md); padding: var(--spacing-md) 0; width: 100%; } .results-list { display: flex; flex-direction: column; gap: var(--spacing-sm); width: 100%; padding-bottom: 20px; /* Minimal padding, robust padding on container */ } /* Album Card (Vertical Layout) */ .album-card { display: flex !important; flex-direction: column !important; background: var(--bg-secondary); border-radius: var(--radius-md); overflow: hidden; cursor: pointer; transition: transform 0.2s ease, background 0.2s ease; } .album-card:hover { transform: translateY(-4px); background: var(--bg-tertiary); } .album-card-art-container { position: relative; width: 100%; aspect-ratio: 1 / 1; } .album-card-art { width: 100%; height: 100%; object-fit: cover; background: var(--bg-tertiary); } /* HiRes Badge */ .hires-badge { position: absolute; bottom: 8px; right: 8px; background: linear-gradient(135deg, #00d4ff 0%, #00b4d8 100%); color: #000; font-size: 0.65rem; font-weight: 700; padding: 3px 8px; border-radius: 4px; text-transform: uppercase; letter-spacing: 0.5px; box-shadow: 0 2px 8px rgba(0, 212, 255, 0.4); } .album-card-info { padding: var(--spacing-sm) var(--spacing-md); } .album-card-title { font-weight: 600; font-size: 0.95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 2px; } .album-card-artist { color: var(--text-secondary); font-size: 0.85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 4px; } .album-card-meta { display: flex; justify-content: space-between; color: var(--text-tertiary); font-size: 0.75rem; } /* Track Card Specifics */ .track-card-play-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; font-size: 2.5rem; color: white; opacity: 0; transition: opacity 0.2s; backdrop-filter: blur(2px); } .album-card:hover .track-card-play-overlay { opacity: 1; } /* Responsive: Larger cards on desktop */ @media (min-width: 1200px) { .results-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); } } /* Mobile: 2-3 cards per row */ @media (max-width: 600px) { .results-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--spacing-sm); } .album-card-info { padding: var(--spacing-xs) var(--spacing-sm); } .album-card-title { font-size: 0.85rem; } .album-card-artist { font-size: 0.75rem; } } /* Sort Filter Button */ .sort-btn { display: flex; align-items: center; gap: 4px; margin-left: auto; /* Push to right side */ background: var(--bg-tertiary); border: 1px solid var(--text-tertiary); opacity: 0.8; } .sort-btn:hover { opacity: 1; background: var(--bg-elevated); } .sort-icon { font-size: 0.8rem; } /* ==================== Empty State ==================== */ .empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--spacing-xl); text-align: center; min-height: 300px; color: var(--text-secondary); } .empty-icon { font-size: 4rem; margin-bottom: var(--spacing-md); } .hint { margin-top: var(--spacing-sm); font-size: 0.875rem; color: var(--text-tertiary); } /* ==================== Misc Fixes ==================== */ .app { display: flex; flex-direction: column; height: 100vh; height: 100dvh; padding-top: var(--safe-top); } .search-container { position: relative; max-width: 600px; margin: 0 auto; } .search-input { width: 100%; padding: var(--spacing-md) 48px var(--spacing-md) var(--spacing-md); background: var(--bg-tertiary); border: 2px solid transparent; border-radius: var(--radius-full); color: var(--text-primary); font-size: 1rem; outline: none; transition: all 0.2s ease; } .search-clear { position: absolute; right: var(--spacing-sm); top: 50%; transform: translateY(-50%); width: 32px; height: 32px; background: none; border: none; color: var(--text-tertiary); font-size: 1.25rem; cursor: pointer; opacity: 0; transition: opacity 0.2s ease; } .search-input:not(:placeholder-shown) + .search-clear { opacity: 1; } .results-section { flex: 1 1 0; min-height: 0; position: relative; overflow: hidden; /* display: flex; Removed - using absolute child methodology */ } .results-container { position: absolute; top: 0; left: 0; right: 0; bottom: 0; overflow-y: auto; overflow-x: hidden; margin: 0; padding: 0 var(--spacing-md); padding-bottom: 120px; /* Space for player bar */ } /* ==================== Player Bar ==================== */ .player-bar { position: fixed; bottom: 0; left: 0; right: 0; background: var(--bg-secondary); border-top: 1px solid var(--bg-tertiary); padding: 12px 16px; padding-bottom: calc(12px + var(--safe-bottom)); z-index: 100; } .player-main-row { display: flex; align-items: center; justify-content: space-between; /* Art/Info on left, Controls on right */ gap: 16px; margin-bottom: 8px; width: 100%; } .player-info { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0; /* Allow text truncate */ margin-bottom: 0; /* Reset */ } .player-art { width: 42px; height: 42px; border-radius: var(--radius-sm); object-fit: cover; background: var(--bg-tertiary); } .player-details { flex: 1; min-width: 0; } .player-title { font-size: 0.95rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .player-artist { color: var(--text-secondary); font-size: 0.8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .player-controls-primary { display: flex; align-items: center; gap: 12px; flex-shrink: 0; } /* More Menu Popout */ .player-more-menu { position: absolute; bottom: 90px; right: 16px; background: var(--bg-elevated); border-radius: 16px; padding: 16px; box-shadow: 0 10px 40px rgba(0,0,0,0.5); z-index: 2000; width: 280px; animation: slideUp 0.2s ease; border: 1px solid var(--bg-tertiary); } .more-menu-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px; justify-items: center; } .more-menu-volume { padding-top: 12px; border-top: 1px solid var(--bg-tertiary); display: flex; align-items: center; justify-content: center; } .more-menu-volume .volume-slider { width: 100%; height: 6px; } /* Playlist Modal */ .playlist-modal-content { max-width: 320px; } .playlist-modal-content h3 { margin-bottom: 16px; font-size: 1.2rem; } .playlist-list { max-height: 200px; overflow-y: auto; margin-bottom: 16px; } .playlist-list-item { padding: 12px 16px; background: var(--bg-tertiary); border-radius: var(--radius-sm); margin-bottom: 8px; cursor: pointer; transition: background 0.2s; } .playlist-list-item:hover { background: var(--accent); color: white; } .create-playlist-row { display: flex; gap: 8px; margin-bottom: 12px; } .new-playlist-input { flex: 1; padding: 10px 12px; background: var(--bg-tertiary); border: 1px solid transparent; border-radius: var(--radius-sm); color: var(--text-primary); font-size: 0.9rem; } .new-playlist-input:focus { border-color: var(--accent); outline: none; } .modal-close-btn { width: 100%; padding: 12px; background: transparent; border: 1px solid var(--bg-tertiary); border-radius: var(--radius-sm); color: var(--text-secondary); cursor: pointer; transition: all 0.2s; } .modal-close-btn:hover { background: var(--bg-tertiary); color: var(--text-primary); } .more-menu-volume { padding-top: 12px; border-top: 1px solid var(--bg-tertiary); display: flex; align-items: center; justify-content: center; } .more-menu-volume .volume-slider { width: 100%; height: 6px; } .control-btn { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-primary); font-size: 1.25rem; cursor: pointer; border-radius: 50%; transition: all 0.2s ease; } .control-btn:hover { background: var(--bg-tertiary); } .play-btn { width: 56px; height: 56px; background: var(--accent) !important; font-size: 1.5rem; } .player-progress { display: flex; align-items: center; gap: var(--spacing-sm); } .time { font-size: 0.75rem; color: var(--text-tertiary); min-width: 36px; text-align: center; } .progress-bar { flex: 1; height: 4px; -webkit-appearance: none; appearance: none; background: var(--bg-tertiary); border-radius: var(--radius-full); cursor: pointer; } .progress-bar::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; background: var(--accent); border-radius: 50%; cursor: pointer; } /* ==================== Queue styles ==================== */ .queue-section { position: fixed; top: 0; bottom: auto; /* Remove bottom constraint */ left: 0; right: 0; max-height: 60vh; background: var(--bg-secondary); border-bottom-left-radius: var(--radius-lg); border-bottom-right-radius: var(--radius-lg); border-top-left-radius: 0; /* Reset top radius */ border-top-right-radius: 0; z-index: 200; overflow: hidden; display: flex; flex-direction: column; box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5); /* Shadow downwards */ border-bottom: 1px solid var(--bg-tertiary); border-top: none; } .queue-section.hidden { display: none; } .queue-header { display: flex; align-items: center; justify-content: space-between; padding: var(--spacing-md); background: var(--bg-elevated); /* Distinction header */ border-bottom: 1px solid var(--bg-tertiary); } .queue-controls { display: flex; gap: var(--spacing-md); align-items: center; } .queue-clear { background: none; border: none; color: var(--error); font-size: 0.875rem; cursor: pointer; font-weight: 500; } .queue-close-btn { width: 28px; height: 28px; background: var(--bg-tertiary); border: none; color: var(--text-primary); border-radius: 50%; cursor: pointer; font-size: 1.2rem; display: flex; align-items: center; justify-content: center; line-height: 1; } .queue-close-btn:hover { background: var(--bg-elevated); } .queue-container { flex: 1; overflow-y: auto; padding: var(--spacing-sm); } /* Spinner */ .spinner { width: 48px; height: 48px; border: 4px solid var(--bg-tertiary); border-top-color: var(--accent); border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto; } /* Error message */ .error-message { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--spacing-xl); text-align: center; } .error-icon { font-size: 3rem; margin-bottom: var(--spacing-md); } .btn-retry { margin-top: var(--spacing-md); padding: var(--spacing-sm) var(--spacing-lg); background: var(--accent); color: white; border: none; border-radius: var(--radius-full); font-weight: 600; cursor: pointer; } /* ==================== Modal ==================== */ .modal { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.8); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 2500; } .modal-content { background: var(--bg-elevated); border-radius: var(--radius-lg); padding: var(--spacing-xl); width: 90%; max-width: 400px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); } .modal-content h3 { margin-bottom: var(--spacing-sm); font-size: 1.25rem; } .modal-content p { color: var(--text-secondary); margin-bottom: var(--spacing-lg); font-weight: 500; } .format-selector { margin-bottom: var(--spacing-xl); } .format-selector label { display: block; margin-bottom: var(--spacing-sm); color: var(--text-tertiary); font-size: 0.875rem; } .format-selector select { width: 100%; padding: var(--spacing-md); background: var(--bg-tertiary); border: 1px solid transparent; border-radius: var(--radius-md); color: var(--text-primary); font-size: 1rem; outline: none; cursor: pointer; } .format-selector select:focus { border-color: var(--accent); } .modal-actions { display: flex; gap: var(--spacing-md); justify-content: flex-end; } .btn-primary, .btn-secondary { padding: var(--spacing-sm) var(--spacing-lg); border-radius: var(--radius-full); font-weight: 600; cursor: pointer; border: none; transition: all 0.2s ease; } .btn-primary { background: var(--accent); color: white; } .btn-primary:hover { background: var(--accent-dark); } .btn-secondary { background: transparent; color: var(--text-secondary); } .btn-secondary:hover { background: var(--bg-tertiary); color: var(--text-primary); } /* Download Button in track item */ .track-actions { display: flex; align-items: center; gap: var(--spacing-sm); z-index: 5; } /* Base style for track action buttons (Queue, Download) */ .track-action-btn { width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-secondary); cursor: pointer; border-radius: 50%; transition: all 0.2s ease; flex-shrink: 0; font-size: 1rem; position: relative; z-index: 10; /* Above duration text */ margin-left: 8px; } /* Container for track buttons with proper gap */ .track-buttons { display: flex; align-items: center; gap: 16px; /* Clear separation */ flex-shrink: 0; } .track-action-btn:hover { background: var(--bg-tertiary); color: var(--accent); } .download-btn { width: 44px; /* Larger hit area */ height: 44px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-secondary); /* Always visible */ cursor: pointer; border-radius: 50%; transition: all 0.2s ease; opacity: 1 !important; /* Always visible */ font-size: 1.2rem; flex-shrink: 0; } .download-btn:hover { background: var(--bg-tertiary); color: var(--accent); transform: scale(1.1); } .delete-track-btn { width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-tertiary); cursor: pointer; border-radius: 50%; font-size: 1rem; transition: all 0.2s ease; } .delete-track-btn:hover { background: var(--error); color: white; } .track-item:hover .download-btn { opacity: 1; } .download-all-btn { background: var(--bg-tertiary); border: none; color: var(--text-primary); font-size: 0.875rem; font-weight: 600; padding: var(--spacing-sm) var(--spacing-md); border-radius: var(--radius-full); cursor: pointer; transition: all 0.2s ease; margin-right: var(--spacing-sm); } .download-all-btn:hover { background: var(--bg-elevated); } .detail-actions { display: flex; gap: var(--spacing-sm); align-items: center; } .shuffle-btn { background: var(--accent); border: none; color: white; font-size: 1rem; font-weight: 600; padding: var(--spacing-md) var(--spacing-lg); border-radius: var(--radius-full); cursor: pointer; transition: all 0.2s ease; } .shuffle-btn:hover { background: var(--accent-hover); transform: scale(1.02); } /* Clickable Links in Player */ .clickable-link { cursor: pointer; transition: color 0.2s; } .clickable-link:hover { color: var(--accent); text-decoration: underline; } /* Queue Remove Button */ .queue-remove-btn { background: none; border: none; color: var(--text-secondary); font-size: 1.2rem; padding: 0.5rem; cursor: pointer; opacity: 0.6; margin-left: auto; flex-shrink: 0; } .queue-remove-btn:hover { color: #ff4757; opacity: 1; } .queue-heart-btn { background: none; border: none; color: var(--text-secondary); font-size: 1rem; padding: 0.25rem; cursor: pointer; opacity: 0.6; flex-shrink: 0; transition: opacity 0.2s, transform 0.2s; } .queue-heart-btn:hover { opacity: 1; transform: scale(1.2); } /* Fullscreen Player */ .fullscreen-player { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(10, 10, 15, 0.98); z-index: 2000; display: flex; justify-content: center; align-items: center; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; backdrop-filter: blur(20px); } .fullscreen-player:not(.hidden) { opacity: 1; pointer-events: auto; } .fs-backdrop { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; background-size: cover; background-position: center; opacity: 0.15; filter: blur(50px); } .fs-content { width: 90%; max-width: 450px; display: flex; flex-direction: column; align-items: center; gap: 1.5rem; text-align: center; z-index: 1; } .fs-header { width: 100%; display: flex; justify-content: flex-end; margin-bottom: 0.5rem; } .fs-close-btn { background: rgba(255,255,255,0.1); border: none; color: white; font-size: 1.5rem; width: 44px; height: 44px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.2s; } .fs-close-btn:hover { background: rgba(255,255,255,0.2); } .fs-art-container { width: 100%; max-width: 350px; position: relative; border-radius: 16px; overflow: hidden; box-shadow: 0 25px 60px rgba(0,0,0,0.5); } .fs-art-container img { width: 100%; height: auto; aspect-ratio: 1/1; object-fit: cover; display: block; } .fs-art-lyrics-btn { position: absolute; bottom: 12px; right: 12px; width: 44px; height: 44px; border-radius: 50%; background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.2); color: white; font-size: 1.3rem; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; opacity: 0.8; } .fs-art-lyrics-btn:hover { opacity: 1; background: rgba(0, 0, 0, 0.8); transform: scale(1.1); } .fs-info h2 { font-size: 1.6rem; font-weight: 700; margin: 0; margin-bottom: 0.5rem; color: white; } .fs-info p { font-size: 1.1rem; color: var(--text-secondary); margin: 0; } .fs-progress-container { width: 100%; display: flex; align-items: center; gap: 12px; color: var(--text-secondary); font-size: 0.85rem; } .fs-progress-container .progress-bar { flex: 1; } .fs-controls { display: flex; align-items: center; gap: 2rem; margin-top: 0.5rem; } .fs-control-btn { background: none; border: none; color: white; font-size: 2rem; cursor: pointer; opacity: 0.8; transition: transform 0.1s, opacity 0.2s; } .fs-control-btn:hover { opacity: 1; transform: scale(1.1); } .fs-control-btn.play-btn { width: 72px; height: 72px; background: var(--accent); border-radius: 50%; color: black; font-size: 2rem; display: flex; align-items: center; justify-content: center; opacity: 1; /* Offset play icon which is visually heavier on right */ padding-left: 4px; } .fs-control-btn.play-btn:hover { background: var(--accent-hover); transform: scale(1.05); } /* Queue item needs flex for remove button alignment */ #queue-container .queue-item { display: flex; align-items: center; padding: 8px 12px; cursor: pointer; border-radius: 8px; transition: background 0.2s; } #queue-container .queue-item:hover { background: var(--bg-tertiary); } #queue-container .queue-item.playing { background: var(--bg-elevated); } /* ========== TOAST NOTIFICATIONS ========== */ .toast-container { position: fixed; bottom: 100px; left: 50%; transform: translateX(-50%); z-index: 3000; display: flex; flex-direction: column; gap: 8px; pointer-events: none; } .toast { background: var(--bg-elevated); color: var(--text-primary); padding: 12px 24px; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.4); font-size: 0.9rem; font-weight: 500; animation: toastIn 0.3s ease, toastOut 0.3s ease 2.7s forwards; pointer-events: auto; } @keyframes toastIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes toastOut { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-20px); } } /* ========== KEYBOARD SHORTCUTS HELP ========== */ .shortcuts-help { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.85); z-index: 3000; display: flex; justify-content: center; align-items: center; backdrop-filter: blur(10px); } .shortcuts-content { background: var(--bg-secondary); border-radius: 16px; padding: 24px; max-width: 500px; width: 90%; } .shortcuts-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .shortcuts-header h3 { margin: 0; font-size: 1.3rem; } .shortcuts-close { background: none; border: none; color: var(--text-secondary); font-size: 1.5rem; cursor: pointer; } .shortcuts-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; } .shortcut { display: flex; align-items: center; gap: 12px; } .shortcut kbd { background: var(--bg-tertiary); padding: 6px 10px; border-radius: 6px; font-family: monospace; font-size: 0.85rem; min-width: 70px; text-align: center; } .shortcut span { color: var(--text-secondary); font-size: 0.9rem; } /* ========== VOLUME CONTROLS ========== */ .volume-controls { display: flex; align-items: center; gap: 8px; margin-left: auto; padding-left: 16px; } .volume-slider { width: 80px; height: 4px; -webkit-appearance: none; appearance: none; background: var(--bg-tertiary); border-radius: 2px; cursor: pointer; } .volume-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; background: var(--text-primary); border-radius: 50%; cursor: pointer; } .volume-btn { font-size: 1.2rem !important; } /* ========== REPEAT BUTTON STATES ========== */ .control-btn.repeat-active { color: var(--accent); } .control-btn.repeat-one::after { content: '1'; font-size: 0.6rem; position: absolute; bottom: 2px; right: 2px; } /* ========== QUEUE DRAG & DROP ========== */ #queue-container .queue-item { cursor: grab; user-select: none; } #queue-container .queue-item:active { cursor: grabbing; } #queue-container .queue-item.dragging { opacity: 0.5; background: var(--accent); } #queue-container .queue-item.drag-over { border-top: 2px solid var(--accent); } /* ========== LYRICS DISPLAY ========== */ .lyrics-container { max-height: 200px; overflow-y: auto; margin-top: 20px; padding: 16px; background: rgba(0,0,0,0.3); border-radius: 12px; text-align: center; } .lyrics-text { font-size: 1rem; line-height: 1.8; color: var(--text-secondary); white-space: pre-wrap; } .lyrics-loading { color: var(--text-tertiary); font-style: italic; } .lyrics-error { color: var(--text-tertiary); } /* Fullscreen lyrics */ .fs-lyrics { max-height: 150px; overflow-y: auto; margin-top: 16px; font-size: 0.95rem; line-height: 1.7; color: var(--text-secondary); text-align: center; padding: 0 20px; } /* ==================== Playlist Manager ==================== */ .save-playlist-btn { background: linear-gradient(135deg, var(--accent) 0%, var(--accent-dark) 100%); color: white; border: none; padding: 10px 20px; border-radius: var(--radius-full); font-size: 0.9rem; font-weight: 600; cursor: pointer; margin-top: 12px; transition: transform 0.2s, box-shadow 0.2s; } .save-playlist-btn:hover { transform: scale(1.05); box-shadow: 0 4px 15px var(--accent-glow); } .delete-playlist-btn { position: absolute; top: 8px; right: 8px; background: rgba(0, 0, 0, 0.6); border: none; border-radius: var(--radius-full); width: 28px; height: 28px; font-size: 14px; cursor: pointer; opacity: 0; transition: opacity 0.2s, background 0.2s; } .playlist-item:hover .delete-playlist-btn { opacity: 1; } .delete-playlist-btn:hover { background: var(--error); } .playlist-item { position: relative; } .favorites-btn { background: linear-gradient(135deg, #ec4899 0%, #f43f5e 100%) !important; } .favorites-btn.active { background: linear-gradient(135deg, #f43f5e 0%, #ec4899 100%) !important; } /* ==================== Equalizer Panel ==================== */ .eq-btn.active { color: var(--accent); } .eq-panel { position: fixed; bottom: 200px; right: 20px; width: 340px; background: var(--bg-elevated); border-radius: var(--radius-lg); padding: 20px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); z-index: 1500; animation: slideUp 0.3s ease; } @keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .eq-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .eq-header h3 { margin: 0; font-size: 1.1rem; } .eq-close-btn { background: none; border: none; color: var(--text-secondary); font-size: 1.5rem; cursor: pointer; padding: 0; line-height: 1; } .eq-close-btn:hover { color: var(--text-primary); } .eq-presets { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; } .eq-preset { background: var(--bg-tertiary); border: none; padding: 8px 14px; border-radius: var(--radius-full); color: var(--text-secondary); font-size: 0.85rem; cursor: pointer; transition: all 0.2s; } .eq-preset:hover { background: var(--bg-secondary); color: var(--text-primary); } .eq-preset.active { background: var(--accent); color: white; } .eq-sliders { display: flex; justify-content: space-between; gap: 8px; height: 120px; margin-bottom: 20px; } .eq-band { display: flex; flex-direction: column; align-items: center; flex: 1; } .eq-slider { writing-mode: vertical-lr; direction: rtl; width: 24px; height: 100px; -webkit-appearance: slider-vertical; appearance: slider-vertical; background: var(--bg-tertiary); border-radius: var(--radius-sm); cursor: pointer; } .eq-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px; height: 16px; background: var(--accent); border-radius: 50%; cursor: pointer; } .eq-label { font-size: 0.7rem; color: var(--text-tertiary); margin-top: 8px; } .eq-extras { display: flex; flex-direction: column; gap: 12px; border-top: 1px solid var(--bg-tertiary); padding-top: 15px; } .eq-extra { display: flex; align-items: center; gap: 12px; } .eq-extra label { font-size: 0.85rem; color: var(--text-secondary); width: 90px; } .eq-boost-slider { flex: 1; -webkit-appearance: none; appearance: none; height: 6px; background: var(--bg-tertiary); border-radius: 3px; cursor: pointer; } .eq-boost-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 14px; height: 14px; background: var(--accent); border-radius: 50%; cursor: pointer; } .eq-extra span { font-size: 0.8rem; color: var(--text-tertiary); width: 40px; text-align: right; } @media (max-width: 400px) { .eq-panel { left: 10px; right: 10px; width: auto; } } /* ==================== Theme Picker ==================== */ .theme-btn { background: none; border: none; font-size: 1.3rem; cursor: pointer; padding: 8px; border-radius: var(--radius-full); transition: background 0.2s; } .theme-btn:hover { background: var(--bg-tertiary); } .header { display: flex; justify-content: space-between; align-items: center; } .theme-picker { position: absolute; top: 60px; right: 20px; background: var(--bg-elevated); border-radius: var(--radius-md); padding: 8px; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4); z-index: 1600; min-width: 140px; } .theme-option { padding: 10px 16px; border-radius: var(--radius-sm); cursor: pointer; transition: background 0.2s; } .theme-option:hover { background: var(--bg-tertiary); } .theme-option.active { background: var(--accent); color: white; } /* ==================== Header Actions & Sync ==================== */ .header-actions { display: flex; gap: 8px; align-items: center; } .header-btn { background: none; border: none; font-size: 1.3rem; cursor: pointer; padding: 8px; border-radius: var(--radius-full); transition: background 0.2s; } .header-btn:hover { background: var(--bg-tertiary); } .header-btn.synced { color: var(--success); } .header-btn.active { background: linear-gradient(135deg, #6366f1 0%, #10b981 100%); color: white; font-weight: 600; font-size: 0.85rem; box-shadow: 0 0 15px rgba(99, 102, 241, 0.5); animation: hifi-pulse 1.5s infinite; } .header-btn.active:hover { background: linear-gradient(135deg, #4f46e5 0%, #059669 100%); } @keyframes hifi-pulse { 0%, 100% { box-shadow: 0 0 15px rgba(99, 102, 241, 0.5); } 50% { box-shadow: 0 0 25px rgba(16, 185, 129, 0.7); } } #hifi-btn { font-size: 0.85rem; padding: 6px 12px; font-weight: 600; color: var(--text-secondary); border: 1px solid var(--border-color); } #hifi-btn:not(.active):hover { color: var(--text-primary); background: var(--bg-tertiary); } /* ==================== Podcast Episode Modal ==================== */ .podcast-modal { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.8); display: flex; align-items: center; justify-content: center; z-index: 2000; padding: 20px; } .podcast-modal-content { background: var(--bg-elevated); border-radius: var(--radius-lg); max-width: 500px; width: 100%; max-height: 80vh; overflow-y: auto; padding: 24px; position: relative; animation: slideUp 0.3s ease; } .podcast-modal-close { position: absolute; top: 12px; right: 12px; background: none; border: none; color: var(--text-secondary); font-size: 1.8rem; cursor: pointer; line-height: 1; } .podcast-modal-close:hover { color: var(--text-primary); } .podcast-modal-art { width: 100%; max-width: 200px; aspect-ratio: 1; border-radius: var(--radius-md); margin: 0 auto 16px; display: block; object-fit: cover; } .podcast-modal-title { font-size: 1.2rem; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; line-height: 1.3; } .podcast-modal-date { font-size: 0.85rem; color: var(--accent); margin-bottom: 4px; } .podcast-modal-duration { font-size: 0.85rem; color: var(--text-tertiary); margin-bottom: 16px; } .podcast-modal-description { font-size: 0.9rem; color: var(--text-secondary); line-height: 1.6; max-height: 200px; overflow-y: auto; margin-bottom: 20px; } .podcast-modal-actions { display: flex; gap: 12px; } .podcast-modal-play { flex: 1; background: linear-gradient(135deg, var(--accent) 0%, var(--accent-dark) 100%); color: white; border: none; padding: 14px 24px; border-radius: var(--radius-full); font-size: 1rem; font-weight: 600; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; } .podcast-modal-play:hover { transform: scale(1.02); box-shadow: 0 4px 15px var(--accent-glow); } /* ==================== DJ Mode ==================== */ /* DJ Mode Active State */ .dj-mode-active #dj-mode-btn { color: var(--accent); background: rgba(var(--accent-rgb, 29, 185, 84), 0.2); } /* BPM and Camelot Badges */ .dj-badge-container { display: none; gap: 6px; margin-top: 4px; } .dj-mode-active .dj-badge-container { display: flex; } .dj-badge { font-size: 0.7rem; font-weight: 600; padding: 2px 6px; border-radius: 4px; display: inline-flex; align-items: center; gap: 3px; } .bpm-badge { background: rgba(255, 255, 255, 0.15); color: var(--text-secondary); } .camelot-badge { color: white; font-weight: 700; } /* Camelot Color Coding - Wheel positions 1-12 mapped to hue values */ .camelot-1A, .camelot-1B { background: hsl(0, 70%, 45%); } .camelot-2A, .camelot-2B { background: hsl(30, 70%, 45%); } .camelot-3A, .camelot-3B { background: hsl(60, 70%, 40%); } .camelot-4A, .camelot-4B { background: hsl(90, 60%, 40%); } .camelot-5A, .camelot-5B { background: hsl(120, 60%, 35%); } .camelot-6A, .camelot-6B { background: hsl(150, 60%, 35%); } .camelot-7A, .camelot-7B { background: hsl(180, 60%, 35%); } .camelot-8A, .camelot-8B { background: hsl(210, 70%, 45%); } .camelot-9A, .camelot-9B { background: hsl(240, 60%, 50%); } .camelot-10A, .camelot-10B { background: hsl(270, 60%, 50%); } .camelot-11A, .camelot-11B { background: hsl(300, 60%, 45%); } .camelot-12A, .camelot-12B { background: hsl(330, 70%, 45%); } .energy-bar { width: 40px; height: 4px; background: rgba(255, 255, 255, 0.2); border-radius: 2px; overflow: hidden; } .energy-fill { height: 100%; background: linear-gradient(90deg, #4ade80, #facc15, #f87171); border-radius: 2px; transition: width 0.3s ease; } /* DJ Generate Set Button - Only visible in DJ mode when queue has tracks */ .dj-generate-set-btn { display: none; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); color: white; border: none; padding: 8px 16px; border-radius: var(--radius-full); font-size: 0.85rem; font-weight: 600; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; margin-left: 8px; } .dj-mode-active .dj-generate-set-btn { display: inline-flex; align-items: center; gap: 6px; } .dj-generate-set-btn:hover { transform: scale(1.05); box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4); } /* DJ Modal */ .dj-modal { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.85); display: flex; align-items: center; justify-content: center; z-index: 2500; padding: 20px; backdrop-filter: blur(10px); } .dj-modal-content { background: var(--bg-elevated); border-radius: var(--radius-lg); max-width: 600px; width: 100%; max-height: 85vh; overflow: hidden; display: flex; flex-direction: column; animation: slideUp 0.3s ease; } .dj-modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; border-bottom: 1px solid var(--bg-tertiary); } .dj-modal-header h2 { margin: 0; font-size: 1.3rem; } .dj-modal-close { background: none; border: none; color: var(--text-secondary); font-size: 1.8rem; cursor: pointer; line-height: 1; } .dj-modal-close:hover { color: var(--text-primary); } .dj-modal-body { padding: 20px 24px; overflow-y: auto; flex: 1; } .dj-style-selector { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; } .dj-style-selector label { font-size: 0.9rem; color: var(--text-secondary); } .dj-style-selector select { flex: 1; background: var(--bg-tertiary); border: 1px solid var(--bg-secondary); color: var(--text-primary); padding: 10px 14px; border-radius: var(--radius-md); font-size: 0.9rem; cursor: pointer; } .dj-loading { text-align: center; padding: 40px 20px; } .dj-loading p { margin-top: 16px; color: var(--text-secondary); } .dj-ordered-tracks { display: flex; flex-direction: column; gap: 8px; } .dj-track-item { display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--bg-tertiary); border-radius: var(--radius-md); transition: background 0.2s; } .dj-track-item:hover { background: var(--bg-secondary); } .dj-track-number { width: 28px; height: 28px; background: var(--accent); color: black; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.85rem; flex-shrink: 0; } .dj-track-info { flex: 1; min-width: 0; } .dj-track-name { font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .dj-track-artist { font-size: 0.85rem; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .dj-track-meta { display: flex; gap: 8px; flex-shrink: 0; } .dj-transition { padding: 8px 16px; margin: 4px 0; background: rgba(99, 102, 241, 0.1); border-left: 3px solid var(--accent); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; font-size: 0.8rem; color: var(--text-secondary); } .dj-transition.harmonic { border-left-color: #4ade80; background: rgba(74, 222, 128, 0.1); } .dj-transition.caution { border-left-color: #facc15; background: rgba(250, 204, 21, 0.1); } .dj-transition-header { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; } .dj-technique-badge { background: var(--accent); color: white; padding: 2px 8px; border-radius: var(--radius-full); font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; } .dj-timing { color: var(--text-tertiary); font-size: 0.75rem; font-style: italic; } .dj-transition-tip { color: var(--text-secondary); font-size: 0.8rem; line-height: 1.4; } .dj-modal-actions { display: flex; gap: 12px; padding: 16px 24px; border-top: 1px solid var(--bg-tertiary); } .dj-modal-actions .btn-primary { flex: 1; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); color: white; border: none; padding: 12px 24px; border-radius: var(--radius-full); font-size: 1rem; font-weight: 600; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; } .dj-modal-actions .btn-primary:hover { transform: scale(1.02); box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4); } .dj-modal-actions .btn-secondary { flex: 1; background: var(--bg-tertiary); color: var(--text-primary); border: none; padding: 12px 24px; border-radius: var(--radius-full); font-size: 1rem; font-weight: 600; cursor: pointer; transition: background 0.2s; } .dj-modal-actions .btn-secondary:hover { background: var(--bg-secondary); } /* ==================== Camelot Wheel Colors (Mixed In Key) ==================== */ /* Minor keys (A column) - Inner wheel */ .camelot-1A { background: #00c8ff !important; color: #000 !important; } /* Abm */ .camelot-2A { background: #00a0e0 !important; color: #fff !important; } /* Ebm */ .camelot-3A { background: #0080c0 !important; color: #fff !important; } /* Bbm */ .camelot-4A { background: #0060a0 !important; color: #fff !important; } /* Fm */ .camelot-5A { background: #004080 !important; color: #fff !important; } /* Cm */ .camelot-6A { background: #400080 !important; color: #fff !important; } /* Gm */ .camelot-7A { background: #800080 !important; color: #fff !important; } /* Dm */ .camelot-8A { background: #c00060 !important; color: #fff !important; } /* Am */ .camelot-9A { background: #e00040 !important; color: #fff !important; } /* Em */ .camelot-10A { background: #ff4020 !important; color: #fff !important; } /* Bm */ .camelot-11A { background: #ff8000 !important; color: #000 !important; } /* F#m */ .camelot-12A { background: #ffc000 !important; color: #000 !important; } /* Dbm/C#m */ /* Major keys (B column) - Outer wheel */ .camelot-1B { background: #00e8ff !important; color: #000 !important; } /* B */ .camelot-2B { background: #00c8e0 !important; color: #000 !important; } /* Gb/F# */ .camelot-3B { background: #00a0c0 !important; color: #fff !important; } /* Db/C# */ .camelot-4B { background: #0080a0 !important; color: #fff !important; } /* Ab */ .camelot-5B { background: #006080 !important; color: #fff !important; } /* Eb */ .camelot-6B { background: #600080 !important; color: #fff !important; } /* Bb */ .camelot-7B { background: #a00080 !important; color: #fff !important; } /* F */ .camelot-8B { background: #e00080 !important; color: #fff !important; } /* C */ .camelot-9B { background: #ff0060 !important; color: #fff !important; } /* G */ .camelot-10B { background: #ff6040 !important; color: #fff !important; } /* D */ .camelot-11B { background: #ffa000 !important; color: #000 !important; } /* A */ .camelot-12B { background: #ffe000 !important; color: #000 !important; } /* E */ /* ==================== AI Search Toggle ==================== */ .ai-search-toggle { background: transparent; border: 2px solid var(--text-tertiary); color: var(--text-tertiary); width: 40px; height: 40px; border-radius: var(--radius-full); cursor: pointer; font-size: 1.2rem; transition: all 0.3s ease; flex-shrink: 0; } .ai-search-toggle:hover { border-color: var(--accent); color: var(--accent); transform: scale(1.05); } .ai-search-toggle.active { background: linear-gradient(135deg, #6366f1 0%, #a855f7 100%); border-color: transparent; color: white; box-shadow: 0 0 20px rgba(99, 102, 241, 0.5); animation: ai-pulse 2s infinite; } @keyframes ai-pulse { 0%, 100% { box-shadow: 0 0 20px rgba(99, 102, 241, 0.5); } 50% { box-shadow: 0 0 30px rgba(168, 85, 247, 0.7); } } .ai-search-hint { background: linear-gradient(135deg, rgba(99, 102, 241, 0.1) 0%, rgba(168, 85, 247, 0.1) 100%); border: 1px solid rgba(99, 102, 241, 0.3); border-radius: var(--radius-sm); padding: 8px 16px; margin-top: 8px; font-size: 0.85rem; color: var(--text-secondary); text-align: center; } .ai-search-hint strong { color: var(--accent-light); } /* Adjust search container to fit AI toggle */ .search-section .search-container { display: flex; align-items: center; gap: 8px; } /* ==================== AI Radio ==================== */ .ai-radio-btn.active { background: linear-gradient(135deg, #6366f1 0%, #ec4899 100%); color: white; box-shadow: 0 0 15px rgba(99, 102, 241, 0.5); animation: ai-radio-pulse 1.5s infinite; } @keyframes ai-radio-pulse { 0%, 100% { box-shadow: 0 0 15px rgba(99, 102, 241, 0.5); } 50% { box-shadow: 0 0 25px rgba(236, 72, 153, 0.7); } } .ai-radio-status { position: fixed; top: 80px; right: 16px; background: linear-gradient(135deg, rgba(99, 102, 241, 0.95) 0%, rgba(236, 72, 153, 0.95) 100%); color: white; padding: 8px 16px; border-radius: var(--radius-full); font-size: 0.85rem; font-weight: 600; display: flex; align-items: center; gap: 8px; box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4); z-index: 1000; animation: ai-radio-status-slide 0.3s ease-out; } @keyframes ai-radio-status-slide { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } .ai-radio-status .spinner-small { width: 16px; height: 16px; border: 2px solid rgba(255, 255, 255, 0.3); border-top-color: white; border-radius: 50%; animation: spin 1s linear infinite; } /* Fix for deprecated slider-vertical */ .eq-slider { writing-mode: vertical-lr; direction: rtl; width: 6px; height: 120px; margin: 10px auto; appearance: auto; } /* Ensure boost sliders allow horizontal */ .eq-boost-slider { width: 100%; margin-top: 5px; } /* ==================== Winamp Mini Player (PiP) ==================== */ .winamp-body { background: #000; margin: 0; padding: 0; overflow: hidden; font-family: 'Courier New', monospace; user-select: none; } .winamp-player { display: flex; flex-direction: column; width: 100vw; height: 100vh; background: #282828; color: #00e000; } .winamp-titlebar { height: 14px; background: linear-gradient(to right, #001040, #002060); border-bottom: 2px solid #606060; border-top: 2px solid #a0a0a0; display: flex; align-items: center; padding: 0 4px; cursor: default; } .winamp-titlebar-text { color: #fff; font-size: 10px; font-weight: bold; letter-spacing: 1px; margin-left: 2px; } .winamp-main { display: flex; flex: 1; padding: 4px; gap: 4px; border: 2px solid #fff; border-right-color: #404040; border-bottom-color: #404040; } .winamp-art { width: 64px; height: 64px; border: 2px solid #404040; border-top-color: #fff; border-left-color: #fff; background: #000; } .winamp-art img { width: 100%; height: 100%; object-fit: cover; } .winamp-content { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; } .winamp-display { background: #000; padding: 4px; border: 2px solid #808080; border-top-color: #202020; border-left-color: #202020; height: 36px; position: relative; overflow: hidden; } .winamp-time { font-size: 20px; font-weight: bold; color: #00e000; position: absolute; left: 4px; top: 6px; text-shadow: 0 0 2px #00e000; z-index: 1; /* Below marquee */ } .winamp-marquee { position: absolute; left: 0; right: 0; top: 2px; font-size: 10px; white-space: nowrap; color: #00e000; overflow: hidden; z-index: 2; /* Above time */ pointer-events: none; /* Let clicks pass through */ } .winamp-marquee span { display: inline-block; padding-left: 100%; animation: marquee 10s linear infinite; } @keyframes marquee { 0% { transform: translate(0, 0); } 100% { transform: translate(-100%, 0); } } .winamp-info-line { position: absolute; bottom: 2px; right: 4px; font-size: 9px; color: #00e000; display: flex; gap: 6px; } .winamp-kbps { color: #e00000; } .winamp-controls { display: flex; align-items: center; gap: 2px; margin-top: auto; } .winamp-btn { width: 22px; height: 18px; background: #c0c0c0; border: 1px solid #404040; border-top-color: #fff; border-left-color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; } .winamp-btn:active { border: 1px solid #fff; border-top-color: #404040; border-left-color: #404040; background: #a0a0a0; } .winamp-btn svg { width: 10px; height: 10px; fill: #000; } .winamp-slider { flex: 1; height: 10px; -webkit-appearance: none; appearance: none; background: transparent; margin: 0 4px; } .winamp-slider::-webkit-slider-thumb { -webkit-appearance: none; height: 10px; width: 20px; background: #c0c0c0; border: 1px solid #000; border-top-color: #fff; border-left-color: #fff; box-shadow: 1px 1px 0 #000; cursor: pointer; } .winamp-slider::-webkit-slider-runnable-track { width: 100%; height: 4px; background: #000; border-bottom: 1px solid #404040; } /* ==================== Mobile Player Bar Optimization ==================== */ /* Ensure More Menu uses 4-column Grid (4x3 layout for 12 buttons) */ .more-menu-grid { display: grid !important; grid-template-columns: repeat(4, 1fr) !important; gap: 8px !important; padding: 8px; } .more-menu-grid.four-col { grid-template-columns: repeat(4, 1fr) !important; } /* Adjust menu width for 4 columns */ .player-more-menu { width: auto !important; min-width: 220px; } /* Mobile Layout Changes */ @media (max-width: 768px) { /* Height and spacing */ .player-bar { height: auto; padding: 12px 14px 20px 14px; /* More bottom padding for safe area */ flex-direction: column; gap: 10px; } .player-main-row { flex-direction: row; flex-wrap: wrap; /* Allow wrapping */ align-items: center; width: 100%; } /* Info takes full width or shares row? User asked for layers: Art/Info above, Controls below/right. Start with Info taking full width for clarity initially. */ .player-info { width: 100%; margin-right: 0; margin-bottom: 8px; padding-right: 0; border-right: none; } .player-details { max-width: calc(100% - 60px); /* Leave room for art */ } /* Controls take full width below */ .player-controls-primary { width: 100%; justify-content: space-evenly; margin-left: 0; gap: 0; } /* Larger touch targets */ .control-btn { width: 48px; height: 48px; font-size: 1.2rem; } /* Play button prominent */ .play-btn { transform: scale(1.1); background: rgba(255, 255, 255, 0.1); border-radius: 50%; } /* Ensure metadata wraps nicely on mobile */ .player-meta-row { flex-wrap: wrap; gap: 6px; margin-top: 4px; } /* Progress bar adjustments */ .player-progress { width: 100%; margin-top: 5px; } /* Mobile text sizes */ .player-title { font-size: 1rem; } .player-artist { font-size: 0.9rem; opacity: 0.8; } /* Ensure more menu popup aligns correctly on mobile */ .player-more-menu { bottom: 80px; right: 10px; } } /* ==================== Branding & UI Polish ==================== */ .brand-text { background: linear-gradient(to right, #8b5cf6, #ff00ff); /* Dark Purple to Neon Pink */ -webkit-background-clip: text; background-clip: text; color: transparent; font-family: 'Permanent Marker', cursive; /* Brush Style Font */ font-weight: 400; /* Permanent Marker is bold by default */ letter-spacing: 1px; filter: drop-shadow(0 0 4px rgba(255, 0, 255, 0.4)); /* Stronger glow */ font-size: 1.4rem; /* 30% smaller than 2rem */ } /* Padding for Progress Numbers (Fix Clipping) */ .player-progress { padding: 6px 0 !important; width: 100%; } /* Taller Progress Bar with Dynamic Fill */ .progress-bar, #fs-progress-bar { -webkit-appearance: none; appearance: none; height: 8px !important; border-radius: 4px; background: linear-gradient(to right, var(--accent) 0%, var(--accent) var(--value, 0%), #404040 var(--value, 0%), #404040 100%); cursor: pointer; outline: none; margin: 0; } /* Thumb Styling */ .progress-bar::-webkit-slider-thumb, #fs-progress-bar::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px; height: 16px; background: #ffffff; border-radius: 50%; cursor: pointer; box-shadow: 0 0 5px rgba(0,0,0,0.5); transition: transform 0.1s; } .progress-bar::-webkit-slider-thumb:hover, #fs-progress-bar::-webkit-slider-thumb:hover { transform: scale(1.2); } /* ==================== Album Details Modal ==================== */ .album-modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 2500; display: flex; justify-content: center; align-items: center; padding: var(--spacing-lg); } .album-modal.hidden { display: none; } .album-modal-overlay { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.85); backdrop-filter: blur(10px); } .album-modal-content { position: relative; width: 100%; max-width: 700px; max-height: 90vh; background: var(--bg-secondary); border-radius: var(--radius-lg); overflow: hidden; display: flex; flex-direction: column; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); } .album-modal-header { display: flex; align-items: center; padding: var(--spacing-md) var(--spacing-lg); background: var(--bg-tertiary); border-bottom: 1px solid var(--text-tertiary); } .album-modal-header h2 { flex: 1; font-size: 1.1rem; font-weight: 600; } .album-modal-close { width: 32px; height: 32px; border: none; background: transparent; color: var(--text-primary); font-size: 1.5rem; cursor: pointer; order: 1; margin-left: var(--spacing-md); } .album-modal-close:hover { color: var(--accent); } .album-modal-body { flex: 1; overflow-y: auto; overflow-x: hidden; padding: var(--spacing-lg); } .album-modal-info { display: flex; gap: var(--spacing-lg); margin-bottom: var(--spacing-lg); } .album-modal-art { width: 160px; height: 160px; border-radius: var(--radius-md); object-fit: cover; flex-shrink: 0; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3); } .album-modal-meta { flex: 1; min-width: 0; } .album-modal-title { font-size: 1.5rem; font-weight: 700; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .album-modal-artist { color: var(--text-secondary); font-size: 1rem; margin-bottom: var(--spacing-sm); } /* Metadata Pills */ .album-meta-pills { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: var(--spacing-md); } .meta-pill { background: var(--bg-tertiary); padding: 4px 10px; border-radius: var(--radius-full); font-size: 0.75rem; color: var(--text-secondary); border: 1px solid var(--text-tertiary); } /* Action Buttons */ .album-action-buttons { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: var(--spacing-md); } .album-action-btn { padding: 8px 4px; border-radius: var(--radius-full); font-size: 0.75rem; display: flex; justify-content: center; align-items: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 600; cursor: pointer; transition: all 0.2s; border: 1px solid var(--text-tertiary); background: transparent; color: var(--text-primary); } .album-action-btn:hover { background: var(--bg-tertiary); border-color: var(--accent); } .album-action-btn.primary { background: var(--accent); border-color: var(--accent); color: white; } .album-action-btn.primary:hover { background: var(--accent-light); } /* Quality Badge */ .album-quality-badge { font-size: 0.75rem; color: var(--text-tertiary); padding: 4px 0; margin-top: 4px; } @media (max-width: 480px) { .album-action-buttons { display: flex; flex-direction: column; gap: 8px; width: 100%; margin: 0 auto; } .album-action-btn { padding: 10px 16px; font-size: 0.8rem; height: auto; min-width: 0; width: 100%; justify-content: center; } } /* Tabs */ .album-tabs { display: flex; gap: 4px; margin-bottom: var(--spacing-md); background: var(--bg-tertiary); border-radius: var(--radius-md); padding: 4px; } .queue-btn { color: var(--text-secondary); font-size: 1.2rem; /* Slightly larger + */ line-height: 1; margin-right: 12px; } .queue-btn:hover { color: var(--accent); background: var(--bg-tertiary); } .album-tab { flex: 1; padding: 8px 16px; border: none; background: transparent; color: var(--text-secondary); font-size: 0.85rem; font-weight: 500; cursor: pointer; border-radius: var(--radius-sm); transition: all 0.2s; } .album-tab.active { background: var(--bg-secondary); color: var(--text-primary); } .album-tab:hover:not(.active) { color: var(--text-primary); } /* Track List in Modal */ .album-modal-tracks { display: flex; flex-direction: column; gap: 4px; } .album-modal-track { display: flex; align-items: center; gap: var(--spacing-sm); padding: var(--spacing-sm) var(--spacing-md); border-radius: var(--radius-sm); cursor: pointer; transition: background 0.2s; } .album-modal-track:hover { background: var(--bg-tertiary); } .album-modal-track.playing { background: rgba(var(--accent-rgb), 0.1); border: 1px solid var(--accent); } .album-track-num { width: 24px; color: var(--text-tertiary); font-size: 0.85rem; text-align: center; } .album-track-play { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-secondary); cursor: pointer; } .album-track-play:hover { color: var(--accent); } .album-track-info { flex: 1; min-width: 0; } .album-track-name { font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .album-track-playlist { background: none; border: none; color: var(--text-tertiary); cursor: pointer; padding: 4px; } .album-track-playlist:hover { color: #ff4757; } .album-track-duration { color: var(--text-tertiary); font-size: 0.8rem; min-width: 40px; text-align: right; } .album-track-actions { display: flex; gap: 4px; } .album-track-actions button { width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--text-tertiary); cursor: pointer; border-radius: var(--radius-sm); } .album-track-actions button:hover { color: var(--accent); background: var(--bg-tertiary); } /* Album Info Tab */ .album-modal-info-tab { padding: var(--spacing-md); color: var(--text-secondary); line-height: 1.6; } .album-modal-info-tab.hidden { display: none; } /* Mobile Responsive */ @media (max-width: 600px) { .album-modal-info { flex-direction: column; align-items: center; text-align: center; } .album-modal-art { width: 140px; height: 140px; } .album-meta-pills { justify-content: center; } .album-action-buttons { justify-content: center; } } /* ==================== Crossfade Toggle ==================== */ .crossfade-toggle { display: flex; align-items: center; gap: var(--spacing-md); padding: var(--spacing-md); background: var(--bg-tertiary); border-radius: var(--radius-md); margin: var(--spacing-sm) var(--spacing-md); } .crossfade-icon { font-size: 1.2rem; color: var(--accent); } .crossfade-info { flex: 1; display: flex; flex-direction: column; gap: 2px; } .crossfade-title { font-weight: 600; font-size: 0.9rem; } .crossfade-desc { font-size: 0.75rem; color: var(--text-secondary); } /* Toggle Switch */ .toggle-switch { position: relative; display: inline-block; width: 48px; height: 28px; } .toggle-switch input { opacity: 0; width: 0; height: 0; } .toggle-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background: #404040; border-radius: 28px; transition: all 0.3s; } .toggle-slider::before { position: absolute; content: ""; height: 22px; width: 22px; left: 3px; bottom: 3px; background: white; border-radius: 50%; transition: all 0.3s; } .toggle-switch input:checked + .toggle-slider { background: var(--accent); } .toggle-switch input:checked + .toggle-slider::before { transform: translateX(20px); } /* CSS Overrides for HiFi Button logic */ /* 16-bit HiFi: Green, active, NO pulse */ /* 16-bit HiFi: Green, active, NO pulse */ #hifi-btn.active:not(.hi-res) { background: linear-gradient(135deg, #10b981, #059669) !important; color: white !important; animation: none !important; /* Stop generic pulse */ box-shadow: 0 0 10px rgba(16, 185, 129, 0.4); border: none; } #hifi-btn.active:not(.hi-res):hover { box-shadow: 0 0 15px rgba(16, 185, 129, 0.6); transform: scale(1.05); } /* 24-bit Hi-Res: Cyan, active, WITH pulse */ #hifi-btn.active.hi-res { background: linear-gradient(135deg, #00f2ff, #00c3ff) !important; color: #000 !important; /* Black text for contrast on bright cyan */ box-shadow: 0 0 15px rgba(0, 242, 255, 0.4); animation: hifi-pulse 1.5s infinite !important; /* Force pulse */ border: none; } #hifi-btn.active.hi-res:hover { box-shadow: 0 0 20px rgba(0, 242, 255, 0.6); transform: scale(1.05); } #hifi-btn.hi-res:hover { box-shadow: 0 0 20px rgba(0, 242, 255, 0.6); transform: scale(1.05); } /* Lossy (MP3) Button Style - Dimmed */ #hifi-btn.lossy { background: var(--bg-tertiary) !important; color: var(--text-tertiary) !important; box-shadow: none; border: 1px solid var(--border-color); } #hifi-btn.lossy:hover { background: var(--bg-secondary) !important; } /* ==================== AI Assistant Modal ==================== */ .ai-btn { background: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%) !important; color: white !important; border: none !important; } .ai-btn:hover { box-shadow: 0 0 15px rgba(139, 92, 246, 0.5); transform: scale(1.05); } .ai-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 10000; display: flex; align-items: center; justify-content: center; animation: fadeIn 0.2s ease; } .ai-modal.hidden { display: none; } .ai-modal-overlay { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(8px); } .ai-modal-content { position: relative; width: 90%; max-width: 500px; max-height: 80vh; background: linear-gradient(135deg, rgba(30, 30, 45, 0.95), rgba(20, 20, 35, 0.98)); border-radius: var(--radius-lg); border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5); overflow: hidden; display: flex; flex-direction: column; } .ai-modal-header { display: flex; justify-content: space-between; align-items: center; padding: var(--spacing-md) var(--spacing-lg); border-bottom: 1px solid rgba(255, 255, 255, 0.1); background: linear-gradient(135deg, rgba(139, 92, 246, 0.2), rgba(99, 102, 241, 0.1)); } .ai-modal-header h2 { margin: 0; font-size: 1.2rem; color: var(--text-primary); } .ai-modal-close { background: none; border: none; color: var(--text-secondary); font-size: 24px; cursor: pointer; padding: 4px 8px; border-radius: 4px; transition: all 0.2s; } .ai-modal-close:hover { color: var(--text-primary); background: rgba(255, 255, 255, 0.1); } /* Tabs styles removed */ .ai-tab-content { padding: var(--spacing-lg); overflow-y: auto; max-height: 50vh; } .ai-tab-content.hidden { display: none; } .ai-tab-desc { margin: 0 0 var(--spacing-md); color: var(--text-secondary); font-size: 0.9rem; } .ai-input { width: 100%; padding: var(--spacing-md); background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: var(--radius-md); color: var(--text-primary); font-size: 1rem; resize: none; font-family: inherit; } .ai-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 10px rgba(139, 92, 246, 0.3); } .ai-examples { display: flex; flex-wrap: wrap; gap: var(--spacing-xs); margin: var(--spacing-sm) 0 var(--spacing-md); } .ai-example { padding: 4px 10px; background: rgba(139, 92, 246, 0.2); border-radius: var(--radius-full); font-size: 0.8rem; color: var(--accent-light); cursor: pointer; transition: all 0.2s; } .ai-example:hover { background: rgba(139, 92, 246, 0.4); transform: scale(1.05); } .ai-duration-row { display: flex; align-items: center; gap: var(--spacing-md); margin: var(--spacing-md) 0; color: var(--text-secondary); } .ai-duration-row input[type="range"] { flex: 1; accent-color: var(--accent); } .ai-action-btn { width: 100%; padding: var(--spacing-md); background: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%); border: none; border-radius: var(--radius-md); color: white; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.2s; } .ai-action-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(139, 92, 246, 0.4); } .ai-action-btn:disabled { opacity: 0.6; cursor: not-allowed; transform: none; } .ai-results { margin-top: var(--spacing-md); } .ai-results-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--spacing-sm); color: var(--text-secondary); font-size: 0.85rem; } .ai-track-item { display: flex; align-items: center; gap: var(--spacing-sm); padding: var(--spacing-sm); background: rgba(255, 255, 255, 0.05); border-radius: var(--radius-sm); margin-bottom: var(--spacing-xs); cursor: pointer; transition: all 0.2s; } .ai-track-item:hover { background: rgba(255, 255, 255, 0.1); transform: translateX(4px); } .ai-track-info { flex: 1; min-width: 0; } .ai-track-title { font-weight: 500; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .ai-track-artist { font-size: 0.85rem; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .ai-add-all-btn { width: 100%; padding: var(--spacing-sm); margin-top: var(--spacing-sm); background: rgba(34, 197, 94, 0.2); border: 1px solid rgba(34, 197, 94, 0.3); border-radius: var(--radius-md); color: #22c55e; cursor: pointer; transition: all 0.2s; } .ai-add-all-btn:hover { background: rgba(34, 197, 94, 0.3); } .ai-loading { text-align: center; padding: var(--spacing-lg); color: var(--text-secondary); } .ai-loading::after { content: ''; display: inline-block; width: 20px; height: 20px; border: 2px solid var(--accent); border-top-color: transparent; border-radius: 50%; animation: spin 1s linear infinite; margin-left: var(--spacing-sm); vertical-align: middle; } @keyframes spin { to { transform: rotate(360deg); } } /* ==================== Keyboard Shortcuts Help ==================== */ .shortcuts-help-btn { position: fixed; bottom: calc(var(--player-height) + var(--safe-bottom) + 16px); left: 16px; width: 36px; height: 36px; background: var(--bg-tertiary); border: 1px solid var(--bg-elevated); border-radius: var(--radius-full); color: var(--text-tertiary); font-size: 1rem; font-weight: 600; cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 100; transition: all 0.2s ease; opacity: 0.6; } .shortcuts-help-btn:hover { background: var(--bg-elevated); color: var(--text-primary); opacity: 1; transform: scale(1.1); } .shortcuts-modal-content { max-width: 420px; width: 90%; } .shortcuts-list { display: flex; flex-direction: column; gap: var(--spacing-lg); padding: var(--spacing-md); } .shortcut-group h4 { font-size: 0.875rem; font-weight: 600; color: var(--accent); margin-bottom: var(--spacing-sm); text-transform: uppercase; letter-spacing: 0.5px; } .shortcut-item { display: flex; align-items: center; justify-content: space-between; padding: var(--spacing-xs) 0; } .shortcut-item kbd { display: inline-block; min-width: 32px; padding: 4px 8px; background: var(--bg-tertiary); border: 1px solid var(--bg-elevated); border-radius: 6px; font-family: inherit; font-size: 0.8rem; font-weight: 600; text-align: center; color: var(--text-primary); box-shadow: 0 2px 0 var(--bg-elevated); } .shortcut-item span { color: var(--text-secondary); font-size: 0.875rem; } @media (max-width: 480px) { .shortcuts-help-btn { display: none; /* Hide on mobile - touchscreens don't use keyboard shortcuts */ } } /* ==================== ListenBrainz Stats Panel ==================== */ .stats-panel { display: flex; gap: var(--spacing-lg); padding: var(--spacing-md); background: var(--bg-secondary); border-radius: var(--radius-md); margin-bottom: var(--spacing-lg); flex-wrap: wrap; } .stats-item { display: flex; flex-direction: column; gap: 4px; } .stats-item.top-artists { flex: 1; min-width: 150px; } .stats-value { font-size: 1.5rem; font-weight: 700; color: var(--accent); } .stats-label { font-size: 0.75rem; color: var(--text-tertiary); text-transform: uppercase; letter-spacing: 0.5px; } .stats-artists { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; } .artist-tag { font-size: 0.8rem; padding: 4px 10px; background: var(--bg-tertiary); border-radius: var(--radius-full); color: var(--text-secondary); } @media (max-width: 400px) { .stats-panel { flex-direction: column; } } /* ==================== Lyrics Modal ==================== */ .lyrics-modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.85); z-index: 10000; display: flex; align-items: center; justify-content: center; padding: 20px; animation: fadeIn 0.2s ease; } .lyrics-modal-content { background: var(--bg-secondary); border-radius: 16px; max-width: 600px; width: 100%; max-height: 85vh; display: flex; flex-direction: column; overflow: hidden; position: relative; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); } .lyrics-modal-close { position: absolute; top: 12px; right: 12px; background: var(--bg-tertiary); border: none; color: var(--text-primary); font-size: 1.5rem; width: 36px; height: 36px; border-radius: 50%; cursor: pointer; z-index: 10; transition: all 0.2s; } .lyrics-modal-close:hover { background: var(--accent-color); transform: scale(1.1); } .lyrics-modal-header { display: flex; gap: 16px; padding: 20px; background: linear-gradient(180deg, var(--bg-tertiary) 0%, transparent 100%); align-items: center; } .lyrics-modal-art { width: 80px; height: 80px; border-radius: 8px; object-fit: cover; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); } .lyrics-modal-info { flex: 1; min-width: 0; } .lyrics-modal-info h2 { font-size: 1.25rem; font-weight: 700; margin: 0 0 4px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .lyrics-modal-info p { margin: 0; color: var(--text-secondary); font-size: 0.9rem; } .lyrics-modal-album { font-size: 0.8rem !important; color: var(--text-tertiary) !important; } /* Tabs */ .lyrics-tabs { display: flex; border-bottom: 1px solid var(--bg-tertiary); padding: 0 20px; } .lyrics-tab { background: none; border: none; color: var(--text-secondary); font-size: 0.9rem; font-weight: 600; padding: 12px 20px; cursor: pointer; position: relative; transition: all 0.2s; } .lyrics-tab:hover { color: var(--text-primary); } .lyrics-tab.active { color: var(--accent-color); } .lyrics-tab.active::after { content: ''; position: absolute; bottom: -1px; left: 0; right: 0; height: 2px; background: var(--accent-color); } /* Tab Content */ .lyrics-tab-content { flex: 1; overflow-y: auto; padding: 20px; } .lyrics-panel { display: none; } .lyrics-panel.active { display: block; } /* Lyrics Text */ .lyrics-text { font-size: 1rem; line-height: 1.8; white-space: pre-wrap; color: var(--text-primary); } /* Loading */ .lyrics-loading { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px; color: var(--text-secondary); } .lyrics-spinner { width: 40px; height: 40px; border: 3px solid var(--bg-tertiary); border-top-color: var(--accent-color); border-radius: 50%; animation: spin 1s linear infinite; margin-bottom: 12px; } /* Not Found */ .lyrics-not-found { text-align: center; padding: 40px; color: var(--text-secondary); } .lyrics-search-link, .genius-link { display: inline-block; color: var(--accent-color); text-decoration: none; margin-top: 12px; font-weight: 500; } .lyrics-search-link:hover, .genius-link:hover { text-decoration: underline; } /* About Section */ .about-content { color: var(--text-primary); } .about-description { font-size: 0.95rem; line-height: 1.7; margin-bottom: 20px; } .about-credits { background: var(--bg-tertiary); padding: 16px; border-radius: 8px; margin-bottom: 16px; } .about-credits p { margin: 0 0 8px 0; font-size: 0.85rem; color: var(--text-secondary); } .about-credits p:last-child { margin-bottom: 0; } .about-credits strong { color: var(--text-primary); } /* Lyrics button active state */ .lyrics-btn.active { color: #f59e0b !important; } /* Annotations */ .annotations-list { display: flex; flex-direction: column; gap: 16px; } .annotation-item { background: var(--bg-tertiary); border-radius: 8px; padding: 16px; border-left: 3px solid var(--accent-color); } .annotation-fragment { font-style: italic; color: var(--accent-color); font-size: 0.9rem; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid rgba(255,255,255,0.1); } .annotation-text { font-size: 0.9rem; line-height: 1.6; color: var(--text-secondary); } /* Mobile adjustments */ @media (max-width: 600px) { .lyrics-modal { padding: 10px; } .lyrics-modal-content { max-height: 90vh; border-radius: 12px; } .lyrics-modal-header { padding: 16px; } .lyrics-modal-art { width: 60px; height: 60px; } .lyrics-modal-info h2 { font-size: 1rem; } } /* ==================== Concerts Modal ==================== */ .concerts-modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.85); z-index: 10000; display: flex; align-items: center; justify-content: center; padding: 20px; animation: fadeIn 0.2s ease; } .concerts-modal-content { background: var(--bg-secondary); border-radius: 16px; max-width: 650px; width: 100%; max-height: 85vh; display: flex; flex-direction: column; overflow: hidden; position: relative; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); } .concerts-modal-close { position: absolute; top: 12px; right: 12px; background: var(--bg-tertiary); border: none; color: var(--text-primary); font-size: 1.5rem; width: 36px; height: 36px; border-radius: 50%; cursor: pointer; z-index: 10; transition: all 0.2s; } .concerts-modal-close:hover { background: var(--accent-color); transform: scale(1.1); } .concerts-modal-header { padding: 20px; border-bottom: 1px solid var(--bg-tertiary); } .concerts-modal-header h2 { margin: 0; font-size: 1.3rem; } .concerts-settings { padding: 16px 20px; background: var(--bg-tertiary); display: flex; gap: 10px; align-items: center; flex-wrap: wrap; } .concerts-settings label { font-size: 0.85rem; color: var(--text-secondary); } .concerts-cities-input { flex: 1; min-width: 200px; padding: 8px 12px; border-radius: 6px; border: 1px solid var(--bg-tertiary); background: var(--bg-primary); color: var(--text-primary); font-size: 0.9rem; } .concerts-save-btn { padding: 8px 16px; background: var(--accent-color); border: none; border-radius: 6px; color: white; cursor: pointer; font-weight: 600; transition: all 0.2s; } .concerts-save-btn:hover { filter: brightness(1.1); } .concerts-tabs { display: flex; padding: 0 20px; border-bottom: 1px solid var(--bg-tertiary); } .concerts-tab { background: none; border: none; color: var(--text-secondary); font-size: 0.9rem; font-weight: 600; padding: 12px 20px; cursor: pointer; position: relative; transition: all 0.2s; } .concerts-tab:hover { color: var(--text-primary); } .concerts-tab.active { color: var(--accent-color); } .concerts-tab.active::after { content: ''; position: absolute; bottom: -1px; left: 0; right: 0; height: 2px; background: var(--accent-color); } .concerts-search-section { padding: 12px 20px; display: flex; gap: 10px; } .concerts-artist-input { flex: 1; padding: 10px 14px; border-radius: 8px; border: 1px solid var(--bg-tertiary); background: var(--bg-primary); color: var(--text-primary); font-size: 0.95rem; } .concerts-search-btn { padding: 10px 16px; background: var(--accent-color); border: none; border-radius: 8px; cursor: pointer; font-size: 1rem; } .concerts-list { flex: 1; overflow-y: auto; padding: 16px 20px; display: flex; flex-direction: column; gap: 12px; } .concert-card { background: var(--bg-tertiary); border-radius: 10px; padding: 16px; display: flex; gap: 16px; align-items: flex-start; transition: all 0.2s; } .concert-card:hover { background: var(--bg-hover); } .concert-date { background: var(--accent-color); color: white; border-radius: 8px; padding: 10px 14px; text-align: center; min-width: 60px; } .concert-date-month { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; } .concert-date-day { font-size: 1.5rem; font-weight: 700; line-height: 1; } .concert-info { flex: 1; min-width: 0; } .concert-artist { font-weight: 700; font-size: 1rem; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .concert-venue { font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 4px; } .concert-location { font-size: 0.85rem; color: var(--text-tertiary); } .concert-ticket-btn { padding: 8px 16px; background: linear-gradient(135deg, var(--accent-color), #f59e0b); border: none; border-radius: 20px; color: white; font-weight: 600; font-size: 0.8rem; cursor: pointer; text-decoration: none; transition: all 0.2s; white-space: nowrap; } .concert-ticket-btn:hover { transform: scale(1.05); filter: brightness(1.1); } .concerts-empty { text-align: center; padding: 40px 20px; color: var(--text-secondary); } .concerts-empty-hint { font-size: 0.85rem; color: var(--text-tertiary); margin-top: 8px; } @media (max-width: 500px) { .concerts-settings { flex-direction: column; align-items: stretch; } .concert-card { flex-direction: column; } .concert-date { display: flex; gap: 8px; align-items: center; } } /* ==================== Audio Visualizer ==================== */ .visualizer-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: #000; z-index: 100000; cursor: default; } .visualizer-overlay.hidden { display: none; } #visualizer-canvas, #visualizer-canvas-webgl { width: 100%; height: 100%; display: block; } .visualizer-controls { position: absolute; bottom: 0; left: 0; right: 0; padding: 20px 30px; background: linear-gradient(transparent, rgba(0,0,0,0.8)); display: flex; justify-content: space-between; align-items: center; opacity: 1; transition: opacity 0.5s, background 0.5s; } /* Base idle state: controls fade out */ .visualizer-overlay.user-idle .visualizer-controls { opacity: 1; /* Keep container 'visible' for child management, but fade bg */ background: transparent; pointer-events: none; } /* Hide specific elements when idle */ .visualizer-overlay.user-idle .visualizer-mode-selector, .visualizer-overlay.user-idle .visualizer-close-btn, .visualizer-overlay.user-idle .visualizer-hint { opacity: 0; transition: opacity 0.5s; } /* Track info - possibly visible */ .visualizer-track-info { transition: opacity 0.5s; opacity: 1; } .visualizer-overlay.user-idle .visualizer-track-info { opacity: 0; } .visualizer-overlay.user-idle .visualizer-track-info.temp-visible { opacity: 1; text-shadow: 0 2px 4px rgba(0,0,0,0.8); } .visualizer-track-info { display: flex; flex-direction: column; gap: 4px; } #viz-track-name { font-size: 1.2rem; font-weight: 700; color: white; } #viz-track-artist { font-size: 0.9rem; color: rgba(255,255,255,0.7); } .visualizer-mode-selector { display: flex; gap: 8px; } .viz-mode-btn { padding: 8px 16px; border: 1px solid rgba(255,255,255,0.3); background: rgba(255,255,255,0.1); color: white; border-radius: 20px; cursor: pointer; font-size: 0.85rem; transition: all 0.2s; } .viz-mode-btn:hover { background: rgba(255,255,255,0.2); } .viz-mode-btn.active { background: var(--accent-color); border-color: var(--accent-color); } .viz-action-btn { padding: 8px 16px; border: 1px solid rgba(255,255,255,0.3); background: rgba(16, 185, 129, 0.2); /* distinct green tint */ color: white; border-radius: 20px; cursor: pointer; font-size: 0.85rem; transition: all 0.2s; } .viz-action-btn:hover { background: rgba(16, 185, 129, 0.4); transform: scale(1.05); } .visualizer-close-btn { padding: 10px 20px; background: rgba(255,255,255,0.15); border: 1px solid rgba(255,255,255,0.3); color: white; border-radius: 8px; cursor: pointer; font-size: 0.9rem; transition: all 0.2s; } .visualizer-close-btn:hover { background: rgba(255,0,0,0.5); border-color: rgba(255,0,0,0.7); } .visualizer-hint { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); color: rgba(255,255,255,0.4); font-size: 0.8rem; opacity: 1; transition: opacity 0.3s; } @media (max-width: 768px) { .visualizer-controls { flex-direction: column; gap: 15px; padding-bottom: 40px; /* More space for exit button */ height: auto; justify-content: flex-end; } .visualizer-mode-selector { flex-wrap: wrap; justify-content: center; gap: 10px; margin-bottom: 15px; } .visualizer-track-info { text-align: center; margin-bottom: 10px; } .visualizer-close-btn { width: 100%; max-width: 200px; } } /* --- Drive Sync Modal --- */ .drive-modal-content { max-width: 700px; width: 95%; } .drive-signin-container { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 30px; } .drive-auth-btn { display: inline-flex; align-items: center; gap: 12px; background-color: white; color: #444; padding: 12px 24px; border-radius: 4px; border: none; font-family: 'Roboto', sans-serif; font-weight: 500; font-size: 16px; cursor: pointer; box-shadow: 0 2px 4px rgba(0,0,0,0.2); transition: background-color 0.2s, box-shadow 0.2s; } .drive-auth-btn:hover { background-color: #f8f8f8; box-shadow: 0 4px 8px rgba(0,0,0,0.3); } .drive-user-info { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid rgba(255,255,255,0.1); margin-bottom: 20px; } #drive-user-email { color: var(--primary-color); font-weight: 600; } .drive-actions-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; } @media (max-width: 600px) { .drive-actions-grid { grid-template-columns: 1fr; } } .sync-group { background: rgba(255, 255, 255, 0.05); padding: 20px; border-radius: 12px; display: flex; flex-direction: column; } .sync-group h3 { margin-bottom: 5px; display: flex; align-items: center; gap: 8px; } .sync-desc { font-size: 0.85em; color: var(--text-secondary); margin-bottom: 15px; } .action-buttons { display: flex; flex-direction: column; gap: 10px; } .action-btn { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 12px; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; transition: transform 0.2s, filter 0.2s; text-align: left; } .action-btn:hover { transform: translateY(-2px); filter: brightness(1.1); } .action-btn:active { transform: translateY(0); } .action-btn.upload { background: linear-gradient(135deg, #10b981, #059669); /* Green */ color: white; } .action-btn.download { background: linear-gradient(135deg, #3b82f6, #2563eb); /* Blue */ color: white; } /* Secondary (Playlists Only / Queue Only) buttons */ .action-btn.secondary { background: transparent; border: 1px solid rgba(255, 255, 255, 0.2); color: var(--text-primary); padding: 8px; font-size: 0.9em; } .action-btn.secondary:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.4); } .action-btn.upload.secondary { border-left: 3px solid #10b981; } .action-btn.download.secondary { border-left: 3px solid #3b82f6; } .btn-icon { font-size: 1.2em; } /* Download Modal Source Hint */ .download-hint { font-size: 0.85em; color: var(--text-secondary); padding: 8px 12px; background: rgba(255, 255, 255, 0.05); border-radius: 6px; margin-bottom: 10px; } /* ========== CONCERT ALERTS MODAL ========== */ .concert-modal-content { max-width: 600px; max-height: 85vh; overflow-y: auto; } .concert-modal-content .modal-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 15px; border-bottom: 1px solid rgba(255, 255, 255, 0.1); margin-bottom: 15px; } .concert-modal-content .modal-header h3 { margin: 0; font-size: 1.3em; } /* City Preferences */ .concert-cities-section { margin-bottom: 20px; } .concert-cities-section label { display: block; font-weight: 500; margin-bottom: 8px; color: var(--text-secondary); } .city-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; } .city-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; background: var(--accent-color); border-radius: 20px; font-size: 0.85em; color: white; } .city-chip button { background: none; border: none; color: rgba(255, 255, 255, 0.7); cursor: pointer; padding: 0; font-size: 1.1em; line-height: 1; } .city-chip button:hover { color: white; } .add-city-wrapper { display: flex; gap: 8px; } .add-city-wrapper input { flex: 1; padding: 8px 12px; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; color: var(--text-primary); font-size: 0.9em; } .add-city-wrapper input::placeholder { color: var(--text-secondary); } /* Concert Tabs */ .concert-tabs { display: flex; gap: 8px; margin-bottom: 15px; border-bottom: 1px solid rgba(255, 255, 255, 0.1); padding-bottom: 10px; } .concert-tab { padding: 8px 16px; background: transparent; border: none; color: var(--text-secondary); font-size: 0.95em; cursor: pointer; border-radius: 6px; transition: all 0.2s ease; } .concert-tab:hover { background: rgba(255, 255, 255, 0.05); color: var(--text-primary); } .concert-tab.active { background: var(--accent-color); color: white; } /* Concert Tab Content */ .concert-tab-content.hidden { display: none; } .concert-hint { color: var(--text-secondary); font-size: 0.85em; margin-bottom: 10px; } /* Concert Search */ .concert-search-wrapper { display: flex; gap: 8px; margin-bottom: 15px; } .concert-search-wrapper input { flex: 1; padding: 10px 14px; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; color: var(--text-primary); font-size: 0.95em; } /* Concert Results */ .concert-results { display: flex; flex-direction: column; gap: 12px; max-height: 400px; overflow-y: auto; } /* Concert Card */ .concert-card { display: flex; gap: 12px; padding: 12px; background: rgba(255, 255, 255, 0.03); border-radius: 10px; border: 1px solid rgba(255, 255, 255, 0.06); transition: all 0.2s ease; } .concert-card:hover { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.1); } .concert-card-image { width: 60px; height: 60px; border-radius: 6px; object-fit: cover; flex-shrink: 0; } .concert-card-image.placeholder { background: linear-gradient(135deg, var(--accent-color), var(--accent-hover)); display: flex; align-items: center; justify-content: center; font-size: 1.5em; } .concert-card-info { flex: 1; min-width: 0; } .concert-card-artist { font-weight: 600; font-size: 0.95em; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .concert-card-venue { color: var(--text-secondary); font-size: 0.85em; margin-bottom: 2px; display: flex; align-items: center; gap: 4px; } .concert-card-date { color: var(--accent-color); font-size: 0.85em; font-weight: 500; } .concert-card-price { color: var(--text-secondary); font-size: 0.8em; margin-top: 4px; } .concert-card-actions { display: flex; flex-direction: column; justify-content: center; gap: 6px; } .concert-ticket-btn { padding: 8px 14px; background: var(--accent-color); color: white; border: none; border-radius: 6px; font-size: 0.85em; font-weight: 500; cursor: pointer; text-decoration: none; transition: all 0.2s ease; display: inline-flex; align-items: center; gap: 4px; } .concert-ticket-btn:hover { background: var(--accent-hover); transform: translateY(-1px); } /* Concert Loading */ .concert-loading { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 30px; color: var(--text-secondary); } .concert-loading .loading-spinner { width: 20px; height: 20px; border: 2px solid rgba(255, 255, 255, 0.1); border-top-color: var(--accent-color); border-radius: 50%; animation: spin 0.8s linear infinite; } /* Concert Empty State */ .concert-empty { text-align: center; padding: 40px 20px; color: var(--text-secondary); } .concert-empty span { font-size: 2.5em; display: block; margin-bottom: 10px; } /* Source Badge */ .concert-source-badge { font-size: 0.7em; padding: 2px 6px; background: rgba(255, 255, 255, 0.1); border-radius: 4px; color: var(--text-secondary); margin-left: 6px; }