Overview then detail Start wide, end narrow, keep your place. The overview's job is to route the reader to the right detail page, which means it needs exactly enough per item to choose and nothing more. npm i lucide-react Tokens this needs: --foreground, --card, --muted, --muted-foreground, --border, --status-nominal, --status-warn, --status-critical, --status-unknown 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. ──────────────────────────────────────────────────────────────────────── // Drilldown.tsx ──────────────────────────────────────────────────────────────────────── import { useState } from "react"; import { Sparkline } from "../sparkline/Sparkline"; import { STATUS_META, type Status } from "../semantic-status-color/status"; /** * Three levels, one subject. The fleet says where to look, the host says which * signal, the signal says what happened. All three stay on screen, so going * back is a glance rather than a page load, and the time range is held once * at the top rather than re-entered at each level. */ export type Signal = { id: string; label: string; status: Status; series: number[]; unit: string }; export type Host = { id: string; status: Status; signals: Signal[] }; export type LogLine = { at: string; text: string }; const CELL: Record = { nominal: "bg-status-nominal", warn: "bg-status-warn", critical: "bg-status-critical", unknown: "bg-status-unknown", }; const STROKE: Record = { nominal: "text-muted-foreground", warn: "text-status-warn", critical: "text-status-critical", unknown: "text-status-unknown", }; const title = "border-b pb-2 text-[11px] uppercase tracking-wide text-muted-foreground"; export function Drilldown({ hosts, range, logsFor, defaultHost, defaultSignal, onNavigate }: { hosts: Host[]; /** Shown once and carried through every level. */ range: string; /** The end of the walk: the lines behind one signal on one host. */ logsFor: (host: Host, signal: Signal) => LogLine[]; defaultHost?: string; defaultSignal?: string; /** Where the viewer is, for the URL, so a bookmark lands at the same depth. */ onNavigate?: (path: { host: string; signal?: string }) => void; }) { const [hostId, setHostId] = useState(defaultHost ?? hosts[0].id); const host = hosts.find((h) => h.id === hostId) ?? hosts[0]; const [signalId, setSignalId] = useState(defaultSignal ?? host.signals[0].id); const signal = host.signals.find((s) => s.id === signalId) ?? host.signals[0]; const pickHost = (h: Host) => { setHostId(h.id); setSignalId(h.signals[0].id); onNavigate?.({ host: h.id }); }; const pickSignal = (s: Signal) => { setSignalId(s.id); onNavigate?.({ host: host.id, signal: s.id }); }; return (

{range}

Fleet

{hosts.map((h) => (

Host · {host.id}

{host.signals.map((s) => ( ))}

{signal.label} · {host.id}

now {signal.series[signal.series.length - 1]}{signal.unit}

    {logsFor(host, signal).map((l) =>
  1. {l.at} {l.text}
  2. )}
); } ──────────────────────────────────────────────────────────────────────── // demo.tsx ──────────────────────────────────────────────────────────────────────── import { Drilldown, type Host, type LogLine, type Signal } from "./Drilldown"; /** * Twenty web hosts, one of them critical on P99. The walk opens on web-07's * P99 panel; clicking any other cell or signal moves the two columns to the * right without touching the one on the left. */ const quiet = (id: string, label: string, series: number[], unit: string): Signal => ({ id, label, status: "nominal", series, unit }); const baseline = (n: number): Signal[] => [ quiet("cpu", "CPU", [31 + n, 34, 30, 36, 33, 35], "%"), quiet("mem", "Memory", [61, 62, 61, 63 + (n % 3), 62, 62], "%"), quiet("rps", "Requests", [410, 420, 405, 440, 430, 425], "/s"), quiet("p99", "P99", [240, 250, 235, 260, 245, 250], "ms"), ]; const HOSTS: Host[] = Array.from({ length: 20 }, (_, i) => { const id = `web-${String(i + 1).padStart(2, "0")}`; if (id !== "web-07") return { id, status: "nominal", signals: baseline(i) }; return { id, status: "critical", signals: [ quiet("cpu", "CPU", [34, 38, 36, 52, 48, 55], "%"), { id: "p99", label: "P99", status: "critical", series: [250, 300, 290, 640, 720, 1420, 1380], unit: "ms" }, quiet("mem", "Memory", [62, 62, 63, 63, 64, 64], "%"), quiet("rps", "Requests", [420, 418, 425, 380, 350, 310], "/s"), ], }; }); const LOGS: Record = { "web-07/p99": [ { at: "14:07:12", text: "GET /checkout 2004ms 504 upstream timeout" }, { at: "14:07:12", text: "pool exhausted: 32/32 connections to pg-primary" }, { at: "14:07:15", text: "GET /checkout 1988ms 504 upstream timeout" }, { at: "14:07:19", text: "retry storm from cart-svc, 3x baseline" }, ], }; export default function Demo() { return ( LOGS[`${h.id}/${s.id}`] ?? [{ at: "—", text: `no events for ${s.label} on ${h.id} in this range` }]} onNavigate={(path) => console.log("route to", path)} /> ); }