Metric targets This is the dashboard knowing what good is. A target turns a number into a judgement, which means the target needs an owner and a date on it or nobody can say whether missing it matters. npx shadcn@latest add card progress Tokens this needs: --background, --card, --card-foreground, --muted, --muted-foreground, --border, --status-warn, --status-critical, --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. ──────────────────────────────────────────────────────────────────────── // MetricTarget.tsx ──────────────────────────────────────────────────────────────────────── import { Card } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; /** * A target is a commitment with provenance, and the provenance is the type. * Owner and review date are required because a target with no name cannot * be revised, only ignored, and an unreviewed one is wrong within a year and * still colouring panels. Panels take a Target; they never retype the number. */ export type Target = { name: string; /** The objective, as a fraction: 0.999 for 99.9%. */ objective: number; /** What the objective is a fraction of: "requests", "checkouts". */ of: string; /** How the indicator is computed, so the reasoning is reachable from the panel. */ measuredAs: string; owner: string; reviewDue: Date; /** What draws or fires on this target. Stored once, referenced from here. */ referencedBy: string[]; }; const DAY = 86_400_000; const pct = (f: number) => `${+(f * 100).toFixed(2)}%`; function review(due: Date, now: Date) { const days = Math.ceil((due.getTime() - now.getTime()) / DAY); if (days < 0) return { text: `overdue by ${-days} days`, cls: "text-status-critical" }; const text = days >= 14 ? `due in ${Math.round(days / 7)} weeks` : `due in ${days} days`; return { text, cls: days <= 30 ? "text-status-warn" : "text-card-foreground" }; } export function TargetCard({ target, now, onOpen }: { target: Target; now: Date; onOpen?: (t: Target) => void }) { const r = review(target.reviewDue, now); return (

{target.name}

objective
{pct(target.objective)} of {target.of}
measured as
{target.measuredAs}
owner
{target.owner}
reviewed
{r.text}

used by

); } /** * The budget is what makes the target usable on a Tuesday. It converts the * pass/fail into a rate: how much of the permitted failure is spent, against * how much of the period has elapsed. */ export function budget(target: Target, period: { start: Date; end: Date }, errors: number, total: number, now: Date) { const allowed = (1 - target.objective) * total; const left = Math.max(0, 1 - errors / allowed); const elapsed = (now.getTime() - period.start.getTime()) / (period.end.getTime() - period.start.getTime()); const daysToGo = Math.ceil((period.end.getTime() - now.getTime()) / DAY); return { left, expectedLeft: 1 - elapsed, daysToGo, fast: left < 1 - elapsed }; } export function ErrorBudget({ target, period, errors, total, now }: { target: Target; /** The period the budget is spread over, usually the quarter. */ period: { start: Date; end: Date }; errors: number; total: number; now: Date; }) { const b = budget(target, period, errors, total, now); return (

Error budget

{Math.round(b.left * 100)}%

left, {b.daysToGo} days to go

{/* Where the budget would be if it were spent evenly over the period. */}

{b.fast ? "burning faster than the quarter allows" : "on pace for the quarter"}

); } ──────────────────────────────────────────────────────────────────────── // demo.tsx ──────────────────────────────────────────────────────────────────────── import { ErrorBudget, TargetCard, type Target } from "./MetricTarget"; /** * One target, stored once, drawn twice: the card that names it and the * budget derived from it. Fifty days into the quarter, 62% of the permitted * failures are spent, so the budget is burning faster than the period allows. */ const NOW = new Date("2026-08-20T09:00:00Z"); const Q3 = { start: new Date("2026-07-01T00:00:00Z"), end: new Date("2026-09-30T00:00:00Z") }; const AVAILABILITY: Target = { name: "Checkout availability", objective: 0.999, of: "requests", measuredAs: "non-5xx / total, 28d", owner: "payments", reviewDue: new Date("2026-09-10T00:00:00Z"), referencedBy: ["availability panel", "the wallboard tile", "the paging rule"], }; export default function Demo() { return (
console.log("open", t.name)} />
); }