Skip to main content

Color Generator System

Overview

The Color Generator System provides algorithmic generation of complete color palettes (shades 50 through 950) from a single base hex color. It handles color space conversions between Hex, RGB, and HSL, and produces CSS custom properties and Tailwind CSS configuration objects. This module is the mathematical foundation upon which the theme system builds its dynamic color palettes.

Architecture

The module (lib/color-generator.ts) is a pure utility library with no side effects and no external dependencies. It sits below the theme layer and is consumed by:

  • lib/theme-color-manager.ts -- Uses generateColorPalette() and generateCssVariables() to apply theme palettes to the DOM.
  • Theme configuration -- Provides Tailwind config generation for build-time theme integration.
color-generator.ts
|-- hexToRgb(), rgbToHex() (Hex <-> RGB conversion)
|-- rgbToHsl(), hslToRgb() (RGB <-> HSL conversion)
|-- generateColorPalette() (Base color -> 11 shades)
|-- generateCssVariables() (Palette -> CSS variable strings)
|-- generateTailwindConfig() (Palette -> Tailwind config object)
|-- generateThemeColors() (Batch: multiple colors at once)

API Reference

Exports

hexToRgb(hex: string): { r: number; g: number; b: number }

Converts a hex color string (with or without # prefix) to an RGB object. Returns { r: 0, g: 0, b: 0 } if parsing fails.

rgbToHex(r: number, g: number, b: number): string

Converts RGB integer values (0-255) to a hex color string with # prefix.

rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: number }

Converts RGB values (0-255) to HSL. Returns hue in degrees (0-360), saturation and lightness as percentages (0-100).

hslToRgb(h: number, s: number, l: number): { r: number; g: number; b: number }

Converts HSL values (h: 0-360, s: 0-100, l: 0-100) to RGB integers (0-255).

generateColorPalette(baseColor: string): ColorPalette

Generates a complete 11-shade palette from a base hex color. The base color maps to shade 500. Lighter shades (50-400) increase lightness and decrease saturation. Darker shades (600-950) decrease lightness and increase saturation.

interface ColorPalette {
50: string; 100: string; 200: string;
300: string; 400: string; 500: string; // Base color
600: string; 700: string; 800: string;
900: string; 950: string;
}

generateCssVariables(variableName: string, palette: ColorPalette): string

Generates CSS custom property declarations from a palette. Returns a newline-separated string.

--theme-primary: #3b82f6;
--theme-primary-50: #e8f0fe;
--theme-primary-100: #d4e4fd;
/* ... */
--theme-primary-950: #0a1a3d;

generateTailwindConfig(className: string): Record<string, string>

Generates a Tailwind CSS color configuration object that references CSS variables.

{
DEFAULT: 'var(--theme-primary)',
50: 'var(--theme-primary-50)',
100: 'var(--theme-primary-100)',
// ...
}

generateThemeColors(colors: Record<string, string>): { css: string; tailwind: Record<string, any> }

Batch generates CSS variables and Tailwind configuration for multiple named colors at once.

Implementation Details

Shade algorithm: The palette is generated by adjusting the HSL lightness and saturation of the base color according to predefined offsets:

ShadeLightness AdjustSaturation Adjust
50+45-30
100+40-25
200+30-20
300+20-10
400+10-5
5000 (base)0 (base)
600-10+5
700-20+10
800-30+15
900-40+20
950-45+25

All computed values are clamped to the valid range (0-100) to prevent overflow.

Color space conversion: The module performs conversions through the standard HSL color model. RGB-to-HSL uses the min/max channel algorithm, and HSL-to-RGB uses the hue2rgb helper for piecewise linear interpolation.

Configuration

No configuration is needed. The shade definitions are hardcoded constants designed to produce visually balanced palettes similar to Tailwind CSS defaults.

Usage Examples

import {
generateColorPalette,
generateCssVariables,
generateTailwindConfig,
generateThemeColors,
hexToRgb,
} from '@/lib/color-generator';

// Generate a full palette from a brand color
const palette = generateColorPalette('#3b82f6');
console.log(palette[500]); // '#3b82f6' (base)
console.log(palette[100]); // lighter shade
console.log(palette[900]); // darker shade

// Generate CSS variables for injection into <style>
const css = generateCssVariables('brand', palette);
// --brand: #3b82f6;
// --brand-50: #e8f0fe;
// ...

// Generate Tailwind config for tailwind.config.ts
const tailwind = generateTailwindConfig('brand');
// { DEFAULT: 'var(--brand)', 50: 'var(--brand-50)', ... }

// Batch generate for an entire theme
const theme = generateThemeColors({
primary: '#3b82f6',
secondary: '#10b981',
accent: '#f59e0b',
});
// theme.css -- all CSS variable declarations
// theme.tailwind -- Tailwind config for all colors

// Convert colors for custom processing
const rgb = hexToRgb('#3b82f6');
// { r: 59, g: 130, b: 246 }

Best Practices

  • Use generateColorPalette() as the single source for all shade values rather than manually picking colors.
  • Prefer generateCssVariables() over inline styles so that themes can be changed dynamically at runtime.
  • When integrating with Tailwind, use generateTailwindConfig() so that utility classes reference CSS variables rather than hardcoded hex values.
  • Always pass valid 6-digit hex colors (e.g., #3b82f6); shorthand hex (e.g., #38f) is not supported by the regex parser.
  • Test generated palettes for WCAG contrast compliance, especially the light (50-200) and dark (800-950) ends.