From 529b2cfb48ff2c4fa85fe4352632dab985a830b6 Mon Sep 17 00:00:00 2001 From: Phelipe Lorran <112786693+httpsphl@users.noreply.github.com> Date: Sat, 3 Oct 2026 14:38:54 -0300 Subject: [PATCH] feat(app): color and corner tokens that read in both themes Light-theme muted, ok, warn and danger get darker so every text color reads at 4.5:1 on canvas, panel and sunken; the accent stays as a fill and words in it use the new accent-text. Dialog scrim and the close button's red become tokens, rounded-md folds into 8 px, and ui/tokens.test.ts checks the contrast of every text token in both themes. Spec 15.3 lists the tokens. --- app/src/features/bots/ChiefBadge.tsx | 2 +- app/src/features/chat/EffortPicker.tsx | 4 +- app/src/features/chat/InboundRow.tsx | 4 +- app/src/features/chat/ModePicker.tsx | 2 +- app/src/features/chat/ToolLines.tsx | 6 +-- app/src/features/crews/CrewView.tsx | 2 +- app/src/features/crews/Sidebar.tsx | 6 +-- app/src/features/messages/MessageRow.tsx | 2 +- app/src/features/routines/ScheduleFields.tsx | 2 +- app/src/features/screens/ScreenFocus.tsx | 4 +- app/src/features/screens/ScreensPanel.tsx | 4 +- app/src/index.css | 22 ++++++-- app/src/setup/Setup.tsx | 2 +- app/src/shell/TitleBar.tsx | 2 +- app/src/shell/sidebarToggle.tsx | 2 +- app/src/ui/Dialog.tsx | 2 +- app/src/ui/toast.tsx | 2 +- app/src/ui/tokens.test.ts | 55 ++++++++++++++++++++ docs/spec.md | 2 + 19 files changed, 98 insertions(+), 29 deletions(-) create mode 100644 app/src/ui/tokens.test.ts diff --git a/app/src/features/bots/ChiefBadge.tsx b/app/src/features/bots/ChiefBadge.tsx index 56dc244d..32a262f7 100644 --- a/app/src/features/bots/ChiefBadge.tsx +++ b/app/src/features/bots/ChiefBadge.tsx @@ -20,7 +20,7 @@ export function ChiefBadge({ crew, compact = false }: { crew: Crew; compact?: bo return ( {c.badge} diff --git a/app/src/features/chat/EffortPicker.tsx b/app/src/features/chat/EffortPicker.tsx index aac55d07..29bef3b7 100644 --- a/app/src/features/chat/EffortPicker.tsx +++ b/app/src/features/chat/EffortPicker.tsx @@ -140,7 +140,7 @@ export function EffortPicker({ bot, onLater }: { bot: Bot; onLater(text: string) left: `${(at(recommended) / LAST) * 100}%`, transform: `translateX(${EDGE[at(recommended)] ?? "-50%"})`, }} - className="absolute top-2.5 whitespace-nowrap text-[0.6875rem] text-accent" + className="absolute top-2.5 whitespace-nowrap text-[0.6875rem] text-accent-text" > {m.recommended} @@ -170,7 +170,7 @@ export function EffortPicker({ bot, onLater }: { bot: Bot; onLater(text: string) pending.current = null; void set("default", recommended ? m.names[recommended] : m.recommended); }} - className="shrink-0 rounded-md px-1.5 py-0.5 font-medium text-ink-soft text-xs hover:bg-sunken hover:text-ink" + className="shrink-0 rounded-lg px-1.5 py-0.5 font-medium text-ink-soft text-xs hover:bg-sunken hover:text-ink" > {m.useRecommended} diff --git a/app/src/features/chat/InboundRow.tsx b/app/src/features/chat/InboundRow.tsx index 8390e8f3..0c8e0cee 100644 --- a/app/src/features/chat/InboundRow.tsx +++ b/app/src/features/chat/InboundRow.tsx @@ -49,7 +49,7 @@ function TaskTag({ message }: { message: Message }) { ); if (message.kind === "routine") { return ( - + {t.routines.tag(routine?.name ?? t.routines.tab)} @@ -60,7 +60,7 @@ function TaskTag({ message }: { message: Message }) { } const Icon = message.kind === "task" ? ListTodo : Reply; return ( - + {message.kind === "task" ? t.chat.inbound.task : t.chat.inbound.result} diff --git a/app/src/features/chat/ModePicker.tsx b/app/src/features/chat/ModePicker.tsx index cfffa7d3..9d9c440e 100644 --- a/app/src/features/chat/ModePicker.tsx +++ b/app/src/features/chat/ModePicker.tsx @@ -91,7 +91,7 @@ export function ModePicker({ bot, onLater }: { bot: Bot; onLater(text: string): } }} trailing={ - + {m.turnOn} } diff --git a/app/src/features/chat/ToolLines.tsx b/app/src/features/chat/ToolLines.tsx index 8a92d0a2..7ee1178b 100644 --- a/app/src/features/chat/ToolLines.tsx +++ b/app/src/features/chat/ToolLines.tsx @@ -134,7 +134,7 @@ function ToolLine({ tool, createdAt }: { tool: ToolItem; createdAt: number }) { title={t.files.showInPanel} aria-label={`${t.files.showInPanel}: ${tool.summary}`} onClick={() => showFile(tool.file as string)} - className="grid size-6 shrink-0 place-items-center rounded-md text-muted transition-colors hover:bg-sunken hover:text-ink" + className="grid size-6 shrink-0 place-items-center rounded-lg text-muted transition-colors hover:bg-sunken hover:text-ink" > @@ -145,7 +145,7 @@ function ToolLine({ tool, createdAt }: { tool: ToolItem; createdAt: number }) { title={t.screens.showInPanel} aria-label={`${t.screens.showInPanel}: ${tool.summary}`} onClick={() => showScreen(tool.file as string)} - className="grid size-6 shrink-0 place-items-center rounded-md text-muted transition-colors hover:bg-sunken hover:text-ink" + className="grid size-6 shrink-0 place-items-center rounded-lg text-muted transition-colors hover:bg-sunken hover:text-ink" > @@ -156,7 +156,7 @@ function ToolLine({ tool, createdAt }: { tool: ToolItem; createdAt: number }) { title={t.browser.showInPanel} aria-label={`${t.browser.showInPanel}: ${title}`} onClick={() => showBrowser()} - className="grid size-6 shrink-0 place-items-center rounded-md text-muted transition-colors hover:bg-sunken hover:text-ink" + className="grid size-6 shrink-0 place-items-center rounded-lg text-muted transition-colors hover:bg-sunken hover:text-ink" > diff --git a/app/src/features/crews/CrewView.tsx b/app/src/features/crews/CrewView.tsx index b322903a..6847a09b 100644 --- a/app/src/features/crews/CrewView.tsx +++ b/app/src/features/crews/CrewView.tsx @@ -79,7 +79,7 @@ export function CrewView({ crew }: { crew: Crew }) { type="button" onClick={openFolder} title={words.openFolder} - className="flex min-w-0 items-center gap-1 rounded-md px-1 hover:bg-sunken hover:text-ink" + className="flex min-w-0 items-center gap-1 rounded-lg px-1 hover:bg-sunken hover:text-ink" > {words.folder(crew.workFolder)} diff --git a/app/src/features/crews/Sidebar.tsx b/app/src/features/crews/Sidebar.tsx index 17644684..3d8dac16 100644 --- a/app/src/features/crews/Sidebar.tsx +++ b/app/src/features/crews/Sidebar.tsx @@ -41,7 +41,7 @@ export function Sidebar() { aria-current={overview ? "page" : undefined} title={words.showAll} onClick={() => selectCrew(null)} - className={`rounded-md px-2 py-1 font-semibold text-xs uppercase tracking-[0.12em] transition-colors hover:bg-sunken hover:text-ink ${overview ? "bg-sunken text-ink" : "text-muted"}`} + className={`rounded-lg px-2 py-1 font-semibold text-xs uppercase tracking-[0.12em] transition-colors hover:bg-sunken hover:text-ink ${overview ? "bg-sunken text-ink" : "text-muted"}`} > {words.label} @@ -98,7 +98,7 @@ function CrewEntry({ crew }: { crew: Crew }) { aria-label={collapsed ? words.expand(crew.name) : words.collapse(crew.name)} title={collapsed ? words.expand(crew.name) : words.collapse(crew.name)} onClick={() => setCollapsed(crew.id, !collapsed)} - className="absolute left-1 z-10 grid size-6 place-items-center rounded-md text-muted hover:bg-line hover:text-ink" + className="absolute left-1 z-10 grid size-6 place-items-center rounded-lg text-muted hover:bg-line hover:text-ink" > {activity && (