diff --git a/static/index.html b/static/index.html
index 8d8ecfb..3628791 100644
--- a/static/index.html
+++ b/static/index.html
@@ -26,7 +26,7 @@
-
+
diff --git a/static/js/voice-library.js b/static/js/voice-library.js
index fe21c6c..4fb70ac 100644
--- a/static/js/voice-library.js
+++ b/static/js/voice-library.js
@@ -766,9 +766,26 @@ async function runVoiceBenchmarkBatch() {
const total = voices.length;
const aggregate = {benchmarked:0, errors:[], voices:[], text, active_only:true};
const stats = {startedAt: Date.now(), ok: 0, slow: 0, errors: 0, last: ''};
+
+ // Mark targeted rows as pending
+ voices.forEach(v => {
+ const row = document.querySelector(`.vl-row[data-id="${CSS.escape(v.id)}"]`);
+ if (row) {
+ row.classList.remove('benchmarking-active', 'benchmarking-done');
+ row.classList.add('benchmarking-pending');
+ }
+ });
+
setBenchmarkProgress(0, total, 'Starting benchmark...', stats);
for (let i = 0; i < voices.length; i++) {
const voice = voices[i];
+ const row = document.querySelector(`.vl-row[data-id="${CSS.escape(voice.id)}"]`);
+ if (row) {
+ row.classList.remove('benchmarking-pending');
+ row.classList.add('benchmarking-active');
+ row.scrollIntoView({ behavior: 'smooth', block: 'center' });
+ }
+
setBenchmarkProgress(i, total, `Benchmarking ${voice.id}`, stats);
status(`Benchmarking ${voice.id} (${i + 1} / ${total})...`);
try {
@@ -794,8 +811,20 @@ async function runVoiceBenchmarkBatch() {
stats.errors++;
stats.last = `${voice.id}: failed · ${e.message}`;
}
+
+ if (row) {
+ row.classList.remove('benchmarking-active');
+ row.classList.add('benchmarking-done');
+ }
setBenchmarkProgress(i + 1, total, `Finished ${voice.id}`, stats);
}
+
+ // Cleanup any remaining pending rows just in case
+ voices.forEach(v => {
+ const row = document.querySelector(`.vl-row[data-id="${CSS.escape(v.id)}"]`);
+ if (row) row.classList.remove('benchmarking-pending');
+ });
+
setBenchmarkProgress(total, total, 'Benchmark complete', stats);
return aggregate;
}
diff --git a/static/style.css b/static/style.css
index a62d9d8..dea99c0 100644
--- a/static/style.css
+++ b/static/style.css
@@ -1265,6 +1265,15 @@ code { background: var(--panel); border-radius: 4px; padding: 1px 5px; font-fami
}
.vl-row.vl-bulk-selected { background: rgba(37,99,235,.06); }
+/* ── Benchmark statuses ──────────────────────────────────────────────────── */
+.vl-row.benchmarking-pending { background: rgba(245, 158, 11, 0.08); border-color: rgba(245, 158, 11, 0.4); transition: background 0.3s; }
+.vl-row.benchmarking-active { background: rgba(37, 99, 235, 0.12); border-color: var(--accent); box-shadow: 0 0 0 2px rgba(37,99,235,0.2); transition: background 0.3s; }
+.vl-row.benchmarking-done { background: rgba(34, 197, 94, 0.08); border-color: rgba(34, 197, 94, 0.4); transition: background 0.8s; }
+
+[data-theme="dark"] .vl-row.benchmarking-pending { background: rgba(245, 158, 11, 0.15); border-color: rgba(245, 158, 11, 0.5); }
+[data-theme="dark"] .vl-row.benchmarking-active { background: rgba(37, 99, 235, 0.25); box-shadow: 0 0 0 2px rgba(37,99,235,0.4); }
+[data-theme="dark"] .vl-row.benchmarking-done { background: rgba(34, 197, 94, 0.15); border-color: rgba(34, 197, 94, 0.5); }
+
.voice-groups-bar {
display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
padding: 7px 10px; border-bottom: 1px solid var(--border);
@@ -1306,6 +1315,12 @@ code { background: var(--panel); border-radius: 4px; padding: 1px 5px; font-fami
.voices-list-pane .vl-row:last-child { border-bottom: none !important; }
.voices-list-pane .vl-row:hover { background: var(--panel) !important; }
.voices-list-pane .vl-row.vr-selected { background: rgba(37,99,235,.07) !important; border-left-color: var(--accent) !important; }
+.voices-list-pane .vl-row.benchmarking-pending { background: rgba(245, 158, 11, 0.08) !important; border-left-color: rgba(245, 158, 11, 0.8) !important; }
+.voices-list-pane .vl-row.benchmarking-active { background: rgba(37, 99, 235, 0.15) !important; border-left-color: var(--accent) !important; }
+.voices-list-pane .vl-row.benchmarking-done { background: rgba(34, 197, 94, 0.08) !important; border-left-color: rgba(34, 197, 94, 0.8) !important; }
+[data-theme="dark"] .voices-list-pane .vl-row.benchmarking-pending { background: rgba(245, 158, 11, 0.15) !important; }
+[data-theme="dark"] .voices-list-pane .vl-row.benchmarking-active { background: rgba(37, 99, 235, 0.25) !important; }
+[data-theme="dark"] .voices-list-pane .vl-row.benchmarking-done { background: rgba(34, 197, 94, 0.15) !important; }
.voices-list-pane .vl-row.vr-disabled { opacity: .5; }
/* Hide everything except the compact div */
.voices-list-pane .vl-row .vr-main-row,