From e441176961e7f0042fac361faa322824832d8fb8 Mon Sep 17 00:00:00 2001 From: Zac Date: Sun, 17 May 2026 19:04:38 -0400 Subject: [PATCH] feat(design): broadcast ops console redesign sweep Confirmed shape brief: ops-console direction, balanced density, blue committed accent, readability emphasized. Design system: surface scale to 5 steps tinted toward hue 266; text contrast lifted (secondary 62->72%, tertiary 44->52, added text-disabled); borders gained faint variant; status tokens renamed semantically (signal-good/warn/bad/idle); typography upgraded (Inter 400/500/600, JetBrains Mono for numerics, new 2xl/3xl/tc scale steps). New components: tc-display timecode classes with blue glow; tally-word with good/warn/bad/rec variants; signal-strip flutter bar with modifiers; chip dense monospaced pill; manifest table styles. Topbar status strip: new js/topbar-strip.js auto-injects a 28px strip on every page with wall clock, page name, live API latency, and system-pulse dot. Per-page: recorders gain live signal-strip above fps line; capture timecode bumped 38->64px with blue glow; ingest drop zone slimmed 200->88px side-by-side layout so manifest gets the real estate. --- services/web-ui/public/capture.html | 11 +- services/web-ui/public/css/common.css | 134 +++++++++++++++++----- services/web-ui/public/index.html | 1 + services/web-ui/public/jobs.html | 1 + services/web-ui/public/js/topbar-strip.js | 56 +++++++++ services/web-ui/public/player.html | 1 + services/web-ui/public/recorders.html | 9 +- services/web-ui/public/upload.html | 18 +-- 8 files changed, 190 insertions(+), 41 deletions(-) create mode 100644 services/web-ui/public/js/topbar-strip.js diff --git a/services/web-ui/public/capture.html b/services/web-ui/public/capture.html index b61892c..ab41fd2 100644 --- a/services/web-ui/public/capture.html +++ b/services/web-ui/public/capture.html @@ -44,17 +44,19 @@ } .timecode-display { - font-size: 38px; - font-weight: 400; + font-family: var(--font-mono); + font-size: 64px; + font-weight: 500; font-variant-numeric: tabular-nums; - letter-spacing: 0.06em; + letter-spacing: 0.05em; color: var(--accent); - font-family: 'SF Mono', 'Consolas', 'Menlo', monospace; + text-shadow: 0 0 18px oklch(55% 0.20 266 / 0.30); line-height: 1; } .timecode-display.inactive { color: var(--text-tertiary); + text-shadow: none; } .timecode-status { @@ -313,6 +315,7 @@
+ + + diff --git a/services/web-ui/public/js/topbar-strip.js b/services/web-ui/public/js/topbar-strip.js new file mode 100644 index 0000000..50dc9cf --- /dev/null +++ b/services/web-ui/public/js/topbar-strip.js @@ -0,0 +1,56 @@ +// Operator status strip mounted at the top of every .main pane. +(function () { + function mount() { + const main = document.querySelector('.main'); + if (!main || main.querySelector('.topbar-strip')) return; + const strip = document.createElement('div'); + strip.className = 'topbar-strip'; + strip.innerHTML = + '' + + 'Z-AMPP' + + '00:00:00' + + '' + + 'Page' + + '' + pageName() + '' + + '' + + 'API' + + '--'; + main.insertBefore(strip, main.firstChild); + tick(); setInterval(tick, 1000); + ping(); setInterval(ping, 10000); + } + function pageName() { + const p = location.pathname.replace(/\.html$/, '').replace(/^\//, ''); + if (!p || p === 'index') return 'Library'; + return p.charAt(0).toUpperCase() + p.slice(1); + } + function tick() { + const n = new Date(); + const hh = String(n.getHours()).padStart(2, '0'); + const mm = String(n.getMinutes()).padStart(2, '0'); + const ss = String(n.getSeconds()).padStart(2, '0'); + const el = document.getElementById('tsNow'); + if (el) el.textContent = hh + ':' + mm + ':' + ss; + } + async function ping() { + const dot = document.getElementById('tsDot'); + const apiEl = document.getElementById('tsApi'); + const t0 = performance.now(); + try { + const r = await fetch('/api/v1/projects', { credentials: 'include', signal: AbortSignal.timeout(4000) }); + const ms = Math.round(performance.now() - t0); + if (r.ok) { + if (dot) { dot.style.background = 'var(--signal-good)'; dot.style.boxShadow = '0 0 8px var(--signal-good)'; } + if (apiEl) apiEl.textContent = ms + ' ms'; + } else { + if (dot) { dot.style.background = 'var(--signal-warn)'; dot.style.boxShadow = '0 0 8px var(--signal-warn)'; } + if (apiEl) apiEl.textContent = 'HTTP ' + r.status; + } + } catch (e) { + if (dot) { dot.style.background = 'var(--signal-bad)'; dot.style.boxShadow = '0 0 8px var(--signal-bad)'; } + if (apiEl) apiEl.textContent = 'offline'; + } + } + if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mount); + else mount(); +})(); diff --git a/services/web-ui/public/player.html b/services/web-ui/public/player.html index 04484c5..6cba698 100644 --- a/services/web-ui/public/player.html +++ b/services/web-ui/public/player.html @@ -305,6 +305,7 @@ + + +