Design system
The tokens, components and patterns this workspace is built from. Every preview is live, every component documents its states, and every interaction works from the keyboard.
- Foundations
- 4
- Color, type, space, icons
- Components
- 21
- Each with a live playground
- States each
- 7
- From default to success
- Themes
- 2
- Every preview switches
Quiet by default
A white sheet on a grey desk, hairline borders instead of shadows, and color only where it carries meaning: brand for focus and selection, status colors for state.
Dense, not cramped
13px interface text, 40px rows that drop to 32px in compact density, tabular numerals for anything that lines up in a column.
Tokens all the way down
Components never reference raw values. Every color flows primitive → semantic → utility → component, so a theme is one block of variables.
Accessible by construction
Radix primitives for focus and keyboard behaviour, contrast-checked color pairs, visible focus rings and motion that respects the reduced-motion setting.
Token architecture
Pick a token to trace it from its raw palette value to the components that use it. Switch the theme to see which layer changes.
- 1
Primitive
iris-600#6246eaDark theme uses iris-400 - 2
Semantic
--brand
Defined in :root and .dark. The only layer that changes with the theme.
- 3
Utility
bg-brand, text-brand, ring-ring
Aliased once in @theme inline, so one class works in both themes.
- 4
Components
- Focus ring
- Active nav icon
- Chart series 1
- AI actions
- Text selection
1/* 1. Primitive: raw palette step */2iris-600: #6246ea iris-400: #8b76ff34/* 2. Semantic: swapped per theme */5:root { --brand: #6246ea; }6.dark { --brand: #8b76ff; }78/* 3. Tailwind alias: one utility for both themes */9@theme inline { --color-brand: var(--brand); }1011/* 4. Component */12<Button className="bg-brand text-brand-foreground">Draft with AI</Button>How pages are built
Every component page follows the same five-part anatomy, so you always know where to look.
- 1PlaygroundLive preview with prop controls and the JSX that produces it.
- 2StatesDefault, hover, focus, loading, disabled, error and success side by side.
- 3PatternsWorking compositions from real product screens.
- 4APIProps, types and defaults.
- 5AccessibilityKeyboard map and the ARIA decisions behind it.
- ColorsSemantic color tokens read live from the active theme, with WCAG contrast checks.CSS variablesTailwind v4 @theme
- TypographyA dense UI type scale, a condensed display cut for headlines and mono for code only.Instrument SansJetBrains Mono
- Spacing & elevationThe 4px spacing grid, radius hierarchy, elevation levels and the density token.4px grid--radius
- IconsA curated lucide set at 16px and 1.75–2 stroke. Search and copy the import.lucide-react
- ButtonActions in six variants and four sizes, with loading and icon-only forms.<button>cva
- InputText fields with labels, helper text, addons and inline validation.<input>InputGroup
- SelectPick one option from a short list, with typeahead and grouped options.Radix Select
- Dropdown menuContextual actions with shortcuts, checkable items, radio groups and submenus.Radix DropdownMenu
- ModalFocused tasks and confirmations that block the page until resolved.Radix Dialog
- DrawerSide sheets for record detail and a draggable bottom drawer for mobile.Radix Dialog (Sheet)vaul
- TabsSwitch between views of the same object without leaving the page.Radix Tabs
- TooltipShort labels for icon buttons and shortcuts, on hover and keyboard focus.Radix Tooltip
- ToastNon-blocking feedback for success, errors, pending work and undo.sonner
- TableSortable, selectable records that follow the density setting.<table>Checkbox
- Data grid1,000 editable rows with sticky header and first column, windowed for speed.Manual windowing
- ChartsLine, bar, area and donut charts on the chart palette with thin strokes.Recharts--chart-n
- CardContainers for stats, records and media, from static to interactive.CardPanel
- FormValidation on blur and submit, inline errors that say how to fix them, and a success state.LabelInput
- Date pickerSingle dates and ranges with presets, in a popover calendar.react-day-pickerPopover
- File uploadDrop zone with type and size validation, progress and removal. Files stay in the browser.Drag and drop API
- Command paletteKeyboard-first search across actions and records with fuzzy matching.cmdk
- AI chatA thread with streaming replies, suggestions, stop and retry, and a composer.Streaming UI
- TimelineChronological activity grouped by day, with typed events and connectors.<ol>
- KanbanDrag cards between columns with pointer, touch or keyboard.@dnd-kit
- CalendarA month view with events, today marker and keyboard day navigation.date-fns