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:
@@ -17,7 +17,7 @@ export function ChatMessage({ role, content, suggestedFlows }: ChatMessageProps)
|
||||
className={`shrink-0 w-8 h-8 rounded-full flex items-center justify-center ${
|
||||
role === 'assistant'
|
||||
? 'bg-primary/15 text-primary'
|
||||
: 'bg-white/[0.08] text-muted-foreground'
|
||||
: 'bg-elevated text-muted-foreground'
|
||||
}`}
|
||||
>
|
||||
{role === 'assistant' ? <Sparkles size={14} /> : <User size={14} />}
|
||||
|
||||
@@ -193,7 +193,7 @@ function ChatItem({
|
||||
className={cn(
|
||||
'group flex items-center gap-2 px-3 py-2.5 mx-1.5 rounded-lg cursor-pointer transition-colors',
|
||||
confirming
|
||||
? 'bg-rose-500/10 border border-rose-500/20'
|
||||
? 'bg-danger-dim border border-danger/20'
|
||||
: isActive
|
||||
? 'bg-accent-dim text-foreground'
|
||||
: 'text-muted-foreground hover:bg-input hover:text-foreground'
|
||||
@@ -203,10 +203,10 @@ function ChatItem({
|
||||
<div className="flex-1 min-w-0">
|
||||
{confirming ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-[0.75rem] text-rose-400 font-medium">Delete?</span>
|
||||
<span className="text-[0.75rem] text-danger font-medium">Delete?</span>
|
||||
<button
|
||||
onClick={e => { e.stopPropagation(); onDelete(); setConfirming(false) }}
|
||||
className="text-[0.6875rem] font-medium text-rose-400 hover:text-rose-300 px-1.5 py-0.5 rounded bg-rose-500/15 hover:bg-rose-500/25 transition-colors"
|
||||
className="text-[0.6875rem] font-medium text-danger hover:text-danger px-1.5 py-0.5 rounded bg-danger/15 hover:bg-danger/25 transition-colors"
|
||||
>
|
||||
Yes
|
||||
</button>
|
||||
@@ -230,14 +230,14 @@ function ChatItem({
|
||||
<div className="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<button
|
||||
onClick={e => { e.stopPropagation(); onTogglePin() }}
|
||||
className="p-1 rounded hover:bg-white/[0.08]"
|
||||
className="p-1 rounded hover:bg-elevated"
|
||||
title={chat.pinned ? 'Unpin' : 'Pin'}
|
||||
>
|
||||
<Pin size={12} className={chat.pinned ? 'text-primary' : ''} />
|
||||
</button>
|
||||
<button
|
||||
onClick={e => { e.stopPropagation(); setConfirming(true) }}
|
||||
className="p-1 rounded hover:bg-white/[0.08] text-muted-foreground hover:text-rose-400"
|
||||
className="p-1 rounded hover:bg-elevated text-muted-foreground hover:text-danger"
|
||||
title="Delete"
|
||||
>
|
||||
<Trash2 size={12} />
|
||||
|
||||
@@ -36,7 +36,7 @@ const OUTCOMES: { value: ConclusionOutcome; label: string; description: string;
|
||||
label: 'Resolved',
|
||||
description: 'Issue has been fixed or answered',
|
||||
icon: CheckCircle2,
|
||||
color: 'text-emerald-400',
|
||||
color: 'text-success',
|
||||
bg: 'bg-emerald-400/10',
|
||||
border: 'border-emerald-400/30',
|
||||
},
|
||||
@@ -45,17 +45,17 @@ const OUTCOMES: { value: ConclusionOutcome; label: string; description: string;
|
||||
label: 'Escalate',
|
||||
description: 'Needs to be handed off or escalated',
|
||||
icon: ArrowUpRight,
|
||||
color: 'text-amber-400',
|
||||
bg: 'bg-amber-400/10',
|
||||
border: 'border-amber-400/30',
|
||||
color: 'text-warning',
|
||||
bg: 'bg-warning-dim',
|
||||
border: 'border-warning/30',
|
||||
},
|
||||
{
|
||||
value: 'paused',
|
||||
label: 'Paused',
|
||||
description: 'Continuing later — saving progress',
|
||||
icon: Pause,
|
||||
color: 'text-blue-400',
|
||||
bg: 'bg-blue-400/10',
|
||||
color: 'text-accent',
|
||||
bg: 'bg-accent-dim',
|
||||
border: 'border-blue-400/30',
|
||||
},
|
||||
]
|
||||
@@ -362,7 +362,7 @@ export function ConcludeSessionModal({
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div className="text-sm text-rose-400 bg-rose-400/10 border border-rose-400/20 rounded-lg px-4 py-2">
|
||||
<div className="text-sm text-danger bg-danger-dim border border-danger/20 rounded-lg px-4 py-2">
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
@@ -410,7 +410,7 @@ export function ConcludeSessionModal({
|
||||
<div className="h-3 bg-elevated rounded w-4/5" />
|
||||
</div>
|
||||
) : streamError ? (
|
||||
<div className="flex items-center gap-2 text-sm text-amber-400">
|
||||
<div className="flex items-center gap-2 text-sm text-warning">
|
||||
<AlertTriangle size={14} />
|
||||
{streamError}
|
||||
</div>
|
||||
@@ -467,7 +467,7 @@ export function ConcludeSessionModal({
|
||||
{/* Paused/Escalated: generating spinner */}
|
||||
{(outcome === 'paused' || outcome === 'escalated') && generatingUpdate && (
|
||||
<div className="flex flex-col items-center justify-center py-8 gap-3">
|
||||
<Loader2 size={24} className="animate-spin text-blue-400" />
|
||||
<Loader2 size={24} className="animate-spin text-accent" />
|
||||
<p className="text-sm text-muted-foreground">Generating status update...</p>
|
||||
</div>
|
||||
)}
|
||||
@@ -544,7 +544,7 @@ export function ConcludeSessionModal({
|
||||
{outcome === 'paused' && (
|
||||
<button
|
||||
onClick={handleResumeNew}
|
||||
className="flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-medium text-blue-400 bg-blue-400/10 border border-blue-400/20 hover:bg-blue-400/15 transition-all"
|
||||
className="flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-medium text-accent bg-accent-dim border border-accent/20 hover:bg-accent/15 transition-all"
|
||||
>
|
||||
<RefreshCw size={14} />
|
||||
Resume in New Chat
|
||||
@@ -566,7 +566,7 @@ export function ConcludeSessionModal({
|
||||
className={cn(
|
||||
'flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-semibold transition-all',
|
||||
copied
|
||||
? 'bg-emerald-400/15 text-emerald-400 border border-emerald-400/30'
|
||||
? 'bg-emerald-400/15 text-success border border-emerald-400/30'
|
||||
: 'bg-primary text-white hover:brightness-110 active:scale-[0.98]'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -360,7 +360,7 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
|
||||
<section>
|
||||
<div className="sticky top-0 z-10 pb-2" style={{ background: 'var(--color-bg-page)' }}>
|
||||
<div className="flex items-center gap-2 text-[10px] font-semibold uppercase tracking-[1.2px] text-muted-foreground pl-0.5">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-[#60a5fa]" />
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-accent" />
|
||||
Diagnostic Checks
|
||||
{actionTasks.every(a => a.state === 'done' || a.state === 'skipped') && (
|
||||
<Check size={10} className="text-success" />
|
||||
|
||||
Reference in New Issue
Block a user