refactor: normalize FlowPilot/Assistant/ScriptBuilder to design system tokens

Replace hardcoded Tailwind color utilities with semantic CSS variable tokens
across 31 files in the FlowPilot, Assistant Chat, and Script Builder feature
communities — the areas graphify identified as design-system-free.

- text-blue-400 → text-accent, bg-blue-500/10 → bg-accent-dim, border-blue-500/20 → border-accent/20
- text-amber-400 → text-warning, bg-amber-400/10 → bg-warning-dim, border-l-amber-500 → border-l-warning
- text-rose-400/500 → text-danger, bg-rose-500/10 → bg-danger-dim
- text-emerald-400 → text-success, bg-emerald-500/10 → bg-success-dim, border-l-emerald-500 → border-l-success
- bg-white/[0.08] → bg-elevated (opacity hack → semantic surface token)
- bg-gradient-to-r from-blue-500 to-blue-400 → bg-accent (no gradient surfaces)
- bg-[#60a5fa] → bg-accent (hard-coded hex removed)

Also adds graphify-out/ to .gitignore.

Theme resilience: accent color has changed twice in 5 weeks. Semantic tokens
mean the next change is a 1-line edit in index.css, not 110 grep-and-replace.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-04-06 20:20:07 -04:00
parent 37179096b0
commit cef853d7ea
25 changed files with 114 additions and 110 deletions

View File

@@ -708,13 +708,13 @@ export default function AssistantChatPage() {
</div>
)}
{upload.status === 'done' && (
<button type="button" onClick={() => handleRemoveUpload(upload.id)} className="absolute -top-1 -right-1 w-4 h-4 rounded-full bg-background border border-border flex items-center justify-center hover:bg-rose-500/20 transition-colors">
<button type="button" onClick={() => handleRemoveUpload(upload.id)} className="absolute -top-1 -right-1 w-4 h-4 rounded-full bg-background border border-border flex items-center justify-center hover:bg-danger/20 transition-colors">
<X size={8} className="text-muted-foreground" />
</button>
)}
{upload.status === 'error' && (
<div className="absolute inset-0 bg-rose-500/20 border-2 border-rose-500 flex items-center justify-center cursor-pointer" onClick={() => retryUpload(upload.id)}>
<RotateCcw size={10} className="text-rose-500" />
<div className="absolute inset-0 bg-danger/20 border-2 border-danger flex items-center justify-center cursor-pointer" onClick={() => retryUpload(upload.id)}>
<RotateCcw size={10} className="text-danger" />
</div>
)}
</div>
@@ -755,11 +755,11 @@ export default function AssistantChatPage() {
)}
{messages.length >= 2 && (
<>
<button type="button" onClick={() => setShowStatusUpdate(true)} disabled={loading} className="flex items-center gap-1.5 rounded-lg px-2 py-1.5 text-xs text-muted-foreground hover:text-blue-400 hover:bg-blue-500/10 transition-colors disabled:opacity-40" title="Share status update">
<button type="button" onClick={() => setShowStatusUpdate(true)} disabled={loading} className="flex items-center gap-1.5 rounded-lg px-2 py-1.5 text-xs text-muted-foreground hover:text-accent hover:bg-accent-dim transition-colors disabled:opacity-40" title="Share status update">
<FileText size={14} />
<span className="hidden sm:inline">Update</span>
</button>
<button type="button" onClick={() => setShowConclude(true)} disabled={loading} className="flex items-center gap-1.5 rounded-lg px-2 py-1.5 text-xs text-muted-foreground hover:text-amber-400 hover:bg-amber-400/10 transition-colors disabled:opacity-40" title="Conclude session">
<button type="button" onClick={() => setShowConclude(true)} disabled={loading} className="flex items-center gap-1.5 rounded-lg px-2 py-1.5 text-xs text-muted-foreground hover:text-warning hover:bg-warning-dim transition-colors disabled:opacity-40" title="Conclude session">
<Flag size={14} />
<span className="hidden sm:inline">Conclude</span>
</button>

View File

@@ -108,7 +108,7 @@ export default function FlowPilotSessionPage() {
return (
<div className="flex items-center justify-center min-h-[50vh]">
<div className="card-flat p-6 text-center max-w-md">
<p className="text-sm text-rose-400">{fp.error}</p>
<p className="text-sm text-danger">{fp.error}</p>
<button
onClick={() => window.location.reload()}
className="mt-3 text-xs text-muted-foreground hover:text-foreground transition-colors"
@@ -160,15 +160,15 @@ export default function FlowPilotSessionPage() {
className="flex items-center gap-3 border-b px-5 py-3 shrink-0"
style={{ borderColor: 'var(--color-border-default)' }}
>
<span className="flex h-7 w-7 items-center justify-center rounded-lg bg-amber-500/10">
<Sparkles size={14} className="text-amber-400" />
<span className="flex h-7 w-7 items-center justify-center rounded-lg bg-warning-dim">
<Sparkles size={14} className="text-warning" />
</span>
<div className="flex-1 min-w-0">
<h1 className="font-heading text-sm font-semibold text-foreground truncate">
Escalation Pickup {fp.session.problem_summary || 'FlowPilot Session'}
</h1>
</div>
<span className="font-sans text-xs rounded-md bg-amber-500/10 px-2 py-0.5 text-[0.625rem] uppercase tracking-wider text-amber-400 border border-amber-500/20">
<span className="font-sans text-xs rounded-md bg-warning-dim px-2 py-0.5 text-[0.625rem] uppercase tracking-wider text-warning border border-warning/20">
Awaiting pickup
</span>
</div>
@@ -196,8 +196,8 @@ export default function FlowPilotSessionPage() {
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80">
<div className="bg-card border border-border rounded-xl w-full max-w-md p-6 shadow-lg">
<div className="flex items-center gap-3 mb-3">
<span className="flex h-9 w-9 items-center justify-center rounded-lg bg-amber-500/10">
<AlertTriangle size={18} className="text-amber-400" />
<span className="flex h-9 w-9 items-center justify-center rounded-lg bg-warning-dim">
<AlertTriangle size={18} className="text-warning" />
</span>
<h2 className="text-lg font-heading font-semibold text-foreground">Active Session</h2>
</div>
@@ -207,7 +207,7 @@ export default function FlowPilotSessionPage() {
<div className="flex gap-2">
<button
onClick={() => blocker.reset()}
className="flex-1 rounded-lg bg-gradient-to-r from-blue-500 to-blue-400 px-4 py-2.5 text-sm font-semibold text-white hover:brightness-110 active:scale-[0.98] transition-all"
className="flex-1 rounded-lg bg-accent px-4 py-2.5 text-sm font-semibold text-white hover:brightness-110 active:scale-[0.98] transition-all"
>
Stay in Session
</button>
@@ -246,7 +246,7 @@ export default function FlowPilotSessionPage() {
<button
onClick={() => setShowResolve(true)}
disabled={!fp.canResolve || fp.isProcessing}
className="flex items-center gap-1.5 rounded-lg bg-emerald-500/10 border border-emerald-500/20 px-3 py-1.5 text-xs font-medium text-emerald-400 hover:bg-emerald-500/20 disabled:opacity-40 disabled:pointer-events-none transition-colors"
className="flex items-center gap-1.5 rounded-lg bg-success-dim border border-success/20 px-3 py-1.5 text-xs font-medium text-success hover:bg-success/20 disabled:opacity-40 disabled:pointer-events-none transition-colors"
>
<CheckCircle2 size={13} />
Resolve
@@ -254,7 +254,7 @@ export default function FlowPilotSessionPage() {
<button
onClick={() => setShowEscalate(true)}
disabled={!fp.canEscalate || fp.isProcessing}
className="flex items-center gap-1.5 rounded-lg bg-amber-500/10 border border-amber-500/20 px-3 py-1.5 text-xs font-medium text-amber-400 hover:bg-amber-500/20 disabled:opacity-40 disabled:pointer-events-none transition-colors"
className="flex items-center gap-1.5 rounded-lg bg-warning-dim border border-warning/20 px-3 py-1.5 text-xs font-medium text-warning hover:bg-warning/20 disabled:opacity-40 disabled:pointer-events-none transition-colors"
>
<ArrowUpRight size={13} />
Escalate
@@ -263,7 +263,7 @@ export default function FlowPilotSessionPage() {
<button
onClick={() => setShowStatusUpdate(true)}
disabled={fp.isProcessing}
className="flex items-center gap-1.5 rounded-lg bg-blue-500/10 border border-blue-500/20 px-3 py-1.5 text-xs font-medium text-blue-400 hover:bg-blue-500/20 disabled:opacity-40 disabled:pointer-events-none transition-colors"
className="flex items-center gap-1.5 rounded-lg bg-accent-dim border border-accent/20 px-3 py-1.5 text-xs font-medium text-accent hover:bg-accent/20 disabled:opacity-40 disabled:pointer-events-none transition-colors"
title="Share Update"
>
<FileText size={13} />
@@ -291,7 +291,7 @@ export default function FlowPilotSessionPage() {
</button>
<button
onClick={() => { setShowOverflow(false); setShowAbandon(true) }}
className="flex w-full items-center gap-2 px-3 py-2 text-xs text-muted-foreground hover:text-rose-400 hover:bg-rose-500/10 transition-colors"
className="flex w-full items-center gap-2 px-3 py-2 text-xs text-muted-foreground hover:text-danger hover:bg-danger-dim transition-colors"
>
<X size={13} />
Close Session
@@ -317,7 +317,7 @@ export default function FlowPilotSessionPage() {
<button
onClick={() => { setShowOverflow(false); setShowResolve(true) }}
disabled={!fp.canResolve}
className="flex w-full items-center gap-2 px-3 py-2.5 text-xs text-emerald-400 hover:bg-emerald-500/10 transition-colors disabled:opacity-40"
className="flex w-full items-center gap-2 px-3 py-2.5 text-xs text-success hover:bg-success-dim transition-colors disabled:opacity-40"
>
<CheckCircle2 size={14} />
Resolve
@@ -325,7 +325,7 @@ export default function FlowPilotSessionPage() {
<button
onClick={() => { setShowOverflow(false); setShowEscalate(true) }}
disabled={!fp.canEscalate}
className="flex w-full items-center gap-2 px-3 py-2.5 text-xs text-amber-400 hover:bg-amber-500/10 transition-colors disabled:opacity-40"
className="flex w-full items-center gap-2 px-3 py-2.5 text-xs text-warning hover:bg-warning-dim transition-colors disabled:opacity-40"
>
<ArrowUpRight size={14} />
Escalate
@@ -333,7 +333,7 @@ export default function FlowPilotSessionPage() {
{fp.allSteps.length >= 2 && (
<button
onClick={() => { setShowOverflow(false); setShowStatusUpdate(true) }}
className="flex w-full items-center gap-2 px-3 py-2.5 text-xs text-blue-400 hover:bg-blue-500/10 transition-colors"
className="flex w-full items-center gap-2 px-3 py-2.5 text-xs text-accent hover:bg-accent-dim transition-colors"
>
<FileText size={14} />
Share Update
@@ -349,7 +349,7 @@ export default function FlowPilotSessionPage() {
</button>
<button
onClick={() => { setShowOverflow(false); setShowAbandon(true) }}
className="flex w-full items-center gap-2 px-3 py-2.5 text-xs text-muted-foreground hover:text-rose-400 hover:bg-rose-500/10 transition-colors"
className="flex w-full items-center gap-2 px-3 py-2.5 text-xs text-muted-foreground hover:text-danger hover:bg-danger-dim transition-colors"
>
<X size={14} />
Close Session
@@ -364,8 +364,8 @@ export default function FlowPilotSessionPage() {
{/* Status badge — non-active states */}
{fp.session.status !== 'active' && (
<span className={`flex items-center gap-1.5 text-[0.625rem] uppercase tracking-wider font-sans ${
fp.session.status === 'resolved' ? 'text-emerald-400' :
fp.session.status === 'escalated' ? 'text-amber-400' :
fp.session.status === 'resolved' ? 'text-success' :
fp.session.status === 'escalated' ? 'text-warning' :
fp.session.status === 'paused' ? 'text-muted-foreground' :
'text-muted-foreground'
}`}>
@@ -437,7 +437,7 @@ export default function FlowPilotSessionPage() {
}
}}
disabled={resolutionSummary.length < 5 || submitting}
className="rounded-lg bg-emerald-500/20 border border-emerald-500/30 px-4 py-2 min-h-[44px] text-sm font-medium text-emerald-400 hover:bg-emerald-500/30 disabled:opacity-50 transition-colors"
className="rounded-lg bg-success/20 border border-success/30 px-4 py-2 min-h-[44px] text-sm font-medium text-success hover:bg-success/30 disabled:opacity-50 transition-colors"
>
{submitting ? 'Resolving...' : 'Resolve Session'}
</button>
@@ -473,7 +473,7 @@ export default function FlowPilotSessionPage() {
}
}}
disabled={submitting}
className="rounded-lg bg-rose-500/20 border border-rose-500/30 px-4 py-2 min-h-[44px] text-sm font-medium text-rose-400 hover:bg-rose-500/30 disabled:opacity-50 transition-colors"
className="rounded-lg bg-danger/20 border border-danger/30 px-4 py-2 min-h-[44px] text-sm font-medium text-danger hover:bg-danger/30 disabled:opacity-50 transition-colors"
>
{submitting ? 'Closing...' : 'Close Session'}
</button>