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

@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

View Colors Documentation →

📝 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

View Spacing Documentation →

🌑 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

View Shadows Documentation →

⭕ 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

View Radius Documentation →

📏 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

View Borders Documentation →

📐 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

View Layout Documentation →

🧭 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 in quality-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-manifest

Installation

npm install @pithyjs/design-system
pnpm add @pithyjs/design-system
yarn add @pithyjs/design-system

Quick 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

Project Documentation

Implementation Details

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 file

Usage 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 toggle

Examples

See working examples:

Contributing

When adding features:

  1. Add @codex annotations for documentation
  2. Write tests
  3. Update progress trackers
  4. 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 document
setTheme(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 dark
const 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 object
const onPrimary = generateOnColor("#3b82f6") // White or black, whichever passes
const onSurface = generateOnColor({ l: 99, c: 0, h: 0 }) // Dark text for light surface
const 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.2
const 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 shift
generateBrandPalette("#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% reduction
destroyTypography();
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 test

License

ISC