feat(11-02): replace 1113 old CSS variable references with Paperclip design tokens

- Replace all bg-[color:var(--old)] with bg-background/bg-card/bg-muted/bg-primary etc.
- Replace all text-[color:var(--old)] with text-foreground/text-muted-foreground/text-primary etc.
- Replace all border-[color:var(--line)] with border-border
- Replace all inline var(--old) with var(--new) equivalents
- Replace all rounded-[6px]/rounded-[8px] with rounded-lg
- Replace .surface class with bg-card border border-border shadow-sm
- Replace .focus-ring class with focus-visible Tailwind utilities
- Replace .mono class with font-mono
- Replace data-theme attribute with class-based dark mode
- 99 files updated, ~1265 lines changed, zero old references remaining
This commit is contained in:
ZacharyZhang-NY committed 2026-03-27 22:12:00 -04:00
1 parent 2ed5dd3388
commit 06ea4c6aec
99 files changed
+1265 -1265

No files matched your search

@@ -11,12 +11,12 @@ import { SocialDraftPreview } from "./SocialDraftPreview"
import { useAppStore } from "../../state/store"
function getTypeBadgeClass(type: string): string {
if (type === "hire_agent") return "bg-[color:var(--accent-soft)] text-[color:var(--accent)]"
if (type === "approve_ceo_strategy") return "bg-[color:var(--warn-soft)] text-[color:var(--warn)]"
if (type === "secret_access") return "bg-[color:var(--danger-soft)] text-[color:var(--danger)]"
if (type === "social_post") return "bg-[color:var(--accent-soft)] text-[color:var(--accent)]"
if (type === "deliverable_review") return "bg-[color:var(--accent-soft)] text-[color:var(--accent)]"
return "bg-[color:var(--panel-soft)] text-[color:var(--muted)]"
if (type === "hire_agent") return "bg-accent text-primary"
if (type === "approve_ceo_strategy") return "bg-yellow-100 dark:bg-yellow-900/50 text-yellow-600 dark:text-yellow-400"
if (type === "secret_access") return "bg-red-100 dark:bg-red-900/50 text-destructive"
if (type === "social_post") return "bg-accent text-primary"
if (type === "deliverable_review") return "bg-accent text-primary"
return "bg-muted text-muted-foreground"
}
export function ApprovalInspector({ approval, agents, tasks, documents, companyId, onDecide, onDeleted }: {
@@ -90,30 +90,30 @@ export function ApprovalInspector({ approval, agents, tasks, documents, companyI
<div className="space-y-6">
<ConfirmDialog open={confirmDelete} title={t("exec.deleteApproval")} message={t("exec.deleteApprovalConfirm")} errorMessage={actionError} onConfirm={() => void handleDelete()} onCancel={() => { setActionError(null); setConfirmDelete(false) }} />
{actionError && !confirmDelete ? <InlineNotice message={actionError} /> : null}
<div className="border-y border-[color:var(--line)] py-4 space-y-4">
<div className="border-y border-border py-4 space-y-4">
<div className="flex items-center gap-3">
<span className={`rounded-full px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] ${getTypeBadgeClass(approval.type)}`}>{approval.type.replaceAll("_", " ")}</span>
<StatusPill status={approval.state} />
</div>
<div className="text-[13px] font-medium text-[color:var(--text)]">{approval.payloadSummary}</div>
{approval.impactSummary ? <div className="text-[13px] text-[color:var(--muted)]">{approval.impactSummary}</div> : null}
<div className="text-[13px] font-medium text-foreground">{approval.payloadSummary}</div>
{approval.impactSummary ? <div className="text-[13px] text-muted-foreground">{approval.impactSummary}</div> : null}
<div className="grid gap-2 text-[13px] md:grid-cols-2">
<div className="flex items-center gap-2 text-[color:var(--muted)]"><Robot size={14} />Requested by: <span className="font-medium text-[color:var(--text)]">{requestingAgent?.name ?? "Unknown"}</span>{requestingAgent?.role ? <span className="text-[10px] text-[color:var(--muted)]">({requestingAgent.role})</span> : null}</div>
{relatedTask ? <div className="flex items-center gap-2 text-[color:var(--muted)]"><Briefcase size={14} />Task: <span className="font-medium text-[color:var(--text)]">{relatedTask.title}</span></div> : null}
<div className="text-[color:var(--muted)]">Created: <span className="mono text-[color:var(--text)]">{formatTime(approval.createdAt)}</span></div>
{approval.updatedAt !== approval.createdAt ? <div className="text-[color:var(--muted)]">Updated: <span className="mono text-[color:var(--text)]">{formatTime(approval.updatedAt)}</span></div> : null}
<div className="flex items-center gap-2 text-muted-foreground"><Robot size={14} />Requested by: <span className="font-medium text-foreground">{requestingAgent?.name ?? "Unknown"}</span>{requestingAgent?.role ? <span className="text-[10px] text-muted-foreground">({requestingAgent.role})</span> : null}</div>
{relatedTask ? <div className="flex items-center gap-2 text-muted-foreground"><Briefcase size={14} />Task: <span className="font-medium text-foreground">{relatedTask.title}</span></div> : null}
<div className="text-muted-foreground">Created: <span className="font-mono text-foreground">{formatTime(approval.createdAt)}</span></div>
{approval.updatedAt !== approval.createdAt ? <div className="text-muted-foreground">Updated: <span className="font-mono text-foreground">{formatTime(approval.updatedAt)}</span></div> : null}
</div>
{approval.type === "hire_agent" ? (() => { const payload = parseApprovalPayloadJson(approval); const payloadAgentId = typeof payload?.agentId === "string" ? payload.agentId : null; const reqSnap = payload?.requestedConfigurationSnapshot && typeof payload.requestedConfigurationSnapshot === "object" && !Array.isArray(payload.requestedConfigurationSnapshot) ? payload.requestedConfigurationSnapshot as Record<string, unknown> : null; const proposedAgent = (approval.relatedAgentId ? (agents.find((a) => a.id === approval.relatedAgentId) ?? null) : null) ?? (payloadAgentId ? (agents.find((a) => a.id === payloadAgentId) ?? null) : null); const mgrId = proposedAgent?.reportsTo ?? (typeof reqSnap?.reportsTo === "string" ? reqSnap.reportsTo : null); const mgr = mgrId ? (agents.find((a) => a.id === mgrId) ?? null) : null; if (!proposedAgent && !reqSnap) return null; return (
<div className="rounded-[8px] border border-[color:var(--accent)] border-opacity-30 bg-[color:var(--accent-soft)] px-4 py-3"><div className="mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--accent)]">Proposed Hire</div><div className="grid gap-1.5 text-[12px]">
<div><span className="text-[color:var(--muted)]">Name:</span> <span className="font-medium text-[color:var(--text)]">{proposedAgent?.name ?? approval.payloadSummary.replace(/^Hire\s+/i, "").split(/\s+as\s+/i)[0] ?? "Pending hire"}</span></div>
<div><span className="text-[color:var(--muted)]">Role:</span> <span className="text-[color:var(--text)]">{proposedAgent?.role ?? (typeof reqSnap?.role === "string" ? reqSnap.role : "Unspecified")}</span></div>
{(proposedAgent?.title || typeof reqSnap?.title === "string") ? <div><span className="text-[color:var(--muted)]">Title:</span> <span className="text-[color:var(--text)]">{proposedAgent?.title || reqSnap?.title as string}</span></div> : null}
{(proposedAgent?.capabilities || typeof reqSnap?.capabilities === "string") ? <div><span className="text-[color:var(--muted)]">Capabilities:</span> <span className="text-[color:var(--text)]">{proposedAgent?.capabilities || reqSnap?.capabilities as string}</span></div> : null}
<div><span className="text-[color:var(--muted)]">Connector:</span> <span className="mono text-[color:var(--text)]">{proposedAgent?.connectorId ?? (typeof reqSnap?.connectorId === "string" ? reqSnap.connectorId : "Unknown")}</span></div>
<div><span className="text-[color:var(--muted)]">Budget:</span> <span className="mono text-[color:var(--text)]">{formatMoney(proposedAgent?.budgetMonthlyUsd ?? (typeof reqSnap?.budgetMonthlyUsd === "number" ? reqSnap.budgetMonthlyUsd : 0))}/mo</span></div>
{mgr ? <div><span className="text-[color:var(--muted)]">Reports to:</span> <span className="text-[color:var(--text)]">{mgr.name}</span></div> : null}
<div className="rounded-lg border border-[color:var(--primary)] border-opacity-30 bg-accent px-4 py-3"><div className="mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-primary">Proposed Hire</div><div className="grid gap-1.5 text-[12px]">
<div><span className="text-muted-foreground">Name:</span> <span className="font-medium text-foreground">{proposedAgent?.name ?? approval.payloadSummary.replace(/^Hire\s+/i, "").split(/\s+as\s+/i)[0] ?? "Pending hire"}</span></div>
<div><span className="text-muted-foreground">Role:</span> <span className="text-foreground">{proposedAgent?.role ?? (typeof reqSnap?.role === "string" ? reqSnap.role : "Unspecified")}</span></div>
{(proposedAgent?.title || typeof reqSnap?.title === "string") ? <div><span className="text-muted-foreground">Title:</span> <span className="text-foreground">{proposedAgent?.title || reqSnap?.title as string}</span></div> : null}
{(proposedAgent?.capabilities || typeof reqSnap?.capabilities === "string") ? <div><span className="text-muted-foreground">Capabilities:</span> <span className="text-foreground">{proposedAgent?.capabilities || reqSnap?.capabilities as string}</span></div> : null}
<div><span className="text-muted-foreground">Connector:</span> <span className="font-mono text-foreground">{proposedAgent?.connectorId ?? (typeof reqSnap?.connectorId === "string" ? reqSnap.connectorId : "Unknown")}</span></div>
<div><span className="text-muted-foreground">Budget:</span> <span className="font-mono text-foreground">{formatMoney(proposedAgent?.budgetMonthlyUsd ?? (typeof reqSnap?.budgetMonthlyUsd === "number" ? reqSnap.budgetMonthlyUsd : 0))}/mo</span></div>
{mgr ? <div><span className="text-muted-foreground">Reports to:</span> <span className="text-foreground">{mgr.name}</span></div> : null}
</div></div>) })() : null}
{approval.type === "approve_ceo_strategy" ? <div className="rounded-[8px] border border-[color:var(--warn)] border-opacity-30 bg-[color:var(--warn-soft)] px-4 py-3"><div className="mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--warn)]">Organization Strategy</div><div className="whitespace-pre-wrap text-[12px] leading-relaxed text-[color:var(--text)]">{approval.payloadSummary}</div></div> : null}
{approval.type === "approve_ceo_strategy" ? <div className="rounded-lg border border-[color:var(--destructive)] border-opacity-30 bg-yellow-100 dark:bg-yellow-900/50 px-4 py-3"><div className="mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-yellow-600 dark:text-yellow-400">Organization Strategy</div><div className="whitespace-pre-wrap text-[12px] leading-relaxed text-foreground">{approval.payloadSummary}</div></div> : null}
{approval.type === "deliverable_review" ? <DeliverableReviewPanel approval={approval} documents={documents} agents={agents} /> : null}
{isSocialPost && approval.payloadJson ? (
<SocialDraftPreview
@@ -133,37 +133,37 @@ export function ApprovalInspector({ approval, agents, tasks, documents, companyI
role="radio"
aria-checked={scheduleMode === "immediate"}
tabIndex={0}
className={`flex h-4 w-4 shrink-0 items-center justify-center rounded-full border-2 ${scheduleMode === "immediate" ? "border-[color:var(--accent)]" : "border-[color:var(--line)]"}`}
className={`flex h-4 w-4 shrink-0 items-center justify-center rounded-full border-2 ${scheduleMode === "immediate" ? "border-[color:var(--primary)]" : "border-border"}`}
onClick={() => { setScheduleMode("immediate"); setScheduleError(null) }}
onKeyDown={(e) => { if (e.key === " " || e.key === "Enter") { setScheduleMode("immediate"); setScheduleError(null) } }}
>
{scheduleMode === "immediate" ? <span className="h-2 w-2 rounded-full bg-[color:var(--accent)]" aria-hidden="true" /> : null}
{scheduleMode === "immediate" ? <span className="h-2 w-2 rounded-full bg-primary" aria-hidden="true" /> : null}
</span>
<span className="text-[13px] font-medium text-[color:var(--text)]">Post immediately</span>
<span className="text-[13px] font-medium text-foreground">Post immediately</span>
</label>
<label className="flex cursor-pointer items-center gap-2">
<span
role="radio"
aria-checked={scheduleMode === "scheduled"}
tabIndex={0}
className={`flex h-4 w-4 shrink-0 items-center justify-center rounded-full border-2 ${scheduleMode === "scheduled" ? "border-[color:var(--accent)]" : "border-[color:var(--line)]"}`}
className={`flex h-4 w-4 shrink-0 items-center justify-center rounded-full border-2 ${scheduleMode === "scheduled" ? "border-[color:var(--primary)]" : "border-border"}`}
onClick={() => setScheduleMode("scheduled")}
onKeyDown={(e) => { if (e.key === " " || e.key === "Enter") setScheduleMode("scheduled") }}
>
{scheduleMode === "scheduled" ? <span className="h-2 w-2 rounded-full bg-[color:var(--accent)]" aria-hidden="true" /> : null}
{scheduleMode === "scheduled" ? <span className="h-2 w-2 rounded-full bg-primary" aria-hidden="true" /> : null}
</span>
<span className="text-[13px] font-medium text-[color:var(--text)]">Schedule for later</span>
<span className="text-[13px] font-medium text-foreground">Schedule for later</span>
</label>
</div>
{scheduleMode === "scheduled" ? (
<div className="flex items-center gap-2">
<Clock size={16} className="text-[color:var(--muted)]" />
<Clock size={16} className="text-muted-foreground" />
<input
type="datetime-local"
value={scheduledAt}
min={minDatetime}
onChange={(e) => { setScheduledAt(e.target.value); setScheduleError(null) }}
className="rounded-[8px] border border-[color:var(--line)] bg-[color:var(--panel)] px-3.5 py-2.5 text-[13px] text-[color:var(--text)] focus:border-[color:var(--accent)] focus:outline-none"
className="rounded-lg border border-border bg-card px-3.5 py-2.5 text-[13px] text-foreground focus:border-[color:var(--primary)] focus:outline-none"
/>
</div>
) : null}
@@ -171,7 +171,7 @@ export function ApprovalInspector({ approval, agents, tasks, documents, companyI
</div>
) : null}
{!isDecided ? <div><label className="mb-1 block text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]">Decision note</label><TextArea value={decisionNote} onChange={setDecisionNote} placeholder="Add a note (optional)" rows={3} /></div> : null}
{!isDecided ? <div><label className="mb-1 block text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground">Decision note</label><TextArea value={decisionNote} onChange={setDecisionNote} placeholder="Add a note (optional)" rows={3} /></div> : null}
<div className="flex flex-wrap gap-3">
{!isDecided ? <>
<ActionButton
@@ -186,7 +186,7 @@ export function ApprovalInspector({ approval, agents, tasks, documents, companyI
</> : null}
{isDecided ? <ActionButton label="Delete" onClick={() => setConfirmDelete(true)} icon={Trash} tone="danger" loading={acting === "delete"} /> : null}
</div>
{approval.decisionNote ? <div className="border-t border-[color:var(--line)] pt-4 text-[13px] text-[color:var(--muted-strong)]">Last note: {approval.decisionNote}</div> : null}
{approval.decisionNote ? <div className="border-t border-border pt-4 text-[13px] text-muted-foreground">Last note: {approval.decisionNote}</div> : null}
</div>
)
}
@@ -200,36 +200,36 @@ function DeliverableReviewPanel({ approval, documents, agents }: { approval: App
return (
<div className="space-y-3">
<div className="text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--accent)]">Deliverable Review</div>
<div className="text-[11px] font-semibold uppercase tracking-[0.08em] text-primary">Deliverable Review</div>
{fullDocs.length > 0 ? fullDocs.map((doc) => {
const isExpanded = expandedDocId === doc.id
const author = doc.authorAgentId ? agents.find((a) => a.id === doc.authorAgentId) : null
return (
<div key={doc.id} className="rounded-[8px] border border-[color:var(--line)] overflow-hidden">
<div key={doc.id} className="rounded-lg border border-border overflow-hidden">
<button
type="button"
onClick={() => setExpandedDocId(isExpanded ? null : doc.id)}
className="flex w-full cursor-pointer items-center gap-3 bg-[color:var(--panel-soft)] px-4 py-3 text-left transition hover:bg-[color:var(--panel)]"
className="flex w-full cursor-pointer items-center gap-3 bg-muted px-4 py-3 text-left transition hover:bg-card"
>
<span className="shrink-0 rounded-full bg-[color:var(--accent-soft)] px-2 py-0.5 text-[10px] font-semibold uppercase text-[color:var(--accent)]">{doc.type.replaceAll("_", " ")}</span>
<span className="min-w-0 flex-1 truncate text-[13px] font-medium text-[color:var(--text)]">{doc.title}</span>
{isExpanded ? <CaretUp size={14} className="shrink-0 text-[color:var(--muted)]" /> : <CaretDown size={14} className="shrink-0 text-[color:var(--muted)]" />}
<span className="shrink-0 rounded-full bg-accent px-2 py-0.5 text-[10px] font-semibold uppercase text-primary">{doc.type.replaceAll("_", " ")}</span>
<span className="min-w-0 flex-1 truncate text-[13px] font-medium text-foreground">{doc.title}</span>
{isExpanded ? <CaretUp size={14} className="shrink-0 text-muted-foreground" /> : <CaretDown size={14} className="shrink-0 text-muted-foreground" />}
</button>
{isExpanded ? (
<div className="border-t border-[color:var(--line)] px-4 py-3">
{author ? <div className="mb-2 text-[11px] text-[color:var(--muted)]">Author: <span className="font-medium text-[color:var(--text)]">{author.name}</span> ({author.role})</div> : null}
<div className="whitespace-pre-wrap text-[12px] leading-relaxed text-[color:var(--text)]">{doc.content || "No content."}</div>
<div className="border-t border-border px-4 py-3">
{author ? <div className="mb-2 text-[11px] text-muted-foreground">Author: <span className="font-medium text-foreground">{author.name}</span> ({author.role})</div> : null}
<div className="whitespace-pre-wrap text-[12px] leading-relaxed text-foreground">{doc.content || "No content."}</div>
</div>
) : null}
</div>
)
}) : docRefs.length > 0 ? docRefs.map((doc) => (
<div key={doc.id} className="flex items-center gap-2 rounded-[8px] border border-[color:var(--line)] bg-[color:var(--panel-soft)] px-4 py-3 text-[12px]">
<span className="rounded-full bg-[color:var(--accent-soft)] px-2 py-0.5 text-[10px] font-semibold uppercase text-[color:var(--accent)]">{doc.type.replaceAll("_", " ")}</span>
<span className="font-medium text-[color:var(--text)]">{doc.title}</span>
<div key={doc.id} className="flex items-center gap-2 rounded-lg border border-border bg-muted px-4 py-3 text-[12px]">
<span className="rounded-full bg-accent px-2 py-0.5 text-[10px] font-semibold uppercase text-primary">{doc.type.replaceAll("_", " ")}</span>
<span className="font-medium text-foreground">{doc.title}</span>
</div>
)) : <div className="text-[12px] text-[color:var(--muted)]">{approval.payloadSummary}</div>}
{approval.impactSummary ? <div className="text-[11px] text-[color:var(--muted)]">{approval.impactSummary}</div> : null}
)) : <div className="text-[12px] text-muted-foreground">{approval.payloadSummary}</div>}
{approval.impactSummary ? <div className="text-[11px] text-muted-foreground">{approval.impactSummary}</div> : null}
</div>
)
}