@pithyjs/design-system
v0.1.0-beta.0
Published
Comprehensive design system for PithyJS with runtime control, theming, and typography management.
Readme
@pithyjs/design-system
Comprehensive design system for PithyJS with runtime control, theming, and typography management.
Overview
The PithyJS Design System provides modular, accessible styling solutions for building consistent user interfaces. It includes two main modules:
🎨 Colors
Complete color theming system with one-seed generation and WCAG AA compliance.
- One-seed generation - Full theme from a single color
- 74+ semantic tokens - Brand, surfaces, text, status, borders, on-colors
- State variants - hover, active, selected, disabled
- Runtime updates - Change colors dynamically
- Light/dark modes - Complete dual-mode support
📝 Typography
Fluid typography system with automatic viewport scaling and variable font support.
- Fluid typography - Smooth viewport-based scaling
- Modular scales - Configurable ratio-based hierarchies
- Variable fonts - Modern font technology support
- Google Fonts - Seamless integration
- Utility classes - Pre-built typographic styles
View Typography Documentation →
📐 Spacing
Fluid spacing system with container-driven responsiveness and density control.
- Fluid spacing - CSS clamp() for smooth scaling
- Container queries - cqw units with viewport fallback
- Density presets - compact, comfortable, spacious
- Semantic tokens - inline, stack, inset, squish, stretch, gutter, section
- Utility classes - Pre-built spacing utilities
🌑 Shadows
First-class shadow design tokens with a configurable shadow engine.
- 5 elevation levels - xs, sm, md, lg, xl
- Shadow engine - Ratio-based controls
- Presets - Flat, Soft, Elevated, Dramatic
- Light/dark mode - Automatic adaptation
- Brand tinting - Optional color tinting
⭕ Radius
First-class border radius system with shape presets.
- 5 radius levels - xs, sm, md, lg, xl/pill
- Shape presets - Sharp, Subtle, Rounded, Bubble
- Computed scale - From base value
- Utility classes - All corners, sides, individual
📏 Borders
Complete border design token system with semantic borders.
- Two-layer tokens - Primitive + semantic
- 5 width levels - none, hairline, thin, medium, thick
- 5 border styles - none, solid, dashed, dotted, double
- 11 semantic borders - card, control, divider, focus-ring, states
- 4 presets - Minimal, Subtle, Standard, Strong
📐 Layout
CSS-only utility classes for display, flexbox, and grid layout.
- Display utilities - block, flex, grid, hidden, contents
- Flexbox - direction, wrap, justify, align, grow/shrink
- Grid - columns, rows, spans, auto-flow, placement
- Common patterns - center, vstack, hstack
- Accessibility - sr-only, visibility
🧭 Theming Manifest
A single generated, typed description of every module's settable theming knobs — the shared theming vocabulary for the studio and the AI proxy.
- Generated from source - aggregated from each module's
tokens.json - Preset-first - presets, base scalars (type/range/default), and (colors only) per-token metadata
- CI drift gate - regenerated and
git diff-checked inquality-gates.yml - Importable -
@pithyjs/design-system/manifest(subpath) or the package root
import { DESIGN_SYSTEM_MANIFEST } from '@pithyjs/design-system/manifest';
DESIGN_SYSTEM_MANIFEST.modules.radius.presets[0].presets;
// ["sharp", "subtle", "rounded", "bubble"]
DESIGN_SYSTEM_MANIFEST.modules.colors.colorTokens.filter((t) => t.hasStateVariants);Regenerate after editing any tokens.json:
pnpm --filter @pithyjs/design-system run sync-manifestInstallation
npm install @pithyjs/design-systempnpm add @pithyjs/design-systemyarn add @pithyjs/design-systemQuick Start
Colors
import { createThemeFromSeed, initTheme } from '@pithyjs/design-system/colors';
// Generate and apply theme from one color
const theme = createThemeFromSeed({ primary: '#3b82f6' });
initTheme(theme);/* Use CSS variables */
.button {
background: var(--color-primary);
color: var(--color-on-primary);
}
.button:hover {
background: var(--color-primary-hover);
}Typography
import { initTypography } from '@pithyjs/design-system/typography';
// Initialize with defaults (fluid typography enabled by default)
initTypography();
// Or with custom configuration
initTypography({
baseSize: 16,
scale: 'major-third', // 1.25
lineHeight: 1.5,
fluid: {
enabled: true,
mode: 'proportional', // All text scales with viewport
ratio: 0.35, // Fluid scaling intensity (0.15-0.5)
headingAmplification: 3, // Headings scale 3x more
}
});<!-- Use utility classes -->
<h1 class="display-1">Hero Headline</h1>
<p class="text-lg font-medium">Large, medium-weight text</p>
<article class="prose">Optimized long-form content</article>Package Exports
The design system is organized as subpath exports:
// Colors
import { initTheme, getColor } from '@pithyjs/design-system/colors';
import '@pithyjs/design-system/colors/styles'; // CSS-only mode
// Typography
import { initTypography } from '@pithyjs/design-system/typography';
import '@pithyjs/design-system/typography/styles'; // CSS-only mode
// Spacing
import { initSpacing } from '@pithyjs/design-system/spacing';
import '@pithyjs/design-system/spacing/styles'; // CSS-only mode
// Shadows
import { initShadows } from '@pithyjs/design-system/shadows';
import '@pithyjs/design-system/shadows/styles'; // CSS-only mode
// Radius
import { initRadius } from '@pithyjs/design-system/radius';
import '@pithyjs/design-system/radius/styles'; // CSS-only mode
// Borders
import { initBorders } from '@pithyjs/design-system/borders';
import '@pithyjs/design-system/borders/styles'; // CSS-only mode
// Layout (CSS-only)
import '@pithyjs/design-system/layout/styles';
// Theming manifest (generated; types + DESIGN_SYSTEM_MANIFEST)
import { DESIGN_SYSTEM_MANIFEST } from '@pithyjs/design-system/manifest';Features
Colors Features
✅ One-seed theme generation
✅ WCAG AA accessibility compliance
✅ 74+ semantic color tokens
✅ State variants (hover, active, selected, disabled)
✅ 5 shadow elevation levels
✅ Light/dark mode support
✅ CSS variables (--color-*)
✅ Runtime theme updates
✅ OKLCH color space with RGB fallbacks
✅ 222+ utility classes
✅ Theme scoping (multi-brand support)
✅ Export/import themes as JSON
Typography Features
✅ Fluid typography (viewport-based scaling)
✅ Proportional fluid mode (site-builder friendly)
✅ Modular type scales (8 built-in ratios)
✅ Variable font support
✅ Google Fonts integration
✅ Custom font upload (WOFF2)
✅ WCAG 2.x compliance
✅ CSS variables (--font-*, --fluid-ratio)
✅ Pre-built utility classes
✅ Accessibility-first design
Spacing Features
✅ Fluid spacing (container/viewport-based scaling)
✅ 5 spacing levels (xs, sm, md, lg, xl)
✅ 3 density presets (compact, comfortable, spacious)
✅ 7 semantic tokens (inline, stack, inset, squish, stretch, gutter, section)
✅ Negative spacing for overlap effects
✅ CSS variables (--space-*)
✅ Container query units with viewport fallback
✅ Pre-built utility classes
✅ CSS-only mode support
Shadows Features
✅ 5 elevation levels (xs, sm, md, lg, xl)
✅ Shadow engine with ratio-based controls
✅ 4 presets (Flat, Soft, Elevated, Dramatic)
✅ Light/dark mode support
✅ Optional brand tinting
✅ CSS variables (--shadow-*)
✅ Pre-built utility classes
✅ Theme integration sync
Radius Features
✅ 5 radius levels (xs, sm, md, lg, xl/pill)
✅ 4 shape presets (Sharp, Subtle, Rounded, Bubble)
✅ Computed scale from base value
✅ CSS variables (--radius-*)
✅ Pre-built utility classes (all corners, sides, individual)
✅ Theme integration sync
Borders Features
✅ Two-layer token system (primitive + semantic)
✅ 5 width levels (none, hairline, thin, medium, thick)
✅ 5 border styles (none, solid, dashed, dotted, double)
✅ 11 semantic borders (card, control, divider, focus-ring, states)
✅ 4 presets (Minimal, Subtle, Standard, Strong)
✅ CSS variables (--border-*)
✅ Pre-built utility classes
✅ Theme integration sync
Layout Features
✅ Display utilities (block, flex, grid, hidden, contents) ✅ Flex direction, wrap, justify, align ✅ Flex grow/shrink/basis shorthands ✅ Grid columns (1-12) and rows (1-6) ✅ Grid span, start/end positioning ✅ Grid auto-flow and placement ✅ Order utilities (1-12, first, last) ✅ Visibility and screen-reader utilities ✅ Common patterns (center, vstack, hstack) ✅ CSS-only (no JavaScript required)
Documentation
Module Documentation
- Colors Module - Complete colors documentation
- Typography Module - Complete typography documentation
- Spacing Module - Complete spacing documentation
- Shadows Module - Complete shadows documentation
- Radius Module - Complete radius documentation
- Borders Module - Complete borders documentation
- Layout Module - Complete layout documentation
Project Documentation
- Design System Docs - Overview and guides
- Colors Docs - Detailed colors guide
- Typography Docs - Detailed typography guide
- Spacing Docs - Detailed spacing guide
- Shadows Docs - Detailed shadows guide
- Radius Docs - Detailed radius guide
- Borders Docs - Detailed borders guide
Implementation Details
- Colors Implementation Plan - Technical architecture
- Colors Progress Tracker - Phase-by-phase status
- Typography Implementation Plan - Technical architecture
- Typography Progress Tracker - Development status
- Spacing Implementation Plan - Technical architecture
- Spacing Progress Tracker - Development status
- Shadows Implementation Plan - Technical architecture
- Shadows Progress Tracker - Development status
- Radius Implementation Plan - Technical architecture
- Radius Progress Tracker - Development status
- Borders Implementation Plan - Technical architecture
- Borders Progress Tracker - Development status
Structure
@pithyjs/design-system/
├── src/
│ ├── colors/ # Colors module
│ │ ├── styles/ # SCSS fallbacks
│ │ ├── tests/ # Unit tests
│ │ ├── scripts/ # Build scripts
│ │ ├── math/ # Color algorithms
│ │ ├── accessibility/ # WCAG validation
│ │ └── README.md # Module docs
│ │
│ ├── typography/ # Typography module
│ │ ├── styles/ # SCSS fallbacks
│ │ ├── core/ # Core functionality
│ │ ├── fonts/ # Font loading
│ │ ├── scales/ # Scale generation
│ │ └── README.md # Module docs
│ │
│ ├── spacing/ # Spacing module
│ │ ├── styles/ # SCSS tokens & utilities
│ │ └── *.ts # TypeScript source
│ │
│ ├── shadows/ # Shadows module
│ │ ├── styles/ # SCSS tokens & utilities
│ │ └── *.ts # TypeScript source
│ │
│ ├── radius/ # Radius module
│ │ ├── styles/ # SCSS tokens & utilities
│ │ └── *.ts # TypeScript source
│ │
│ ├── borders/ # Borders module
│ │ ├── styles/ # SCSS tokens & utilities
│ │ └── *.ts # TypeScript source
│ │
│ ├── layout/ # Layout module (CSS-only)
│ │ └── styles/ # SCSS utilities
│ │
│ └── index.ts # Main exports
│
└── README.md # This fileUsage Modes
Both modules support multiple usage modes:
1. Full Runtime Mode (Recommended)
Maximum features and flexibility:
import { createThemeFromSeed, initTheme } from '@pithyjs/design-system/colors';
import { initTypography } from '@pithyjs/design-system/typography';
const theme = createThemeFromSeed({ primary: '#3b82f6' });
initTheme(theme);
initTypography({ scaleRatio: 1.25 });2. CSS-Only Mode
Zero JavaScript, SSR-friendly:
import '@pithyjs/design-system/colors/styles';
import '@pithyjs/design-system/typography/styles';3. Hybrid Mode
Progressive enhancement:
// Static CSS for instant render
import '@pithyjs/design-system/colors/styles';
// Enhance with runtime features
import { getThemeManager } from '@pithyjs/design-system/colors';
const theme = getThemeManager();
theme.toggleMode(); // Add dark mode toggleExamples
See working examples:
- Theme Studio - Interactive colors demo
- Typography Demo - Typography showcase
Contributing
When adding features:
- Add
@codexannotations for documentation - Write tests
- Update progress trackers
- Add examples
Status
Colors Module
✅ Complete - All core features implemented (Phases 1-7)
Typography Module
✅ Complete - All core features implemented (11/12 phases at 100%, 158 tests passing)
Spacing Module
✅ Complete - All 7 phases implemented
Shadows Module
✅ Complete - All 6 phases implemented
Radius Module
✅ Complete - All 6 phases implemented
Borders Module
✅ Complete - All 6 phases implemented
Layout Module
✅ Complete - CSS-only utilities for display, flexbox, and grid
API Reference
Note: Methods listed below are grouped by module. Class methods are prefixed with their class name. For detailed per-module API docs, see the module READMEs linked above.
A11y
| API | Signature | Stability |
| --- | --- | --- |
| A11yManager | class A11yManager | stable |
| A11yManager.destroy | () => void | stable |
| initA11y | (options?: A11yOptions) => A11yManager | stable |
| getA11yManager | () => A11yManager \| null | stable |
| destroyA11y | () => void | stable |
Borders
| API | Signature | Stability |
| --- | --- | --- |
| BorderManager | class BorderManager | stable |
| BorderManager.setPreset | (preset: BorderPreset) => void | stable |
| BorderManager.getPreset | () => BorderPreset \| 'custom' | stable |
| BorderManager.getBorder | (semantic: SemanticBorder) => string | stable |
| BorderManager.setRingWidth | (width: RingWidthLevel) => void | stable |
| BorderManager.setRingOffset | (offset: RingOffsetLevel) => void | stable |
| BorderManager.setRingColor | (color: RingColor) => void | stable |
| BorderManager.setRingColorCustom | (color: string) => void | stable |
| BorderManager.setRingOffsetColor | (color: string) => void | stable |
| BorderManager.destroy | () => void | stable |
| initBorders | (options?: BorderOptions) => BorderManager | stable |
| getBorderManager | () => BorderManager \| null | stable |
| destroyBorders | () => void | stable |
| DEFAULT_PRESET | BorderPreset | stable |
| getPresetConfig | (preset: BorderPreset) => BorderPresetConfig | stable |
| formatBorder | (def: SemanticBorderDefinition) => string | stable |
| generateAllCSSVariables | (config: BorderPresetConfig) => Record<string, string> | stable |
| generateRingCSSVariables | (config?: RingConfig) => Record<string, string> | stable |
| getRingColorVar | (color: RingColor) => string | stable |
Colors — Theme Manager
| API | Signature | Stability |
| --- | --- | --- |
| ThemeManager | class ThemeManager | experimental |
| ThemeManager.getMode | () => ThemeMode | stable |
| ThemeManager.setMode | (mode: ThemeMode) => void | stable |
| ThemeManager.toggleMode | () => ThemeMode | stable |
| ThemeManager.getToken | (token: ColorToken) => OKLCHColor | stable |
| ThemeManager.setToken | (token: ColorToken, value: ColorInput, mode?: ThemeMode) => void | stable |
| ThemeManager.updateTokens | (updates: Partial<ThemeTokens>, mode?: ThemeMode) => void | stable |
| ThemeManager.setTheme | (tokens: ThemeDefinition, options?: { mode?: ThemeMode }) => void | stable |
| ThemeManager.getAllTokens | (mode?: ThemeMode) => ThemeTokens | stable |
| ThemeManager.getVariableName | (token: ColorToken) => string | stable |
| ThemeManager.getVariableValue | (token: ColorToken) => string | stable |
| ThemeManager.getComputedToken | (token: ColorToken) => OKLCHColor \| null | stable |
| ThemeManager.applyTheme | () => void | stable |
| ThemeManager.exportTheme | () => ThemeDefinition | stable |
| ThemeManager.importTheme | (theme: ThemeDefinition, validate?: boolean) => boolean | stable |
| ThemeManager.onModeChange | (callback: (mode: ThemeMode) => void) => () => void | stable |
| ThemeManager.getValidationStatus | () => ValidationStatus | experimental |
| ThemeManager.getPreviewedTokens | () => ColorToken[] | experimental |
| ThemeManager.previewColor | (token: ColorToken, value: ColorInput, mode?: ThemeMode) => void | experimental |
| ThemeManager.previewColors | (updates: Partial<Record<ColorToken, ColorInput>>, mode?: ThemeMode) => void | experimental |
| ThemeManager.validateAndApply | () => Promise<ValidationReport> | experimental |
| ThemeManager.discardPreviews | () => void | experimental |
| ThemeManager.destroy | () => void | stable |
Colors — Convenience Functions
| API | Signature | Stability |
| --- | --- | --- |
| initTheme | (tokens?: ThemeDefinition, options?: CSSVariableOptions) => ThemeManager | stable |
| getThemeManager | () => ThemeManager | stable |
| destroyTheme | () => void | stable |
| getColor | (token: ColorToken) => OKLCHColor | stable |
| setColor | (token: ColorToken, value: ColorInput) => void | stable |
| setTheme | (tokens: ThemeDefinition, options?: { mode?: ThemeMode }) => void | stable |
| getValidationStatus | () => ValidationStatus | experimental |
| getPreviewedTokens | () => ColorToken[] | experimental |
| previewColor | (token: ColorToken, value: ColorInput) => void | experimental |
| previewColors | (updates: Partial<Record<ColorToken, ColorInput>>) => void | experimental |
| validateAndApply | () => Promise<ValidationReport> | experimental |
| discardPreviews | () => void | experimental |
| loadThemeFromCSS | () => ThemeDefinition | stable |
| DEFAULT_THEME | ThemeDefinition | stable |
| getDefaultTheme | (loadFromCSS?: boolean) => ThemeDefinition | stable |
Colors — Scoped Themes
| API | Signature | Stability |
| --- | --- | --- |
| applyScopedTheme | (element: HTMLElement \| string, theme: ThemeDefinition, mode?: ThemeMode) => void | experimental |
| removeScopedTheme | (element: HTMLElement \| string) => void | experimental |
Colors — Validation & Serialization
| API | Signature | Stability |
| --- | --- | --- |
| validateThemeStructure | (theme: any) => ThemeValidationResult | stable |
| validateThemeJSON | (json: string) => { valid: boolean; theme: ThemeDefinition \| null; errors: string[]; warnings: string[] } | stable |
| exportThemeJSON | (theme: ThemeDefinition) => string \| null | stable |
| importThemeJSON | (json: string) => ThemeDefinition \| null | stable |
Colors — Math & Conversion
| API | Signature | Stability |
| --- | --- | --- |
| formatOKLCH | (color: OKLCHColor) => string | stable |
| formatRGB | (color: RGBColor) => string | stable |
| parseOKLCH | (oklchString: string) => OKLCHColor \| null | stable |
| getCSSVariableName | (token: string, prefix?: string) => string | stable |
| hexToRgb | (hex: string) => RGBColor | stable |
| oklchToHex | (color: OKLCHColor) => string | stable |
| hexToOklch | (hex: string) => OKLCHColor | stable |
| parseColor | (color: string) => OKLCHColor | stable |
| oklchToRgb | (color: OKLCHColor) => RGBColor | stable |
| rgbToOklch | (rgb: RGBColor) => OKLCHColor | stable |
| normalizeHue | (hue: number) => number | stable |
| interpolateHue | (hue1: number, hue2: number, t: number) => number | stable |
| normalizeColorInput | (color: ColorInput) => OKLCHColor | stable |
| isInGamut | (color: OKLCHColor) => boolean | stable |
| gamutDistance | (color: OKLCHColor) => number | stable |
| clipToGamut | (color: OKLCHColor) => OKLCHColor | stable |
| oklchToRgbClipped | (color: OKLCHColor) => RGBColor | stable |
| getMaxChroma | (l: number, h: number) => number | stable |
Colors — Accessibility
| API | Signature | Stability |
| --- | --- | --- |
| setContrastConfig | (config: Partial<ContrastConfig>) => void | stable |
| getContrastConfig | () => ContrastConfig | stable |
| resetContrastConfig | () => void | stable |
| getLuminanceFromRgb | (rgb: RGBColor) => number | stable |
| getLuminanceFromOklch | (color: OKLCHColor) => number | stable |
| getContrastRatioOklch | (color1: ColorInput, color2: ColorInput) => number | stable |
| getContrastRatioRgb | (rgb1: RGBColor, rgb2: RGBColor) => number | stable |
| meetsWCAG_AA | (color1: ColorInput, color2: ColorInput, textSize?: TextSize) => boolean | stable |
| meetsWCAG_AAA | (color1: ColorInput, color2: ColorInput, textSize?: TextSize) => boolean | stable |
| getWCAGReport | (color1: ColorInput, color2: ColorInput) => WCAGReport | stable |
| ensureWCAG_AA | (baseColor: ColorInput, color: ColorInput, textSize?: TextSize) => OKLCHColor | experimental |
| generateOnColor | (baseColor: ColorInput, config?: OnColorConfig) => OKLCHColor | stable |
| generateOnColors | (tokens: ThemeTokens) => ThemeTokens | stable |
| validateOnColor | (baseColor: ColorInput, onColor: ColorInput, textSize?: TextSize) => ValidationResult | stable |
| generateBestOnColor | (baseColor: ColorInput) => OKLCHColor | stable |
| generateTintedOnColor | (baseColor: ColorInput, chromaReduction?: number) => OKLCHColor | experimental |
| getOnColorDiagnostics | (tokens: ThemeTokens) => OnColorDiagnostics[] | stable |
| generateContrastMatrix | (tokens: ThemeTokens, mode: 'light' \| 'dark', customPairs?: ColorPair[]) => ContrastMatrix | stable |
| getFailedChecks | (matrix: ContrastMatrix) => ContrastCheckResult[] | stable |
| generateThemeDiagnostics | (theme: ThemeDefinition) => ThemeDiagnostics | stable |
| validateTheme | (theme: ThemeDefinition) => { passes: boolean; score: number; issues: number } | stable |
Colors — Derivation & Theme Generation
| API | Signature | Stability |
| --- | --- | --- |
| selectDerivationStrategy | (primary: ColorInput) => DerivationStrategy | stable |
| deriveColors | (primary: ColorInput, strategy?: DerivationStrategy, analogousOffset?: number) => DerivedColors | stable |
| deriveSecondary | (primary: ColorInput, strategy?: DerivationStrategy) => OKLCHColor | stable |
| deriveTertiary | (primary: ColorInput, strategy?: DerivationStrategy) => OKLCHColor | stable |
| deriveColorsWithChromaAdjustment | (primary: ColorInput, strategy?: DerivationStrategy) => DerivedColors | stable |
| applyHueTint | (baseColor: OKLCHColor, tintColor: OKLCHColor, intensity: number) => OKLCHColor | stable |
| getDefaultTintIntensity | (type: 'text' \| 'surface' \| 'shadow') => number | stable |
| generateStateVariants | (baseColor: OKLCHColor, mode: ThemeMode, config?: StateVariantConfig) => Record<ColorState, OKLCHColor> | stable |
| shouldHaveStateVariants | (token: string) => boolean | stable |
| createThemeFromSeed | (seed: ThemeSeed) => ThemeDefinition | stable |
| createQuickTheme | (primaryColor: ColorInput) => ThemeDefinition | stable |
| createThemeWithStrategy | (primaryColor: ColorInput, strategy: DerivationStrategy) => ThemeDefinition | stable |
| createHarmonicTheme | (primaryColor: ColorInput) => ThemeDefinition | stable |
| mapPalettesToTokens | (palettes: ThemePalettes, mapping: ToneMapping) => ThemeTokens | stable |
| mapPalettesToTheme | (palettes: ThemePalettes, lightMapping?: ToneMapping, darkMapping?: ToneMapping) => ThemeDefinition | stable |
| createCustomMapping | (base: ToneMapping, overrides: Partial<ToneMapping>) => ToneMapping | stable |
Colors — Tonal Palettes
| API | Signature | Stability |
| --- | --- | --- |
| generateBrandPalette | (seed: ColorInput, chromaCurve?: Partial<ChromaCurveConfig>) => TonalPalette | stable |
| generateNeutralPalette | (seed: ColorInput, chromaCurve?: Partial<ChromaCurveConfig>) => TonalPalette | stable |
| getTone | (palette: TonalPalette, tone: ToneStep) => OKLCHColor | stable |
| getClosestTone | (targetLightness: number) => ToneStep | stable |
| interpolateTones | (palette: TonalPalette, tone1: ToneStep, tone2: ToneStep, t: number) => OKLCHColor | experimental |
| previewChromaCurve | (config: ChromaCurveConfig) => Partial<Record<ToneStep, number>> | stable |
| deriveNeutralSeed | (brandSeed: ColorInput, chromaReduction?: number) => OKLCHColor | stable |
Colors — CSS Utilities
| API | Signature | Stability |
| --- | --- | --- |
| generateAllUtilities | (config?: UtilityGeneratorConfig) => string | stable |
Layout
| API | Signature | Stability |
| --- | --- | --- |
| CONTAINER_BREAKPOINTS | Record<'sm'\|'md'\|'lg'\|'xl', string> | stable |
| ContainerBreakpoint | type ContainerBreakpoint = 'sm' \| 'md' \| 'lg' \| 'xl' | stable |
| CONTAINER_BREAKPOINT_NAMES | ContainerBreakpoint[] | stable |
Motion
| API | Signature | Stability |
| --- | --- | --- |
| MotionManager | class MotionManager | stable |
| MotionManager.destroy | () => void | stable |
| initMotion | (options?: MotionOptions) => MotionManager | stable |
| getMotionManager | () => MotionManager \| null | stable |
| destroyMotion | () => void | stable |
| KEYFRAMES | Record<AnimationPattern, string> | stable |
| injectKeyframes | (target?: Document) => HTMLStyleElement \| null | stable |
| removeKeyframes | (target?: Document) => void | stable |
| computeEffectiveDuration | (baseMs: number, intensity: number) => number | stable |
| generateMotionVariables | (config: MotionConfig) => Record<string, string> | stable |
Radius
| API | Signature | Stability |
| --- | --- | --- |
| RadiusManager.destroy | () => void | stable |
| getRadiusManager | () => RadiusManager \| null | stable |
| destroyRadius | () => void | stable |
| generateRadiusTokens | (scale: RadiusScale) => RadiusTokens | stable |
| generateAllCSSVariables | (scale: RadiusScale, tokens: RadiusTokens) => Record<string, string> | stable |
Shadows
| API | Signature | Stability |
| --- | --- | --- |
| ShadowManager | class ShadowManager | stable |
| ShadowManager.destroy | () => void | stable |
| initShadows | (options?: ShadowOptions) => ShadowManager | stable |
| getShadowManager | () => ShadowManager \| null | stable |
| destroyShadows | () => void | stable |
| initShadowsWithSync | (themeManager: ThemeManagerLike, options?: ShadowOptions) => { shadowManager: ShadowManager; unsubscribe: () => void } | stable |
| generateShadowTokens | (base: ShadowBase, ratios: ShadowRatios) => ShadowTokens | stable |
| generateAllCSSVariables | (base: ShadowBase, ratios: ShadowRatios, tokens: ShadowTokens) => Record<string, string> | stable |
| applyTinting | (base: ShadowBase, tintColor: [number, number, number], intensity: number) => ShadowBase | stable |
| hexToRgbTuple | (hex: string) => [number, number, number] \| null | stable |
Shared
| API | Signature | Stability |
| --- | --- | --- |
| detectThemeMode | (target?: HTMLElement) => ThemeMode | stable |
Examples
initA11y({ preset: 'strict' });const manager = getA11yManager();
manager?.setControlSize('lg');destroyA11y();import { initBorders } from '@pithyjs/design-system/borders';
// Initialize with default preset
initBorders();
// Initialize with specific preset
initBorders({ preset: 'strong' });
// Initialize with overrides
initBorders({
preset: 'standard',
overrides: {
card: { width: 'medium', style: 'solid', colorVar: 'var(--color-primary)' }
}
});const manager = getBorderManager();
manager?.setPreset('minimal');destroyBorders();const config = getPresetConfig('minimal');
console.log(config.card.width); // 'none'formatBorder({ width: 'thin', style: 'solid', colorVar: 'var(--color-border)' });
// => "2px solid var(--color-border)"
formatBorder({ width: 'none', style: 'none', colorVar: 'var(--color-border)' });
// => "none"const config = getPresetConfig('standard');
const vars = generateAllCSSVariables(config);
// Apply to element
Object.entries(vars).forEach(([name, value]) => {
document.documentElement.style.setProperty(name, value);
});const vars = generateRingCSSVariables({ width: 'default', offset: 'default' });
// Apply to element
Object.entries(vars).forEach(([name, value]) => {
document.documentElement.style.setProperty(name, value);
});getRingColorVar('primary');
// => "var(--color-primary)"// Load SSR theme into runtime
const theme = loadThemeFromCSS();
initTheme(theme);// Full runtime mode - use hardcoded fallback
const theme = getDefaultTheme();// Hybrid/SSR mode - load from CSS
const theme = getDefaultTheme(true);const css = generateAllUtilities();
// Write to file or inject into documentsetTheme(importedTheme, { mode: 'dark' });// Custom theme
const theme = createThemeFromSeed({ primary: '#3b82f6' });
initTheme(theme);// Default theme
initTheme();// SSR hydration - load from CSS
initTheme(getDefaultTheme(true));destroyTheme();setColor('primary', '#3b82f6');
setColor('primary', 'rgb(59, 130, 246)');
setColor('primary', { l: 65, c: 0.16, h: 250 });// Apply theme to admin panel
applyScopedTheme('.admin-panel', adminTheme);
// Apply theme to specific element
const modal = document.querySelector('.modal');
applyScopedTheme(modal, modalTheme, 'dark');const result = validateThemeStructure(theme);
if (!result.valid) {
console.error('Theme validation failed:', result.errors);
}const { valid, theme, errors } = validateThemeJSON(jsonString);
if (valid && theme) {
initTheme(theme);
}const json = exportThemeJSON(theme);
if (json) {
localStorage.setItem('theme', json);
}const theme = importThemeJSON(localStorage.getItem('theme'));
if (theme) {
initTheme(theme);
}import { injectKeyframes } from '@pithyjs/design-system/motion';
injectKeyframes(); // adds <style id="pithy-motion-keyframes"> to <head>initMotion({ preset: 'snappy' });const manager = getMotionManager();
manager?.setPreset('calm');destroyMotion();const vars = generateMotionVariables(config);
// vars['--motion-duration-fast'] === '70ms' (100 * 0.7 for snappy)
// vars['--motion-easing-standard'] === 'cubic-bezier(0.2, 0, 0, 1)'const manager = getRadiusManager();
manager?.setPreset('sharp');destroyRadius();const tokens = generateRadiusTokens({ baseRadius: 4, scaleFactor: 1.5, maxRadius: 16, pill: 9999 });
console.log(tokens.md); // "9px"import { initTheme, getThemeManager } from '@pithyjs/design-system/colors';
import { initShadowsWithSync } from '@pithyjs/design-system/shadows';
const theme = initTheme(myTheme);
const { shadowManager, unsubscribe } = initShadowsWithSync(theme, { preset: 'soft' });initShadows({ preset: 'soft' });const manager = getShadowManager();
manager?.setPreset('dramatic');destroyShadows();const tokens = generateShadowTokens(defaultBase.light, shadowPresets.elevated);
console.log(tokens.md); // "0px 3px 6px 0px rgba(0, 0, 0, 0.070)"const mode = detectThemeMode();
// Returns "dark" if data-theme="dark" or system prefers darkconst matrix = generateContrastMatrix(theme.light, 'light');
console.log(`Pass rate: ${matrix.summary.passRate}%`);
matrix.checks.filter(c => !c.passes).forEach(c => {
console.log(`FAIL: ${c.pair.purpose} - ${c.ratio.toFixed(2)}:1`);
});const diagnostics = generateThemeDiagnostics(theme);
console.log(`Score: ${diagnostics.overall.score}/100 (${diagnostics.overall.grade})`);
console.log(`Level: ${diagnostics.overall.level}`);
diagnostics.overall.recommendations.forEach(rec => console.log(`- ${rec}`));// Stricter requirements
setContrastConfig({ normalText: 5.0, largeText: 3.5 });
// More lenient for large UI elements
setContrastConfig({ graphical: 2.5 });getContrastRatioOklch("#3b82f6", "#ffffff")
getContrastRatioOklch({ l: 65, c: 0.16, h: 250 }, { l: 100, c: 0, h: 0 })meetsWCAG_AA("#3b82f6", "#ffffff") // true
meetsWCAG_AA({ l: 65, c: 0.16, h: 250 }, "#fff")meetsWCAG_AAA("#3b82f6", "#ffffff")getWCAGReport("#3b82f6", "#ffffff")ensureWCAG_AA("#3b82f6", "#888888") // Adjusts gray to meet AA on blue// Auto-select strategy based on chroma
const { secondary, tertiary, strategy } = deriveColors("#3b82f6")
console.log(strategy) // "complementary"
// Explicit strategy
const colors = deriveColors("#3b82f6", DerivationStrategy.TRIADIC)
// Analogous with custom offset
const colors = deriveColors("#3b82f6", DerivationStrategy.ANALOGOUS, 45)const secondary = deriveSecondary("#3b82f6")
const secondary2 = deriveSecondary("#3b82f6", DerivationStrategy.COMPLEMENTARY)const tertiary = deriveTertiary("#3b82f6")const colors = deriveColorsWithChromaAdjustment("#3b82f6")normalizeColorInput("#3b82f6") // Returns { l: 65, c: 0.16, h: 250 }
normalizeColorInput({ l: 65, c: 0.16, h: 250 }) // Returns same objectconst onPrimary = generateOnColor("#3b82f6") // White or black, whichever passes
const onSurface = generateOnColor({ l: 99, c: 0, h: 0 }) // Dark text for light surfaceconst tokens = mapPalettesToTokens(palettes, LIGHT_MODE_MAPPING);
const withOnColors = generateOnColors(tokens);const valid = validateOnColor("#3b82f6", "#ffffff")
console.log(valid.passes) // true
console.log(valid.ratio) // 8.2const onColor = generateBestOnColor("#888888") // Mid-gray - could go either way// Blue background gets slightly blue-tinted text
const onBlue = generateTintedOnColor("#3b82f6")const diagnostics = getOnColorDiagnostics(tokens)
diagnostics.forEach(d => {
console.log(`${d.token}: ${d.ratio.toFixed(2)}:1 ${d.passes ? '✓' : '✗'}`)
})const theme = mapPalettesToTheme(palettes)
const customTheme = mapPalettesToTheme(palettes, customLightMap, customDarkMap)const customLight = createCustomMapping(LIGHT_MODE_MAPPING, {
primary: 70, // Slightly lighter primary
text: 15, // Darker text
})const variants = generateStateVariants(primaryColor, 'light');
// { hover: {...}, active: {...}, selected: {...}, disabled: {...} }// Simplest usage - just a hex color
const theme = createThemeFromSeed({ primary: "#3b82f6" })
// With custom secondary
const theme = createThemeFromSeed({
primary: "#3b82f6",
secondary: "#ec4899",
tertiary: "auto",
})
// Full control
const theme = createThemeFromSeed({
primary: "#3b82f6",
derivation: "complementary",
harmonicStatuses: true,
statuses: {
success: "#10b981",
danger: "#ef4444",
},
})const theme = createQuickTheme("#3b82f6")const theme = createThemeWithStrategy("#3b82f6", "triadic")const theme = createHarmonicTheme("#3b82f6")const tintedText = applyHueTint(
{ l: 20, c: 0.02, h: 0 }, // neutral gray text
{ l: 65, c: 0.16, h: 250 }, // blue primary
0.05 // 5% tint
);
// Result: text with slight blue hue shiftgenerateBrandPalette("#3b82f6")
generateBrandPalette({ l: 65, c: 0.16, h: 250 })generateNeutralPalette("#3b82f6") // Will use low chroma
generateNeutralPalette({ l: 50, c: 0.02, h: 250 })deriveNeutralSeed("#3b82f6") // Creates low-chroma blue neutral
deriveNeutralSeed({ l: 65, c: 0.16, h: 250 }, 0.90) // 90% reductiondestroyTypography();const fluidSizes = calculateProportionalFluidSizes({
baseSize: 0.9, // Base size in rem
ratio: 0.35, // vw multiplier
headingAmplification: 3, // Headings scale 3x more
});
// Result:
// {
// body: 'clamp(1rem, calc(0.9rem + 0.35vw), 1.4rem)',
// h1: 'clamp(2.1rem, calc(2.475rem + 1.4vw), 4.5rem)',
// ...
// }Testing
1,073 tests across 41 test files, all passing.
| Module | Test Files | Tests | Key Coverage | | --- | --- | --- | --- | | Colors | 6 | ~300+ | Theme generation, color math, accessibility, tonal palettes, utils, ThemeManager | | Typography | 6 | ~150+ | Fluid scale, font loader, Google Fonts, accessibility validation, diagnostics, TypographyManager | | Spacing | 3 | ~80+ | Token computation, density presets, SpacingManager | | Shadows | 4 | ~100+ | Token generation, ShadowManager, theme sync integration, generated presets | | Radius | 3 | ~60+ | Token generation, RadiusManager, generated presets | | Borders | 4 | ~80+ | Border formatting, presets, ring tokens, BorderManager | | A11y | 2 | ~50+ | A11yManager, CSS variable tokens | | Iconography | 3 | ~60+ | Token computation, IconographyManager, generated tokens | | Motion | 4 | ~80+ | Keyframe injection, MotionManager, token generation, generated presets | | Init | 1 | ~30+ | Unified initialization, selective module init | | Token Infra | 5 | ~80+ | Computation utils, formatters, validation, orchestrator, snapshot tests |
Run all tests:
cd packages/design-system && pnpm testLicense
ISC
