import { cn } from '@/lib/cn'; import { IMPORTANCE_LABELS, OPENNESS_LABELS, STATUS_LABELS, TIER_LABELS, TYPE_COLOR_KEY, typeLabel } from '@/lib/site'; const base = 'inline-flex items-center gap-1 whitespace-nowrap rounded-[3px] px-1.5 py-[1px] text-[11px] font-medium leading-4 tracking-wide'; /** Entity-type badge: coloured text + faint tint, letter-spaced. `small` variant for dense feeds. */ export function EntityBadge({ type, className, small = false }: { type: string; className?: string; small?: boolean }) { const key = TYPE_COLOR_KEY[type] ?? 'tool'; return ( {typeLabel(type)} ); } /** Source tier 1–4 (official → unverified). */ export function TierBadge({ tier, className, withLabel = false }: { tier: number | null | undefined; className?: string; withLabel?: boolean }) { if (tier === null || tier === undefined) return tier —; const t = Math.min(4, Math.max(1, Math.round(tier))); return ( T{t} {withLabel && · {TIER_LABELS[t]}} ); } const CONF: Record = { verified: 'text-positive bg-positive-soft', high: 'text-positive bg-positive-soft', medium: 'text-accent bg-accent-soft', low: 'text-warning bg-warning-soft', conflicted: 'text-danger bg-danger-soft' }; export function ConfidenceBadge({ confidence, className }: { confidence: string | null | undefined; className?: string }) { if (!confidence) return null; return {confidence}; } const STATUS: Record = { active: 'text-positive bg-positive-soft', preview: 'text-accent bg-accent-soft', announced: 'text-accent bg-accent-soft', 'limited-availability': 'text-warning bg-warning-soft', deprecated: 'text-warning bg-warning-soft', retired: 'text-danger bg-danger-soft', }; export function StatusBadge({ status, className }: { status: string | null | undefined; className?: string }) { if (!status || status === 'unknown') return null; return {STATUS_LABELS[status] ?? status}; } const OPEN: Record = { 'open-weights': 'text-positive bg-positive-soft', 'open-source': 'text-positive bg-positive-soft', proprietary: 'text-ink-2 bg-surface-2', restricted: 'text-warning bg-warning-soft' }; export function OpennessBadge({ openness, className }: { openness: string | null | undefined; className?: string }) { if (!openness) return null; return {OPENNESS_LABELS[openness] ?? openness}; } /** Importance 0–3 as a small stepped meter (■■■□). */ export function ImportanceMark({ importance, className }: { importance: number; className?: string }) { const n = Math.min(3, Math.max(0, importance)); return ( {[1, 2, 3].map((i) => ( ))} ); } /** Generic neutral chip (tags, families, modalities). */ export function Chip({ children, className, tone = 'neutral' }: { children: React.ReactNode; className?: string; tone?: 'neutral' | 'accent' | 'estimated' }) { return ( {children} ); } /** Derived/estimated label linking to methodology. */ export function Estimated({ className }: { className?: string }) { return ( Estimated ); }