import Link from "next/link"; import { cx } from "@/lib/format"; import type { CoverageSummary } from "@/lib/types"; /** Source Redundancy block (server component). Numbers come from the coverage engine, never hard-coded. */ export function RedundancyPanel({ coverage: c, className, prominent }: { coverage: CoverageSummary; className?: string; prominent?: boolean }) { const f = c.byFamilies; const bars: Array<[string, number, string]> = [ ["≥ 5 sources", f[">=5"], "bg-positive"], ["≥ 3", f[">=3"] - f[">=5"], "bg-accent"], ["2", f[">=2"] - f[">=3"], "bg-warning"], ["single source", f["1"], "bg-stale"], ]; const pct = (n: number) => (c.quoted ? (n / c.quoted) * 100 : 0); const tierA = c.tiers.A; return (

Source redundancy

Source coverage →
{c.multiSource} of {c.quoted} quoted instruments observed through ≥ 2 independent source families
{bars.map(([label, n, cls]) => (n > 0 ? : null))}
{bars.map(([label, n, cls]) => ( {n} {label} ))}
Weighted redundancy score {c.weightedScore.toFixed(1)}%
); } function Row({ k, v, sub }: { k: string; v: string; sub?: string }) { return (
{k}
{v}
{sub &&
{sub}
}
); }