import { Check, Minus, X } from 'lucide-react';
import Link from 'next/link';
import type { ReactNode } from 'react';
import { Estimated } from '@/components/ui/badges';
import { Hint } from '@/components/ui/hint';
import { Note } from '@/components/ui/section';
import { cn } from '@/lib/cn';
import { fmtGb, fmtInt, fmtUsdPerM, num } from '@/lib/format';
import type { Fit, ModelLicence, Num, PriceDistribution, PriceDistributionStats } from '@/lib/types';
/*
Small server-safe building blocks shared by the intelligence surfaces (frontier · prices · providers · open · run-locally …).
Every number is passed in from the API; nothing here computes a score.
*/
/** Methodology footnote under a section: the API's own `methodology` / `note` string, never paraphrased into a claim. */
export function Methodology({ text, children, className }: { text?: string | null; children?: ReactNode; className?: string }) {
if (!text && !children) return null;
return (
Method
{text}
{children}{' '}
/methodology
);
}
/** Tiny min · p25 · median · p75 · max range bar on a log₁₀ axis shared by the whole column (`domain`). Amber = money. */
export function RangeBar({ d, domain, format = (v) => fmtUsdPerM(v), className, label }: { d: PriceDistributionStats | null | undefined; domain: [number, number]; format?: (v: number) => string; className?: string; label?: string }) {
const min = num(d?.min);
const p25 = num(d?.p25);
const med = num(d?.median);
const p75 = num(d?.p75);
const max = num(d?.max);
if (min === null || max === null || med === null) return — ;
const [lo, hi] = domain;
const L = (v: number) => Math.log10(Math.max(v, lo));
const pct = (v: number) => (hi === lo ? 50 : ((L(v) - L(lo)) / (L(hi) - L(lo))) * 100);
const title = `${label ?? 'Distribution'}: min ${format(min)} · p25 ${p25 === null ? '—' : format(p25)} · median ${format(med)} · p75 ${p75 === null ? '—' : format(p75)} · max ${format(max)}${num(d?.n) !== null ? ` · n=${fmtInt(d?.n)}` : ''}`;
return (
{p25 !== null && p75 !== null && }
{format(med)} med
);
}
/** Log-domain helper for a column of distributions. */
export function distDomain(items: (PriceDistributionStats | null | undefined)[]): [number, number] {
const mins = items.map((d) => num(d?.min)).filter((v): v is number => v !== null && v > 0);
const maxs = items.map((d) => num(d?.max)).filter((v): v is number => v !== null && v > 0);
if (!mins.length || !maxs.length) return [0.01, 100];
return [Math.min(...mins), Math.max(...maxs)];
}
/** Histogram of current offers by price bucket (from `/prices/index.distribution`). */
export function DistBars({ d, className }: { d: PriceDistribution | null | undefined; className?: string }) {
const buckets = d?.buckets ?? [];
const vals = buckets.map((b) => num(b.offers) ?? 0);
const max = Math.max(1, ...vals);
if (!buckets.length) return
No distribution returned.
;
return (
{buckets.map((b, i) => {
const v = vals[i] ?? 0;
return (
{v ? fmtInt(v) : ''}
);
})}
{buckets.map((b) => (
{b.label}
))}
{fmtInt(d?.offers)} current offers · {d?.unit ?? 'USD per 1M tokens'} · {d?.metric?.replace(/_per_mtok$/, '').replace(/_/g, ' ')}
);
}
/** Estimated fit result: ✓/✗ + estimated memory + headroom, always next to an `Estimated` label. `compact` for table cells. */
export function FitCell({ fit, compact = false, className }: { fit: Partial | null | undefined; compact?: boolean; className?: string }) {
if (!fit || fit.fits === null || fit.fits === undefined) return — ;
const mem = num(fit.estimated_memory_gb);
const head = num(fit.headroom_gb);
return (
{fit.fits ? '✓ fits' : '✗ too large'}
{mem !== null && {fmtGb(mem, 1)} }
{!compact && head !== null && {head >= 0 ? '+' : '−'}{fmtGb(Math.abs(head), 1)} headroom }
{fit.quantization && {fit.quantization} }
);
}
/** Fit breakdown (weights est./observed · KV cache + method · overhead · reserve) as a compact inline list. */
export function FitBreakdownList({ fit, className }: { fit: Fit; className?: string }) {
const b = fit.breakdown;
if (!b) return fit.note ? {fit.note}
: null;
return (
weights {fmtGb(b.weights_gb, 1)}
KV cache {fmtGb(b.kv_cache_gb, 2)} ({b.kv_cache_method})
overhead {fmtGb(b.overhead_gb, 1)}
reserved {fmtGb(b.reserved_gb, 0)}
context {fmtInt(b.context)} × batch {fmtInt(b.batch)}
);
}
/** "observed" (green, file size read from the artifact) vs "estimated" (dashed warning). */
export function SourceTag({ source }: { source: string | null | undefined }) {
if (source === 'observed') return observed ;
return estimated ;
}
/** Banner above any table of estimates: label + the API assumptions (never our own wording). */
export function EstimateBanner({ assumptions, note, counts, className }: { assumptions?: string[]; note?: string | null; counts?: { fits?: Num; evaluated?: Num } | null; className?: string }) {
return (
All fit figures are estimates, not measurements.
{counts && num(counts.fits) !== null && num(counts.evaluated) !== null && (
{fmtInt(counts.fits)} of {fmtInt(counts.evaluated)} evaluated models fit
)}
{note &&
{note}
}
{assumptions && assumptions.length > 0 && (
Assumptions ({assumptions.length})
{assumptions.map((a) => (
{a}
))}
)}
);
}
/** Licence permission glyphs: commercial · redistribution · derivatives · hosting (✓ allowed · ✗ restricted · – unknown). */
export function LicencePerms({ l, className, withLabel = false }: { l: ModelLicence | null | undefined; className?: string; withLabel?: boolean }) {
if (!l || l.key === null) {
return (
{l?.raw ? {l.raw} : — }
unclassified
);
}
const items: [string, boolean | null | undefined, boolean][] = [
['Commercial use', l.commercial_use, false],
['Redistribution', l.redistribution, false],
['Derivatives', l.derivatives, false],
['Hosting', l.hosting_restrictions === null || l.hosting_restrictions === undefined ? null : !l.hosting_restrictions, false],
];
return (
{withLabel && {l.label ?? l.key} }
{!withLabel && {l.key} }
{items.map(([label, v]) => (
{v === true ? : v === false ? : }
))}
);
}
export function LicenceLegend({ className }: { className?: string }) {
return (
Permissions, in order:
commercial use
· redistribution
· derivatives
· hosting
allowed
restricted
unknown
);
}
/** Trust level chip (leaderboard rows). */
const TRUST_TONE: Record = {
'official-benchmark': 'bg-positive-soft text-positive',
'peer-reviewed': 'bg-positive-soft text-positive',
'independent-evaluator': 'bg-accent-soft text-accent',
'official-model-card': 'bg-warning-soft text-warning',
community: 'bg-surface-2 text-ink-2',
unverified: 'bg-danger-soft text-danger',
};
export function TrustChip({ level, label, className }: { level: string | null | undefined; label?: string | null; className?: string }) {
if (!level) return — ;
return (
{level.replace(/-/g, ' ')}
);
}
/** Rank chips "benchmark #n" (observed dimensions, never summed). */
export function RankChips({ ranks, max = 4, className }: { ranks: Record | { benchmark: string; rank: number }[] | undefined | null; max?: number; className?: string }) {
const arr = !ranks ? [] : Array.isArray(ranks) ? ranks : Object.entries(ranks).map(([benchmark, rank]) => ({ benchmark, rank }));
const sorted = arr.slice().sort((a, b) => a.rank - b.rank);
if (!sorted.length) return — ;
return (
{sorted.slice(0, max).map((r) => (
{r.benchmark}
#{r.rank}
))}
{sorted.length > max && +{sorted.length - max} }
);
}
/** Column header with a sort link (keeps the rest of the URL). */
export function SortTh({ active, href, children, num: n, dir = 'asc' }: { active: boolean; href: string; children: ReactNode; num?: boolean; dir?: 'asc' | 'desc' }) {
return (
{children}
{active && {dir === 'asc' ? '↑' : '↓'} }
);
}
/** Label + definition tooltip pair used in rails and strips. */
export function Defined({ label, definition }: { label: ReactNode; definition?: string | null }) {
return (
{label}
{definition && }
);
}
/** Shared form control classes for the GET forms in rails. */
export const CTRL = 'h-11 lg:h-10 w-full border border-rule bg-surface px-2.5 text-sm text-ink focus:border-accent focus:outline-none';
export const CTRL_LG = 'h-11 w-full border border-rule bg-surface px-2.5 text-[15px] text-ink focus:border-accent focus:outline-none';
export const BTN_PRIMARY = 'inline-flex h-11 items-center justify-center gap-1.5 bg-ink px-4 text-sm font-medium text-canvas hover:opacity-90';
export const BTN_GHOST = 'inline-flex h-11 lg:h-10 items-center justify-center border border-rule px-3 text-sm text-ink-2 hover:border-rule-strong hover:text-ink';
/** Field wrapper for rail forms. */
export function Field({ label, children, hint, className }: { label: string; children: ReactNode; hint?: ReactNode; className?: string }) {
return (
{label}
{children}
{hint && {hint} }
);
}