Source list Sources placed above the answer so calibration comes first. Each carries a domain and a date, a paywalled one and an inaccessible one are marked, and the count says how many candidates were retrieved against how many were used. npx shadcn@latest add button npm i lucide-react Tokens this needs: --card-foreground, --muted, --muted-foreground, --border, --status-warn, --chart-1 The status, chart, scale, state and direction names are an extension, not a rename. shadcn has --destructive and five --chart-* and nothing else in this territory. ──────────────────────────────────────────────────────────────────────── // SourceList.tsx ──────────────────────────────────────────────────────────────────────── import { useState, type ReactNode } from "react"; import { Lock } from "lucide-react"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; /** * A row is judged before the click, so the things that decide the judgement * are required: the domain, the date, and whether the reader can open it at * all. `access` is a closed set because each value wants a different mark and * a different explanation, and "unavailable" would cover none of them. */ export type Access = "open" | "paywalled" | "no-access" | "dead"; export type Source = { title: string; /** Host, or a path for a document in the viewer's own corpus. */ domain: string; /** As the source states it: "Jan 2026". */ date: string; url: string; access: Access; }; const ACCESS_LABEL: Record, string> = { paywalled: "paywalled", "no-access": "no access", dead: "link dead", }; export function SourceList({ sources, retrieved, max = 8, onOpen, children }: { /** What the answer drew on, most-used first. */ sources: Source[]; /** How many candidates retrieval returned before generation chose. Required: * the used count alone hides how thin the basis was. */ retrieved: number; /** Rows shown before the expander. */ max?: number; onOpen?: (source: Source) => void; /** The answer. It renders below the list, so the reader is calibrated first. */ children: ReactNode; }) { const [expanded, setExpanded] = useState(false); const shown = expanded ? sources : sources.slice(0, max); const used = sources.length; return (

retrieved {retrieved}, used {used}

{sources.length > max && ( )}
{children}
); } ──────────────────────────────────────────────────────────────────────── // demo.tsx ──────────────────────────────────────────────────────────────────────── import { SourceList, type Source } from "./SourceList"; /** * Four sources used out of twenty retrieved, above the answer they produced. * Two are open, one is behind a paywall, and the figures spreadsheet is one * the viewer cannot open, which the answer then has to admit. */ const SOURCES: Source[] = [ { title: "Histograms and summaries", domain: "prometheus.io", date: "Jan 2026", url: "https://prometheus.io/docs/practices/histograms/", access: "open" }, { title: "Dashboards: making charts and graphs easier to understand", domain: "nngroup.com", date: "Apr 2026", url: "https://www.nngroup.com/articles/dashboards-preattentive/", access: "open" }, { title: "Cloud spending rises as software firms chase AI capacity", domain: "wsj.com", date: "Aug 2026", url: "https://www.wsj.com/tech/ai/cloud-spending-ai-capacity", access: "paywalled" }, { title: "Q3 figures", domain: "finance/Q3.xlsx", date: "Sep 2026", url: "drive://finance/Q3.xlsx", access: "no-access" }, ]; export default function Demo() { return (
console.log("opened", s.domain)}>

Report latency at p50, p95 and p99 rather than as a mean, since the tail is what pages someone, and put the comparison window beside every figure on the tile. The sector benchmark is taken from the WSJ piece's summary only, and the Q3 spreadsheet could not be read, so the infrastructure line below is from last quarter's figures.

); }