Skip to main content

Source: ocean/docs/theme-system-figma-workflow.md | ✏️ Edit on GitHub

Theme System and Figma Token Workflow

Overview

Ocean uses a token-based design system that integrates seamlessly with Figma through design tokens. This allows for a single source of truth between design and development, ensuring consistency across the application.

Architecture

1. Token-Based Design System

Our design tokens are stored in design-tokens/tokens.json and include:

  • Colors (light and dark themes)
  • Border radius values
  • Spacing (future)
  • Typography (future)

2. CSS Variable Generation

The build-tokens.mjs script automatically generates CSS variables from the JSON tokens:

pnpm run build:tokens

This creates src/styles/tokens.css with all CSS variables.

3. Dark Mode Support

We've implemented a ThemeProvider component that:

  • Detects system theme preferences
  • Allows manual theme switching (light/dark/system)
  • Persists user preference in localStorage
  • Applies the appropriate class to the document root

4. ShadCN UI Integration

All ShadCN UI components use CSS variables for theming:

  • bg-background instead of hardcoded colors
  • text-foreground for text colors
  • Theme-aware hover and focus states

Figma Integration Workflow

Setting Up Figma Tokens

  1. Install Tokens Studio Plugin in Figma

    • Go to Figma → Plugins → Browse plugins
    • Search for "Tokens Studio for Figma"
    • Install the plugin
  2. Import Tokens to Figma

    • Open Tokens Studio plugin
    • Click "Import" → "From URL" or "From File"
    • Use the design-tokens/tokens.json file
    • Tokens will be available in Figma
  3. Design with Tokens

    • Use token references instead of hardcoded values
    • Example: Use color.background instead of #FFFFFF
    • Maintain consistency between themes

Development Workflow

  1. Updating Tokens from Figma

    # After exporting tokens from Figma to design-tokens/tokens.json
    pnpm run build:tokens
  2. Adding New Token Categories

    • Update design-tokens/tokens.json
    • Modify build-tokens.mjs to handle new token types
    • Run pnpm run build:tokens
  3. Theme-Aware Components

    // Use CSS variables for all colors
    <div className="bg-card text-card-foreground">Content</div>

    // Dark mode is handled automatically
    // No need for dark: prefixes when using CSS variables

Token Structure

Color Tokens

{
"color": {
"background": { "value": "oklch(1 0 0)" },
"foreground": { "value": "oklch(0.145 0 0)" }
// ... other light theme colors
},
"dark": {
"background": { "value": "oklch(0.145 0 0)" },
"foreground": { "value": "oklch(0.985 0 0)" }
// ... other dark theme colors
}
}

Adding New Colors

  1. Add to design-tokens/tokens.json:

    {
    "color": {
    "warning": { "value": "oklch(0.84 0.16 84)" },
    "warning-foreground": { "value": "oklch(0.28 0.07 46)" }
    },
    "dark": {
    "warning": { "value": "oklch(0.41 0.11 46)" },
    "warning-foreground": { "value": "oklch(0.99 0.02 95)" }
    }
    }
  2. Run token build:

    pnpm run build:tokens
  3. Use in components:

    <div className="bg-warning text-warning-foreground">Warning message</div>

Best Practices

  1. Always Use Tokens

    • Never hardcode color values
    • Use semantic token names (background, foreground, etc.)
    • Keep token names consistent with Figma
  2. Theme Testing

    • Test all components in both light and dark modes
    • Use the mode toggle to quickly switch themes
    • Verify contrast ratios meet accessibility standards
  3. Figma Sync

    • Regular sync between Figma and code tokens
    • Document any custom tokens added in code
    • Keep token structure consistent
  4. Component Development

    • Use bg-[token] and text-[token]-foreground pattern
    • Avoid dark: prefixes when using CSS variables
    • Let the theme provider handle mode switching

Troubleshooting

If dropdowns appear transparent in dark mode:

  1. Check --popover value differs from --card in dark theme
  2. Ensure components use bg-popover not custom backgrounds
  3. Keep ShadCN default styling unless necessary

Token Not Applying

  1. Verify pnpm run build:tokens was run
  2. Check browser dev tools for CSS variable values
  3. Ensure component uses correct token name
  4. Clear browser cache if needed

Figma Token Mismatch

  1. Export latest tokens from Figma
  2. Compare with design-tokens/tokens.json
  3. Run build process after updates
  4. Verify token names match between systems