From b8bc3f1f04aa36d2258f18428c7eb8c9e41574e4 Mon Sep 17 00:00:00 2001 From: slitty-codes Date: Tue, 19 May 2026 17:33:15 +1200 Subject: [PATCH] fix(ui): unify MeasurementDashboard sub-boxes onto canonical tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces 18 hex-literal sub-box className pairs in MeasurementDashboard.tsx with the canonical design tokens defined in `apps/ui/src/index.css` (`bg-bg-surface-dark` + `border-border`/`border-border-light`). The numbered section wrappers were migrated to DeviceRack in #76/#77/#78, but the inner sub-boxes still carried 7 distinct background shades (`#101010` / `#111111` / `#121212` / `#141414` / `#15120b`) and 6 distinct border shades (`#1e1e1e` / `#202020` / `#232323` / `#242424` / `#2a2416` / `#2e2614`). These all collapse onto the canonical token pair, so the dashboard reads coherently inside the new DeviceRack and stays in sync with future token tweaks. Five outliers preserved (semantic-distinct tones, not generic panels): the "Assumed 4/4" amber chip, the unselected toggle off-state, the groove and tempo-stability progress-bar tracks, and the Swing-tile inner bar track. Verified: `npm run lint` clean, 645 Vitest tests pass, `npm run build` clean. Visual review deferred to PR — if `#222` reads weak inside the DeviceRack `#444` gradient, the same 8 substring edits can be re-run with `bg-bg-surface-darker` (`#1a1a1a`) instead. Co-Authored-By: Claude Opus 4.7 --- .../src/components/MeasurementDashboard.tsx | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/apps/ui/src/components/MeasurementDashboard.tsx b/apps/ui/src/components/MeasurementDashboard.tsx index b5e31587..827a68d5 100644 --- a/apps/ui/src/components/MeasurementDashboard.tsx +++ b/apps/ui/src/components/MeasurementDashboard.tsx @@ -527,7 +527,7 @@ const BreathingBpmPulse = ({ bpm, bpmSource }: { bpm: number; bpmSource?: string initial={{ opacity: 0, scale: 0.9 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 0.5 }} - className="flex min-h-[188px] w-full shrink-0 items-center justify-center rounded-sm border border-[#1e1e1e] bg-[#141414] px-4 py-5 shadow-[inset_0_1px_0_rgba(255,255,255,0.03)] md:w-[176px]" + className="flex min-h-[188px] w-full shrink-0 items-center justify-center rounded-sm border border-border bg-bg-surface-dark px-4 py-5 shadow-[inset_0_1px_0_rgba(255,255,255,0.03)] md:w-[176px]" > @@ -668,7 +668,7 @@ const ComparativeMetricTile = ({ initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.4, delay }} - className="bg-[#141414] border border-[#1e1e1e] rounded-sm p-3" + className="bg-bg-surface-dark border border-border rounded-sm p-3" > { return (
@@ -836,7 +836,7 @@ const RhythmGridPanel = ({ phase1 }: { phase1: Phase1Result }) => {
{barNumber} @@ -847,7 +847,7 @@ const RhythmGridPanel = ({ phase1 }: { phase1: Phase1Result }) => {
{lanes.map((lane) => (
-
+
{ return (
= 0.7 ? 'heavy' : resolvedStrength >= 0.4 ? 'moderate' : 'subtle'; return ( -
+
Sidechain Envelope @@ -995,7 +995,7 @@ const SidechainEnvelope = ({
-
+
Confidence @@ -1003,7 +1003,7 @@ const SidechainEnvelope = ({ {Math.round(resolvedConfidence * 100)}%
-
+
Regularity @@ -1049,7 +1049,7 @@ const EffectsFieldPanel = ({ const pulseCells = Array.from({ length: 16 }, (_, index) => index % pulseStride === 0); return ( -
+
@@ -1066,7 +1066,7 @@ const EffectsFieldPanel = ({ {pulseCells.map((active, index) => (
-
+
Gate Events @@ -1090,7 +1090,7 @@ const EffectsFieldPanel = ({ {gatingEventCount ?? 'n/a'}
-
+
Gate Regularity @@ -1113,7 +1113,7 @@ const EffectsFieldPanel = ({ ]; return ( -
+
@@ -1163,7 +1163,7 @@ const PhraseStructureTimeline = ({ phraseGrid }: { phraseGrid: PhraseGrid }) => ]; return ( -
+
Phrase Structure @@ -2330,7 +2330,7 @@ export function MeasurementDashboard({
{phase1.grooveDetail && ( -
+
Swing
@@ -2369,7 +2369,7 @@ export function MeasurementDashboard({
)} {phase1.beatsLoudness && ( -
+
Sidechain & Effects -
+