[object Object]

← back to Ventura Corridor

feat(coverage): per-type accept-rate mini-bars in idea-loop section

df2073dae9b0879b2aff254c15e3c4042ed9d23d · 2026-05-07 22:54:36 -0700 · SteveStudio2

Replaces the one-line stats string with a grid: type / horizontal bar
showing accept share / "N/total · pct%" label. Shows the bias the panel
has toward "connection" ideas (6/21 = 40%) vs renames (1/11 = 9%) vs
products/automations/kills.

Pure client-side render — same /api/ideas/stats endpoint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit df2073dae9b0879b2aff254c15e3c4042ed9d23d
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Thu May 7 22:54:36 2026 -0700

    feat(coverage): per-type accept-rate mini-bars in idea-loop section
    
    Replaces the one-line stats string with a grid: type / horizontal bar
    showing accept share / "N/total · pct%" label. Shows the bias the panel
    has toward "connection" ideas (6/21 = 40%) vs renames (1/11 = 9%) vs
    products/automations/kills.
    
    Pure client-side render — same /api/ideas/stats endpoint.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 public/coverage.html | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/public/coverage.html b/public/coverage.html
index 3f29571..89c9f9f 100644
--- a/public/coverage.html
+++ b/public/coverage.html
@@ -161,13 +161,28 @@ async function load() {
   renderBars(d.by_vertical, document.getElementById('vert'));
   renderBars(d.by_city, document.getElementById('city'));
 
-  // Idea-loop stats line
+  // Idea-loop stats — text line + per-type accept-rate mini-bars
   try {
     const stats = await fetch('/api/ideas/stats').then(r => r.json());
     const pct = (stats.accept_rate * 100).toFixed(1);
-    const types = Object.entries(stats.accepted_by_type || {}).map(([k,v]) => k + ':' + v).join(' · ');
-    document.getElementById('idea-stats').textContent =
-      `${stats.accepted} accepted · ${stats.rejected} rejected · ${pct}% accept rate${types ? ' · by type: ' + types : ''}`;
+    const acc = stats.accepted_by_type || {};
+    const rej = stats.rejected_by_type || {};
+    const types = [...new Set([...Object.keys(acc), ...Object.keys(rej)])].sort();
+    const bars = types.map(t => {
+      const a = acc[t] || 0, r = rej[t] || 0, tot = a + r;
+      const rate = tot ? (a / tot * 100) : 0;
+      const aw = tot ? (a / tot * 100).toFixed(1) : 0;
+      return `<div style="display:grid;grid-template-columns:90px 1fr 90px;gap:8px;align-items:center;font-size:10px;letter-spacing:.12em;color:var(--ink-mute);text-transform:uppercase;padding:3px 0">
+        <span>${t}</span>
+        <div style="height:10px;background:#2a2622;position:relative">
+          <div style="position:absolute;left:0;top:0;bottom:0;width:${aw}%;background:linear-gradient(90deg,var(--metal),var(--metal-glow))"></div>
+        </div>
+        <span style="font-family:var(--mono);text-align:right">${a}/${tot} · ${rate.toFixed(0)}%</span>
+      </div>`;
+    }).join('');
+    document.getElementById('idea-stats').innerHTML =
+      `<div style="margin-bottom:8px;font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute)">${stats.accepted} accepted · ${stats.rejected} rejected · ${pct}% accept rate</div>` +
+      bars;
   } catch(e) {}
 
   // Idea-loop feed

← faa570d feat(coverage): /api/ideas/stats + accept-rate line on /cove  ·  back to Ventura Corridor  ·  feat(news): "Hot only" toggle on /news.html filter bar 4927f54 →