green that means "healthy" becomes the success token
Fifteen sites across thirteen files where a raw green stood in for a semantic state: connection dots, health lights, completed-job ticks, the copied-to-clipboard check, the installed badge, the checksum-matched line. All of them meant "on / connected / succeeded", and matched each other only because several people happened to pick the same palette number. The values do move: --success is #16a34a where green-500 was #22c55e and emerald-500 #10b981. That is the point — one token, so a theme can change its mind once, and under plain.css (the leak-detection theme, which greys --success to #404040) these now go colourless instead of staying green. Left alone, deliberately: the confetti palette and the Start button in start-confetti-button, the duck-avatar debug HUD, MetricCard's up/down delta ramp, CommandBlock's check on its hardcoded dark block, the react-email template, and the plain.css comment that names the anti-pattern. Reds are untouched — that is a separate pass, so some ternaries now read bg-success : bg-red-500 until it happens. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -102,7 +102,7 @@ export const ActivityScreen = () => {
|
||||
title={t.cwd}
|
||||
>
|
||||
<span
|
||||
className={`inline-block h-2 w-2 shrink-0 rounded-full ${t.active ? 'bg-emerald-500 animate-pulse' : 'bg-muted-foreground/40'}`}
|
||||
className={`inline-block h-2 w-2 shrink-0 rounded-full ${t.active ? 'bg-success animate-pulse' : 'bg-muted-foreground/40'}`}
|
||||
/>
|
||||
<span className="truncate font-mono text-xs">{t.id}</span>
|
||||
</Link>
|
||||
|
||||
@@ -43,7 +43,7 @@ export const TabList = () => {
|
||||
<Globe className="h-4 w-4 opacity-60" />
|
||||
<span className="text-sm font-medium">Browser</span>
|
||||
<div
|
||||
className={`ml-auto h-2 w-2 rounded-full ${isConnected ? 'bg-green-500' : 'bg-red-500'}`}
|
||||
className={`ml-auto h-2 w-2 rounded-full ${isConnected ? 'bg-success' : 'bg-red-500'}`}
|
||||
title={isConnected ? 'Extension connected' : 'Extension not connected'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -142,7 +142,7 @@ const StatusIcon = ({ status, className }: { status: string; className?: string
|
||||
switch (status) {
|
||||
case 'completed':
|
||||
case 'complete':
|
||||
return <CheckCircle2 className={`${base} text-green-500`} />;
|
||||
return <CheckCircle2 className={`${base} text-success`} />;
|
||||
case 'failed':
|
||||
case 'error':
|
||||
return <AlertCircle className={`${base} text-red-500`} />;
|
||||
|
||||
@@ -44,7 +44,7 @@ const formatDate = (iso: string) =>
|
||||
const StatusIcon = ({ status }: { status: JobSummary['status'] }) => {
|
||||
switch (status) {
|
||||
case 'completed':
|
||||
return <CheckCircle2 className="h-4 w-4 text-green-500 shrink-0" />;
|
||||
return <CheckCircle2 className="h-4 w-4 text-success shrink-0" />;
|
||||
case 'failed':
|
||||
return <AlertCircle className="h-4 w-4 text-red-500 shrink-0" />;
|
||||
case 'running':
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ export const ApifyConfig = () => {
|
||||
{status && (
|
||||
<div className="flex items-center gap-2 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-3">
|
||||
<div
|
||||
className={`h-2.5 w-2.5 rounded-full shrink-0 ${status.configured ? 'bg-green-500' : 'bg-duck-dark/20 dark:bg-foreground/20'}`}
|
||||
className={`h-2.5 w-2.5 rounded-full shrink-0 ${status.configured ? 'bg-success' : 'bg-duck-dark/20 dark:bg-foreground/20'}`}
|
||||
/>
|
||||
<span className="text-sm text-duck-dark dark:text-foreground">
|
||||
{status.configured ? 'API token configured' : 'Not configured'}
|
||||
|
||||
+2
-2
@@ -63,7 +63,7 @@ export const BrowserRelay = () => {
|
||||
<div className="grid gap-4">
|
||||
{isConnected ? (
|
||||
<div className="flex items-center gap-3 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-4">
|
||||
<div className="h-2.5 w-2.5 rounded-full bg-green-500 shrink-0" />
|
||||
<div className="h-2.5 w-2.5 rounded-full bg-success shrink-0" />
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-sm font-medium text-duck-dark dark:text-foreground">Connected</p>
|
||||
<p className="text-xs text-duck-dark/50 dark:text-foreground/50">
|
||||
@@ -193,7 +193,7 @@ const CredentialRow = ({ label, value, masked, copied, onCopy }: CredentialRowPr
|
||||
onClick={onCopy}
|
||||
className="shrink-0 p-1 rounded hover:bg-duck-dark/10 dark:hover:bg-foreground/10 cursor-pointer"
|
||||
>
|
||||
{copied ? <Check className="h-3.5 w-3.5 text-green-500" /> : <Copy className="h-3.5 w-3.5 opacity-50" />}
|
||||
{copied ? <Check className="h-3.5 w-3.5 text-success" /> : <Copy className="h-3.5 w-3.5 opacity-50" />}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ export const GoogleAccount = () => {
|
||||
{status.connected ? (
|
||||
<>
|
||||
<div className="flex items-center gap-3 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-4">
|
||||
<div className="h-2.5 w-2.5 rounded-full bg-green-500 shrink-0" />
|
||||
<div className="h-2.5 w-2.5 rounded-full bg-success shrink-0" />
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-sm font-medium text-duck-dark dark:text-foreground">Connected</p>
|
||||
<p className="text-xs text-duck-dark/50 dark:text-foreground/50 truncate">{status.email}</p>
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ const CredentialStatus = ({ status, isVerifying }: { status: VerifyStatus; isVer
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-3">
|
||||
<div className={`h-2.5 w-2.5 rounded-full shrink-0 ${status.valid ? 'bg-green-500' : 'bg-red-500'}`} />
|
||||
<div className={`h-2.5 w-2.5 rounded-full shrink-0 ${status.valid ? 'bg-success' : 'bg-red-500'}`} />
|
||||
<span className={`text-sm ${status.valid ? 'text-duck-dark dark:text-foreground' : 'text-red-500'}`}>
|
||||
{status.valid ? 'Credentials valid' : (status.error ?? 'Invalid credentials')}
|
||||
</span>
|
||||
|
||||
+2
-2
@@ -290,7 +290,7 @@ export const AIHarnessesSection = () => {
|
||||
{localProviders.map((lp: LocalProviderEntry) => (
|
||||
<div key={lp.id} className="flex items-center gap-2">
|
||||
<span
|
||||
className={`inline-block h-2 w-2 shrink-0 rounded-full ${lp.id in localHealth ? (localHealth[lp.id] ? 'bg-green-500' : 'bg-red-500') : 'bg-duck-dark/20'}`}
|
||||
className={`inline-block h-2 w-2 shrink-0 rounded-full ${lp.id in localHealth ? (localHealth[lp.id] ? 'bg-success' : 'bg-red-500') : 'bg-duck-dark/20'}`}
|
||||
title={lp.id in localHealth ? (localHealth[lp.id] ? 'Online' : 'Offline') : 'Checking...'}
|
||||
/>
|
||||
<span className="text-duck-dark/70 dark:text-foreground/70 font-medium">{lp.name}</span>
|
||||
@@ -439,7 +439,7 @@ export const AIHarnessesSection = () => {
|
||||
<span
|
||||
className={`inline-block h-2 w-2 shrink-0 rounded-full ${
|
||||
remoteHealth[provider.providerId] === true
|
||||
? 'bg-green-500'
|
||||
? 'bg-success'
|
||||
: remoteHealth[provider.providerId] === false
|
||||
? 'bg-red-500'
|
||||
: 'bg-duck-dark/20'
|
||||
|
||||
@@ -6,7 +6,7 @@ type CheckMarkProps = {
|
||||
|
||||
export const CheckMark = ({ className }: CheckMarkProps) => {
|
||||
return (
|
||||
<div className={cn('inline-block h-8 w-8 rounded-full bg-[#10b981]', className)}>
|
||||
<div className={cn('inline-block h-8 w-8 rounded-full bg-success', className)}>
|
||||
<svg className="m-auto mt-2 h-4 w-4 text-white" focusable="false" aria-hidden="true" viewBox="0 0 24 24">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -26,7 +26,7 @@ function StatusBadge({ item }: { item: StoreItem }) {
|
||||
if (item.processStatus && item.processStatus !== 'online') {
|
||||
return <AlertTriangle className="h-3.5 w-3.5 text-amber-500" aria-label={item.processStatus} />;
|
||||
}
|
||||
return <Check className="h-3.5 w-3.5 text-emerald-500" aria-label="installed" />;
|
||||
return <Check className="h-3.5 w-3.5 text-success" aria-label="installed" />;
|
||||
}
|
||||
|
||||
export const AppStoreList = () => {
|
||||
|
||||
@@ -155,7 +155,7 @@ export const QrReceiver = () => {
|
||||
|
||||
{done && (
|
||||
<div className="flex flex-col items-center gap-2 text-sm">
|
||||
<p className={done.ok ? 'text-emerald-600' : 'text-red-500'}>
|
||||
<p className={done.ok ? 'text-success' : 'text-red-500'}>
|
||||
{done.ok ? 'Complete — checksum matches' : 'Complete, but the checksum does NOT match'}
|
||||
</p>
|
||||
<a
|
||||
|
||||
@@ -7,7 +7,7 @@ const ConnectionIndicator = ({ panelId }: { panelId: string }) => {
|
||||
const [state] = useGlobal<TerminalConnectionState>(`terminal-conn-${panelId}`, 'disconnected');
|
||||
|
||||
if (state === 'connected') {
|
||||
return <Circle className="h-2 w-2 shrink-0 fill-emerald-500 text-emerald-500" />;
|
||||
return <Circle className="h-2 w-2 shrink-0 fill-success text-success" />;
|
||||
}
|
||||
|
||||
if (state === 'reconnecting') {
|
||||
|
||||
Reference in New Issue
Block a user