diff --git a/webui/index.html b/webui/index.html
index bdef4cfa..ca63d727 100644
--- a/webui/index.html
+++ b/webui/index.html
@@ -7033,6 +7033,10 @@
+
+ Playing from
+
+
No track
Unknown Artist
Unknown Album
diff --git a/webui/static/media-player.js b/webui/static/media-player.js
index 23072eab..b030f509 100644
--- a/webui/static/media-player.js
+++ b/webui/static/media-player.js
@@ -222,6 +222,7 @@ function clearTrack() {
// Clear track state
currentTrack = null;
isPlaying = false;
+ npSetPlayContext(''); // hide "Playing from" when nothing's playing
const trackTitleElement = document.getElementById('track-title');
trackTitleElement.innerHTML = '
No track';
@@ -1466,6 +1467,13 @@ function npSetRadioMode(enabled, options = {}) {
if (toast) {
showToast(npRadioMode ? 'Radio mode on - similar tracks will auto-queue' : 'Radio mode off', 'success');
}
+ // Context label: only set the generic "Radio" if a more specific one (e.g.
+ // "
Radio") wasn't already set by the caller.
+ if (npRadioMode) {
+ if (!npPlayContext || !/radio/i.test(npPlayContext)) npSetPlayContext('Radio');
+ } else if (/radio/i.test(npPlayContext)) {
+ npSetPlayContext('');
+ }
if (npRadioMode && fetchIfNeeded && currentTrack && currentTrack.id && !npLoadingQueueItem && !npQueueHasNext()) {
npEnsureCurrentTrackInQueue();
npFetchRadioTracks();
@@ -2114,6 +2122,21 @@ function handleNpRepeat() {
// QUEUE MANAGEMENT
// ===============================
+// "Playing from" context shown above the track title (Spotify-style).
+let npPlayContext = '';
+function npSetPlayContext(text) {
+ npPlayContext = text || '';
+ const box = document.getElementById('np-play-context');
+ const nameEl = document.getElementById('np-play-context-name');
+ if (!box || !nameEl) return;
+ if (npPlayContext) {
+ nameEl.textContent = npPlayContext;
+ box.classList.remove('hidden');
+ } else {
+ box.classList.add('hidden');
+ }
+}
+
function addToQueue(track) {
npQueue.push(track);
showToast('Added to queue', 'success');
diff --git a/webui/static/stats-automations.js b/webui/static/stats-automations.js
index 37f1d51d..b46cbd1c 100644
--- a/webui/static/stats-automations.js
+++ b/webui/static/stats-automations.js
@@ -4757,6 +4757,9 @@ async function playArtistRadio() {
// Enable radio mode + immediately seed the queue with similar tracks —
// same path the modal's Radio button uses (fetchIfNeeded also adds the
// current track to the queue first).
+ if (typeof npSetPlayContext === 'function') {
+ npSetPlayContext(`${artistName || 'Artist'} Radio`);
+ }
if (typeof npSetRadioMode === 'function') {
npSetRadioMode(true, { toast: false, fetchIfNeeded: true });
} else {
diff --git a/webui/static/style.css b/webui/static/style.css
index 7ee3be99..020a9264 100644
--- a/webui/static/style.css
+++ b/webui/static/style.css
@@ -48664,6 +48664,18 @@ textarea.enhanced-meta-field-input {
box-shadow: 0 30px 92px rgba(0,0,0,0.66), 0 12px 40px rgba(var(--accent-rgb),0.28) !important;
}
+/* ── "Playing from" context label (above the title) ── */
+.np-play-context { display: flex; align-items: center; gap: 7px; margin-bottom: 10px; }
+.np-play-context.hidden { display: none; }
+.np-play-context-label {
+ font-size: 10px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
+ color: rgba(255,255,255,0.32);
+}
+.np-play-context-name {
+ font-size: 12px; font-weight: 700; color: rgb(var(--accent-light-rgb));
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px;
+}
+
/* ── Track meta ── */
.np-track-info { text-align: left !important; }
.np-track-title { font-size: 28px !important; font-weight: 800 !important; letter-spacing: -0.02em !important; line-height: 1.1 !important; }