Introducing Real Design System
One of the most common AI code generation failures is component duplication - AI creates new UI components instead of reusing existing ones. This happens because existing components are scattered, undocumented, and inconsistently named. A real design system solves this by providing a single source of truth for UI components.
Key Insight: AI cannot "discover" unorganized components. If components aren't in expected locations with clear documentation, they effectively don't exist to AI.
Problem Statement
Current State: Component Chaos
Evidence from Team Feedback
| Team | Issue | Impact |
|---|---|---|
| Android | UI components scattered, no unified management | AI reimplements existing components |
| Web | 28,476 LOC in models directory, 60+ service classes | AI context window exceeded |
| iOS | No component mapping in design-spec | AI doesn't know which components to use |
| All | Design tokens not systematized | AI hardcodes style values |
Real Examples
Android Team:
"UI components in the Android project mostly haven't been systematically organized. When AI was implementing Floor Plan, it would implement UI itself first, creating more duplicate code."
Web Team:
"DeviceFactory.js (232 lines) defines service mappings that create devices with dynamically composed services... AI context window cannot contain full service mapping context."
Proposal: Unified Design System
Target State
Design System Architecture
design-system/
├── README.md # Design system overview & AI guidelines
├── COMPONENT_INDEX.md # Searchable component directory
│
├── tokens/
│ ├── colors.md # Color palette definitions
│ ├── typography.md # Font styles and sizes
│ ├── spacing.md # Spacing scale
│ ├── shadows.md # Shadow definitions
│ └── breakpoints.md # Responsive breakpoints
│
├── foundations/
│ ├── grid.md # Layout grid system
│ ├── icons.md # Icon library and usage
│ └── motion.md # Animation guidelines
│
├── components/
│ ├── buttons/
│ │ ├── README.md # Button variants and usage
│ │ ├── Button.vue # Web implementation
│ │ ├── Button.swift # iOS implementation
│ │ └── Button.kt # Android implementation
│ │
│ ├── cards/
│ │ ├── README.md
│ │ ├── DeviceCard.vue
│ │ ├── DeviceCard.swift
│ │ └── DeviceCard.kt
│ │
│ ├── lists/
│ │ ├── README.md
│ │ ├── DeviceList.vue
│ │ ├── SiteList.vue
│ │ └── ...
│ │
│ └── forms/
│ ├── README.md
│ ├── Input.vue
│ ├── Select.vue
│ └── ...
│
├── patterns/
│ ├── error-handling.md # Error display patterns
│ ├── loading-states.md # Loading indicator patterns
│ ├── empty-states.md # Empty state designs
│ └── navigation.md # Navigation patterns
│
└── cross-platform/
└── component-mapping.md # Cross-platform equivalentsComponent Documentation Standard
Component README Template
# DeviceCard
A card component for displaying device information with status indicators.
## Preview
[Screenshot or Figma link]
## Usage
### When to Use
- Displaying individual device in a list
- Device detail summary
- Device selection interfaces
### When NOT to Use
- Simple text-only device references (use DeviceLabel)
- Compact list views (use DeviceListItem)
## Variants
| Variant | Use Case | Props |
|---------|----------|-------|
| `default` | Standard device display | `device`, `onClick` |
| `compact` | Space-constrained views | `device`, `hideStatus` |
| `selectable` | Multi-select interfaces | `device`, `selected`, `onSelect` |
## Props
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `device` | `Device` | Yes | - | Device object to display |
| `onClick` | `Function` | No | - | Click handler |
| `variant` | `'default' \| 'compact' \| 'selectable'` | No | `'default'` | Visual variant |
## Platform Implementations
| Platform | File | Notes |
|----------|------|-------|
| Web | `components/DeviceCard.vue` | Uses Tailwind CSS |
| iOS | `Components/DeviceCard.swift` | SwiftUI implementation |
| Android | `ui/components/DeviceCard.kt` | Jetpack Compose |
## Examples
### Web (Vue)
```vue
<DeviceCard
:device="camera"
variant="default"
@click="handleDeviceClick"
/>iOS (SwiftUI)
DeviceCard(device: camera, variant: .default) {
handleDeviceClick()
}Android (Compose)
DeviceCard(
device = camera,
variant = DeviceCardVariant.Default,
onClick = { handleDeviceClick() }
)AI Guidelines
@ai-hint When displaying a device, use this component. Do not implement custom device cards. @ai-hint For lists of devices, combine with DeviceList component. @see DeviceList for displaying multiple devices @see DeviceListItem for compact list rows
## Cross-Platform Component Mapping
### Component Mapping Table
```markdown
# Cross-Platform Component Mapping
This table maps design system components to their platform-specific implementations.
| Component | Web | iOS | Android | Notes |
|-----------|-----|-----|---------|-------|
| **Navigation** |
| TabBar | `TabBar.vue` | `TabView` | `BottomNavigation` | Platform-native |
| NavHeader | `NavHeader.vue` | `NavigationBar` | `TopAppBar` | Custom styling |
| **Content** |
| DeviceCard | `DeviceCard.vue` | `DeviceCard.swift` | `DeviceCard.kt` | Unified design |
| DeviceList | `DeviceList.vue` | `DeviceListView.swift` | `DeviceListComposable.kt` | Virtual scrolling |
| SiteCard | `SiteCard.vue` | `SiteCard.swift` | `SiteCard.kt` | Unified design |
| **Forms** |
| Input | `Input.vue` | `TextField` | `OutlinedTextField` | Platform-native base |
| Select | `Select.vue` | `Picker` | `DropdownMenu` | Custom styling |
| Button | `Button.vue` | `Button.swift` | `Button.kt` | Design system |
| **Feedback** |
| Toast | `Toast.vue` | `Toast.swift` | `Snackbar` | Platform conventions |
| LoadingSpinner | `Loading.vue` | `ProgressView` | `CircularProgressIndicator` | Consistent timing |
| ErrorState | `ErrorState.vue` | `ErrorView.swift` | `ErrorComposable.kt` | Unified messaging |
## AI Usage
When implementing features across platforms:
1. Check this mapping first
2. Use existing components before creating new ones
3. If creating new component, add to this mapping
4. Ensure consistent props/parameters across platformsDesign Tokens
Token Documentation Format
# Colors
## Semantic Colors
Use semantic colors for UI elements. Never use raw color values.
| Token | Light Mode | Dark Mode | Usage |
|-------|------------|-----------|-------|
| `--color-primary` | `#0066CC` | `#4D9FFF` | Primary actions, links |
| `--color-secondary` | `#6B7280` | `#9CA3AF` | Secondary text, icons |
| `--color-success` | `#10B981` | `#34D399` | Success states |
| `--color-warning` | `#F59E0B` | `#FBBF24` | Warning states |
| `--color-error` | `#EF4444` | `#F87171` | Error states |
| `--color-background` | `#FFFFFF` | `#1F2937` | Page background |
| `--color-surface` | `#F9FAFB` | `#374151` | Card backgrounds |
## Device Status Colors
| Token | Value | Usage |
|-------|-------|-------|
| `--device-online` | `#10B981` | Online device indicator |
| `--device-offline` | `#6B7280` | Offline device indicator |
| `--device-error` | `#EF4444` | Device error state |
| `--device-recording` | `#EF4444` | Recording indicator |
## AI Guidelines
@ai-hint Always use semantic tokens, never hardcode colors.
@ai-hint For device status, use the device status color tokens.
@ai-hint Check dark mode compatibility for all color usage.Implementation Roadmap
Phase 1: Inventory (Week 1-2)
Goal: Document existing components across all platforms.
Deliverables:
- [ ] List of all existing UI components per platform
- [ ] Duplicate component identification
- [ ] Initial cross-platform mapping table
Phase 2: Foundation (Week 3-4)
Goal: Establish design tokens and core components.
Deliverables:
- [ ] Design tokens defined (colors, typography, spacing)
- [ ] 5 core components documented (Button, Input, Card, List, Modal)
- [ ] Component README template established
- [ ] COMPONENT_INDEX.md created
Phase 3: Migration (Week 5-8)
Goal: Consolidate existing components into design system.
Deliverables:
- [ ] Move shared components to design system directory
- [ ] Update imports across codebase
- [ ] Add deprecation notices to old component locations
- [ ] Update CLAUDE.md with design system guidelines
Phase 4: AI Integration (Week 9-10)
Goal: Ensure AI consistently uses design system.
Deliverables:
- [ ] Add AI hints to all component documentation
- [ ] Create design system search guidelines in CLAUDE.md
- [ ] Test AI component generation accuracy
- [ ] Iterate on documentation based on AI behavior
CLAUDE.md Integration
Add to project CLAUDE.md:
## Design System
### Component Usage
- **Always check** `design-system/COMPONENT_INDEX.md` before creating new components
- **Use existing components** from `design-system/components/`
- **Follow patterns** from `design-system/patterns/`
### Search Strategy
When looking for UI components:
1. First search in `design-system/components/`
2. Check `COMPONENT_INDEX.md` for component names
3. Only create new component if nothing exists
### Prohibited
- Creating new components without checking design system
- Hardcoding colors (use tokens from `design-system/tokens/`)
- Duplicating existing component functionality
- Using platform-native components when design system equivalent exists
### Adding New Components
If a new component is needed:
1. Create in `design-system/components/[category]/`
2. Follow README template
3. Add to COMPONENT_INDEX.md
4. Create implementations for all platformsSuccess Metrics
| Metric | Before | Target | How to Measure |
|---|---|---|---|
| Component duplication | High | Near zero | Audit for similar components |
| AI component reuse rate | ~40% | >90% | Track AI-generated PRs |
| Time to find component | Minutes | Seconds | Developer survey |
| Cross-platform consistency | Low | High | Visual comparison audit |
| Design token adoption | Partial | 100% | grep for hardcoded values |
Anti-Patterns to Avoid
1. Design System as Afterthought
Problem: Creating design system documentation but not enforcing usage.
Solution: Add pre-commit checks for component usage, integrate with PR reviews.
2. Platform-First Thinking
Problem: Each platform creates components independently, then tries to map.
Solution: Design components platform-agnostic first, then create platform implementations.
3. Over-Engineering
Problem: Creating complex component APIs that AI can't understand.
Solution: Simple, consistent prop interfaces. Prefer composition over configuration.
4. Stale Documentation
Problem: Component documentation doesn't match implementation.
Solution: Generate documentation from code where possible. Regular audits.
Reference Implementation: @vivotek/design-tokens
An existing implementation demonstrates these principles in practice. The @vivotek/design-tokens package provides a real-world example of how to build a design token system that supports both AI comprehension and cross-platform consistency.
Key Implementation Features
W3C DTCG Compliance
Tokens follow the W3C Design Tokens Community Group specification:
{
"colors": {
"$type": "color",
"$description": "VIVOTEK brand color tokens - primitive color scales",
"primary": {
"base": {
"$value": "#006bd6",
"$description": "Primary color - darkened from brand 500 to meet WCAG AA contrast"
},
"foreground": {
"$value": "{colors.white}",
"$description": "Text color on primary background"
}
}
}
}The $description property provides human and AI-readable context, while $value with reference syntax ({colors.white}) enables token aliasing.
Multi-Format Output
Using Style Dictionary v5, the same token source generates:
| Output Format | Use Case | File |
|---|---|---|
| CSS Custom Properties | Web applications | tokens.css |
| TypeScript/JavaScript | Programmatic access | index.ts |
| Tailwind CSS Preset | Utility-first CSS | tailwind-preset.js |
| iOS Swift | Native iOS apps | DesignTokens.swift |
| Android Compose | Jetpack Compose | Color.kt, Spacing.kt |
| Android XML | Legacy Android | colors.xml, dimens.xml |
Domain-Specific Semantic Colors
Beyond generic UI colors, the system includes domain-specific tokens for VSaaS features:
{
"colors": {
"status": {
"online": { "base": "{colors.success.base}" },
"offline": { "base": "{colors.secondary.base}" },
"recording": { "base": "{colors.info.base}" },
"error": { "base": "{colors.error.base}" }
},
"detection": {
"motion": { "base": "{colors.info.base}" },
"intrusion": { "base": "{colors.error.base}" },
"loitering": { "base": "{colors.warning.base}" }
},
"analytics": {
"human": { "base": "{colors.primary.base}" },
"vehicle": { "base": "{colors.warning.base}" },
"face": { "base": "{colors.primary.base}" }
}
}
}This enables AI to understand domain semantics:
- Device status colors map to operational states
- Detection event colors indicate severity levels
- Analytics colors distinguish object types
Theme Support
Light and dark themes use separate token files with the same structure:
tokens/vivotek/
├── colors.tokens.json # Primitive colors
├── colors-light.tokens.json # Light theme semantics
├── colors-dark.tokens.json # Dark theme semantics
├── colors-domain-light.tokens.json
└── colors-domain-dark.tokens.jsonGenerated CSS automatically handles theme switching:
:root {
--primary: #006bd6;
--status-online: #22c55e;
}
.dark {
--primary: #3d8fe8;
--status-online: #4ade80;
}Validation Pipeline
Automated validation ensures token quality:
pnpm validate
# Validates:
# 1. DTCG Schema - All tokens have required properties
# 2. Token References - All aliases point to existing tokens
# 3. WCAG Contrast - Semantic color pairs meet AA standards (4.5:1)This prevents accessibility regressions and ensures AI-generated code using these tokens will be compliant.
Lessons for AI Integration
- Descriptive Metadata: Every token includes
$descriptionfor AI comprehension - Consistent Structure: Predictable paths (
colors.status.online.base) enable reliable code generation - Reference-Based Aliases: Semantic tokens reference primitives, showing relationships
- Multi-Platform Parity: Same token names across all output formats reduce AI confusion
- Domain Vocabulary: Domain-specific color groups align with ubiquitous language
Related: shadcn/ui as Foundation | Back: Proposals Overview
References
- W3C Design Tokens Community Group - Design token specification standard
- Style Dictionary - Amazon's design token build system
- Claude Code Documentation - Official documentation for CLAUDE.md AI guidance files