diff --git a/webui/static/media-player.js b/webui/static/media-player.js
index 6eb0c586..93c99952 100644
--- a/webui/static/media-player.js
+++ b/webui/static/media-player.js
@@ -1038,8 +1038,21 @@ function _npLyricsRenderSynced(lines) {
}
content.innerHTML = lines.map((line, idx) => {
const safe = (line.text || '').replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])) || ' ';
- return `
${safe}
`;
+ return `${safe}
`;
}).join('');
+
+ // Click a line → seek playback to its timestamp (synced lyrics only).
+ content.querySelectorAll('.np-lyrics-line').forEach(el => {
+ el.addEventListener('click', () => {
+ const idx = Number(el.dataset.idx);
+ const line = _npLyricsState.lines[idx];
+ if (!line || !audioPlayer || !isFinite(line.time)) return;
+ try {
+ audioPlayer.currentTime = line.time;
+ if (audioPlayer.paused) audioPlayer.play().catch(() => {});
+ } catch (_) {}
+ });
+ });
}
function _npLyricsRenderPlain(text) {
diff --git a/webui/static/style.css b/webui/static/style.css
index ee2e0184..06260e8a 100644
--- a/webui/static/style.css
+++ b/webui/static/style.css
@@ -48702,9 +48702,11 @@ textarea.enhanced-meta-field-input {
.np-queue-item.active .np-queue-item-title { color: rgb(var(--accent-light-rgb)) !important; }
.np-radio-btn.active, .np-queue-toggle.active { color: rgb(var(--accent-light-rgb)) !important; }
-/* ── Close button + lyrics active line ── */
+/* ── Close button + lyrics (active line + click-to-seek affordance) ── */
.np-close-btn:hover { color: #fff !important; background: rgba(255,255,255,0.1) !important; }
.np-lyrics-line.active { color: rgb(var(--accent-light-rgb)) !important; font-weight: 700 !important; }
+.np-lyrics-line { cursor: pointer; border-radius: 6px; transition: background 0.12s, color 0.12s; }
+.np-lyrics-line:hover { background: rgba(var(--accent-rgb),0.10); color: rgb(var(--accent-light-rgb)); }
/* ── Crafted entrance: controls stagger-fade in when modal opens ──
(Art container is intentionally excluded — its transform is reserved for the