Owner: hover-only values were invisible. Now VISIBLE: - Trades panel: Entry + Exit$ columns (projection now carries entry_price/ exit_price; were hidden entirely). - Armed triggers: entry/stop/now levels shown inline (were tooltip-only). UI-REVIEW fix 1 (color): collapsed 3 greens->1 (#34d17e) and dup reds-> canonical #ff5a60 across CSS AND canvas markers (one --green/--red now). UI-REVIEW fix 2 (a11y): :focus-visible outlines on all controls + aria-labels on the money-path buttons (approve/reject/exit/flatten) — keyboard operators were flying blind. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5.8 KiB
UI Review — Momentum Dashboard (api/static/dashboard.html)
Audited: 2026-07-20 · retroactive 6-pillar visual audit (no UI-SPEC exists → audited against abstract standards). Adversarial stance: assume failure until the code proves otherwise. Scores are 1–4, not averaged upward.
Scope: the primary operator dashboard (dashboard.html, ~1600 lines,
single-file inline CSS/JS) plus its siblings backtest.html / admin.html.
Method: static analysis of color/spacing/typography tokens, structure, and
interaction states (the auditor's grep-based method; a headless render pass is
the standing follow-up).
Scorecard
| Pillar | Score | One-line verdict |
|---|---|---|
| 1. Copywriting | 4 | Domain-precise, explains why — not generic |
| 2. Visuals / hierarchy | 3 | Clear strip→panel structure; dense but legible |
| 3. Color | 3 | Real token system, undermined by duplicate semantic colors + 90 hardcoded values |
| 4. Typography | 3 | Sensible mono scale; 9px floor is too small |
| 5. Spacing | 2 | No systematic scale — 20 distinct px values incl. arbitrary 7/9/11/13 |
| 6. Experience design | 4 | Standout — confirm-to-destruct, full empty/loading/error/connection states |
Overall: a genuinely competent, purpose-built operator UI. The failures are consistency-and-accessibility drift, not structural — this is a good dashboard with three fixable rough edges, not a rebuild.
Findings
Pillar 1 — Copywriting · 4
Labels state intent, not just nouns: "closest to fire on top", "why each entry was taken or refused · value → threshold per gate", "held long with no / short protective stop". Empty states teach ("No armed gappers — waiting for the open"). No lorem, no vague "Loading…" without context. No fix needed.
Pillar 2 — Visuals / hierarchy · 3
Strong top-down hierarchy: risk-strip → P&L-strip → collapsible <details>
panels, colour-coded side pills, sparklines, R-bars. Weakness: extreme density
(10–11px body across 51 elements) with little whitespace — correct for a trading
terminal, but the eye has few rest points. WARNING — acceptable for the
audience; revisit if non-expert users are ever a target.
Pillar 3 — Color · 3
Real foundation: 17 CSS custom properties, 149 var(--…) uses, coherent dark
theme, defensible 60/30/10 (bg dominant / panels secondary / #5ba3ff accent on
interactive). But two concrete defects:
- Duplicate semantic colors — THREE greens (
#2fbf71,#2ecc71,#34d17e) and FOUR reds (#e5484d,#ff4d4f,#ff5a60,#ff8589) all meaning "up/good" and "down/bad". These should be one--green/--red(+ one intentional bright variant), not near-identical one-offs. - 90 hardcoded hex values bypass the token system that already exists. WARNING — the system is right; application drifted.
Pillar 4 — Typography · 3
One monospace family (correct for aligned numeric data), a real size ladder (9→27px), weight used for hierarchy. Defect: the 9px floor (4 elements) is below comfortable-read and fails WCAG minimums; 10–11px carries most of the UI, which is tight. WARNING — raise the 9px labels to ≥11px.
Pillar 5 — Spacing · 2 (lowest)
20 distinct padding/margin values including arbitrary 7px, 9px, 11px,
13px with no discernible 4/8 rhythm. Dense layout justifies tightness, not
arbitrariness — the values look hand-tuned per element rather than drawn from a
scale. WARNING — adopt a spacing scale (e.g. 2/4/8/12/16/24) and snap values
to it; the visual result changes little but future edits stay consistent.
Pillar 6 — Experience design · 4 (standout)
This is where the dashboard earns its keep:
- Confirm-to-destruct: EXIT/FLATTEN/PAUSE use an arm-then-confirm pattern
(
armButton, 8 sites) — no accidental market flatten. - Full state coverage: 38 loading/loader refs, 20 explicit empty states, 7 error/connection-lost handlers ("stream lost — polling", "render error").
- Resilience: SSE with polling fallback, degrade-gracefully panels.
- 3
@mediabreakpoints — responsive to phone/tablet. No fix needed — this pillar is a model for the rest.
Cross-cutting — Accessibility (drags 2 & 6)
0 ARIA roles/labels, only 2 :focus styles on a dashboard whose buttons
submit real orders (Approve / Reject / EXIT / FLATTEN). Keyboard and
screen-reader users cannot see focus or understand controls. Not a visual defect
but a real usability gap for the money-path controls. WARNING (borderline
BLOCKER for keyboard operators).
Top 3 priority fixes
- Collapse duplicate semantic colors + migrate hardcoded values (Pillar 3).
Define
--green/--red(+ one bright variant each), replace the 3 greens / 4 reds and the 90 hardcoded hex. Highest consistency-per-effort. WARNING. - Add focus + ARIA to money-path controls (Accessibility).
:focus-visibleoutlines andaria-labelon Approve/Reject/EXIT/FLATTEN. A keyboard operator currently flies blind on the destructive buttons. WARNING → BLOCKER for keyboard use. - Adopt a spacing scale (Pillar 5). Snap the 20 ad-hoc px values to a 2/4/8/12/16/24 ladder; raise the 9px type floor to ≥11px. WARNING.
What NOT to touch
Experience design (Pillar 6) and copywriting (Pillar 1) are strengths — don't regress the confirm-to-destruct flow or the explanatory empty states while refactoring color/spacing. The density is a deliberate, correct choice for the trading-terminal audience; do not "add whitespace" reflexively.
No UI-SPEC exists for this project. If the dashboard becomes a maintained
surface, the highest-leverage next step is extracting the existing :root tokens
into a small declared design contract so future changes have a baseline to audit
against — the token system is 80% there already.