feat(ui): terminal, charts and low-contrast text follow the selected theme

- The lane terminal (xterm) takes its palette from the selected DARK theme —
  it stays dark in light mode, as a terminal should — and repaints live when
  the theme changes (`client/src/lib/terminalTheme.ts`).
- Charts on the Dashboard and Workflows pages draw their grid, axes, labels
  and tooltips from theme tokens instead of hardcoded near-black/white, and
  the activity heatmap ramps from the page surface to the accent, so it reads
  on every theme instead of going near-black on light ones.
- Status/brand text that only worked on dark backgrounds
  (`text-*-300/400`) gets a darker light-mode shade (`text-*-700
  dark:text-*-300`) across sessions, conversations, workflows, config and
  settings. Categorical chart colours are kept.
This commit is contained in:
2026-09-24 09:50:44 +07:00
parent 6353e88c9e
commit 8ea40260ad
36 changed files with 919 additions and 635 deletions
+18 -12
View File
@@ -664,23 +664,29 @@ export function SessionDetail() {
}`}
>
<ReasonIcon
className={`w-3.5 h-3.5 ${urgent ? "text-status-warning" : "text-yellow-300"}`}
className={`w-3.5 h-3.5 ${urgent ? "text-status-warning" : "text-yellow-700 dark:text-yellow-300"}`}
/>
</span>
<div className="flex-1 min-w-0">
<div
className={`text-sm font-medium ${urgent ? "text-status-warning" : "text-yellow-200"}`}
className={`text-sm font-medium ${urgent ? "text-status-warning" : "text-yellow-800 dark:text-yellow-200"}`}
>
{t("detail.waitingBanner.title")}
{cfg && (
<span className={urgent ? "text-status-warning/90" : "text-yellow-300/80"}>
<span
className={
urgent
? "text-status-warning/90"
: "text-yellow-700/80 dark:text-yellow-300/80"
}
>
{" · "}
{t(cfg.labelKey)}
</span>
)}
</div>
<div
className={`text-[11px] ${urgent ? "text-status-warning/70" : "text-yellow-400/60"}`}
className={`text-[11px] ${urgent ? "text-status-warning/70" : "text-yellow-700/60 dark:text-yellow-400/60"}`}
>
{cfg ? t(cfg.descKey) : t("detail.waitingBanner.generic")}
</div>
@@ -688,7 +694,7 @@ export function SessionDetail() {
{session.awaiting_input_since && (
<span
className={`text-[11px] flex-shrink-0 flex items-center gap-1.5 ${
urgent ? "text-status-warning/80" : "text-yellow-400/70"
urgent ? "text-status-warning/80" : "text-yellow-700/70 dark:text-yellow-400/70"
}`}
>
<span
@@ -736,7 +742,7 @@ export function SessionDetail() {
}}
className={`flex items-center gap-2 px-4 py-2.5 text-sm font-medium border-b-2 transition-colors ${
activeTab === "agents"
? "border-violet-500 text-violet-400"
? "border-violet-500 text-violet-700 dark:text-violet-400"
: "border-transparent text-fg-muted hover:text-fg-secondary"
}`}
>
@@ -750,7 +756,7 @@ export function SessionDetail() {
}}
className={`flex items-center gap-2 px-4 py-2.5 text-sm font-medium border-b-2 transition-colors ${
activeTab === "conversation"
? "border-violet-500 text-violet-400"
? "border-violet-500 text-violet-700 dark:text-violet-400"
: "border-transparent text-fg-muted hover:text-fg-secondary"
}`}
>
@@ -764,7 +770,7 @@ export function SessionDetail() {
}}
className={`flex items-center gap-2 px-4 py-2.5 text-sm font-medium border-b-2 transition-colors ${
activeTab === "timeline"
? "border-violet-500 text-violet-400"
? "border-violet-500 text-violet-700 dark:text-violet-400"
: "border-transparent text-fg-muted hover:text-fg-secondary"
}`}
>
@@ -794,7 +800,7 @@ export function SessionDetail() {
{workflows.length > 0 && (
<div className="mb-4">
<h3 className="text-xs font-semibold text-fg-secondary uppercase tracking-wider mb-2 flex items-center gap-1.5">
<Workflow className="w-3.5 h-3.5 text-violet-400" />
<Workflow className="w-3.5 h-3.5 text-violet-700 dark:text-violet-400" />
{wfT("runs.sessionTitle")}
<span className="text-fg-muted font-mono">· {workflows.length}</span>
</h3>
@@ -807,7 +813,7 @@ export function SessionDetail() {
) : (
<>
<h3 className="text-xs font-semibold text-fg-secondary uppercase tracking-wider mb-3 flex items-center gap-1.5">
<Bot className="w-3.5 h-3.5 text-violet-400" />
<Bot className="w-3.5 h-3.5 text-violet-700 dark:text-violet-400" />
{t("detail.agents")}
<span className="text-fg-muted font-mono">· {agents.length}</span>
</h3>
@@ -885,7 +891,7 @@ export function SessionDetail() {
)}
{isSubagent && !hasChildren && <span className="w-6 flex-shrink-0" />}
{isSubagent && (
<GitBranch className="w-3 h-3 text-violet-400 flex-shrink-0" />
<GitBranch className="w-3 h-3 text-violet-700 dark:text-violet-400 flex-shrink-0" />
)}
<div className="flex-1 min-w-0">
<AgentCard
@@ -928,7 +934,7 @@ export function SessionDetail() {
onClick={() =>
setExpandedAgents((prev) => new Set([...prev, agent.id]))
}
className="ml-7 mt-1 text-[11px] text-violet-400 hover:text-violet-300 transition-colors"
className="ml-7 mt-1 text-[11px] text-violet-700 dark:text-violet-400 hover:text-violet-700 dark:hover:text-violet-300 transition-colors"
>
{t("common:subagent_label", { count: totalDesc })}
</button>