fix(frontend): finish the token migration — raw grey classes -> theme tokens

UI_REDESIGN chunk 4 was never finished: 39 app/component files still used
raw Tailwind greys, kept readable in light mode only by the !important
override sheet. In dark mode text-gray-600 is ~2.3:1 on surface, and the
light override maps it to #94a3b8 (~2.6:1 on white) — unreadable in both.

Mechanical mapping (886 classes): gray-100/200 -> ink, 300/400 -> ink-2,
500/600/700 -> ink-muted, bg 950/900/800 -> page/surface/raised,
border 800 -> line, 700/600 -> line-strong, plus hover/divide/placeholder.
Alpha suffixes kept (tokens are color-mix, so /60 works). bg-gray-700,
text-white and marketing pages left alone. text-[9px] -> text-[10px].

Frontend unverified: no Node on the authoring box (#207).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Logan Cusano
2026-10-25 21:29:13 -04:00
co-authored by Claude Opus 5.5
parent 3968b49b80
commit bf206334e3
39 changed files with 655 additions and 655 deletions
+13 -13
View File
@@ -39,11 +39,11 @@ function CreateKeyModal({ onClose, onCreated }: { onClose: () => void; onCreated
<div className="fixed inset-0 z-50 bg-black/70 flex items-center justify-center p-4">
<Card padding="lg" className="w-full max-w-lg space-y-4">
<h2 className="text-white font-semibold">Key created</h2>
<p className="text-xs text-gray-400">
<p className="text-xs text-ink-2">
Copy this key now — it won&apos;t be shown again. This is a sample key from the demo module in{" "}
<code className="text-gray-300">lib/apiKeys.ts</code>; it doesn&apos;t authenticate against anything.
<code className="text-ink-2">lib/apiKeys.ts</code>; it doesn&apos;t authenticate against anything.
</p>
<div className="bg-gray-800 border border-gray-700 rounded-lg p-3">
<div className="bg-raised border border-line-strong rounded-lg p-3">
<p className="text-xs text-indigo-300 break-all font-mono">{rawKey}</p>
</div>
<div className="flex gap-3">
@@ -61,11 +61,11 @@ function CreateKeyModal({ onClose, onCreated }: { onClose: () => void; onCreated
<h2 className="text-white font-semibold mb-4">New API key</h2>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="text-xs text-gray-400 block mb-1">Label</label>
<label className="text-xs text-ink-2 block mb-1">Label</label>
<input
required value={name} onChange={(e) => setName(e.target.value)}
placeholder="e.g. Ops dashboard integration"
className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
className="w-full bg-raised border border-line-strong rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
/>
</div>
<div className="flex gap-3">
@@ -96,9 +96,9 @@ export default function ApiKeysSettingsPage() {
<div className="space-y-4">
<div className="bg-indigo-600/10 border border-indigo-600/40 rounded-xl p-4">
<p className="text-indigo-300 text-sm font-semibold">Preview feature</p>
<p className="text-gray-400 text-xs mt-1 leading-relaxed">
<p className="text-ink-2 text-xs mt-1 leading-relaxed">
Organization API keys aren&apos;t backed by a real endpoint yet — this screen runs against an in-memory
demo module (<code className="text-gray-300">lib/apiKeys.ts</code>) so the flow can be reviewed end to
demo module (<code className="text-ink-2">lib/apiKeys.ts</code>) so the flow can be reviewed end to
end. See that file for the exact backend routes a real integration needs.
</p>
</div>
@@ -108,7 +108,7 @@ export default function ApiKeysSettingsPage() {
)}
<div className="flex items-center justify-between">
<p className="text-sm text-gray-500">{loading ? "Loading…" : `${active.length} active key${active.length !== 1 ? "s" : ""}`}</p>
<p className="text-sm text-ink-muted">{loading ? "Loading…" : `${active.length} active key${active.length !== 1 ? "s" : ""}`}</p>
<Button size="sm" onClick={() => setShowCreate(true)}>+ Create key</Button>
</div>
@@ -118,7 +118,7 @@ export default function ApiKeysSettingsPage() {
<Card padding="none" className="overflow-hidden">
<table className="w-full text-sm">
<thead>
<tr className="text-xs text-gray-500 uppercase tracking-wider border-b border-gray-800 bg-gray-900">
<tr className="text-xs text-ink-muted uppercase tracking-wider border-b border-line bg-surface">
<th className="px-4 py-3 text-left">Label</th>
<th className="px-4 py-3 text-left">Key</th>
<th className="px-4 py-3 text-left hidden sm:table-cell">Created</th>
@@ -129,11 +129,11 @@ export default function ApiKeysSettingsPage() {
</thead>
<tbody>
{keys.map((k) => (
<tr key={k.key_id} className="border-b border-gray-800 last:border-0">
<tr key={k.key_id} className="border-b border-line last:border-0">
<td className="px-4 py-3 text-white">{k.name}</td>
<td className="px-4 py-3 text-gray-500 font-mono text-xs">{k.key_prefix}…</td>
<td className="px-4 py-3 text-gray-400 text-xs hidden sm:table-cell">{fmtDate(k.created_at)}</td>
<td className="px-4 py-3 text-gray-400 text-xs hidden sm:table-cell">{k.last_used_at ? fmtDate(k.last_used_at) : "Never"}</td>
<td className="px-4 py-3 text-ink-muted font-mono text-xs">{k.key_prefix}…</td>
<td className="px-4 py-3 text-ink-2 text-xs hidden sm:table-cell">{fmtDate(k.created_at)}</td>
<td className="px-4 py-3 text-ink-2 text-xs hidden sm:table-cell">{k.last_used_at ? fmtDate(k.last_used_at) : "Never"}</td>
<td className="px-4 py-3">
{k.revoked ? <Badge tone="danger">Revoked</Badge> : <Badge tone="success">Active</Badge>}
</td>