# DSS Core Principles ## 1. Monolithic Design System Structure **DSS defines THE canonical design system structure. It does not change.** ``` DSS Core Structure (Immutable) ├── tokens/ │ ├── colors/ # color.primary.500, color.neutral.100 │ ├── spacing/ # spacing.xs, spacing.sm, spacing.md │ ├── typography/ # font.size.base, font.weight.bold │ ├── borders/ # border.radius.sm, border.width.default │ ├── shadows/ # shadow.sm, shadow.md, shadow.lg │ └── motion/ # duration.fast, easing.default ├── components/ │ ├── Button/ # Canonical Button implementation │ ├── Input/ # Canonical Input implementation │ ├── Card/ # Canonical Card implementation │ └── ... └── patterns/ ├── forms/ ├── navigation/ └── layouts/ ``` **This structure is sacred. External systems adapt to us, not the reverse.** --- ## 2. Translation Dictionaries (Per-Project) Each client project maintains a **Translation Dictionary** that maps their legacy tokens/styles to DSS canonical tokens. ``` project-acme/ ├── .dss/ │ ├── config.json │ └── translations/ │ ├── figma.json # Figma → DSS mappings │ ├── legacy-css.json # Legacy CSS → DSS mappings │ └── custom.json # Custom props specific to ACME ``` **Translation Dictionary Example:** ```json { "$schema": "dss-translation-v1", "project": "acme-corp", "source": "legacy-css", "mappings": { "tokens": { "--brand-blue": "color.primary.500", "--brand-dark": "color.primary.700", "--text-main": "color.neutral.900", "$spacing-unit": "spacing.base", "var(--gap-small)": "spacing.sm" }, "components": { ".btn-primary": "Button[variant=primary]", ".card-wrapper": "Card", ".input-field": "Input" } }, "custom_props": { "color.brand.acme": "#1E40AF", "color.brand.acme.light": "#3B82F6" } } ``` --- ## 3. Custom Props Strategy When a client needs something outside DSS core: 1. **Never modify DSS core** - The canonical structure stays intact 2. **Add to project's custom namespace** - `color.brand.{client}.*` 3. **Create Storybook template for custom case** - Shows variant without polluting core 4. **Document in translation dictionary** - Full traceability ``` DSS Core (immutable) Client Custom (per-project) ───────────────────── ───────────────────────────── color.primary.500 color.brand.acme.primary color.neutral.100 color.brand.acme.secondary spacing.md spacing.brand.acme.card-gap Button Button + acme-specific props ``` --- ## 4. Multi-System Ingestion Flow ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Figma Tokens │ │ Legacy CSS │ │ Other MCP │ │ (client-a) │ │ (client-b) │ │ (shadcn) │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────┐ │ TRANSLATION LAYER │ │ • Map to DSS canonical tokens │ │ • Identify custom props (not in DSS) │ │ • Store mappings in project translation dictionary │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ DSS CORE (immutable) │ │ + Project Custom Props (isolated namespace) │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ OUTPUT │ │ • Storybook with core + custom stories │ │ • Token files (CSS/SCSS/TS) │ │ • Component library │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 5. Storybook Strategy - **Core Stories** - All DSS canonical components (never modified) - **Client Stories** - Custom variations in isolated `/stories/clients/{client}/` - **Template Stories** - Edge cases, specific customizations ``` storybook/ ├── core/ │ ├── Button.stories.tsx # DSS canonical Button │ ├── Card.stories.tsx # DSS canonical Card │ └── ... ├── clients/ │ ├── acme/ │ │ ├── Button.acme.stories.tsx # ACME-specific Button variant │ │ └── CustomWidget.stories.tsx # ACME-only component │ └── globex/ │ └── Button.globex.stories.tsx # Globex-specific Button variant └── templates/ ├── dark-mode.stories.tsx └── rtl-support.stories.tsx ``` --- ## 6. Component Extension Model ```typescript // DSS Core Component (never changes) interface ButtonProps { variant: 'primary' | 'secondary' | 'ghost'; size: 'sm' | 'md' | 'lg'; children: React.ReactNode; onClick?: () => void; } // Client Extension (in client's codebase, not DSS) interface AcmeButtonProps extends ButtonProps { // ACME-specific props acmeIcon?: 'rocket' | 'star' | 'badge'; acmeTracking?: string; } // Usage: Client wraps DSS component const AcmeButton: React.FC = ({ acmeIcon, acmeTracking, ...props }) => { return ( ); }; ``` --- ## 7. Token Merge System DSS provides intelligent token merging from multiple sources with conflict resolution. ### Merge Strategies | Strategy | Behavior | Use Case | |----------|----------|----------| | `FIRST` | Keep first occurrence | Preserve original values | | `LAST` | Override with latest | Latest source wins | | `PREFER_FIGMA` | Prioritize Figma source | Design-led workflow | | `PREFER_CODE` | Prioritize CSS/SCSS | Code-led workflow | | `PREFER_SPECIFIC` | Prefer concrete values over references | Resolve `var()` references | | `MERGE_METADATA` | Combine metadata, use latest value | Preserve history | ### Merge Flow ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Source A │ │ Source B │ │ Source C │ │ (CSS) │ │ (SCSS) │ │ (Figma) │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ └────────────┬────┴────────────────┘ ▼ ┌──────────────────────┐ │ TOKEN MERGER │ │ • Detect conflicts │ │ • Apply strategy │ │ • Track resolution │ └──────────┬───────────┘ ▼ ┌──────────────────────┐ │ MERGE RESULT │ │ • Unified tokens │ │ • Conflict report │ │ • Resolution log │ └──────────────────────┘ ``` ### Conflict Resolution Example ```python from tools.ingest import TokenMerger, MergeStrategy # Merge with Figma priority merger = TokenMerger(strategy=MergeStrategy.PREFER_FIGMA) result = merger.merge([css_tokens, scss_tokens, figma_tokens]) # Check conflicts for conflict in result.conflicts: print(f"{conflict.token_name}: {conflict.resolution}") print(f" Kept: {conflict.resolved_token.value}") ``` --- ## 8. UI Library Atomic Structure Comparison Different UI libraries use fundamentally different atomic structures. DSS normalizes them all. ### Comparison Table | Feature | HeroUI | shadcn | Legacy CSS | DSS Canonical | |---------|--------|--------|------------|---------------| | **Color System** | Numeric scales (50-900) | Semantic pairs | Inconsistent | Numeric scales | | **Granularity** | HIGH (10 shades) | LOW (2 values) | VARIES | HIGH (10 shades) | | **Naming** | `--heroui-primary-500` | `--primary` | `--brand-blue` | `color.primary.500` | | **CSS Prefix** | `heroui-` | None | Various | None (dot notation) | | **Theme Layers** | content1-4 | card, popover, muted | Random | neutral.50-900 | | **Spacing** | `--heroui-spacing-unit` | None (Tailwind) | `--space-*` | `spacing.xs-2xl` | | **Radius** | `--heroui-radius-{size}` | `--radius` | Various | `radius.sm-full` | ### Translation Patterns **HeroUI → DSS** (Direct 1:1 mapping, strip prefix): ``` --heroui-primary-500 → color.primary.500 --heroui-primary-600 → color.primary.600 --heroui-content1 → color.neutral.50 --heroui-content2 → color.neutral.100 --heroui-radius-small → radius.sm --heroui-radius-medium → radius.md --heroui-shadow-small → shadow.sm ``` **shadcn → DSS** (Expand semantic to scale): ``` --primary → color.primary.500 (default value) --primary-foreground → color.primary.50 (contrast) --secondary → color.secondary.500 --muted → color.neutral.200 --muted-foreground → color.neutral.600 --destructive → color.danger.500 --border → color.neutral.200 --radius → radius.md ``` **Legacy CSS → DSS** (Normalize chaos): ``` --brand-blue → color.primary.500 --brand-dark-blue → color.primary.700 --brandAccent → color.warning.500 (camelCase normalized) --SPACING_LG → spacing.lg (SCREAMING_CASE normalized) --space-xs → spacing.xs --spacing-md → spacing.md (different prefix normalized) ``` ### Key Insight: Headless vs Full Design Systems ``` ┌─────────────────────────────────────────────────────────────────────┐ │ ATOMIC STRUCTURE TYPES │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ FULL DESIGN SYSTEM (HeroUI) HEADLESS (shadcn) │ │ ───────────────────────────── ───────────────── │ │ • Complete color scales • Semantic tokens only │ │ • 10 shades per color • 2 values (color + contrast) │ │ • Ready-to-use values • Expects Tailwind to fill │ │ • Opinionated styling • Minimal, composable │ │ │ │ DSS APPROACH: │ │ • HeroUI: Direct mapping (strip prefix) │ │ • shadcn: Expand semantics to full scales │ │ • Both: Translate TO canonical structure │ │ │ └─────────────────────────────────────────────────────────────────────┘ ``` --- ## 9. Translation Dictionary Schema ### Full Schema Definition ```json { "$schema": "dss-translation-v1", "project": "project-name", "source": "heroui | shadcn | css | scss | figma | tailwind", "version": "1.0.0", "created": "2025-01-15", "mappings": { "tokens": { "": "" }, "components": { "": "[variant=value]" }, "patterns": { "": "" } }, "custom_props": { "": "" }, "unmapped": [ "List of source tokens that couldn't be mapped" ], "notes": [ "Human-readable notes about this translation" ] } ``` ### Example: Complete HeroUI Translation ```json { "$schema": "dss-translation-v1", "project": "heroui-migration", "source": "heroui", "version": "1.0.0", "mappings": { "tokens": { "--heroui-primary-50": "color.primary.50", "--heroui-primary-100": "color.primary.100", "--heroui-primary-200": "color.primary.200", "--heroui-primary-300": "color.primary.300", "--heroui-primary-400": "color.primary.400", "--heroui-primary-500": "color.primary.500", "--heroui-primary-600": "color.primary.600", "--heroui-primary-700": "color.primary.700", "--heroui-primary-800": "color.primary.800", "--heroui-primary-900": "color.primary.900", "--heroui-content1": "color.neutral.50", "--heroui-content2": "color.neutral.100", "--heroui-content3": "color.neutral.200", "--heroui-content4": "color.neutral.300", "--heroui-radius-small": "radius.sm", "--heroui-radius-medium": "radius.md", "--heroui-radius-large": "radius.lg", "--heroui-shadow-small": "shadow.sm", "--heroui-shadow-medium": "shadow.md", "--heroui-shadow-large": "shadow.lg" }, "components": { "Button": "Button", "Card": "Card", "Input": "Input", "Modal": "Modal", "Dropdown": "Select" } }, "custom_props": {}, "notes": [ "HeroUI uses numeric scales - direct 1:1 mapping", "Content layers map to neutral scale", "Component APIs are similar, minimal translation needed" ] } ``` ### Example: Complete shadcn Translation ```json { "$schema": "dss-translation-v1", "project": "shadcn-migration", "source": "shadcn", "version": "1.0.0", "mappings": { "tokens": { "--background": "color.neutral.50", "--foreground": "color.neutral.900", "--primary": "color.primary.500", "--primary-foreground": "color.primary.50", "--secondary": "color.secondary.500", "--secondary-foreground": "color.secondary.50", "--muted": "color.neutral.200", "--muted-foreground": "color.neutral.600", "--accent": "color.accent.500", "--accent-foreground": "color.accent.50", "--destructive": "color.danger.500", "--card": "color.neutral.50", "--card-foreground": "color.neutral.900", "--popover": "color.neutral.50", "--popover-foreground": "color.neutral.900", "--border": "color.neutral.200", "--input": "color.neutral.200", "--ring": "color.primary.500", "--radius": "radius.md" }, "components": { "Button": "Button", "Card": "Card", "Input": "Input", "Dialog": "Modal", "Popover": "Popover", "Select": "Select", "Checkbox": "Checkbox", "RadioGroup": "RadioGroup" } }, "custom_props": { "color.chart.1": "hsl(12 76% 61%)", "color.chart.2": "hsl(173 58% 39%)", "color.chart.3": "hsl(197 37% 24%)", "color.chart.4": "hsl(43 74% 66%)", "color.chart.5": "hsl(27 87% 67%)", "color.sidebar.primary": "var(--sidebar-primary)", "color.sidebar.accent": "var(--sidebar-accent)" }, "notes": [ "shadcn is HEADLESS - no numeric color scales", "Semantic names expand to 500 (default) DSS values", "foreground variants map to contrast colors (50)", "Chart colors are shadcn-specific, isolated in custom_props", "Sidebar colors are shadcn-specific, isolated in custom_props" ] } ``` --- ## Summary | Principle | Rule | |-----------|------| | **Structure** | DSS core is monolithic and immutable | | **Translation** | Each project has translation dictionaries | | **Custom Props** | Isolated namespace, never pollute core | | **Storybook** | Core + client-specific stories separated | | **Components** | Clients extend/wrap, never modify core | | **Ingestion** | All external systems translate TO DSS | | **Merge** | Multiple strategies for conflict resolution | | **Atomic Structure** | Normalize all UI libraries to canonical format |