Adopt WorkClaw's shadcn/ui Neutral token contract (Tailwind v4)

Replace the hand-rolled @theme color block with a real shadcn init shape:
bare :root (light) + .dark (dark) tokens mapped to --color-* via
@theme inline, plus the missing semantic/chart/radius tokens. --accent
is now neutral (#262626) to match WorkClaw; the ~16 coral-via-accent
usages migrate to the dedicated `coral` brand token so they stay coral.

Adds cn() (clsx + tailwind-merge) and components.json so future
`npx shadcn add` works. Clawmates-specific tokens (coral brand,
marketing palette, measured shadows, motion, layout, type scale) are
preserved verbatim in a separate @theme block. Root <html> gains `dark`
(app/login read .dark; marketing stays light via explicit colors).

We do NOT add shadcn's Button/Card/etc. — they'd conflict with the
existing measured-to-WorkClaw components.

Verified value-preserving: typecheck/lint/86 unit/31 E2E all green, and
all 6 visual baselines pass with no diff. Compiled + live CSS confirm
bg-accent→#262626 (neutral), text-coral→#f96565, chart tokens present.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-11 22:00:06 -05:00
co-authored by Claude Opus 4.8
parent e6f50c7ecb
commit 5ff2b2ca33
15 changed files with 198 additions and 45 deletions
@@ -43,9 +43,9 @@ export function ApprovalCard({ approval, onDecide, agentName }: ApprovalCardProp
return (
<section
aria-label="Review and approve"
className="mt-2 max-w-md rounded-(--radius) border border-accent/40 bg-surface-warm p-3 shadow-(--shadow-card) motion-safe:animate-[scale-in_var(--duration-fast)_var(--ease-app)]"
className="mt-2 max-w-md rounded-(--radius) border border-coral/40 bg-surface-warm p-3 shadow-(--shadow-card) motion-safe:animate-[scale-in_var(--duration-fast)_var(--ease-app)]"
>
<p className="text-xs font-semibold uppercase tracking-wide text-accent">
<p className="text-xs font-semibold uppercase tracking-wide text-coral">
Review &amp; approve
</p>
<p className="pt-1 text-sm">
@@ -76,7 +76,7 @@ export function ApprovalCard({ approval, onDecide, agentName }: ApprovalCardProp
type="button"
disabled={pending}
onClick={() => decide("approve")}
className="rounded-(--radius-button) bg-accent px-4 py-1.5 text-xs font-medium text-background shadow-(--shadow-cta) hover:bg-coral-light disabled:opacity-50"
className="rounded-(--radius-button) bg-coral px-4 py-1.5 text-xs font-medium text-background shadow-(--shadow-cta) hover:bg-coral-light disabled:opacity-50"
>
Approve
</button>