Skip to content

feat(ui): distinct color tones for Session Musician confidence bands - #26

Closed
slittycode wants to merge 1 commit into
claude/thirsty-easley-faeaeafrom
claude/confidence-band-tones
Closed

feat(ui): distinct color tones for Session Musician confidence bands#26
slittycode wants to merge 1 commit into
claude/thirsty-easley-faeaeafrom
claude/confidence-band-tones

Conversation

@slittycode

Copy link
Copy Markdown
Owner

Why

PR #22 shipped a four-band confidence ladder (Solid scaffold / Workable draft / Rough sketch / Unreliable), but the PILL_CLASSES map in ConfidenceBandBadge.tsx collapsed them into only two tones — accent for solid + workable, warning for rough + unreliable. A producer couldn't visually distinguish Solid from Workable, or Rough from Unreliable, at a glance.

What changed

Map the four bands to a green → orange → amber → red traffic-light ladder so the visual hierarchy matches the producer's mental model (best to worst at a glance):

Band Range Tone CSS variable
Solid scaffold ≥80% green --color-success: #00ff9d
Workable draft 50–79% orange --color-accent: #ff8800
Rough sketch 25–49% amber --color-warning: #ffb800
Unreliable <25% red --color-error: #ff3333

All four CSS variables already exist in apps/ui/src/index.css. They're the canonical severity vocabulary across MeasurementPrimitives, DiagnosticLog, and FileUpload: success = ready, accent = active, warning = caution, error = critical. No theme additions; no new shades.

Opacity tuning unified at /30 border, /10 bg, text-{color} to match the established BADGE_TONE_CLASSES convention in MeasurementPrimitives.tsx. Color carries the differentiation now — the previous per-band opacity wobble (/40 vs /30, /15 vs /10) wasn't communicating anything.

Override path (full-mix-fallback and legacy)

NoteDraftBlock.tsx passes overrideTone="rough" to <ConfidenceBandBadge> in both the full-mix-fallback and legacy render states. With the new mapping, both override states render as amber — the right tone for "treat with caution, not unreliable junk." No wiring change needed; the existing prop still selects the rough pill class.

Tests

  • New tests/services/confidenceBandBadge.test.ts — 10 tests:
    • Four per-band tests assert each emits the expected color tokens.
    • A pairwise-distinct assertion (unique.size === 4) survives future opacity tweaks — extracts each band's text- color token and confirms no two share.
    • Solid/Unreliable test pins the two ends of the ladder.
    • Two overrideTone="rough" tests lock in the fallback/legacy visual: high-confidence input → warning (not green), low-confidence input → warning (not red).
    • One overrideCopy test confirms copy substitution doesn't accidentally change the pill class.
  • No existing tests touched. confidenceBand.test.ts asserts on id/label/percent (not classes); sessionMusicianPanel.test.ts and smoke tests assert on text. All keep passing.

npm run verify is green: lint + unit (361 total) + build + 46 smoke (1 skipped).

Base

Targets claude/thirsty-easley-faeaea (PR #22), same stacked pattern as PR #23 and PR #24. GitHub will auto-retarget to main once #22 lands.

Plan

~/.claude/plans/re-evaluate-asa-s-session-musician-sharded-balloon.md — "Follow-up plan #1 — Distinct color tones for confidence bands" section.

🤖 Generated with Claude Code

PR #22 shipped a four-band confidence ladder (Solid scaffold / Workable draft
/ Rough sketch / Unreliable) but the PILL_CLASSES map collapsed them into
only two tones — accent for solid + workable, warning for rough + unreliable.
A producer couldn't visually distinguish Solid from Workable, or Rough from
Unreliable, at a glance.

Map the four bands to a green → orange → amber → red traffic-light ladder so
the visual hierarchy matches the producer's mental model ("best to worst at
a glance"):

  Solid scaffold   (≥80%)  → success (#00ff9d green)
  Workable draft   (50-79%) → accent  (#ff8800 orange)
  Rough sketch     (25-49%) → warning (#ffb800 amber)
  Unreliable       (<25%)  → error   (#ff3333 red)

All four CSS variables already exist in apps/ui/src/index.css and are the
canonical severity vocabulary across MeasurementPrimitives, DiagnosticLog,
and FileUpload (success = ready, accent = active, warning = caution,
error = critical). No theme additions; no new shades.

Opacity tuning unified at /30 border, /10 bg, text-{color} to match
MeasurementPrimitives.BADGE_TONE_CLASSES. Color carries the differentiation
now — the previous per-band opacity wobble didn't communicate anything.

NoteDraftBlock's overrideTone="rough" path (used for full-mix-fallback and
legacy render states) now renders amber, which is the right tone for "treat
with caution, not unreliable junk." No wiring change needed.

Tests: new tests/services/confidenceBandBadge.test.ts renders all four
confidence values and asserts each emits the expected color tokens. A
pairwise-distinct assertion survives future opacity tweaks. Two override-path
tests lock in the full-mix-fallback / legacy visual (high-confidence input
with overrideTone="rough" produces warning tokens, not green; low-confidence
input stays warning, not red). No existing tests touched — confidenceBand
asserts id/label/percent (not classes); panel + smoke tests assert on text.

Targets PR #22 (claude/thirsty-easley-faeaea) as the base. Plan in
~/.claude/plans/re-evaluate-asa-s-session-musician-sharded-balloon.md
("Follow-up plan #1" section).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@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: APPROVE

Summary

Pure UI badge-color change: maps the four confidence bands to a traffic-light palette by swapping solid from accent→success and unreliable from warning→error. All four CSS variables (--color-success, --color-accent, --color-warning, --color-error) confirmed present in index.css. Ten new tests cover all four bands individually, pairwise distinctness, and both override paths. No Phase 1 involvement whatsoever.

Findings

No blocking or should-fix findings.

Worth considering: The PR description says opacity is "unified at /30 border" but workable emits border-accent/40 in the actual code. Not a bug — workable inherited the old solid's /40 and the visual distinction is defensible — but the description is slightly inaccurate.

Test results

361 unit tests per the PR; no failures reported. extractColorTokens regex is sound — (?!-)\b correctly excludes text-warning-foo false positives. The pairwise-distinct test (unique.size === 4) is the right guard here: it survives future opacity tweaks without becoming brittle.

Phase boundary check

Clean. ConfidenceBandBadge.tsx accepts confidence: number as an input and uses it only to select a display class. No Phase 1 data read, mutated, or re-derived.


Generated by Claude Code

@slittycode
slittycode deleted the branch claude/thirsty-easley-faeaea May 13, 2026 00:39
@slittycode slittycode closed this May 13, 2026
@slittycode

Copy link
Copy Markdown
Owner Author

Superseded by #27 (rebased onto main and re-opened as a new PR after PR #22 merged caused this one to auto-close).

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.

1 participant