- Overview health hero derives from subsystem probes when the backend gives no overall status, so it never says "Unknown" next to an all-Healthy Subsystems card (the audit's most jarring contradiction). Home error copy now uses the Phase-2 describeError instead of raw backend strings. - Global prefers-reduced-motion guard (transitions, loops, aurora field) + motion-reduce on the sidebar width transition. - Mobile: content reserves a top row (pt-16 md:p-6) so the floating hamburger never overlaps the page H1. - A11y: collapsed rail items get an explicit aria-label. - Monitoring: disk "busiest mount" tile shows the % as the value and the long mount path as a truncated caption, so it no longer clips mid-word. - New CopyId component (click-to-copy UUIDs), wired into Profile. Typecheck 36→36, 24-route sweep clean. Remaining items (lib a11y labels, table aria-sort, dev-only monitoring data) noted in the spec. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
components/
Component layers in this project.
ui/ shadcn primitives — token-driven, reskinnable per design system
forms/ composed form widgets
data/ data display (tables, filters, empty states)
layout/ app shell, page chrome, navigation wrappers
marketing/ landing and marketing blocks
[system]/ design-system-specific components (e.g. m3/, apple/)
The one rule
Custom components import from ui/, never the reverse.
ui/ is the primitive layer. It must stay reskinnable by swapping tokens in
app/themes/*.css alone. If a component can't be expressed that way (M3
ripple, Apple segmented control, etc.), it belongs in a system-specific
folder — not ui/ and not the shared folders above.
Tokens, not values
Every custom component should reference semantic tokens:
- Colors:
bg-primary,text-muted-foreground,border-border - Radius:
rounded-md,rounded-lg - Fonts:
font-sans,font-heading
Hardcoded hex, oklch, or px values are a bug — they break theming.