# 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.