From 3fc96eb1013f1502871e7e3d0c16994b33d88ff7 Mon Sep 17 00:00:00 2001 From: Guus Ekkelenkamp Date: Tue, 2 Jun 2026 13:58:27 +0200 Subject: [PATCH] =?UTF-8?q?fix(ui):=20distinct=20color=20per=20confidence?= =?UTF-8?q?=20level=20(4=20=E2=89=A0=205,=202=20=E2=89=A0=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Confidence 4 and 5 rendered identical green (both "hoog"), and 1/2 identical red, so the badge number was the only difference. Give each level its own shade along a green → amber → red gradient in both the timeline blocks and the leftover sidebar chips: 5 deep green, 4 light green, 3 amber, 2 orange, 1 red. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/ui/components/DayTimeline.tsx | 8 +++++--- src/ui/components/LeftoverSidebar.tsx | 26 ++++++++++++++------------ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/ui/components/DayTimeline.tsx b/src/ui/components/DayTimeline.tsx index d3ed9e7..ed6db55 100644 --- a/src/ui/components/DayTimeline.tsx +++ b/src/ui/components/DayTimeline.tsx @@ -24,10 +24,12 @@ const CONFIDENCE_COLORS: Record<1 | 2 | 3 | 4 | 5, { bg: string; borderStyle: string; borderColor: string; borderLeft: string; titleColor: string; subColor: string; badgeBg: string; badgeColor: string }> = { - 5: { bg: '#f0fdf4', borderStyle: 'solid', borderColor: '#86efac', borderLeft: '#16a34a', titleColor: '#14532d', subColor: '#16a34a', badgeBg: '#dcfce7', badgeColor: '#16a34a' }, - 4: { bg: '#f0fdf4', borderStyle: 'solid', borderColor: '#86efac', borderLeft: '#16a34a', titleColor: '#14532d', subColor: '#16a34a', badgeBg: '#dcfce7', badgeColor: '#16a34a' }, + // Each level gets a distinct shade along a green → amber → red gradient, so + // 5 ≠ 4 and 2 ≠ 1 at a glance (not just in the badge number). + 5: { bg: '#dcfce7', borderStyle: 'solid', borderColor: '#4ade80', borderLeft: '#15803d', titleColor: '#14532d', subColor: '#15803d', badgeBg: '#bbf7d0', badgeColor: '#15803d' }, + 4: { bg: '#f0fdf4', borderStyle: 'solid', borderColor: '#86efac', borderLeft: '#22c55e', titleColor: '#166534', subColor: '#16a34a', badgeBg: '#dcfce7', badgeColor: '#16a34a' }, 3: { bg: '#fffbeb', borderStyle: 'solid', borderColor: '#fcd34d', borderLeft: '#d97706', titleColor: '#78350f', subColor: '#d97706', badgeBg: '#fef3c7', badgeColor: '#d97706' }, - 2: { bg: '#fff1f2', borderStyle: 'dashed', borderColor: '#fca5a5', borderLeft: '#ef4444', titleColor: '#7f1d1d', subColor: '#ef4444', badgeBg: '#fee2e2', badgeColor: '#ef4444' }, + 2: { bg: '#fff7ed', borderStyle: 'dashed', borderColor: '#fdba74', borderLeft: '#ea580c', titleColor: '#7c2d12', subColor: '#ea580c', badgeBg: '#ffedd5', badgeColor: '#ea580c' }, 1: { bg: '#fff1f2', borderStyle: 'dashed', borderColor: '#fca5a5', borderLeft: '#ef4444', titleColor: '#7f1d1d', subColor: '#ef4444', badgeBg: '#fee2e2', badgeColor: '#ef4444' }, } diff --git a/src/ui/components/LeftoverSidebar.tsx b/src/ui/components/LeftoverSidebar.tsx index fddd17a..2f295bc 100644 --- a/src/ui/components/LeftoverSidebar.tsx +++ b/src/ui/components/LeftoverSidebar.tsx @@ -16,19 +16,22 @@ interface Props { readOnly?: boolean } -type Tier = 'high' | 'mid' | 'low' +interface ChipColors { swatch: string; badgeBg: string; badgeColor: string; name: string } -const TIER: Record = { - high: { swatch: '#16a34a', badgeBg: '#dcfce7', badgeColor: '#16a34a', name: '#14532d' }, - mid: { swatch: '#d97706', badgeBg: '#fef3c7', badgeColor: '#d97706', name: '#78350f' }, - low: { swatch: '#ef4444', badgeBg: '#fee2e2', badgeColor: '#ef4444', name: '#7f1d1d' }, +// One distinct shade per confidence level (matches DayTimeline's gradient) so +// 5 ≠ 4 and 2 ≠ 1 at a glance, not just in the badge number. +const CONF_COLORS: Record<1 | 2 | 3 | 4 | 5, ChipColors> = { + 5: { swatch: '#15803d', badgeBg: '#bbf7d0', badgeColor: '#15803d', name: '#14532d' }, + 4: { swatch: '#22c55e', badgeBg: '#dcfce7', badgeColor: '#16a34a', name: '#166534' }, + 3: { swatch: '#d97706', badgeBg: '#fef3c7', badgeColor: '#d97706', name: '#78350f' }, + 2: { swatch: '#ea580c', badgeBg: '#ffedd5', badgeColor: '#ea580c', name: '#7c2d12' }, + 1: { swatch: '#ef4444', badgeBg: '#fee2e2', badgeColor: '#ef4444', name: '#7f1d1d' }, } +const WARN_COLORS: ChipColors = { swatch: '#d97706', badgeBg: '#fef3c7', badgeColor: '#d97706', name: '#d97706' } -function tierFor(block: ClassifiedBlock): Tier { - if (!block.projectId || !block.serviceId) return 'mid' // missing project → amber warn - if (block.confidence >= 4) return 'high' - if (block.confidence === 3) return 'mid' - return 'low' +function colorsFor(block: ClassifiedBlock): ChipColors { + if (!block.projectId || !block.serviceId) return WARN_COLORS // missing project → amber warn + return CONF_COLORS[block.confidence] ?? CONF_COLORS[1] } function reasonLabel(block: ClassifiedBlock): string { @@ -99,8 +102,7 @@ export function LeftoverSidebar({ leftovers, onBook, onDismiss, readOnly = false {/* Chips */}
{leftovers.map(block => { - const tier = tierFor(block) - const t = TIER[tier] + const t = colorsFor(block) const missing = !block.projectId || !block.serviceId const isHovered = hovered === block.urlPattern const showActions = !readOnly && (isHovered || missing)