feat(ui): light/dark theme toggle and light mode color support

Add ThemeContext with localStorage persistence and FOUC-preventing
inline script. Add theme toggle button in sidebar. Update status
badges, toast notifications, live indicators, and approval cards
with dark: prefixed classes for proper light mode rendering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Forgotten
2026-02-26 16:33:29 -06:00
parent e2c5b6698c
commit 5cd12dec89
13 changed files with 245 additions and 92 deletions

View File

@@ -165,16 +165,16 @@ export function ApprovalDetail() {
return (
<div className="space-y-6 max-w-3xl">
{showApprovedBanner && (
<div className="border border-green-700/40 bg-green-900/20 rounded-lg px-4 py-3 animate-in fade-in zoom-in-95 duration-300">
<div className="border border-green-300 dark:border-green-700/40 bg-green-50 dark:bg-green-900/20 rounded-lg px-4 py-3 animate-in fade-in zoom-in-95 duration-300">
<div className="flex items-start justify-between gap-3">
<div className="flex items-start gap-2">
<div className="relative mt-0.5">
<CheckCircle2 className="h-4 w-4 text-green-300" />
<Sparkles className="h-3 w-3 text-green-200 absolute -right-2 -top-1 animate-pulse" />
<CheckCircle2 className="h-4 w-4 text-green-600 dark:text-green-300" />
<Sparkles className="h-3 w-3 text-green-500 dark:text-green-200 absolute -right-2 -top-1 animate-pulse" />
</div>
<div>
<p className="text-sm text-green-100 font-medium">Approval confirmed</p>
<p className="text-xs text-green-200/90">
<p className="text-sm text-green-800 dark:text-green-100 font-medium">Approval confirmed</p>
<p className="text-xs text-green-700 dark:text-green-200/90">
Requesting agent was notified to review this approval and linked issues.
</p>
</div>
@@ -182,7 +182,7 @@ export function ApprovalDetail() {
<Button
size="sm"
variant="outline"
className="border-green-600/50 text-green-100 hover:bg-green-900/30"
className="border-green-400 dark:border-green-600/50 text-green-800 dark:text-green-100 hover:bg-green-100 dark:hover:bg-green-900/30"
onClick={() => navigate(resolvedCta.to)}
>
{resolvedCta.label}

View File

@@ -455,10 +455,10 @@ export function DesignGuide() {
<SubSection title="Run invocation badges">
<div className="flex items-center gap-2 flex-wrap">
{[
["timer", "bg-blue-900/50 text-blue-300"],
["assignment", "bg-violet-900/50 text-violet-300"],
["on_demand", "bg-cyan-900/50 text-cyan-300"],
["automation", "bg-neutral-800 text-neutral-400"],
["timer", "bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-300"],
["assignment", "bg-violet-100 text-violet-700 dark:bg-violet-900/50 dark:text-violet-300"],
["on_demand", "bg-cyan-100 text-cyan-700 dark:bg-cyan-900/50 dark:text-cyan-300"],
["automation", "bg-muted text-muted-foreground"],
].map(([label, cls]) => (
<span key={label} className={`rounded-full px-1.5 py-0.5 text-[10px] font-medium ${cls}`}>
{label}

View File

@@ -185,7 +185,7 @@ function FailedRunCard({
<div className="min-w-0 flex-1">
<div className="flex items-center gap-2">
<span className="rounded-md bg-red-500/20 p-1.5">
<XCircle className="h-4 w-4 text-red-400" />
<XCircle className="h-4 w-4 text-red-600 dark:text-red-400" />
</span>
{linkedAgentName ? (
<Identity name={linkedAgentName} size="sm" />
@@ -586,7 +586,7 @@ export function Inbox() {
to={`/issues/${issue.identifier ?? issue.id}`}
className="flex cursor-pointer items-center gap-3 px-4 py-3 transition-colors hover:bg-accent/50 no-underline text-inherit"
>
<UserCheck className="h-4 w-4 shrink-0 text-blue-400" />
<UserCheck className="h-4 w-4 shrink-0 text-blue-600 dark:text-blue-400" />
<PriorityIcon priority={issue.priority} />
<StatusIcon status={issue.status} />
<span className="text-xs font-mono text-muted-foreground">
@@ -719,7 +719,7 @@ export function Inbox() {
to="/agents"
className="flex cursor-pointer items-center gap-3 px-4 py-3 transition-colors hover:bg-accent/50 no-underline text-inherit"
>
<AlertTriangle className="h-4 w-4 shrink-0 text-red-400" />
<AlertTriangle className="h-4 w-4 shrink-0 text-red-600 dark:text-red-400" />
<span className="text-sm">
<span className="font-medium">{dashboard!.agents.error}</span>{" "}
{dashboard!.agents.error === 1 ? "agent has" : "agents have"} errors