/* ========================================================= diora — dark radio player theme ========================================================= */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --bg: #000; --bg-card: transparent; --bg-alt: transparent; --bg-row: transparent; --bg-row-alt: transparent; --border: #2a2a2a; --accent: #e63946; --accent-hover: #ff4d58; --green: #2ecc71; --yellow: #f1c40f; --font: 'Courier New', Courier, monospace; --radius: 3px; --nav-h: 48px; --bar-h: 72px; /* contrast scheme — default: white on dark */ --fg: #fff; --fg-muted: #fff; --outline: #000; --text: var(--fg); --text-muted: var(--fg); } /* inverted: black on bright */ body.bright-bg { --fg: #000; --fg-muted: #000; --outline: #fff; --border: #bbb; } html, body { background: var(--bg); color: var(--fg); font-family: var(--font); font-size: 14px; font-weight: 600; line-height: 1.5; min-height: 100vh; text-shadow: -1px -1px 0 var(--outline), 1px -1px 0 var(--outline), -1px 1px 0 var(--outline), 1px 1px 0 var(--outline); } /* Elements with their own coloured backgrounds — no outline, no override */ .btn-play, .btn-amazon, .btn-lastfm, .btn-danger, .btn-primary, .navbar-brand { text-shadow: none; } /* Accent colour stays red regardless of scheme */ .navbar-brand { color: var(--accent); } .tab-btn.active { color: var(--accent); } a { color: var(--accent); text-decoration: none; } a:hover { color: var(--accent-hover); text-decoration: underline; } /* ========================================================= NAVBAR ========================================================= */ .navbar { position: sticky; top: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; height: var(--nav-h); padding: 0 1.5rem; background: transparent; border-bottom: 1px solid var(--border); } .navbar-brand { font-size: 1.4rem; font-weight: bold; letter-spacing: 0.05em; color: var(--accent); text-decoration: none; } .navbar-brand:hover { color: var(--accent-hover); text-decoration: none; } .navbar-links { display: flex; align-items: center; gap: 1rem; } .navbar-user { color: var(--text-muted); font-size: 0.85rem; } /* ========================================================= MAIN CONTENT ========================================================= */ .main-content { max-width: 1100px; margin: 0 auto; padding: 1rem 1.5rem calc(var(--bar-h) + 2rem); } /* ========================================================= MESSAGES ========================================================= */ .messages { margin-bottom: 1rem; } .message { padding: 0.6rem 1rem; border-radius: var(--radius); margin-bottom: 0.4rem; background: var(--bg-alt); border-left: 3px solid var(--text-muted); } .message-error { border-color: var(--accent); } .message-success { border-color: var(--green); } .message-warning { border-color: var(--yellow); } /* ========================================================= NOW PLAYING BAR (fixed at bottom) ========================================================= */ .now-playing-bar { position: fixed; bottom: 0; left: 0; right: 0; height: var(--bar-h); background: transparent; border-top: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; padding: 0 1.5rem; z-index: 200; gap: 1rem; } .now-playing-info { display: flex; flex-direction: column; flex: 1; min-width: 0; overflow: hidden; } .now-playing-station { font-size: 0.75rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .now-playing-track { font-size: 0.95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text); } .now-playing-controls { display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0; } .volume-label { display: flex; align-items: center; gap: 0.4rem; color: var(--text-muted); font-size: 0.75rem; } .volume-slider { width: 80px; accent-color: var(--accent); cursor: pointer; } /* ========================================================= AFFILIATE SECTION ========================================================= */ .affiliate-section { display: flex; align-items: center; gap: 1.25rem; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem; margin-bottom: 1.5rem; } .affiliate-artwork { width: 80px; height: 80px; object-fit: cover; border-radius: var(--radius); flex-shrink: 0; background: var(--bg-alt); } .affiliate-info { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; } .affiliate-track { font-size: 1rem; font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .affiliate-artist { font-size: 0.85rem; color: var(--text-muted); } .affiliate-album { font-size: 0.8rem; color: var(--text-muted); font-style: italic; } .btn-amazon { display: inline-block; margin-top: 0.5rem; background: #ff9900; color: #000; padding: 0.3rem 0.8rem; border-radius: var(--radius); font-weight: bold; font-size: 0.8rem; } .btn-amazon:hover { background: #ffad33; color: #000; text-decoration: none; } /* ========================================================= TABS ========================================================= */ .tabs { display: flex; border-bottom: 1px solid var(--border); margin-bottom: 1.25rem; gap: 0; } .tab-btn { background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-muted); cursor: pointer; font-family: var(--font); font-size: 0.9rem; padding: 0.5rem 1.25rem; transition: color 0.15s, border-color 0.15s; } .tab-btn:hover { color: var(--text); } .tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); } .tab-panel { min-height: 200px; } /* ========================================================= SEARCH ========================================================= */ .search-bar { display: flex; gap: 0.5rem; margin-bottom: 1rem; } .search-input { flex: 1; background: transparent; border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); font-family: var(--font); font-size: 0.9rem; padding: 0.4rem 0.7rem; outline: none; } .search-input:focus { border-color: var(--accent); } .status-msg { color: var(--text-muted); font-size: 0.85rem; min-height: 1.4em; margin-bottom: 0.5rem; } /* ========================================================= TABLES ========================================================= */ .data-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; } .data-table th { background: var(--bg-alt); border-bottom: 1px solid var(--border); color: var(--text-muted); font-weight: normal; padding: 0.45rem 0.7rem; text-align: left; } .data-table td { padding: 0.4rem 0.7rem; border-bottom: 1px solid var(--border); vertical-align: middle; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .data-table tbody tr:nth-child(odd) { background: transparent; } .data-table tbody tr:nth-child(even) { background: transparent; } .data-table tbody tr:hover { background: rgba(255, 255, 255, 0.05); } .empty-msg { color: var(--text-muted); text-align: center; padding: 1.5rem !important; } .history-time { color: var(--text-muted); font-size: 0.75rem; white-space: nowrap; } /* ========================================================= BUTTONS ========================================================= */ .btn { background: transparent; border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); cursor: pointer; font-family: var(--font); font-size: 0.85rem; padding: 0.35rem 0.75rem; transition: background 0.1s, border-color 0.1s; white-space: nowrap; } .btn:hover { background: rgba(255, 255, 255, 0.07); border-color: #444; } .btn-play { background: var(--accent); border-color: var(--accent); color: #fff; font-size: 0.9rem; padding: 0.4rem 1rem; } .btn-play:hover { background: var(--accent-hover); border-color: var(--accent-hover); } .btn-play.playing { background: #333; border-color: #555; color: var(--text); } .btn-save { color: var(--yellow); border-color: #444; } .btn-save:hover { background: #2a2a00; border-color: var(--yellow); } .btn-sm { font-size: 0.78rem; padding: 0.25rem 0.5rem; } .btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; } .btn-primary:hover { background: var(--accent-hover); } .btn-danger { background: #300; border-color: #700; color: #faa; } .btn-danger:hover { background: #500; border-color: #a00; color: #fff; } .btn-lastfm { background: #d51007; border-color: #d51007; color: #fff; display: inline-block; padding: 0.4rem 1rem; border-radius: var(--radius); font-family: var(--font); font-size: 0.9rem; cursor: pointer; border: 1px solid transparent; } .btn-lastfm:hover { background: #ff1a0e; color: #fff; text-decoration: none; } .btn-full { width: 100%; padding: 0.55rem; font-size: 0.95rem; } .btn-link { background: none; border: none; color: var(--accent); cursor: pointer; font-family: var(--font); font-size: 1rem; padding: 0; } .btn-link:hover { color: var(--accent-hover); text-decoration: underline; } .btn-icon { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 1rem; padding: 0; line-height: 1; } .btn-icon.active { color: var(--yellow); } .btn-icon:hover { color: var(--yellow); } .inline-form { display: inline; } /* ========================================================= AUTH FORMS ========================================================= */ .auth-container { max-width: 400px; margin: 3rem auto; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); padding: 2rem; } .auth-title { font-size: 1.4rem; margin-bottom: 1.5rem; color: var(--text); } .auth-form { display: flex; flex-direction: column; gap: 1rem; } .form-group { display: flex; flex-direction: column; gap: 0.25rem; } .form-label { font-size: 0.85rem; color: var(--text-muted); } .auth-form input[type="text"], .auth-form input[type="password"], .auth-form input[type="email"] { background: var(--bg-alt); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); font-family: var(--font); font-size: 0.9rem; padding: 0.45rem 0.7rem; outline: none; width: 100%; } .auth-form input:focus { border-color: var(--accent); } .field-errors { list-style: none; color: var(--accent); font-size: 0.8rem; } .form-errors { color: var(--accent); font-size: 0.85rem; background: #1a0000; border: 1px solid #500; border-radius: var(--radius); padding: 0.5rem 0.75rem; } .field-help { color: var(--text-muted); font-size: 0.75rem; } .auth-switch { margin-top: 1.25rem; font-size: 0.85rem; color: var(--text-muted); text-align: center; } /* ========================================================= SETTINGS ========================================================= */ .settings-container { max-width: 600px; margin: 2rem auto; } .settings-title { font-size: 1.4rem; margin-bottom: 1.5rem; } .settings-section { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.25rem; margin-bottom: 1.25rem; } .settings-section h2 { font-size: 1rem; color: var(--text-muted); margin-bottom: 1rem; text-transform: uppercase; letter-spacing: 0.08em; } .lastfm-description { color: var(--text-muted); font-size: 0.85rem; margin-bottom: 0.75rem; } .connected-status { margin-bottom: 0.75rem; font-size: 0.9rem; } .checkbox-label { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; font-size: 0.9rem; } .auth-prompt { color: var(--text-muted); padding: 1.5rem 0; } /* ========================================================= RESPONSIVE ========================================================= */ /* ========================================================= RECOMMENDATIONS ========================================================= */ .recommendations-section { padding: 12px 16px 4px; border-bottom: 1px solid #222; } .recommendations-context { font-size: 0.75rem; color: var(--fg); margin: 0 0 8px; text-transform: uppercase; letter-spacing: 0.05em; } .recommendations-list { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 8px; } .recommendations-list li { display: flex; align-items: center; gap: 6px; } .muted { color: var(--fg); font-size: 0.8rem; } @media (max-width: 600px) { .main-content { padding: 0.75rem 0.75rem calc(var(--bar-h) + 1.5rem); } .now-playing-bar { flex-direction: column; height: auto; padding: 0.5rem 0.75rem; gap: 0.4rem; } .now-playing-info { width: 100%; } .now-playing-controls { width: 100%; justify-content: space-between; } .volume-slider { width: 60px; } .affiliate-section { flex-direction: column; align-items: flex-start; } .data-table th:nth-child(3), .data-table td:nth-child(3), .data-table th:nth-child(4), .data-table td:nth-child(4) { display: none; } .auth-container { margin: 1rem; padding: 1.25rem; } } .import-bar { padding: 8px 16px; display: flex; align-items: center; gap: 10px; border-bottom: 1px solid #1a1a1a; } /* ========================================================= TIMER WIDGET ========================================================= */ .timer-widget { display: flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; margin-left: 8px; } .timer-phase { font-size: 0.7rem; color: var(--fg); text-transform: uppercase; letter-spacing: 0.05em; width: 36px; text-align: right; } .timer-display { font-size: 1rem; font-weight: 600; letter-spacing: 0.05em; min-width: 48px; } /* ========================================================= DO NOT DISTURB / FOCUS MODE ========================================================= */ body.dnd-mode .navbar, body.dnd-mode .tabs, body.dnd-mode .tab-panel, body.dnd-mode .affiliate-section { display: none !important; } body.dnd-mode .now-playing-bar { position: fixed; inset: 0; height: 100vh; flex-direction: column; justify-content: center; align-items: center; gap: 24px; background: transparent; z-index: 9999; } body.dnd-mode.dnd-dark .now-playing-bar { background: #000; } .dnd-only { display: none; } body.dnd-mode .dnd-only { display: inline; } body.dnd-mode .now-playing-info { text-align: center; flex-direction: column; gap: 12px; } body.dnd-mode .now-playing-station { font-size: 1.6rem; } body.dnd-mode .now-playing-track { font-size: 1rem; color: var(--fg); } body.dnd-mode .timer-display { font-size: 3.5rem; } /* ========================================================= MOOD CHIPS ========================================================= */ .mood-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 16px; border-bottom: 1px solid #1a1a1a; } .mood-chip { background: transparent; border: 1px solid #333; color: #ccc; border-radius: 999px; padding: 3px 12px; font-size: 0.78rem; cursor: pointer; transition: background 0.15s, border-color 0.15s; } .mood-chip:hover { background: rgba(255, 255, 255, 0.05); border-color: #555; } .focus-today { font-size: 0.72rem; color: var(--fg); margin-left: 8px; white-space: nowrap; } .curated-lists-container { padding: 12px 16px 0; } .curated-section { margin-bottom: 16px; } .curated-label { font-size: 0.75rem; color: var(--fg); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; } .curated-stations { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; } .curated-stations li { display: flex; align-items: center; gap: 8px; } .curated-name { font-size: 0.85rem; color: var(--fg); } .btn-delete-history { background: none; border: none; color: var(--muted, #888); cursor: pointer; font-size: 0.75rem; padding: 0 4px; opacity: 0.5; } .btn-delete-history:hover { opacity: 1; color: #e55; }