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
);
}