fix(ui): remove blue-shifted hardcoded colors from timeline components

Replace hardcoded blue-shifted rgba values and slate-* classes with neutral
CSS variable references in timeline resource/project panels, tooltips,
constants, and heatmap mono palette. Change utilization row tint from blue
to green. Replace slate-950 open demand backgrounds with --surface-card.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 10:46:41 +02:00
parent 60d89a1bc8
commit 5afc6c8c94
5 changed files with 19 additions and 19 deletions
@@ -556,11 +556,11 @@ function TimelineProjectPanelInner({
data-project-resource-row="true" data-project-resource-row="true"
data-project-id={row.project.id} data-project-id={row.project.id}
data-resource-id={row.resource.id} data-resource-id={row.resource.id}
className="flex border-b border-gray-100 dark:border-gray-800 hover:bg-blue-50/20 dark:hover:bg-gray-800/30 group" className="flex border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50/40 dark:hover:bg-[rgb(var(--surface-elevated)/0.3)] group"
style={{ height: ROW_HEIGHT }} style={{ height: ROW_HEIGHT }}
> >
<div <div
className="flex-shrink-0 border-r border-gray-200 dark:border-gray-700 flex items-center pl-8 pr-4 gap-2 bg-white dark:bg-gray-900 sticky left-0 z-30 group-hover:bg-blue-50 dark:group-hover:bg-gray-800" className="flex-shrink-0 border-r border-gray-200 dark:border-gray-700 flex items-center pl-8 pr-4 gap-2 bg-white dark:bg-[rgb(var(--surface-card))] sticky left-0 z-30 group-hover:bg-gray-50 dark:group-hover:bg-[rgb(var(--surface-elevated))]"
style={{ width: LABEL_WIDTH }} style={{ width: LABEL_WIDTH }}
> >
<div className="w-6 h-6 rounded-full bg-gray-100 dark:bg-gray-700 flex items-center justify-center text-[10px] font-bold text-gray-600 dark:text-gray-300 flex-shrink-0"> <div className="w-6 h-6 rounded-full bg-gray-100 dark:bg-gray-700 flex items-center justify-center text-[10px] font-bold text-gray-600 dark:text-gray-300 flex-shrink-0">
@@ -708,14 +708,14 @@ function renderOpenDemandRow(
<div <div
data-project-demand-row="true" data-project-demand-row="true"
data-project-id={projectId} data-project-id={projectId}
className="group relative isolate flex border-b border-dashed border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-slate-950 hover:bg-amber-100/80 dark:hover:bg-slate-900" className="group relative isolate flex border-b border-dashed border-amber-200 bg-amber-50 dark:border-amber-800 dark:bg-[rgb(var(--surface-card))] hover:bg-amber-100/80 dark:hover:bg-[rgb(var(--surface-elevated))]"
style={{ height: rowHeight }} style={{ height: rowHeight }}
> >
<div <div
className="sticky left-0 z-30 flex flex-shrink-0 items-center gap-2 border-r border-amber-200 bg-amber-50 pl-8 pr-4 dark:border-amber-800 dark:bg-slate-950" className="sticky left-0 z-30 flex flex-shrink-0 items-center gap-2 border-r border-amber-200 bg-amber-50 pl-8 pr-4 dark:border-amber-800 dark:bg-[rgb(var(--surface-card))]"
style={{ width: LABEL_WIDTH, height: rowHeight }} style={{ width: LABEL_WIDTH, height: rowHeight }}
> >
<div className="pointer-events-none absolute inset-0 bg-amber-50 dark:bg-slate-950" /> <div className="pointer-events-none absolute inset-0 bg-amber-50 dark:bg-[rgb(var(--surface-card))]" />
<div className="relative z-10 flex items-center gap-2 min-w-0"> <div className="relative z-10 flex items-center gap-2 min-w-0">
<div className="w-6 h-6 rounded-full bg-amber-100 dark:bg-amber-900/50 flex items-center justify-center text-[10px] font-bold text-amber-600 dark:text-amber-400 flex-shrink-0 border border-dashed border-amber-400 dark:border-amber-600"> <div className="w-6 h-6 rounded-full bg-amber-100 dark:bg-amber-900/50 flex items-center justify-center text-[10px] font-bold text-amber-600 dark:text-amber-400 flex-shrink-0 border border-dashed border-amber-400 dark:border-amber-600">
? ?
@@ -730,7 +730,7 @@ function renderOpenDemandRow(
</div> </div>
<div <div
className="relative overflow-hidden bg-amber-50 touch-none dark:bg-slate-950" className="relative overflow-hidden bg-amber-50 touch-none dark:bg-[rgb(var(--surface-card))]"
style={{ width: totalCanvasWidth, height: rowHeight }} style={{ width: totalCanvasWidth, height: rowHeight }}
onMouseLeave={onClearHoverTooltips} onMouseLeave={onClearHoverTooltips}
> >
@@ -416,7 +416,7 @@ function TimelineResourcePanelInner({
const utilBg = utilPct > 100 const utilBg = utilPct > 100
? "rgba(254,202,202,0.18)" // red tint for over-utilized ? "rgba(254,202,202,0.18)" // red tint for over-utilized
: utilPct >= 50 : utilPct >= 50
? `rgba(59,130,246,${Math.min(0.06 + (utilPct - 50) * 0.0014, 0.12)})` // faint blue tint scaling 50-100% ? `rgba(34,197,94,${Math.min(0.04 + (utilPct - 50) * 0.001, 0.08)})` // faint green tint scaling 50-100%
: undefined; : undefined;
return ( return (
@@ -434,7 +434,7 @@ function TimelineResourcePanelInner({
> >
<div <div
className={clsx( className={clsx(
"flex border-b border-gray-100 dark:border-gray-800 hover:bg-blue-50/20 dark:hover:bg-gray-800/30 group transition-colors", "flex border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50/40 dark:hover:bg-[rgb(var(--surface-elevated)/0.3)] group transition-colors",
dragState.isDragging && isContextResource && "border-l-4 border-l-brand-400", dragState.isDragging && isContextResource && "border-l-4 border-l-brand-400",
)} )}
style={{ height: rowHeight, ...(utilBg ? { backgroundColor: utilBg } : {}) }} style={{ height: rowHeight, ...(utilBg ? { backgroundColor: utilBg } : {}) }}
@@ -442,7 +442,7 @@ function TimelineResourcePanelInner({
{/* Label column */} {/* Label column */}
<div <div
className={clsx( className={clsx(
"flex-shrink-0 border-r border-gray-200 dark:border-gray-700 flex items-center px-4 gap-2.5 bg-white dark:bg-gray-900 sticky left-0 z-30 group-hover:bg-blue-50 dark:group-hover:bg-gray-800", "flex-shrink-0 border-r border-gray-200 dark:border-gray-700 flex items-center px-4 gap-2.5 bg-white dark:bg-[rgb(var(--surface-card))] sticky left-0 z-30 group-hover:bg-gray-50 dark:group-hover:bg-[rgb(var(--surface-elevated))]",
dragState.isDragging && isContextResource && "bg-brand-50 dark:bg-brand-950/40", dragState.isDragging && isContextResource && "bg-brand-50 dark:bg-brand-950/40",
)} )}
style={{ width: LABEL_WIDTH }} style={{ width: LABEL_WIDTH }}
@@ -285,7 +285,7 @@ export function TimelineTooltip({
tooltipRef={demandTooltipRef} tooltipRef={demandTooltipRef}
dataTestId="timeline-demand-tooltip" dataTestId="timeline-demand-tooltip"
position={demandTooltipPos} position={demandTooltipPos}
backgroundColor="rgba(3, 7, 18, 0.96)" backgroundColor="rgba(10, 10, 10, 0.96)"
className="fixed z-40 max-w-sm pointer-events-none rounded-xl border border-gray-800 bg-gray-950/96 px-3 py-2 text-xs text-white shadow-2xl" className="fixed z-40 max-w-sm pointer-events-none rounded-xl border border-gray-800 bg-gray-950/96 px-3 py-2 text-xs text-white shadow-2xl"
> >
<div className="flex items-start justify-between gap-3"> <div className="flex items-start justify-between gap-3">
@@ -359,7 +359,7 @@ export function TimelineTooltip({
(vacationTooltipRef as React.MutableRefObject<HTMLDivElement | null>).current = null; (vacationTooltipRef as React.MutableRefObject<HTMLDivElement | null>).current = null;
}} }}
position={heatmapTooltipPos} position={heatmapTooltipPos}
backgroundColor="rgba(3, 7, 18, 0.96)" backgroundColor="rgba(10, 10, 10, 0.96)"
className="fixed z-40 max-w-sm pointer-events-none rounded-xl border border-gray-800 bg-gray-950/96 px-3 py-2 text-xs text-white shadow-2xl" className="fixed z-40 max-w-sm pointer-events-none rounded-xl border border-gray-800 bg-gray-950/96 px-3 py-2 text-xs text-white shadow-2xl"
> >
<div className="flex items-center justify-between gap-3"> <div className="flex items-center justify-between gap-3">
@@ -388,7 +388,7 @@ export function TimelineTooltip({
<TooltipSurface <TooltipSurface
tooltipRef={heatmapTooltipRef} tooltipRef={heatmapTooltipRef}
position={heatmapTooltipPos} position={heatmapTooltipPos}
backgroundColor="rgba(3, 7, 18, 0.96)" backgroundColor="rgba(10, 10, 10, 0.96)"
className="fixed z-40 max-w-sm pointer-events-none rounded-xl border border-gray-800 bg-gray-950/96 px-3 py-2 text-xs text-white shadow-2xl" className="fixed z-40 max-w-sm pointer-events-none rounded-xl border border-gray-800 bg-gray-950/96 px-3 py-2 text-xs text-white shadow-2xl"
> >
<div className="flex items-center justify-between gap-3"> <div className="flex items-center justify-between gap-3">
@@ -32,12 +32,12 @@ export const HEATMAP_PALETTES: Record<HeatmapColorScheme, [number, string, strin
[125, "rgba(109,40,217,0.64)", "rgba(109,40,217,0.88)"], [125, "rgba(109,40,217,0.64)", "rgba(109,40,217,0.88)"],
], ],
"mono": [ "mono": [
[0, "rgba(156,163,175,0.18)", "rgba(156,163,175,0.60)"], [0, "rgba(160,160,160,0.18)", "rgba(160,160,160,0.60)"],
[25, "rgba(107,114,128,0.25)", "rgba(107,114,128,0.68)"], [25, "rgba(115,115,115,0.25)", "rgba(115,115,115,0.68)"],
[50, "rgba(75,85,99,0.30)", "rgba(75,85,99,0.74)"], [50, "rgba(85,85,85,0.30)", "rgba(85,85,85,0.74)"],
[75, "rgba(55,65,81,0.36)", "rgba(55,65,81,0.80)"], [75, "rgba(65,65,65,0.36)", "rgba(65,65,65,0.80)"],
[90, "rgba(31,41,55,0.42)", "rgba(31,41,55,0.85)"], [90, "rgba(42,42,42,0.42)", "rgba(42,42,42,0.85)"],
[100, "rgba(17,24,39,0.52)", "rgba(17,24,39,0.88)"], [100, "rgba(24,24,24,0.52)", "rgba(24,24,24,0.88)"],
[125, "rgba(0,0,0,0.60)", "rgba(0,0,0,0.90)"], [125, "rgba(0,0,0,0.60)", "rgba(0,0,0,0.90)"],
], ],
}; };
@@ -12,7 +12,7 @@ export const ORDER_TYPE_COLORS: Record<string, { bg: string; text: string; light
CHARGEABLE: { bg: "bg-emerald-500", text: "text-white", light: "bg-emerald-50 border-emerald-200 dark:bg-emerald-950 dark:border-emerald-800" }, CHARGEABLE: { bg: "bg-emerald-500", text: "text-white", light: "bg-emerald-50 border-emerald-200 dark:bg-emerald-950 dark:border-emerald-800" },
INTERNAL: { bg: "bg-blue-500", text: "text-white", light: "bg-blue-50 border-blue-200 dark:bg-blue-950 dark:border-blue-800" }, INTERNAL: { bg: "bg-blue-500", text: "text-white", light: "bg-blue-50 border-blue-200 dark:bg-blue-950 dark:border-blue-800" },
BD: { bg: "bg-violet-500", text: "text-white", light: "bg-violet-50 border-violet-200 dark:bg-violet-950 dark:border-violet-800" }, BD: { bg: "bg-violet-500", text: "text-white", light: "bg-violet-50 border-violet-200 dark:bg-violet-950 dark:border-violet-800" },
OVERHEAD: { bg: "bg-slate-400", text: "text-white", light: "bg-slate-50 border-slate-200 dark:bg-slate-800 dark:border-slate-700" }, OVERHEAD: { bg: "bg-gray-400", text: "text-white", light: "bg-gray-50 border-gray-200 dark:bg-gray-800 dark:border-gray-700" },
}; };
export const ORDER_TYPE_BADGE: Record<string, string> = { export const ORDER_TYPE_BADGE: Record<string, string> = {