npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@marioschmidt/design-system-tokens

v1.8.2

Published

BILD Design System Token Pipeline with Style Dictionary - Multi-brand design tokens for BILD, SportBILD, and Advertorial

Readme

🎨 BILD Design System - Token Pipeline

Part of the BILD Design Ops Pipeline | Icon Documentation | Component Documentation

Multi-platform design token transformation pipeline powered by Style Dictionary v4 with Figma-scoped semantic type detection.

npm version Build Status


📋 Table of Contents


🎯 Overview

This pipeline processes the multi-layer, multi-brand BILD Design System architecture:

  • 3 Brands: BILD, SportBILD, Advertorial
  • 3 Platforms: Web (CSS, JSON), iOS (SwiftUI), Android (Compose)
  • Multiple Modes: Density (3), Breakpoints (4), Color Modes (2)
  • Token Types: Primitives, Semantic Tokens, Component Tokens (~970 files)
  • Shadow DOM Compatible: Works with Stencil, Lit, and native Web Components

Token Architecture (4 Layers)

┌─────────────────────────────────────────────────────────────────────────────┐
│  LAYER 4: Component Tokens                                                   │
│  ─────────────────────────────────────────────────────────────────────────  │
│  Button, Card, Teaser, Alert, InputField, etc.                              │
│  Modes: color (light/dark), density, breakpoint, typography                 │
│  References → Semantic Tokens                                               │
├─────────────────────────────────────────────────────────────────────────────┤
│  LAYER 3: Semantic Tokens                                                    │
│  ─────────────────────────────────────────────────────────────────────────  │
│  text-color-primary, surface-color-secondary, border-color-*, etc.          │
│  Modes: color (light/dark), breakpoint                                      │
│  References → Brand Mapping                                                 │
├─────────────────────────────────────────────────────────────────────────────┤
│  LAYER 2: Brand Mapping + Density                                            │
│  ─────────────────────────────────────────────────────────────────────────  │
│  BrandColorMapping: Color Primitives → Brands                               │
│  BrandTokenMapping: Other Primitives → Brands                               │
│  Density: default, dense, spacious                                          │
│  Modes: BILD, SportBILD, Advertorial                                        │
├─────────────────────────────────────────────────────────────────────────────┤
│  LAYER 1: Primitives (Global)                                                │
│  ─────────────────────────────────────────────────────────────────────────  │
│  colorprimitive, spaceprimitive, sizeprimitive, fontprimitive               │
│  Absolute values: --bildred: #DD0000, --space2x: 16px                       │
└─────────────────────────────────────────────────────────────────────────────┘

CSS var() Alias Chain

Tokens use var() references to maintain the alias chain from Figma:

/* Color: Component → Semantic → Primitive */
--button-primary-bg-color: var(--core-color-primary, #DD0000);
                                ↓
--core-color-primary: var(--bildred, #DD0000);
                           ↓
--bildred: #DD0000;

/* Spacing: BreakpointMode → Density → Primitive */
--stack-space-resp-md: var(--density-xs-stack-space-resp-md);
                                ↓
--density-xs-stack-space-resp-md: var(--space-1-p-5-x, 12px);
                                       ↓
--space-1-p-5-x: 12px;

/* Shadow Effects: Mode-agnostic with var() for all properties */
[data-color-brand="bild"] .shadow-soft-sm {
  box-shadow: var(--size-0-x, 0px) var(--size-0-p-25-x, 2px) ... var(--shadow-color-soft-key-sm);
}
/* Colors are theme-aware, dimensions are constant */

This enables:

  • Theme switching without recompiling (change primitives = change all)
  • Brand switching via data attributes
  • Density switching via data-density attribute (default/dense/spacious)
  • Mode-agnostic shadows with theme-aware colors via var()
  • Conditional fallbacks (primitives get fallbacks, semantics don't)

Pipeline Flow

┌─────────────────────────────────────────────────┐
│ Figma Variables (Design Source)                 │
│ • BILD Design System file                       │
│ • Variables with Scopes & Aliases               │
│ • CodeBridge plugin export                      │
└───────────────────────┬─────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────┐
│ Raw Export (src/design-tokens/)                 │
│ • bild-design-system-raw-data.json              │
└───────────────────────┬─────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────┐
│ Preprocessing (scripts/tokens/preprocess.js)    │
│ • Scope-based type determination                │
│ • Alias resolution                              │
│ • Component token detection                     │
└───────────────────────┬─────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────┐
│ Intermediate (tokens/)                          │
│ • Style Dictionary format                       │
│ • ~920 JSON files (tracked in Git)              │
└───────────────────────┬─────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────┐
│ Style Dictionary Build                          │
│ • Platform-specific transforms                  │
│ • iOS: CGFloat Points (not px strings)          │
│ • iOS: SwiftUI Color                            │
└───────────────────────┬─────────────────────────┘
                        ↓
┌─────────────────────────────────────────────────┐
│ Build Output (dist/)                            │
│ • 969 successful builds                         │
│ • NOT tracked in Git (CI artifacts)             │
└─────────────────────────────────────────────────┘

Installation

Web (npm)

npm install @marioschmidt/design-system-tokens

iOS (Swift Package Manager)

In Xcode: File → Add Package Dependencies

URL: https://github.com/UXWizard25/bild-design-system.git
Product: BildDesignTokens

✅ No authentication required (public repository)

Android (GitHub Packages Maven)

See packages/tokens-android/README.md for detailed setup instructions.

// build.gradle.kts
implementation("de.bild.design:tokens:1.0.0")

⚠️ GitHub Packages requires authentication (GitHub Personal Access Token with read:packages scope)

Quick Start

# Full build (tokens + components)
npm run build

# Build tokens only
npm run build:tokens   # Preprocess + Style Dictionary + bundles

# Build everything (tokens + icons + components)
npm run build:all

# Stencil Web Components
npm run build:components  # Build Stencil components (requires tokens built first)
npm run dev:stencil       # Dev server with hot reload (port 3333)

Monorepo Structure

This package is part of the monorepo with platform-specific token packages:

| Package | Package Name | Location | |---------|--------------|----------| | Tokens (Web) | @marioschmidt/design-system-tokens (npm) | packages/tokens/ | | Tokens (iOS) | BildDesignTokens (SPM) | packages/tokens-ios/ | | Tokens (Android) | de.bild.design:tokens (Maven) | packages/tokens-android/ | | Icons | @marioschmidt/design-system-icons (npm) | packages/icons/ | | Components | @marioschmidt/design-system-components (npm) | packages/components/core/ | | React | @marioschmidt/design-system-react (npm) | packages/components/react/ | | Vue | @marioschmidt/design-system-vue (npm) | packages/components/vue/ |

Token Type Mapping

Figma token types ($type) are automatically mapped to platform-specific types:

| Figma $type | CSS | Swift (iOS) | Kotlin (Android) | |---------------|-----|-------------|------------------| | dimension | var(--token) (px) | CGFloat | Dp (.dp) | | fontSize | var(--token) (px¹) | CGFloat | TextUnit (.sp) | | lineHeight | var(--token) (unitless²) | CGFloat | TextUnit (.sp) | | letterSpacing | var(--token) (px) | CGFloat | TextUnit (.sp) | | fontWeight | var(--token) | FontWeight | FontWeight | | number | var(--token) | CGFloat | Float | | fontFamily | var(--token) | String | String | | string | var(--token) | String | String | | boolean | var(--token) | Bool | Boolean | | opacity | var(--token) (0-1) | CGFloat | Float | | color | var(--token) (hex/rgba) | Color | Color | | shadow | box-shadow | ShadowStyle | ShadowStyle | | typography | CSS classes | TextStyle | DesignTextStyle |

¹ fontSize CSS unit is configurable via FONT_SIZE_UNIT in style-dictionary.config.js ('px' or 'rem'). Default: 'px'. ² lineHeight CSS output is always unitless (ratio = lineHeight ÷ fontSize, e.g., 1.33). Scales proportionally with font-size.

Token Type Distribution

| $type | Count | Description | |-------|-------|-------------| | dimension | 3557 | Spacing, sizing, layout values | | typography | 1356 | Composite font definitions | | fontSize | 1086 | Font size values | | color | 1012 | Color values (hex, rgba) | | lineHeight | 840 | Line height values | | fontWeight | 318 | Font weight values (100-1000) | | fontFamily | 307 | Font family names | | letterSpacing | 155 | Letter spacing values | | string | 133 | String values (e.g., breakpoint names) | | boolean | 102 | Boolean flags | | shadow | 78 | Drop shadow definitions | | opacity | 72 | Opacity percentages (0-100) | | number | 24 | Generic numeric values |

Platform Usage

CSS

@import '@marioschmidt/design-system-tokens/css/brands/bild/semantic/color/colormode-light.css';

.button {
  background-color: var(--text-color-accent-constant);
  padding: var(--space2x);
  opacity: var(--layer-opacity50);
}

iOS Swift

import SwiftUI
import BildDesignTokens

// Colors (SwiftUI Color)
Rectangle()
    .fill(BildColorsLight.textColorPrimary)

// Dimensions (CGFloat)
let padding: CGFloat = BildSizingCompact.space2x  // 16

// With Theme Provider
.designSystemTheme(colorBrand: .bild, darkTheme: false) {
    theme.colors.textColorPrimary
}

Android Jetpack Compose (Dual-Axis Architecture)

See Android USAGE.md for complete documentation

import com.bild.designsystem.shared.DesignSystemTheme
import com.bild.designsystem.shared.ColorBrand
import com.bild.designsystem.shared.ContentBrand
import com.bild.designsystem.bild.components.ButtonTokens

@Composable
fun MyScreen() {
    // Dual-Axis Theme Provider
    DesignSystemTheme(
        colorBrand = ColorBrand.Bild,        // Color palette (Bild or Sportbild)
        contentBrand = ContentBrand.Bild,    // Sizing/Typography (Bild, Sportbild, Advertorial)
        darkTheme = isSystemInDarkTheme(),
        sizeClass = WindowSizeClass.Compact,
        density = Density.Default
    ) {
        // Polymorphic access via unified interfaces
        Text(color = DesignSystemTheme.colors.textColorPrimary)
        val fontSize = DesignSystemTheme.sizing.headline1FontSize

        // Component tokens via current() accessors
        val bgColor = ButtonTokens.Colors.current().buttonPrimaryBgColorIdle
    }
}

// Advertorial with SportBILD colors (key use case)
DesignSystemTheme(
    colorBrand = ColorBrand.Sportbild,
    contentBrand = ContentBrand.Advertorial
) { AdvertorialContent() }

Dual-Axis Architecture

Separates color selection from content selection:

| Axis | Enum | Values | Purpose | |------|------|--------|---------| | Color | ColorBrand | Bild, Sportbild | Color palette & effects | | Content | ContentBrand | Bild, Sportbild, Advertorial | Sizing, typography, layout |

Unified Interfaces (Polymorphic Access)

Both iOS and Android implement identical unified protocols/interfaces for polymorphic theme access:

| Interface | Purpose | Property Count | iOS Type | Android Type | |-----------|---------|----------------|----------|--------------| | DesignColorScheme | All color tokens | 80+ colors | Color | Color | | DesignSizingScheme | All sizing tokens | 180+ values | CGFloat | Dp | | DesignTypographyScheme | All text styles | 37 styles | TextStyle | DesignTextStyle | | DesignEffectsScheme | Shadow tokens (brand-independent) | 8 shadows | ShadowStyle | ShadowStyle | | DesignDensityScheme | Density spacing tokens (brand-independent, internal) | 28 tokens | CGFloat | Dp |

Note: Full iOS/Android architecture parity. Both platforms provide theme.colors, theme.sizing, theme.typography, and theme.effects accessors with polymorphic brand switching at runtime.

Density-Aware Spacing (Consumer API)

Density tokens are internal and resolved automatically via BreakpointMode properties:

// Android - Use BreakpointMode token names (NOT densitySpacing directly)
@Composable
fun MyLayout() {
    val respSpacing = DesignSystemTheme.stackSpaceRespMd   // Responsive: varies by WindowSizeClass × Density
    val constSpacing = DesignSystemTheme.stackSpaceConstLg // Constant: same across all WindowSizeClasses

    Column(verticalArrangement = Arrangement.spacedBy(respSpacing)) {
        // Content
    }
}
// iOS - Use BreakpointMode token names (NOT densitySpacing directly)
struct MyLayout: View {
    @Environment(\.designSystemTheme) var theme

    var body: some View {
        VStack(spacing: theme.stackSpaceRespMd) {   // Responsive: varies by SizeClass × Density
            // Or constant: theme.stackSpaceConstLg  // Same across all SizeClasses
        }
    }
}

| Token Type | Example | Behavior | |------------|---------|----------| | Responsive | stackSpaceRespMd | Varies by WindowSizeClass/SizeClass × Density mode | | Constant | stackSpaceConstLg | Same value across all WindowSizeClasses, varies by Density only |

Note: The densitySpacing property is internal. Always use the semantic token names (stackSpaceRespMd, stackSpaceConstLg, etc.) which automatically resolve based on the current sizeClass and density mode.

Important - Single Entry Point: Density-aware spacing tokens (stackSpaceRespMd, stackSpaceConstLg, etc.) are NOT part of DesignSizingScheme. They are only accessible via DesignSystemTheme resolvers, which perform the WindowSizeClass × Density matrix lookup.

Component Token Accessors

All Component Tokens provide theme-aware current() accessors:

| Accessor | Selects based on | iOS Values | Android Values | |----------|-----------------|------------|----------------| | Colors.current() | isDarkTheme | Light / Dark | Light / Dark | | Sizing.current() | sizeClass | Compact / Regular | Compact / Medium / Expanded | | Typography.current() | sizeClass | Compact / Regular | Compact / Medium / Expanded | | Density.current() | density | Dense / Default / Spacious | Dense / Default / Spacious | | Effects.current() | isDarkTheme | Light / Dark | Light / Dark |

Note: Android uses Material 3 WindowSizeClass with 3 values (Compact/Medium/Expanded), while iOS uses Apple's 2-value system (compact/regular).

iOS SwiftUI (Dual-Axis Architecture)

See iOS USAGE.md for complete documentation

import SwiftUI

struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .designSystemTheme(
                    colorBrand: .bild,        // Color palette
                    contentBrand: .bild,      // Sizing/Typography
                    darkTheme: false,
                    sizeClass: .compact
                )
        }
    }
}

struct MyView: View {
    @Environment(\.designSystemTheme) var theme

    var body: some View {
        // Polymorphic access via unified protocols
        Text("Hello")
            .foregroundColor(theme.colors.textColorPrimary)
            .textStyle(theme.typography.headline1)  // Typography

        // Sizing tokens
        let padding = theme.sizing.gridSpaceRespBase

        // Component tokens
        Button("Click") { }
            .background(ButtonTokens.Colors.light.buttonPrimaryBrandBgColorIdle)
    }
}

// Advertorial with SportBILD colors
.designSystemTheme(
    colorBrand: .sportbild,
    contentBrand: .advertorial
)

iOS Unified Protocols

| Protocol | Purpose | |----------|---------| | DesignColorScheme | All color tokens | | DesignSizingScheme | All sizing tokens | | DesignTypographyScheme | All text styles (TextStyle composites) | | DesignEffectsScheme | Shadow tokens (ShadowStyle composites, brand-independent) |

Web Components (Stencil, Lit)

CSS Custom Properties inherit through Shadow DOM, enabling seamless theming:

// Stencil Component
@Component({
  tag: 'my-button',
  shadow: true,
  styles: `
    .btn {
      /* Token values inherit from Light DOM automatically! */
      background: var(--button-primary-brand-bg-color-idle);
      color: var(--button-primary-label-color);
      padding: var(--button-stack-space) var(--button-inline-space);
      border-radius: var(--button-border-radius);
    }
    .btn:hover {
      background: var(--button-primary-brand-bg-color-hover);
    }
  `
})
export class MyButton { /* ... */ }
<!-- Usage: Tokens on body, components inherit automatically -->
<body data-color-brand="bild" data-content-brand="bild" data-theme="light" data-density="default">
  <my-button>BILD Button</my-button>  <!-- Red -->
</body>

<body data-color-brand="sportbild" data-content-brand="sportbild" data-theme="dark" data-density="dense">
  <my-button>Sport Button</my-button>  <!-- Blue -->
</body>

Theming Attributes:

| Attribute | Options | Purpose | |-----------|---------|---------| | data-color-brand | bild, sportbild | Colors & effects | | data-content-brand | bild, sportbild, advertorial | Typography & sizing | | data-theme | light, dark | Color mode | | data-density | default, dense, spacious | Spacing density |

Note: See docs/css.md for complete Shadow DOM documentation.

Responsive CSS Architecture

Breakpoint Implementation

Breakpoints use native @media queries instead of data-breakpoint attributes:

/* Base values (xs breakpoint) */
[data-brand="bild"] {
  --headline1-font-size: 32px;
}

/* Responsive overrides */
@media (min-width: 390px) {  /* sm */
  [data-brand="bild"] { --headline1-font-size: 40px; }
}
@media (min-width: 600px) {  /* md */
  [data-brand="bild"] { --headline1-font-size: 48px; }
}
@media (min-width: 1024px) { /* lg */
  [data-brand="bild"] { --headline1-font-size: 64px; }
}

Breakpoint Values: | Breakpoint | Min-Width | Use Case | |------------|-----------|----------| | xs | 320px | Mobile (default) | | sm | 390px | Large mobile | | md | 600px | Tablet | | lg | 1024px | Desktop |

Native Sizeclass Mapping (iOS/Android)

Native platforms use different size class systems:

iOS (2 Size Classes - Apple HIG)

Web Breakpoints         iOS Size Classes
─────────────────       ────────────────
xs (320px) ─────┐
                ├────→  compact (Phones)
sm (390px) ─────┘

md (600px) ─────┐
                ├────→  regular (Tablets)
lg (1024px) ────┘

| Size Class | iOS Trait | Web Breakpoint | |------------|-----------|----------------| | compact | .compact | sm (390px) | | regular | .regular | lg (1024px) |

Android (3 Size Classes - Material 3 WindowSizeClass)

Web Breakpoints         Android WindowSizeClass
─────────────────       ───────────────────────
xs (320px) ─────┐
                ├────→  Compact (< 600dp)
sm (390px) ─────┘

md (600px) ──────────→  Medium (600-839dp)

lg (1024px) ─────────→  Expanded (≥ 840dp)

| Size Class | Material 3 Range | Web Breakpoint | |------------|------------------|----------------| | Compact | width < 600dp | sm (390px) | | Medium | 600dp ≤ width < 840dp | md (600px) | | Expanded | width ≥ 840dp | lg (1024px) |


Token Transform Reference

Naming Conventions

| Platform | Convention | Example | |----------|-----------|---------| | CSS | kebab-case with -- | --text-color-primary | | iOS Swift | camelCase | textColorPrimary | | Android Compose | camelCase | textColorPrimary |

Name Transformations

The pipeline applies these transformations to token names:

| Input | CSS/SCSS | JS/Swift/Compose | Notes | |-------|----------|------------------|-------| | TextColorPrimary | text-color-primary | textColorPrimary | CamelCase → kebab/camel | | bildred | bildred | bildred | Lowercase preserved | | bild085 | bild085 | bild085 | Numbers allowed | | alpha-black-20 | alpha-black-20 | alphaBlack20 | Numbers at end OK | | space2x | space2x | space2x | Dimension pattern | | 700-black | 700-black | n700Black | Number prefix → n prefix |

Important: Tokens with numeric prefixes (e.g., 700-black-font-weight) get an n prefix in camelCase platforms to ensure valid identifiers.

Token Types

Colors

| Platform | Format | Example | |----------|--------|---------| | CSS | #HEX / rgba() | #DD0000 | | iOS Swift | SwiftUI Color | Color(red: 0.867, ...) | | Android Compose | Color(0xFF...) | Color(0xFFDD0000) |

Dimensions

| Platform | Format | Example | |----------|--------|---------| | CSS | Xpx (or Xrem for fontSize) | 16px, 1rem | | iOS Swift | CGFloat number | 16 | | Android Compose | X.dp | 16.dp |

Note: CSS lineHeight tokens are unitless ratios (e.g., 1.33), not px. CSS fontSize unit is controlled by FONT_SIZE_UNIT setting (default: px).

Typography (Compose)

Typography tokens in Compose use .sp for accessibility scaling:

| Property | Format | Example | |----------|--------|---------| | fontSize | X.sp | 16.sp | | lineHeight | X.sp | 24.sp | | letterSpacing | Xf.sp | 0.5f.sp | | fontWeight | Int | 700 | | fontStyle | FontStyle | FontStyle.Italic | | fontFamily | String | "Gotham XNarrow" |

Opacity

| Platform | Format | Example | |----------|--------|---------| | CSS | 0-1 number | 0.5 | | iOS Swift | CGFloat | 0.5 | | Android Compose | Float | 0.5f |

Note: Figma exports opacity as percentage (5, 10, 70). Transform converts to decimal: 50.05. iOS/Swift uses per-token type detection to correctly map opacity tokens to CGFloat in component protocols.

Output Toggles

The build pipeline supports toggles to enable/disable specific outputs:

// In scripts/tokens/build.js

// Platform output toggles
const COMPOSE_ENABLED = true;         // Enables dist/android/compose/ output

// Token type toggles
const BOOLEAN_TOKENS_ENABLED = false; // Excludes visibility tokens

| Toggle | Default | Description | |--------|---------|-------------| | COMPOSE_ENABLED | true | Jetpack Compose Kotlin output in dist/android/compose/ | | BOOLEAN_TOKENS_ENABLED | false | Boolean/visibility tokens (13 tokens like hideOnMobile) |


📁 Output Structure

Token outputs are distributed across three packages for platform-native distribution:

Web Package (packages/tokens/dist/)

packages/tokens/dist/
├── css/
│   ├── shared/                      # Primitives
│   ├── bundles/                     # Convenience bundles (Quick Start)
│   └── {brand}/
│       ├── density/
│       ├── components/              # ~48 component files
│       └── semantic/
└── json/                            # Same structure as css/

iOS Package (packages/tokens-ios/)

Distribution: Swift Package Manager (SPM) - BildDesignTokens

packages/tokens-ios/
├── Package.swift                    # SPM manifest
├── README.md                        # Installation & usage docs
└── Sources/BildDesignTokens/        # 169 Swift files
    ├── shared/                      # Primitives, protocols, theme provider
    └── brands/{brand}/
        ├── semantic/                # Colors, sizing, typography
        └── components/              # Component tokens

Android Package (packages/tokens-android/)

Distribution: Maven via GitHub Packages - de.bild.design:tokens

packages/tokens-android/
├── build.gradle.kts                 # Gradle build with Maven publishing
├── settings.gradle.kts
├── README.md                        # Installation & usage docs
└── src/main/kotlin/                 # 182 Kotlin files
    └── de/bild/design/tokens/
        ├── shared/
        │   ├── DesignTokenPrimitives.kt   # All primitives consolidated
        │   ├── Density.kt                 # Dense/Default/Spacious enum
        │   ├── WindowSizeClass.kt         # Material 3: Compact/Medium/Expanded
        │   ├── Brand.kt                   # Bild/Sportbild/Advertorial enum
        │   └── DesignSystemTheme.kt       # Multi-brand theme provider
        └── brands/{brand}/
            ├── components/{Component}/
            │   └── {Component}Tokens.kt   # Aggregated with current() accessors
            ├── semantic/
            │   ├── {Brand}SemanticTokens.kt
            │   ├── color/
            │   │   ├── ColorsLight.kt     # BildColorScheme interface
            │   │   └── ColorsDark.kt      # BildDarkColors object
            │   └── sizeclass/
            │       ├── SizingCompact.kt   # BildSizingScheme interface
            │       ├── SizingMedium.kt    # Material 3 Medium
            │       └── SizingExpanded.kt  # Material 3 Expanded
            └── theme/
                └── {Brand}Theme.kt        # CompositionLocal Theme Provider

Compose File Organization

Compose output is optimized for Android development:

Shared Files (brand-independent):

| File | Content | Access Pattern | |------|---------|----------------| | shared/DesignTokenPrimitives.kt | All primitives (Colors, Space, Size, Font) | DesignTokenPrimitives.Colors.bildred | | shared/Density.kt | UI density enum | Density.Dense, Density.Default, Density.Spacious | | shared/WindowSizeClass.kt | Material 3 responsive layout enum | WindowSizeClass.Compact, WindowSizeClass.Medium, WindowSizeClass.Expanded | | shared/ColorBrand.kt, ContentBrand.kt | Dual-axis brand enums | ColorBrand.Bild, ContentBrand.Advertorial | | shared/DesignColorScheme.kt | Unified color interface | DesignSystemTheme.colors.textColorPrimary | | shared/DesignSizingScheme.kt | Unified sizing interface | DesignSystemTheme.sizing.gridSpaceRespBase | | shared/DesignTypographyScheme.kt | Unified typography interface | DesignSystemTheme.typography.headline1 | | shared/DesignTextStyle.kt | Typography composite type | .toComposeTextStyle() | | shared/DesignEffectsScheme.kt | Unified effects interface | DesignSystemTheme.effects.shadowSoftMd | | shared/DropShadow.kt, ShadowStyle.kt | Shadow composite types | .toModifier() | | shared/EffectsLight.kt, EffectsDark.kt | Light/Dark shadows | Brand-independent, only theme-dependent | | shared/DesignSystemTheme.kt | Multi-brand theme provider | DesignSystemTheme(colorBrand, contentBrand) { } |

Brand Files:

| File | Content | Access Pattern | |------|---------|----------------| | {Brand}Theme.kt | CompositionLocal Theme Provider | BildTheme { }, BildTheme.colors.x, BildTheme.sizing.x | | {Brand}SemanticTokens.kt | Colors + Sizing aggregated | BildSemanticTokens.Colors.Light.textColorPrimary | | ColorsLight.kt / ColorsDark.kt | ColorScheme interface + impl | Used by BildTheme internally | | SizingCompact.kt / SizingRegular.kt | SizingScheme interface + impl | Used by BildTheme internally | | {Component}Tokens.kt | Component tokens with current() | ButtonTokens.Colors.current().buttonPrimaryBgColorIdle |

🔗 Figma Integration & Dependencies

Supported Figma Scopes

| Scope | Assigned Type | Output Format | |-------|---------------|---------------| | FONT_SIZE | fontSize | px/rem (CSS), .sp (Compose) | | LINE_HEIGHT | lineHeight | unitless (CSS), .sp (Compose) | | LETTER_SPACING | letterSpacing | px (CSS), .sp (Compose) | | FONT_WEIGHT | fontWeight | Unitless integer (100-900) | | FONT_FAMILY | fontFamily | String | | FONT_STYLE | fontStyle | String, FontStyle.Italic (Compose) | | OPACITY | opacity | 0-1 decimal (÷100) | | WIDTH_HEIGHT | dimension | px (CSS), .dp (Compose) | | GAP | dimension | px (CSS), .dp (Compose) | | CORNER_RADIUS | dimension | px (CSS), .dp (Compose) | | STROKE_FLOAT | dimension | px (CSS), .dp (Compose) | | PARAGRAPH_SPACING | dimension | px (CSS), .dp (Compose) | | PARAGRAPH_INDENT | dimension | px (CSS), .dp (Compose) | | ALL_FILLS, FRAME_FILL, SHAPE_FILL, TEXT_FILL | color | #HEX, Color(0xFF...) | | STROKE_COLOR, EFFECT_COLOR | color | #HEX, Color(0xFF...) |

Compose Unit Mapping

Android Compose uses type-safe units. The pipeline automatically maps token types:

| Token Type | Compose Unit | Example Output | |------------|--------------|----------------| | fontSize | .sp | 16.sp | | lineHeight | .sp | 24.sp | | letterSpacing | .sp | 0.5f.sp | | dimension | .dp | 16.dp | | fontWeight | Int | 700 | | fontStyle | FontStyle | FontStyle.Italic | | fontFamily | String | "Gotham XNarrow" | | color | Color | Color(0xFFDD0000) | | opacity | Int | 50 (percentage) |

Note: .sp (scale-independent pixels) is used for text-related measurements to support accessibility scaling. .dp (density-independent pixels) is used for layout dimensions.

Stable Changes

| Change Type | Impact | Auto-Recovery | |-------------|--------|---------------| | New token | Added | Yes | | Edit value | Updated | Yes | | Add scope | Better typing | Yes | | New component | Folder created | Yes |

Unstable Changes

| Change Type | Impact | Fix Required | |-------------|--------|--------------| | Delete collection | Build fails | Code update | | Rename collection | Tokens skipped | Code update | | Circular alias | Token unresolved | Fix in Figma |

🔄 CI/CD Workflows

build-tokens.yml

  • Trigger: Push to main, develop, claude/**
  • Outputs: Build artifacts (30-day retention)

auto-pr-from-figma.yml

  • Trigger: Push to figma-tokens branch
  • Creates: Pull Request to main with release notes

publish-on-merge.yml

  • Trigger: Push to main
  • Actions: Impact-based version bump, npm publish, GitHub Release

Impact-Based Semantic Versioning

The publish workflow automatically determines the version bump based on token changes:

| Impact Level | Condition | Version Bump | |--------------|-----------|--------------| | breaking | Tokens/files removed | minor | | moderate | Token values modified | patch | | minor | Tokens/files added | patch | | none | No token changes | patch |

The compare-builds.js script analyzes the diff between the current build and the previous release to calculate the impact level.

Race Condition Prevention

concurrency:
  group: publish-main
  cancel-in-progress: false

Only one publish workflow runs at a time. Subsequent pushes queue and wait.

Synchronized Versioning

All packages (tokens, icons, components, react, vue) are published with the same version number.

🆘 Troubleshooting

Missing dist/ Folder

# Generate locally
npm run build

# Or download from CI artifacts

Build Failures

npm run clean
npm install
npm run build

iOS px String Issue

Fixed: iOS now uses custom/size/ios-points transform. Verify:

grep "Space2x" dist/ios/shared/Spaceprimitive.swift
# Expected: public static let Space2x = 16 (not "16px")

🔗 Related

| Document | Description | |----------|-------------| | 📖 Main README | Project overview | | 📖 docs/css.md | CSS Custom Properties documentation | | 📖 Android USAGE.md | Android Jetpack Compose (Dual-Axis) | | 📖 iOS USAGE.md | iOS SwiftUI (Dual-Axis) | | 📖 Icons README | Icon pipeline documentation | | 📖 Components README | Stencil Web Components | | 📖 React README | React wrapper components | | 📖 Vue README | Vue 3 wrapper components | | Style Dictionary | Build tool documentation |


🤝 Contributing

⚠️ IMPORTANT: Figma is the Single Source of Truth

Design Tokens must NOT be edited directly in the repository. All token changes must be made in Figma and exported via the CodeBridge Plugin.

Workflow:

  1. Edit/create tokens in Figma
  2. Export with CodeBridge Plugin
  3. Review and merge PR

NOT Allowed:

  • ❌ Direct changes to src/design-tokens/*.json
  • ❌ Manual commits to figma-tokens branch
  • ❌ Changes to generated files in dist/

Allowed (Pipeline Development):

  • ✅ Changes to build scripts (scripts/)
  • ✅ Changes to configuration (build-config/)
  • ✅ Pipeline configuration (build-config/pipeline.config.js - single source of truth)
  • ✅ Workflow adjustments (.github/workflows/)
  • ✅ Documentation

Configuration:

  • All pipeline settings are centralized in build-config/pipeline.config.js
  • See PIPELINE-CONFIG.md for full documentation

📄 License

MIT License - See LICENSE file.


Built with ❤️ for the BILD Design System

| Feature | Status | |---------|--------| | 3 Platforms (Web, iOS, Android) | ✅ | | 3 Brands | ✅ | | ~970 Files | ✅ | | Figma Scopes | ✅ | | var() Aliases | ✅ | | Responsive CSS | ✅ | | Jetpack Compose | ✅ | | Theme Provider | ✅ | | Shadow DOM / Web Components | ✅ | | Stencil Components | ✅ |