/* RangerHQ Tuner — New Tab Page. Full-viewport landing that replaces Chrome's default new tab. Same earthy palette as the popup, but laid out as a focal page (player centered + quick stations + browsable list). */ :root { --bg: #0f1411; --bg-soft: #1a221c; --bg-row: #1f2823; --bg-row-hi: #2a3530; --fg: #e8e4d4; --fg-muted: #97a094; --accent: #6dbf7a; --accent-dim: #2a7d3e; --cream: #f4e9b7; --danger: #c9685b; --radius: 8px; --maxw: 760px; --watermark-opacity: 0.025; } /* ────────────────────────────────────────────────────────────────────── Light mode (v0.5.0) — auto-follows OS theme. Same approach as popup: override :root vars so every existing rule using var(--*) keeps working unchanged. Watermark opacity bumped slightly since the helmet contrasts more against light bg. ────────────────────────────────────────────────────────────────────── */ /* OS-follow light mode */ @media (prefers-color-scheme: light) { :root { --bg: #f6f4ed; --bg-soft: #ece5d2; --bg-row: #ddd6c0; --bg-row-hi: #c8c0a8; --fg: #2a2f28; --fg-muted: #6a7064; --accent: #2a7d3e; --accent-dim: #6dbf7a; --cream: #b8861a; --danger: #b53a2b; --watermark-opacity: 0.04; } .nt-state-pill[data-state="playing"] { color: #fff; } .nt-state-pill[data-state="buffering"] { color: #fff; } .nt-state-pill[data-state="error"] { color: #fff; } .nt-btn--primary[aria-pressed="true"] { color: #fff; } } /* Manual override — force LIGHT */ html[data-theme="light"] { --bg: #f6f4ed; --bg-soft: #ece5d2; --bg-row: #ddd6c0; --bg-row-hi: #c8c0a8; --fg: #2a2f28; --fg-muted: #6a7064; --accent: #2a7d3e; --accent-dim: #6dbf7a; --cream: #b8861a; --danger: #b53a2b; --watermark-opacity: 0.04; } html[data-theme="light"] .nt-state-pill[data-state="playing"] { color: #fff; } html[data-theme="light"] .nt-state-pill[data-state="buffering"] { color: #fff; } html[data-theme="light"] .nt-state-pill[data-state="error"] { color: #fff; } html[data-theme="light"] .nt-btn--primary[aria-pressed="true"] { color: #fff; } /* Manual override — force DARK */ html[data-theme="dark"] { --bg: #0f1411; --bg-soft: #1a221c; --bg-row: #1f2823; --bg-row-hi: #2a3530; --fg: #e8e4d4; --fg-muted: #97a094; --accent: #6dbf7a; --accent-dim: #2a7d3e; --cream: #f4e9b7; --danger: #c9685b; --watermark-opacity: 0.025; } html[data-theme="dark"] .nt-state-pill[data-state="playing"] { color: var(--bg); } html[data-theme="dark"] .nt-state-pill[data-state="buffering"] { color: var(--bg); } html[data-theme="dark"] .nt-state-pill[data-state="error"] { color: var(--cream); } html[data-theme="dark"] .nt-btn--primary[aria-pressed="true"] { color: var(--bg); } * { box-sizing: border-box; } html, body { margin: 0; padding: 0; width: 100%; min-height: 100vh; background: var(--bg); color: var(--fg); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; } /* Subtle background watermark — the helmet, very faint */ body::before { content: ""; position: fixed; inset: 0; background-image: url('../assets/img/ranger.png'); background-repeat: no-repeat; background-position: center; background-size: min(60vh, 600px); opacity: var(--watermark-opacity); pointer-events: none; z-index: 0; } /* Everything else sits on top */ .nt-header, .nt-main, .nt-footer { position: relative; z-index: 1; } /* ========== Header ========== */ .nt-header { display: flex; justify-content: space-between; align-items: center; padding: 18px 28px; border-bottom: 1px solid var(--bg-soft); } .nt-brand { display: flex; align-items: center; gap: 10px; } .nt-helmet { width: 26px; height: 26px; object-fit: contain; } .nt-brand-name { font-size: 14px; font-weight: 600; letter-spacing: 0.4px; } .nt-clock { text-align: right; } .nt-time { font-size: 22px; font-weight: 600; letter-spacing: 1px; font-variant-numeric: tabular-nums; display: inline-flex; align-items: baseline; gap: 4px; } .nt-secs { font-size: 13px; font-weight: 500; color: var(--fg-muted); letter-spacing: 0.5px; } .nt-date { font-size: 11px; color: var(--fg-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; } /* ========== Main ========== */ .nt-main { max-width: var(--maxw); margin: 0 auto; padding: 40px 28px 28px; display: flex; flex-direction: column; gap: 28px; } /* Now playing — large + centered */ .nt-now { text-align: center; padding: 24px 0 8px; } .nt-station { font-size: 26px; font-weight: 600; letter-spacing: 0.2px; margin-bottom: 6px; } .nt-track { font-size: 15px; color: var(--fg-muted); min-height: 1.4em; margin-bottom: 16px; } .nt-state-pill { display: inline-block; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; padding: 4px 12px; border-radius: 999px; background: var(--bg-row); color: var(--fg-muted); } .nt-state-pill[data-state="playing"] { background: var(--accent); color: var(--bg); } .nt-state-pill[data-state="buffering"] { background: var(--cream); color: var(--bg); } .nt-state-pill[data-state="error"] { background: var(--danger); color: var(--cream); } /* Controls — generous click targets */ .nt-controls { display: flex; justify-content: center; align-items: center; gap: 16px; padding: 10px 0; } .nt-btn { font-size: 15px; font-weight: 500; padding: 10px 22px; border: 1px solid var(--accent-dim); border-radius: var(--radius); background: var(--bg-row); color: var(--fg); cursor: pointer; } .nt-btn:hover:not(:disabled) { background: var(--bg-row-hi); } .nt-btn:disabled { opacity: 0.4; cursor: not-allowed; } .nt-btn--primary { background: var(--accent-dim); min-width: 120px; } .nt-btn--primary[aria-pressed="true"] { background: var(--accent); color: var(--bg); } .nt-vol-wrap { display: flex; align-items: center; gap: 8px; min-width: 240px; } .nt-vol-label { font-size: 11px; color: var(--fg-muted); letter-spacing: 1px; text-transform: uppercase; } #nt-volume { flex: 1; accent-color: var(--accent); } /* Quick stations — chip row */ .nt-quick { border-top: 1px solid var(--bg-soft); padding-top: 18px; } .nt-quick-label { font-size: 11px; color: var(--fg-muted); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 10px; } .nt-quick-list { display: flex; flex-wrap: wrap; gap: 8px; } .nt-quick-chip { font-size: 12px; padding: 6px 12px; border: 1px solid var(--bg-row-hi); border-radius: 999px; background: var(--bg-row); color: var(--fg); cursor: pointer; white-space: nowrap; } .nt-quick-chip:hover { background: var(--bg-row-hi); border-color: var(--accent-dim); } .nt-quick-chip.is-active { background: var(--accent); color: var(--bg); border-color: var(--accent); } .nt-quick-empty { font-size: 12px; color: var(--fg-muted); } /* ========== Tabs (Stations / History / Favourites) ========== */ .nt-tabs { border-top: 1px solid var(--bg-soft); padding-top: 18px; } .nt-tab-bar { display: flex; align-items: center; gap: 4px; margin-bottom: 12px; border-bottom: 1px solid var(--bg-soft); } .nt-tab { font-size: 12px; font-weight: 500; padding: 8px 14px; background: transparent; color: var(--fg-muted); border: 0; border-bottom: 2px solid transparent; cursor: pointer; font-family: inherit; text-decoration: none; } .nt-tab:hover { color: var(--fg); } .nt-tab.is-active { color: var(--fg); border-bottom-color: var(--accent); } .nt-tab--link { margin-left: auto; font-size: 16px; padding: 6px 10px; line-height: 1; border-bottom: none; } .nt-tab--link:hover { color: var(--accent); } .nt-tab-pane[hidden] { display: none; } .nt-pane-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; } .nt-pane-count { font-size: 11px; color: var(--fg-muted); text-transform: uppercase; letter-spacing: 0.5px; } .nt-pane-action { font-size: 11px; padding: 4px 10px; background: var(--bg-row); color: var(--fg-muted); border: 1px solid var(--bg-row-hi); border-radius: 4px; cursor: pointer; } .nt-pane-action:hover { color: var(--danger); border-color: var(--danger); } /* ========== Track list (History + Favourites) ========== */ .nt-track-list { margin: 0; padding: 0; list-style: none; max-height: 380px; overflow-y: auto; border: 1px solid var(--bg-soft); border-radius: var(--radius); } .nt-track-row { display: grid; grid-template-columns: 1fr auto; gap: 8px 14px; padding: 10px 14px; border-bottom: 1px solid var(--bg-soft); } .nt-track-row:last-child { border-bottom: none; } .nt-track-row:hover { background: var(--bg-row); } .nt-track-main { min-width: 0; } .nt-track-title { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .nt-track-artist { font-size: 12px; color: var(--accent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .nt-track-meta { font-size: 10px; color: var(--fg-muted); letter-spacing: 0.3px; margin-top: 2px; } .nt-track-controls { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; } .nt-fav-btn { background: transparent; border: 1px solid var(--bg-row-hi); border-radius: 999px; width: 26px; height: 26px; cursor: pointer; color: var(--fg-muted); font-size: 14px; line-height: 1; padding: 0; } .nt-fav-btn:hover { color: var(--cream); border-color: var(--cream); } .nt-fav-btn[aria-pressed="true"] { color: var(--cream); border-color: var(--cream); background: rgba(244, 233, 183, 0.08); } .nt-search-row { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 5px; padding-top: 4px; } .nt-search-link { font-size: 10px; font-weight: 600; padding: 3px 8px; border-radius: 3px; text-decoration: none; color: var(--fg); letter-spacing: 0.3px; border: 1px solid transparent; text-transform: uppercase; } /* Service-specific brand-leaning colours — kept muted so they don't shout */ .nt-search-link--spotify { background: #1ed76015; color: #1ed760; border-color: #1ed76040; } .nt-search-link--youtube { background: #ff000015; color: #ff5a5a; border-color: #ff5a5a40; } .nt-search-link--apple { background: #fa57c115; color: #fa57c1; border-color: #fa57c140; } .nt-search-link--bandcamp { background: #629aa915; color: #6dbdd0; border-color: #6dbdd040; } .nt-search-link:hover { filter: brightness(1.3); } .nt-track-empty { padding: 28px 16px; text-align: center; color: var(--fg-muted); font-size: 12px; } /* (Legacy alias — older code referenced .nt-browse for the bottom section. Keep here in case any styles bleed through during transition.) */ .nt-browse { border-top: 1px solid var(--bg-soft); padding-top: 18px; } .nt-search-wrap { display: block; margin-bottom: 10px; } #nt-search { width: 100%; padding: 10px 12px; font-size: 13px; background: var(--bg-row); color: var(--fg); border: 1px solid var(--bg-row-hi); border-radius: var(--radius); } #nt-search:focus { outline: none; border-color: var(--accent); } .nt-station-list { margin: 0; padding: 0; list-style: none; max-height: 320px; overflow-y: auto; border: 1px solid var(--bg-soft); border-radius: var(--radius); } .nt-station-row { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--bg-soft); cursor: pointer; } .nt-station-row:last-child { border-bottom: none; } .nt-station-row:hover { background: var(--bg-row); } .nt-station-row.is-active { background: var(--bg-row-hi); border-left: 3px solid var(--accent); padding-left: 11px; } .nt-station-art { width: 32px; height: 32px; border-radius: 4px; background: var(--bg-soft); flex-shrink: 0; object-fit: cover; } .nt-station-meta { flex: 1; min-width: 0; } .nt-station-name { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .nt-station-genre { font-size: 11px; color: var(--fg-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* ========== Footer ========== */ .nt-footer { max-width: var(--maxw); margin: 0 auto; padding: 20px 28px 28px; text-align: center; font-size: 11px; color: var(--fg-muted); display: flex; justify-content: center; align-items: center; gap: 8px; flex-wrap: wrap; } .nt-footer a { color: var(--fg-muted); text-decoration: none; border-bottom: 1px dotted var(--bg-row-hi); } .nt-footer a:hover { color: var(--accent); border-bottom-color: var(--accent); } .nt-dot { opacity: 0.5; } /* Scrollbar — subtle */ .nt-station-list::-webkit-scrollbar { width: 8px; } .nt-station-list::-webkit-scrollbar-thumb { background: var(--bg-row-hi); border-radius: 4px; } .nt-station-list::-webkit-scrollbar-track { background: transparent; } /* Tighter spacing on smaller windows */ @media (max-height: 700px) { .nt-main { padding-top: 24px; gap: 18px; } .nt-now { padding: 12px 0 4px; } .nt-station { font-size: 22px; } .nt-station-list { max-height: 220px; } } /* ────────────────────────────────────────────────────────────────────── First-run UX hint (v0.4.0) Subtle accent-green pulse around the Quick Stations row + a bouncing ↓ arrow on the now-playing area. Both disappear the moment a station is picked. Existing users never see them. ────────────────────────────────────────────────────────────────────── */ @keyframes nt-pulse-glow { 0%, 100% { box-shadow: 0 0 0 0 rgba(109, 191, 122, 0); } 50% { box-shadow: 0 0 0 6px rgba(109, 191, 122, 0.18); } } @keyframes nt-bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(4px); } } body.is-first-run .nt-quick { animation: nt-pulse-glow 2.4s ease-in-out infinite; border-radius: var(--radius); padding: 14px; margin: 0 -14px; } body.is-first-run .nt-track { color: var(--accent); font-weight: 500; } body.is-first-run .nt-track::after { content: " ↓"; display: inline-block; animation: nt-bounce 1.8s ease-in-out infinite; margin-left: 6px; }