Skip to content

feat(ui): D.6b UnavailableMeasurementCard → EmptyState - #77

Merged
slittycode merged 1 commit into
mainfrom
claude/ui-restyle-pr10b-dashboard-sections
May 18, 2026
Merged

feat(ui): D.6b UnavailableMeasurementCard → EmptyState#77
slittycode merged 1 commit into
mainfrom
claude/ui-restyle-pr10b-dashboard-sections

Conversation

@slittycode

Copy link
Copy Markdown
Owner

Summary

PR 10 (sub-step b) of 16. Second of three small PRs against MeasurementDashboard.tsx — folds the local UnavailableMeasurementCard into the EmptyState primitive while preserving its (title, description, detail) call-site API.

Changes

  • UnavailableMeasurementCard's body now delegates to <EmptyState tone="neutral" padding="md" ...> with title + description passed through. The optional detail line renders as a children slot (EmptyState's first-class props stop at description; children is the documented escape hatch).
  • The dashed-border + bg-bg-surface-dark visual treatment carries over via className override on EmptyState.
  • The two call sites at :1805 and :1858 are untouched — they continue to call <UnavailableMeasurementCard title=... description=... detail=...> exactly as before.

Deviation from plan §D.6b

The plan flagged bg-blue-500 at :438 as drift to fix → bg-accent. Inspecting the context, that class is one of three colors (bg-red-500 kick / bg-yellow-500 mid / bg-blue-500 high) on a "Beat Dominance" 3-band content visualization stack — the same data-coded vocabulary the plan explicitly protects for spectral content colors (:99-134) and LUFS_METER_GRADIENT. Changing only the blue band to accent would also break the visual coherence of the 3-band stack (warm/neutral/cool). Leaving all three Beat Dominance colors as data-coding to match the protection spirit. The plan's note was likely from a stale grep against a moved/removed call site.

Preserved verbatim

  • UnavailableMeasurementCard's external API (title, description, detail) so call sites don't change.
  • The Beat Dominance band-color visualization at :428/:433/:438 (red/yellow/blue) — treated as data, not chrome.
  • All spectral content colors at :99-134.
  • LUFS_METER_GRADIENT.
  • All data-testid attributes inside the dashboard.

Test plan

  • npm run lint — clean
  • npm run test:unit — 628/628 passing
  • npm run build — clean
  • npm run test:smoke — sandbox blocks Playwright browser; call-site API + data-testids preserved
  • Manual: confirm the two "unavailable measurement" panels (likely Dynamics and Texture when those sub-feeds are absent) still render with dashed border + the same text content

Up next

D.6c — migrate the local SectionHeader at :288-303 to the SectionHeader primitive.

https://claude.ai/code/session_01WNtYcWXwn4mVnnjxqT7uAe


Generated by Claude Code

PR 10 (sub-step b) of 16. Second of three small PRs against
MeasurementDashboard.tsx — folds the local
UnavailableMeasurementCard into the EmptyState primitive while
preserving its (title, description, detail) call-site API.

Changes:
- UnavailableMeasurementCard's body now delegates to <EmptyState
  tone="neutral" padding="md" ...> with title + description passed
  through. The optional `detail` line renders as a children slot
  (EmptyState's first-class props stop at description; children is
  the documented escape hatch).
- The dashed-border + bg-bg-surface-dark visual treatment carries
  over via className override on EmptyState.
- The two call sites at :1805 and :1858 are untouched — they continue
  to call <UnavailableMeasurementCard title=... description=...
  detail=...> exactly as before.

Deviation from plan §D.6b: the plan flagged `bg-blue-500` at :438 as
drift to fix → bg-accent. Inspecting the context, that class is one
of three colors (bg-red-500 kick / bg-yellow-500 mid / bg-blue-500
high) on a "Beat Dominance" 3-band content visualization stack — the
same data-coded vocabulary the plan explicitly protects for spectral
content colors (:99-134) and LUFS_METER_GRADIENT. Changing only the
blue band to accent would also break the visual coherence of the
3-band stack (warm/neutral/cool). Leaving all three Beat Dominance
colors as data-coding to match the protection spirit. The plan's
note was likely from a stale grep against a moved/removed call site.

Preserved verbatim:
- UnavailableMeasurementCard's external API (title, description,
  detail) so call sites don't change.
- The Beat Dominance band-color visualization at :428/:433/:438
  (red/yellow/blue) — treated as data, not chrome.
- All spectral content colors at :99-134.
- LUFS_METER_GRADIENT.
- All data-testid attributes inside the dashboard.

Verified: lint clean, 628/628 unit tests passing, build clean.

Next: D.6c — migrate the local SectionHeader at :288-303 to the
SectionHeader primitive.

https://claude.ai/code/session_01WNtYcWXwn4mVnnjxqT7uAe
@slittycode
slittycode merged commit abcfaec into main May 18, 2026
2 of 3 checks passed
@slittycode
slittycode deleted the claude/ui-restyle-pr10b-dashboard-sections branch May 18, 2026 23:29

@slittycode slittycode left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: COMMENT

Summary

Pure UI refactor — UnavailableMeasurementCard now delegates its rendering to the EmptyState primitive while keeping its (title, description, detail) call-site API intact. No Phase 1/2/3 logic is touched. Tests pass (645/649, 4 pre-existing skips). The deviation decision on Beat Dominance colors is sound. One issue worth flagging before merge.

Findings

Should fix: EmptyState's base classes introduce silent visual changes the PR description doesn't account for

The PR says "the dashed-border + bg-bg-surface-dark visual treatment carries over via className override." The background and border-color do carry over — cn() + tailwind-merge handles those correctly. But EmptyState's CVA base string is flex flex-col items-center justify-center gap-2 rounded-sm border text-center, which introduces changes the className override does not and cannot suppress:

  • Text alignment: text-center forced by the base. The original rendered left-aligned text. For dashboard "unavailable" cards this is a visible layout shift.
  • Layout model: flex flex-col items-center justify-center vs the original block div. Content is now vertically centered in the card, not top-anchored.
  • Title: EmptyState hardcodes text-[11px] text-text-primary (MeasurementDashboard.tsx:47). Original was text-[10px] text-text-secondary — 1px larger and a color step up toward primary.
  • Description: EmptyState drops the tracking-[0.14em] and opacity modifier (text-text-secondary/80text-text-secondary) and adds leading-snug max-w-prose.
  • Spacing: space-y-3 (12px) → gap-2 (8px).

If these changes are intentional "leveling up" to the canonical primitive — fine, that's a reasonable restyle decision. But the PR description presents this as a "preserved verbatim" visual treatment and doesn't mention any of it, which will make the next person reading git blame confused about why the card looks different.

Either: (a) explicitly note the changes in the PR description as intentional visual alignment, or (b) add className overrides to suppress the EmptyState defaults that don't match the original (particularly text-center and the title's text-text-primary).

Test results

645 passed / 4 skipped (pre-existing). No failures.

Phase boundary check

Clean. No Phase 1, 2, or 3 code touched.


Generated by Claude Code

slittycode pushed a commit that referenced this pull request May 18, 2026
PR 14 of 16 in the UI consistency overhaul. Final cleanup pass.

Removes three CSS utility classes from index.css:
- .ableton-panel
- .ableton-device
- .ableton-header

All three were retired by D.* migrations — every former consumer now
uses the canonical primitives from components/ui/ (Panel, DeviceRack,
SectionHeader). `grep -rn` against apps/ui/src/ confirms zero
remaining usages.

.ableton-shell and .ableton-toolbar STAY because App.tsx:952,956 still
consumes them for the outer app chrome (the load-bearing
section-grid shell). A focused follow-up could migrate those two to
DeviceRack / a future AppShell primitive; out of scope here.

Deferred (preserved as-is):
- components/MeasurementPrimitives.tsx cannot be fully deleted yet —
  5 consumers still depend on timeline/lane primitives (LaneContainer,
  LaneRow, StatsBar, TimeRuler) that the plan explicitly preserved.
  The shipped primitives (StatusBadge, DeltaBadge, MetricBar,
  MetricBarRow, OutlinePillButton, TokenBadgeList, StyledDataTable,
  AccentMetricCard) also still have consumers in MeasurementDashboard
  and AnalysisResults sections that weren't migrated (StructureLanes,
  HarmonyLanes, AnalysisResults remaining sections). Keep the file
  intact.
- components/Tooltip.tsx stays as a re-export shim; the file isn't
  causing any drift and external imports may still target it.

Verified: lint clean, 628/628 unit tests passing, build clean.

D.* migrations summary (all merged or open at time of this PR):
- D.0 Foundation (#64) ✓
- D.1 Primitives complete (#65) ✓
- D.2 SamplePlayback (#66) ✓
- D.3 SignalChain marquee (#67) ✓
- D.4 FileUpload + Input Source (#69) ✓
- D.5a Results header + metric strip (#71) ✓
- D.5b Mix Chain (#73) ✓
- D.5c Patches (#74) ✓
- D.5d Section headers (#75) ✓
- D.6a Dashboard structure (#76) ✓
- D.6b Dashboard sections (#77) ✓
- D.6c Dashboard headers (#78) ✓
- D.7 SessionMusicianPanel + MixDoctorPanel (#79) — open
- D.8 Signal Monitor + SpectrogramViewer drift (#80) — open
- D.9 DenseDawConcept drift (#81) — open
- D.10 Cleanup (this PR) ✓

https://claude.ai/code/session_01WNtYcWXwn4mVnnjxqT7uAe
slittycode added a commit that referenced this pull request May 19, 2026
…82)

PR 14 of 16 in the UI consistency overhaul. Final cleanup pass.

Removes three CSS utility classes from index.css:
- .ableton-panel
- .ableton-device
- .ableton-header

All three were retired by D.* migrations — every former consumer now
uses the canonical primitives from components/ui/ (Panel, DeviceRack,
SectionHeader). `grep -rn` against apps/ui/src/ confirms zero
remaining usages.

.ableton-shell and .ableton-toolbar STAY because App.tsx:952,956 still
consumes them for the outer app chrome (the load-bearing
section-grid shell). A focused follow-up could migrate those two to
DeviceRack / a future AppShell primitive; out of scope here.

Deferred (preserved as-is):
- components/MeasurementPrimitives.tsx cannot be fully deleted yet —
  5 consumers still depend on timeline/lane primitives (LaneContainer,
  LaneRow, StatsBar, TimeRuler) that the plan explicitly preserved.
  The shipped primitives (StatusBadge, DeltaBadge, MetricBar,
  MetricBarRow, OutlinePillButton, TokenBadgeList, StyledDataTable,
  AccentMetricCard) also still have consumers in MeasurementDashboard
  and AnalysisResults sections that weren't migrated (StructureLanes,
  HarmonyLanes, AnalysisResults remaining sections). Keep the file
  intact.
- components/Tooltip.tsx stays as a re-export shim; the file isn't
  causing any drift and external imports may still target it.

Verified: lint clean, 628/628 unit tests passing, build clean.

D.* migrations summary (all merged or open at time of this PR):
- D.0 Foundation (#64) ✓
- D.1 Primitives complete (#65) ✓
- D.2 SamplePlayback (#66) ✓
- D.3 SignalChain marquee (#67) ✓
- D.4 FileUpload + Input Source (#69) ✓
- D.5a Results header + metric strip (#71) ✓
- D.5b Mix Chain (#73) ✓
- D.5c Patches (#74) ✓
- D.5d Section headers (#75) ✓
- D.6a Dashboard structure (#76) ✓
- D.6b Dashboard sections (#77) ✓
- D.6c Dashboard headers (#78) ✓
- D.7 SessionMusicianPanel + MixDoctorPanel (#79) — open
- D.8 Signal Monitor + SpectrogramViewer drift (#80) — open
- D.9 DenseDawConcept drift (#81) — open
- D.10 Cleanup (this PR) ✓

https://claude.ai/code/session_01WNtYcWXwn4mVnnjxqT7uAe

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants