fix(ui): add dark mode variants to dashboard, layout, notification and chargeability components

Add missing dark: class variants for backgrounds, borders, and text across
dashboard widgets, AppShell sidebar, notification cards, and the chargeability
report table. Replace hardcoded slate/gray hex values with CSS variable
references. Fix chargeability hover tint and remove ineffective sticky thead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 09:20:50 +02:00
parent 2a91257e69
commit 9ba49c9ab8
9 changed files with 46 additions and 42 deletions
@@ -539,10 +539,10 @@ export function ChargeabilityReportClient() {
return (
<tr
key={r.id}
className="cursor-pointer transition-colors hover:bg-gray-50/90 dark:hover:bg-gray-800/50"
className="cursor-pointer transition-colors hover:bg-gray-50/90 dark:hover:bg-[rgb(var(--surface-elevated)/0.5)]"
onClick={() => setExpandedResource(expandedResource === r.id ? null : r.id)}
>
<td className="sticky left-0 z-10 bg-white/95 px-4 py-3 backdrop-blur dark:bg-slate-950/95">
<td className="sticky left-0 z-10 bg-white/95 px-4 py-3 backdrop-blur dark:bg-[rgb(var(--surface-card)/0.97)]">
<div className="font-semibold text-gray-900 dark:text-gray-100">{r.displayName}</div>
<div className="mt-1 text-xs text-gray-500 dark:text-gray-400">
{[r.eid, formatLocation(r), r.orgUnit].filter(Boolean).join(" · ")}
@@ -574,8 +574,8 @@ export function ChargeabilityReportClient() {
function renderExpandedRow(r: ResourceRow) {
if (expandedResource !== r.id) return null;
return (
<tr key={`${r.id}-detail`} className="bg-gray-50/80 dark:bg-slate-900/70">
<td className="sticky left-0 z-10 bg-gray-50/95 px-4 py-3 backdrop-blur dark:bg-slate-900/95" colSpan={3}>
<tr key={`${r.id}-detail`} className="bg-gray-50/80 dark:bg-[rgb(var(--surface-elevated)/0.7)]">
<td className="sticky left-0 z-10 bg-gray-50/95 px-4 py-3 backdrop-blur dark:bg-[rgb(var(--surface-elevated)/0.97)]" colSpan={3}>
<div className="space-y-1 text-xs text-gray-500 dark:text-gray-400">
<div>Mgmt: {r.mgmtGroup ?? "—"} / {r.mgmtLevel ?? "—"}</div>
<div>Calendar basis: {formatLocation(r)}</div>
@@ -592,7 +592,7 @@ export function ChargeabilityReportClient() {
</td>
{r.months.map((m) => (
<td key={m.monthKey} className="px-3 py-3 text-center">
<div className="grid grid-cols-1 gap-1 rounded-xl bg-white/70 px-2 py-2 text-[10px] text-gray-500 shadow-sm dark:bg-slate-950/40 dark:text-gray-400">
<div className="grid grid-cols-1 gap-1 rounded-xl bg-white/70 px-2 py-2 text-[10px] text-gray-500 shadow-sm dark:bg-[rgb(var(--surface-elevated)/0.6)] dark:text-gray-400">
<span className="font-semibold text-green-600 dark:text-green-400">{pct(monthChargeabilityRatio(m))}</span>
<span>{pct(monthBusinessDevelopmentRatio(m))}</span>
<span>{pct(monthMarketDevelopmentInnovationRatio(m))}</span>
@@ -629,7 +629,7 @@ export function ChargeabilityReportClient() {
) {
const bg = isOverall
? "bg-brand-50/90 dark:bg-brand-900/25"
: "bg-slate-100/90 dark:bg-slate-800/70";
: "bg-slate-100/90 dark:bg-[rgb(var(--surface-elevated)/0.7)]";
return (
<tr
className={`${bg} font-semibold ${onClick ? "cursor-pointer" : ""}`}
@@ -849,29 +849,29 @@ export function ChargeabilityReportClient() {
</div>
<div className="mt-4 grid gap-4 lg:grid-cols-3">
<div className="rounded-2xl border border-gray-200/80 bg-gray-50/70 p-3 dark:border-gray-800 dark:bg-slate-900/60">
<div className="rounded-2xl border border-gray-200/80 bg-gray-50/70 p-3 dark:border-gray-700/60 dark:bg-gray-800/50">
<div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-gray-500">Location basis</div>
<div className="mt-2 flex flex-wrap gap-2">
{data.explainability.locationFields.map((field) => (
<span key={field} className="rounded-full border border-gray-200 bg-white px-2 py-1 text-xs text-gray-600 dark:border-gray-700 dark:bg-slate-950 dark:text-gray-300">
<span key={field} className="rounded-full border border-gray-200 bg-white px-2 py-1 text-xs text-gray-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300">
{toTitleLabel(field)}
</span>
))}
</div>
</div>
<div className="rounded-2xl border border-gray-200/80 bg-gray-50/70 p-3 dark:border-gray-800 dark:bg-slate-900/60">
<div className="rounded-2xl border border-gray-200/80 bg-gray-50/70 p-3 dark:border-gray-700/60 dark:bg-gray-800/50">
<div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-gray-500">Month derivation</div>
<div className="mt-2 flex flex-wrap gap-2">
{data.explainability.monthDerivationFields.map((field) => (
<span key={field} className="rounded-full border border-gray-200 bg-white px-2 py-1 text-xs text-gray-600 dark:border-gray-700 dark:bg-slate-950 dark:text-gray-300">
<span key={field} className="rounded-full border border-gray-200 bg-white px-2 py-1 text-xs text-gray-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300">
{toTitleLabel(field)}
</span>
))}
</div>
</div>
<div className="rounded-2xl border border-gray-200/80 bg-gray-50/70 p-3 dark:border-gray-800 dark:bg-slate-900/60">
<div className="rounded-2xl border border-gray-200/80 bg-gray-50/70 p-3 dark:border-gray-700/60 dark:bg-gray-800/50">
<div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-gray-500">Active filters</div>
<div className="mt-2 flex flex-wrap gap-2">
{data.explainability.activeFilters.length > 0 ? data.explainability.activeFilters.map((field) => (
@@ -879,7 +879,7 @@ export function ChargeabilityReportClient() {
{toTitleLabel(field)}
</span>
)) : (
<span className="rounded-full border border-gray-200 bg-white px-2 py-1 text-xs text-gray-500 dark:border-gray-700 dark:bg-slate-950 dark:text-gray-400">
<span className="rounded-full border border-gray-200 bg-white px-2 py-1 text-xs text-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400">
none
</span>
)}
@@ -913,8 +913,8 @@ export function ChargeabilityReportClient() {
<div className="overflow-x-auto">
<table className="min-w-full text-sm">
<thead>
<tr>
<th className="sticky left-0 z-10 min-w-[240px] bg-gray-50/95 px-4 py-3 text-left backdrop-blur dark:bg-gray-800/95">
<tr className="bg-gray-50 dark:bg-[rgb(var(--surface-elevated))]">
<th className="sticky left-0 z-10 min-w-[240px] bg-gray-50 px-4 py-3 text-left dark:bg-[rgb(var(--surface-elevated))]">
Resource
</th>
<th className="w-20 px-3 py-3 text-center"><span className="inline-flex items-center justify-center gap-0.5">FTE<InfoTooltip content="Full-Time Equivalent. 1.0 = full-time, 0.5 = half-time. Used to weight chargeability averages." /></span></th>