- Reconcile TIER_CONFIG/TIER_COLORS into single TIER_CONFIG with both `color` (pill style) and `border` (bordered badge style) fields - Remove TemplatePalette alias indirection (TIER_LABELS_SHARED → direct import) - Extract inline spinner SVGs to shared Spinner component (3 copies → 1) - Migrate status dot colors from 6 remaining files to shared tokens: SearchDialog, StatusDot, Legend, ContextMenu, Toolbar + add statusDotClass() - Add COMM_TYPE_LABELS to design-tokens, used by CommunicationOverlay sr-only - Update reduced-motion tests: components that delegate to design-tokens pass the guard check via import detection; add design-tokens.ts own test - 507/507 tests pass, build clean Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
72 lines
2.7 KiB
TypeScript
72 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import { STATUS_CONFIG } from "@/lib/design-tokens";
|
|
|
|
const LEGEND_STATUSES = ["online", "provisioning", "degraded", "failed", "paused", "offline"] as const;
|
|
|
|
export function Legend() {
|
|
return (
|
|
<div className="fixed bottom-6 left-4 z-30 bg-zinc-900/95 border border-zinc-700/50 rounded-xl px-4 py-3 shadow-xl shadow-black/30 backdrop-blur-sm max-w-[280px]">
|
|
<div className="text-[11px] font-semibold text-zinc-400 uppercase tracking-wider mb-2">Legend</div>
|
|
|
|
{/* Status */}
|
|
<div className="mb-2">
|
|
<div className="text-[11px] text-zinc-500 font-medium mb-1">Status</div>
|
|
<div className="flex flex-wrap gap-x-3 gap-y-1">
|
|
{LEGEND_STATUSES.map((s) => (
|
|
<StatusItem key={s} color={STATUS_CONFIG[s].dot} label={STATUS_CONFIG[s].label} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Tiers */}
|
|
<div className="mb-2">
|
|
<div className="text-[11px] text-zinc-500 font-medium mb-1">Tier</div>
|
|
<div className="flex flex-wrap gap-x-3 gap-y-1">
|
|
<TierItem tier={1} label="Sandboxed" color="text-sky-300 bg-sky-950/40 border-sky-700/30" />
|
|
<TierItem tier={2} label="Standard" color="text-violet-300 bg-violet-950/40 border-violet-700/30" />
|
|
<TierItem tier={3} label="Full Access" color="text-amber-300 bg-amber-950/40 border-amber-700/30" />
|
|
</div>
|
|
</div>
|
|
|
|
{/* Communication */}
|
|
<div>
|
|
<div className="text-[11px] text-zinc-500 font-medium mb-1">Communication</div>
|
|
<div className="flex flex-wrap gap-x-3 gap-y-1">
|
|
<CommItem icon="↗" color="text-cyan-400" label="A2A Out" />
|
|
<CommItem icon="↙" color="text-blue-400" label="A2A In" />
|
|
<CommItem icon="◆" color="text-amber-400" label="Task" />
|
|
<CommItem icon="!" color="text-red-400" label="Error" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function StatusItem({ color, label }: { color: string; label: string }) {
|
|
return (
|
|
<div className="flex items-center gap-1">
|
|
<div className={`w-1.5 h-1.5 rounded-full ${color}`} />
|
|
<span className="text-[11px] text-zinc-400">{label}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function TierItem({ tier, label, color }: { tier: number; label: string; color: string }) {
|
|
return (
|
|
<div className="flex items-center gap-1">
|
|
<span className={`text-[11px] font-mono px-1 py-0.5 rounded border ${color}`}>T{tier}</span>
|
|
<span className="text-[11px] text-zinc-400">{label}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function CommItem({ icon, color, label }: { icon: string; color: string; label: string }) {
|
|
return (
|
|
<div className="flex items-center gap-1">
|
|
<span className={`text-[11px] ${color}`}>{icon}</span>
|
|
<span className="text-[11px] text-zinc-400">{label}</span>
|
|
</div>
|
|
);
|
|
}
|