@avidly/themes
v3.0.0
Published
A modern, responsive design system with Figma token integration and Panda CSS optimization.
Downloads
1,828
Readme
@avidly/public-theme
A modern, responsive design system with Figma token integration and Panda CSS optimization.
🎯 Key Features
- 🎨 Figma Token Integration: Direct parsing from Figma JSON exports
- ✍️ Dynamic Text Styles: Automatic text style generation from Figma textStyles.json with responsive fontSize mapping
- 📱 Responsive Typography: Automatic mobile/desktop fontSize scaling without hardcoded rem values
- 🌗 Dark/Light Mode: Conditional color tokens with
_darksupport - 🔧 Panda CSS Optimized: Uses only supported token types
- 🏗️ Clean Architecture: Primitive tokens (-base suffix) and semantic tokens (clean names) separation
- 🚀 Zero Maintenance: Automatic token parsing and fallbacks
- 📊 Complete Coverage: Colors, spacing, typography, layout, text styles, and component tokens
🚀 Quick Start
Installation
bun add @avidly/public-themeBasic Usage
import { theme } from '@avidly/public-theme';
// Use semantic tokens in components
<Box bg="bg-primary" p="md" color="text-primary" />
// Use dynamic text styles from Figma (automatically responsive)
<Text textStyle="heading-3x-large">Dynamic Figma Typography</Text>
<Text textStyle="paragraph-medium">Body text with automatic styling</Text>
// Responsive fontSize tokens automatically adapt
<Text fontSize="3xl"> {/* Mobile: 5.6875rem, Desktop: 8.5625rem */}
<Text fontSize="lg"> {/* Mobile: 1.6875rem, Desktop: 2.5rem */}
<Box p="2xl"> {/* Mobile: 5rem, Desktop: 8rem */}Panda CSS Integration
// panda.config.ts
import { defineConfig } from '@pandacss/dev';
import { theme } from '@avidly/public-theme';
export default defineConfig({
theme: {
extend: {
tokens: theme.tokens,
semanticTokens: theme.semanticTokens,
},
},
});📊 Token System
Pre-Parsing Architecture (8x Performance Boost!)
The theme system uses a two-stage token generation approach for optimal performance:
┌─────────────────────┐ ┌───────────────────┐ ┌─────────────────────┐
│ Figma DTCG Export │ → │ generateTheme.ts │ → │ generated-tokens.ts │
│ │ │ │ │ │
│ • Primitive.Value │ │ • parseDTCGTokens │ │ • Resolved tokens │
│ • Semantic.Desktop │ │ • Reference res. │ │ • Type-safe exports │
│ • Semantic.Mobile │ │ • Dark mode merge │ │ • Ready for import │
│ • Semantic (Color) │ │ • Responsive obj │ │ │
│ • text.styles │ │ │ │ │
└─────────────────────┘ └───────────────────┘ └─────────────────────┘
│
┌──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Panda CSS Config │
│ (Imports pre-parsed tokens) │
│ │
│ import { tokens, semanticTokens, textStyles } │
│ from './themes/avidly/generated-tokens.js'; │
│ │
│ export default defineConfig({ │
│ theme: { extend: { tokens, semanticTokens, textStyles } } │
│ }); │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ All Packages │
│ │
│ import { css } from '@avidly/public-theme/css'; │
│ // Gets optimized DTCG tokens automatically! │
└─────────────────────────────────────────────────────────────────────────┘Performance Impact
Before (8x redundant parsing):
@avidly/public-theme: 🎨 Parsing tokens... (28ms)
@avidly/ui: 🎨 Parsing tokens... (25ms)
@avidly/remix: 🎨 Parsing tokens... (30ms)
@avidly/vite: 🎨 Parsing tokens... (27ms)
... (4 more packages)
Total: ~200ms + blockingAfter (1x pre-parsing):
@avidly/public-theme: 🎨 Parsing tokens... (28ms) → generates file
@avidly/ui: ✅ Using pre-parsed tokens (0ms)
@avidly/remix: ✅ Using pre-parsed tokens (0ms)
@avidly/vite: ✅ Using pre-parsed tokens (0ms)
Total: ~28ms, no blockingToken Generation Files
| File | Purpose | When It Runs |
| ----------------------------------- | -------------------------------------- | ----------------------------------- |
| scripts/generateTheme.ts | Producer - Generates static tokens | Build time (bun run parse-tokens) |
| utils/parseDTCGTokens.ts | Parser - DTCG format parser | Used by generateTheme.ts |
| themes/avidly/generated-tokens.ts | Generated - Pre-parsed token cache | Created by generateTheme.ts |
How generateTheme.ts Works
#!/usr/bin/env bun
// 1. Import DTCG format JSON files
import primitiveTokens from '../themes/avidly/tokens/dtcg/Primitive.Value.tokens.json';
import semanticDesktop from '../themes/avidly/tokens/dtcg/Semantic.Desktop.tokens.json';
import semanticMobile from '../themes/avidly/tokens/dtcg/Semantic.Mobile.tokens.json';
import semanticColorLight from '../themes/avidly/tokens/dtcg/Semantic (Color).Light.tokens.json';
import semanticColorDark from '../themes/avidly/tokens/dtcg/Semantic (Color).Dark.tokens.json';
import dtcgTextStyles from '../themes/avidly/tokens/dtcg/text.styles.tokens.json';
import manifest from '../themes/avidly/tokens/dtcg/manifest.json';
// 2. Parse DTCG tokens once at build time
const parsedTokens = parseAllDTCGTokens({
primitive: primitiveTokens,
semanticDesktop,
semanticMobile,
semanticColorLight,
semanticColorDark,
textStyles: dtcgTextStyles,
manifest,
});
// 3. Merge with default tokens
const tokens = { ...parsedTokens, ...defaultTokens };
const semanticTokens = { ...parsedTokens.semanticTokens, ...defaultTokens.semanticTokens };
const textStyles = { ...parsedTokens.textStyles, ...defaultTokens.textStyles };
// 4. Generate static TypeScript file with type validation
const tsContent = `
export const tokens: PrimitiveTokens = ${JSON.stringify(tokens, null, 2)};
export const semanticTokens: SemanticTokens = ${JSON.stringify(semanticTokens, null, 2)};
export const textStyles: TextStyles = ${JSON.stringify(textStyles, null, 2)};
`;
// 5. Write to generated-tokens.ts
writeFileSync(outputPath, tsContent, 'utf-8');How Panda Config Uses Tokens
import { tokens, semanticTokens, textStyles } from './themes/avidly/generated-tokens.js';
import { defaultTokens } from './themes/avidly/tokenDefaults.js';
export default defineConfig({
theme: {
extend: {
// Pre-parsed DTCG tokens (no runtime overhead)
tokens,
semanticTokens,
textStyles,
// Additional recipe and style definitions
recipes: { /* ... */ },
slotRecipes: { /* ... */ },
},
},
});Build Integration
// packages/theme/package.json
{
"scripts": {
"parse-tokens": "bun run src/scripts/generateTheme.ts",
"prepare": "bun run parse-tokens && panda codegen"
}
}Automatic triggers:
bun run parse-tokens- Manual token generationbun run prepare- Runs during theme buildbun run build- Full monorepo build includes token generation
Architecture Overview
┌──────────────────┐ ┌──────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Primitive.Value │ │ Semantic.Desktop │ │ Semantic (Color)│ │ text.styles │
│ (base values) │ │ Semantic.Mobile │ │ .Light / .Dark │ │ (typography) │
│ │ │ (responsive) │ │ (dark mode) │ │ │
└──────────────────┘ └──────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │ │
└─────────────────────┼──────────────────────┼────────────────────┘
│ │
┌────────────▼──────────────────────▼──────────┐
│ parseDTCGTokens.ts │
│ (W3C DTCG format parser) │
│ • Extract primitives │
│ • Merge responsive (Desktop+Mobile) │
│ • Merge dark mode (Light+Dark) │
│ • Parse nested text styles │
└──────────────────┬───────────────────────────┘
│
┌──────────────────▼───────────────────────────┐
│ Panda CSS │
│ tokens + semanticTokens + textStyles │
└──────────────────────────────────────────────┘Token Categories
| Category | Type | Examples | Features |
| --------------- | -------------------- | --------------------------------------------------- | ---------------------------- |
| Colors | Primitive + Semantic | colors.dark, bg-primary | Light/dark mode with _dark |
| Spacing | Primitive + Semantic | spacing.md-base, spacing.md | Responsive values |
| Typography | Primitive + Semantic | fontSizes.lg-mobile-base, fontSizes.lg | Mobile/desktop variants |
| Text Styles | Dynamic Generation | heading-3x-large, paragraph-medium | Auto-generated from Figma |
| Sizes | Primitive + Semantic | sizes.container-full-base, sizes.container-full | Container responsiveness |
| Component | Semantic Only | component-button-filled-bg | Component-specific colors |
Responsive FontSize Architecture
The theme includes a sophisticated responsive fontSize system that automatically maps Figma textStyles to responsive tokens:
// 🔧 Primitive tokens (internal use, -base suffix)
fontSizes: {
"md-mobile-base": { value: "1.375rem" }, // 22px mobile
"md-desktop-base": { value: "1.6875rem" }, // 27px desktop
"lg-mobile-base": { value: "1.6875rem" }, // 27px mobile
"lg-desktop-base": { value: "2.5rem" }, // 40px desktop
}
// 🎯 Semantic tokens (developer API, clean names)
semanticTokens: {
fontSizes: {
md: {
value: {
base: "{fontSizes.md-mobile-base}", // Mobile-first
md: "{fontSizes.md-desktop-base}" // Desktop breakpoint
}
},
lg: {
value: {
base: "{fontSizes.lg-mobile-base}",
md: "{fontSizes.lg-desktop-base}"
}
}
}
}
// ✍️ TextStyles automatically use responsive fontSize tokens
textStyles: {
"heading-large": {
fontSize: "{fontSizes.lg}", // 🎉 Automatically responsive!
fontWeight: "700",
// ... other properties
}
}Key Benefits:
- 📱 Automatic responsiveness: TextStyles adapt across breakpoints
- 🎯 No hardcoded values: All fontSize values reference semantic tokens
- 🔧 Maintainable: Update Figma tokens and everything updates automatically
- 🏗️ Clean separation: Primitive (-base) vs semantic (clean) token names
- ✅ Panda CSS compliant: Uses proper plural token names (
fontSizes,fonts,fontWeights,letterSpacings)
Primitive vs Semantic Tokens
// ✅ Primitive tokens (internal, -base suffix)
spacing: {
'md-base': { value: '2rem' },
'xl-mobile-base': { value: '5rem' },
'xl-desktop-base': { value: '8rem' }
}
// ✅ Semantic tokens (external, clean names)
semanticTokens: {
spacing: {
'md': { value: '{spacing.md-base}' },
'xl': {
value: {
base: '{spacing.xl-mobile-base}',
md: '{spacing.xl-desktop-base}'
}
}
}
}✍️ Dynamic Text Styles
Text styles are automatically generated from Figma's textStyles.json export, providing type-safe typography that stays in sync with your design system.
How It Works
- Export from Figma: Export text styles as JSON from your Figma design system
- Automatic Parsing: The system converts Figma text styles to Panda CSS format
- Type Safety: All text styles are available in your IDE with full autocomplete
Generated Text Styles
// Figma "Heading/3X-Large" becomes "heading-3x-large"
<Text textStyle="heading-3x-large">Large heading</Text>
// Figma "Paragraph/Medium" becomes "paragraph-medium"
<Text textStyle="paragraph-medium">Body text</Text>
// Figma "Semantic/Navigation item" becomes "semantic-navigation-item"
<Text textStyle="semantic-navigation-item">Menu text</Text>Available Text Styles
From your current Figma export:
- Headings:
heading-3x-large,heading-2x-large,heading-x-large,heading-large,heading-medium,heading-small,heading-x-small - Paragraphs:
paragraph-large,paragraph-medium,paragraph-small,paragraph-x-small - Semantic:
semantic-navigation-item,semantic-navigation-item-small,semantic-code,semantic-case-eyebrow - Specialized:
cookiebot-heading,cookiebot-paragraph
Font Family Mapping
The system automatically maps Figma font families to your design tokens:
// Automatic font family conversion
'Inter Tight' → 'heading' // Main display font
'JetBrains Mono' → 'mono' // Code/monospace font
'SF Compact' → 'system' // System UI fontFont Weight Conversion
Figma font weights are automatically converted to CSS values:
'Regular' → '400' 'SemiBold' → '600' 'Bold' → '700'
'Medium' → '500' 'Light' → '300' 'Black' → '900'🎨 Dark Mode Support
Colors automatically adapt to light/dark themes using Panda CSS's _dark condition:
// Color tokens with dark mode
semanticTokens: {
colors: {
'bg-primary': {
value: { base: '#f8f6ef', _dark: '#282828' }
},
'text-primary': {
value: { base: '#282828', _dark: '#f8f6ef' }
},
'component-button-filled-bg': {
value: { base: '#282828', _dark: '#f8f6ef' }
}
}
}📱 Responsive Design
Tokens automatically handle mobile/desktop breakpoints:
// Responsive font sizes
fontSizes: {
'3xl': {
value: {
base: '5.6875rem', // Mobile
md: '8.5625rem' // Desktop (768px+)
}
}
}
// Usage in components
<Heading fontSize="3xl">Responsive Typography</Heading>🏗️ File Structure
packages/theme/
├── src/
│ ├── themes/avidly/
│ │ ├── tokens/dtcg/ # DTCG format Figma exports (JSON)
│ │ │ ├── Primitive.Value.tokens.json # Base values
│ │ │ ├── Semantic.Desktop.tokens.json # Desktop tokens
│ │ │ ├── Semantic.Mobile.tokens.json # Mobile tokens
│ │ │ ├── Semantic (Color).Light.tokens.json # Light mode colors
│ │ │ ├── Semantic (Color).Dark.tokens.json # Dark mode colors
│ │ │ ├── text.styles.tokens.json # Typography styles
│ │ │ └── manifest.json # Export metadata
│ │ ├── tokenDefaults.ts # Hardcoded defaults & fallbacks
│ │ ├── generated-tokens.ts # Generated pre-parsed tokens
│ │ ├── index.ts # Theme assembly
│ │ └── slotRecipes/ # Component styles & slot recipes
│ ├── utils/
│ │ ├── parseDTCGTokens.ts # DTCG format parser
│ │ └── tokenHelpers.ts # Utility functions
│ └── scripts/
│ └── generateTheme.ts # Token generation script🔄 Development Workflow
1. Update Figma Tokens
Export new DTCG format JSON files from Figma to src/themes/avidly/tokens/dtcg/:
Primitive.Value.tokens.json- Base colors, spacing, sizesSemantic.Desktop.tokens.json&Semantic.Mobile.tokens.json- Responsive valuesSemantic (Color).Light.tokens.json&Semantic (Color).Dark.tokens.json- Dark mode colorstext.styles.tokens.json- Typography styles from Figma
2. Automatic Processing
Run the build process:
bun run prepare # Generates Panda CSS tokensThe system automatically:
- ✅ Parses all JSON token files
- ✅ Creates primitive tokens with
-basesuffixes - ✅ Generates semantic tokens with clean names
- ✅ Converts Figma text styles to Panda CSS textStyles
- ✅ Handles responsive values (
base/md) - ✅ Implements dark mode (
base/_dark) - ✅ Resolves token references (
{colors.dark}) - ✅ Maps font families and weights automatically
3. Use Immediately
// New tokens and text styles available instantly
<Box bg="new-color-from-figma" p="new-spacing-from-figma" />
<Text textStyle="new-heading-style-from-figma">Typography from Figma</Text>🛠️ Development Commands
# Build theme and generate Panda CSS
bun run prepare
# Development mode with file watching
bun run dev
# Build for production
bun run build
# Launch Panda Studio for token visualization
bun run studio🎯 Best Practices
✅ Do
// Use semantic tokens (clean names)
<Box bg="bg-primary" color="text-primary" p="md" />
// Use Figma text styles
<Text textStyle="heading-large">Heading from Figma</Text>
<Text textStyle="paragraph-medium">Body text from Figma</Text>
// Use responsive tokens
<Text fontSize="3xl">Responsive text</Text>
// Use component-specific tokens
<Button bg="component-button-filled-bg">Themed button</Button>❌ Don't
// Don't use primitive tokens directly
<Box bg="colors.dark-base" p="spacing.md-base" />
// Don't use hardcoded values
<Box bg="#282828" p="2rem" />
// Don't hardcode typography
<Text fontSize="40px" fontWeight="700" fontFamily="Inter Tight" />📚 Token Reference
Available Semantic Tokens
- Colors:
bg-primary,text-primary,component-button-filled-bg, etc. - Spacing:
3xs,xs,sm,md,lg,xl,2xl,3xl - Font Sizes:
xs,sm,md,lg,xl,2xl,3xl,4xl - Text Styles:
heading-3x-large,paragraph-medium,semantic-navigation-item, etc. - Sizes:
container-full,container-wide,container-normal,container-narrow - Component Colors: All button, icon, and input color variants
Available Text Styles
- Headings:
heading-3x-large,heading-2x-large,heading-x-large,heading-large,heading-medium,heading-small,heading-x-small - Paragraphs:
paragraph-large,paragraph-medium,paragraph-small,paragraph-x-small - Semantic:
semantic-navigation-item,semantic-navigation-item-small,semantic-code,semantic-case-eyebrow - Specialized:
cookiebot-heading,cookiebot-paragraph - Legacy:
body,p,small,hero,card,footer,menu,h1-h6, etc.
Responsive Breakpoints
base: Mobile-first (default)md: Desktop (768px+)
Color Modes
base: Light mode (default)_dark: Dark mode
Perfect design-to-code consistency with dynamic text styles, modern responsive design, and comprehensive theming capabilities! 🚀✍️
