Semantic grouping Panels that belong together by meaning, laid out so the grouping is visible without a box around everything. A heading and a gap do more work than a border, and cost less ink. npx shadcn@latest add separator card Tokens this needs: --card, --muted-foreground, --border, --status-warn, --status-critical 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. ──────────────────────────────────────────────────────────────────────── // PanelGroups.tsx ──────────────────────────────────────────────────────────────────────── import type { ReactNode } from "react"; import { Separator } from "@/components/ui/separator"; import { cn } from "@/lib/utils"; /** One axis per page. Subsystem, signal type or audience, chosen once, so a * page cannot group by service at the top and by signal further down. */ export type Axis = "subsystem" | "signal" | "audience"; export type Group = { /** Specific. "Misc", "Other" and "Metrics" are confessions, and they are * flagged rather than silently accepted. */ label: string; /** Ordered by importance, never by when they were added. */ panels: ReactNode[]; }; type Props = { axis: Axis; groups: Group[]; columns?: 2 | 3 | 4; }; const SAYS_NOTHING = /^(misc|miscellaneous|other|metrics|general|stuff)$/i; const COLS = { 2: "grid-cols-2", 3: "grid-cols-3", 4: "grid-cols-4" }; export function PanelGroups({ axis, groups, columns = 3 }: Props) { return (
Nothing here yet.
)}{label}
{value}