File size: 8,760 Bytes
1b2323a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# MediaRouter Design System v1

## Purpose

The MediaRouter Design System is the backend-agnostic UI foundation for the
workspace product. It is intentionally not a collection of application pages:
future Dashboard, Projects, AI, media, publishing, analytics, and automation
experiences compose these primitives instead of adding one-off visual rules.

The implementation lives in `frontend/` and works with the Next.js App Router,
TypeScript, Tailwind CSS, shadcn-compatible Radix primitives, CVA,
Framer Motion, Lucide, React Hook Form, Zod, TanStack Table/Virtual/Query,
Zustand, `next-themes`, and Storybook.

## Architecture

```text
design-system/
  tokens/       typed references to CSS semantic tokens
  themes/       theme provider and high-contrast control
  foundations/  shared conventions and accessibility rules
  motion/       Framer Motion presets
  icons/        the only Lucide import boundary for new system components
components/
  ui/           accessible Radix/shadcn-compatible primitives
  layout/       workspace, panel, split-pane and responsive layout primitives
  navigation/   navigation, breadcrumbs, switchers and quick actions
  feedback/     alerts, toast API, loading/empty/error/offline/progress states
  forms/        composable RHF/Zod-ready controls
  charts/       backend-neutral chart frame
  timeline/     timeline primitives
  media/        backend-neutral media and asset cards
hooks/          interaction, reduced-motion, Zod form and table hooks
stories/        Storybook component catalog
```

No primitive makes a REST, MCP, n8n, SDK, storage, or provider call. Data and
actions are injected by a consuming feature.

## Tokens and theming

`app/globals.css` owns CSS custom-property values. Tailwind maps only semantic
names such as `bg-surface`, `text-text-secondary`, `border-border`,
`bg-ai`, `text-success`, and `bg-timeline-track`. Component source must never
add a literal color value.

Semantic color tokens cover background, surface, elevated surface, border,
primary, secondary, accent, success, warning, danger, info, muted, three text
levels, overlay, focus ring, selection, timeline track/marker/cursor, and AI,
publishing, analytics, and automation accents. Each has light, dark, and
high-contrast values.

The standardized spacing scale is 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80,
and 96 pixels (`space-1` through `space-24`). New components use classes such
as `gap-space-3`, `p-space-6`, and `px-space-4`, not arbitrary spacing.

Radius tokens are `ds-sm`, `ds-md`, `ds-lg`, `ds-xl`, `ds-2xl`, and `ds-full`.
Shadow tokens are `ds-sm`, `ds-md`, `ds-lg`, `floating`, `modal`, and
`popover`.

`ThemeProvider` in `design-system/themes/theme-provider.tsx` wraps
`next-themes` and supports `light`, `dark`, `system`, and `high-contrast`.
Theme preferences are client-side presentation preferences only; no backend
state is required. `ThemeToggle` cycles all modes.

## Typography, icons, and motion

`components/typography/typography.tsx` provides Display, Heading, Title,
Subtitle, Body, Caption, LabelText, Code, and the composable `Typography`
primitive. The scale uses semantic font-size tokens and balances dense
workspace information with readable hierarchy.

New design-system components import icons only from
`design-system/icons/icon.tsx`. `Icon` uses size tokens, a consistent 1.8
stroke, and is decorative unless a `label` is supplied. This prevents raw
Lucide usage from fragmenting icon weights and accessibility behavior.

`design-system/motion/presets.ts` supplies page, sidebar, dialog, popover,
tooltip, toast, hover, press, accordion, tabs, card, list, timeline, drawer,
bottom-sheet, loading, skeleton, and progress presets. Use
`useMediaRouterReducedMotion()` for interactive Framer Motion consumers. The
global stylesheet also reduces native/Tailwind motion when the operating system
requests reduced motion.

## Component inventory

### Core UI

- Button, IconButton, ToggleButton, SplitButton, DropdownMenu
- Card, Panel, Section, Container, Stack, Grid, Page, ContentArea
- Dialog, Drawer, BottomSheet, Popover, Tooltip, Tabs, Accordion
- Badge, StatusBadge, ProviderBadge, AIBadge, Avatar, Separator
- Command/CommandPalette/Spotlight, Combobox, Pagination, Calendar/DatePicker
- Progress and Skeleton

### Forms

- Input, Textarea, Select, Checkbox, RadioGroup, Switch, Slider
- Email, URL, phone, number, currency, search, password, OTP, and color inputs
- Field shell with helper, success, required, disabled, and error states
- FileDropzone, TagInput, MediaSelector, RHF `Form`, and `useZodForm`

### Data, media, and feedback

- `useDataTable`, DataTable, and VirtualTable (sorting, filtering, grouping,
  selection, visibility, sticky headers, responsive overflow)
- MetricCard, StatCard, KPICard, Timeline, ActivityItem
- MediaCard, AssetCard, ProjectCard, ChartContainer
- Alert, Error/Retry/Success banners, toast API, Empty/Error/Offline states,
  and job/upload/AI/publishing progress

### Navigation and workspace layout

- WorkspaceShell, Sidebar, Topbar, Inspector, SplitPane, ResizablePanel,
  Toolbar, Dock, FloatingPanel
- Sidebar/Mobile navigation, Breadcrumb, WorkspaceSwitcher, ProjectSwitcher,
  and QuickActions

## Accessibility standard

The minimum target is WCAG 2.2 AA:

- Radix primitives provide focus traps, escape handling, menu/listbox/dialog
  keyboard behavior, and screen-reader relationships.
- Interactive controls have visible semantic focus rings and disabled states.
- Icon-only controls require a text label; decorative icons are hidden.
- Form fields offer label, helper, required, success, and `role=alert` error
  affordances.
- Tables use semantic headers and rows; loading and progress use `aria-busy`,
  `progress`, status regions, and live text where appropriate.
- High-contrast theme tokens increase contrast without changing component
  source. Reduced-motion preferences disable decorative motion.
- Storybook includes `@storybook/addon-a11y` configured to fail accessibility
  checks in the component catalog.

Consumers remain responsible for meaningful labels, error copy, logical tab
order across a composed page, and testing real content contrast.

## Responsive behavior

The system is mobile-first. `xs`, tablet, laptop, desktop, wide, and
ultra-wide breakpoints are available. Grid and workspace primitives collapse
to a single column before sidebars/inspectors appear. Tables retain semantics
with horizontal overflow; consuming features may use their own compact-card
renderer for intentionally collapsed mobile views. The bottom dock and bottom
sheet are mobile-ready, including safe-area padding.

## Storybook

Run from `frontend/`:

```bash
npm run storybook
npm run storybook:build
```

Stories cover UI foundations, interactive overlays and controls, forms,
feedback, layout/navigation, data display, media, states, sizes, loading,
dark/high-contrast controls, and responsive composition. The Storybook toolbar
selects light, dark, and high-contrast themes.

## Best practices

1. Compose primitives; do not introduce page-local UI primitives.
2. Use semantic Tailwind tokens and spacing/radius/shadow tokens.
3. Keep backend queries, mutation logic, API URLs, and provider credentials
   outside the design system.
4. Add closed typed props and CVA variants before adding a visual state.
5. Use `forwardRef` for DOM controls and primitives intended for composition.
6. Use `Icon` rather than raw Lucide imports in all new system code.
7. Use `loading`, empty, error, offline, and disabled states intentionally.
8. Do not animate state merely because it changed; apply motion presets only
   when they clarify hierarchy or progress.

## Contribution guide

For each new primitive:

1. Confirm that it cannot be composed from an existing primitive.
2. Add semantic tokens only when the state has a cross-product meaning.
3. Implement typed props, CVA variants, focus/keyboard behavior, high
   contrast, reduced motion, loading/empty/error where applicable, and a
   `forwardRef` when it owns a DOM element.
4. Add a Storybook story that covers variants, sizes, disabled/loading, dark
   mode, high contrast, keyboard behavior, and responsive behavior.
5. Run `npm run lint`, `npm run typecheck`, `npm test`, `npm run build`, and
   `npm run storybook:build` before merging.

## Future extensions

The foundations intentionally leave backend-bound concerns for future feature
work: workspace data adapters, project data, provider-specific visual
metadata, server-driven chart schemas, persisted user layout preferences,
internationalization, more date-range/calendar behavior, and advanced grid
column personalization. Those additions must consume this system rather than
add page-local visual foundations.