OKHSL-based color theme generator with WCAG contrast solving
Glaze generates robust light, dark, and high-contrast color schemes from a single hue/saturation seed. WCAG contrast is preserved via explicit dependency declarations — no hidden role math, no magic multipliers.
- OKHSL color space — perceptually uniform hue and saturation
- WCAG 2 contrast solving — automatic lightness adjustment to meet AA/AAA targets
- Mix colors — blend two colors with OKHSL or sRGB interpolation, opaque or transparent, with optional contrast solving
- Shadow colors — OKHSL-native shadow computation with automatic alpha, fg/bg tinting, and per-scheme adaptation
- Light + Dark + High-Contrast — all schemes from one definition
- Per-color hue override — absolute or relative hue shifts within a theme
- Multi-format output —
okhsl,rgb,hsl,oklchwith modern CSS space syntax - CSS custom properties export — ready-to-use
--var: value;declarations per scheme - Import/Export — serialize and restore theme configurations
- Create from hex/RGB — start from an existing brand color
- Zero dependencies — pure math, runs anywhere (Node.js, browser, edge)
- Tree-shakeable ESM + CJS — dual-format package
- TypeScript-first — full type definitions included
pnpm add @tenphi/glazenpm install @tenphi/glazeyarn add @tenphi/glazeimport { glaze } from '@tenphi/glaze';
const primary = glaze(280, 80);
primary.colors({
surface: { lightness: 97, saturation: 0.75 },
text: { base: 'surface', lightness: '-52', contrast: 'AAA' },
border: { base: 'surface', lightness: ['-7', '-20'], contrast: 'AA-large' },
'accent-fill': { lightness: 52, mode: 'fixed' },
'accent-text': { base: 'accent-fill', lightness: '+48', contrast: 'AA', mode: 'fixed' },
'shadow-md': { type: 'shadow', bg: 'surface', fg: 'text', intensity: 10 },
});
const danger = primary.extend({ hue: 23 });
const success = primary.extend({ hue: 157 });
const palette = glaze.palette(
{ primary, danger, success },
{ primary: 'primary' },
);
const tokens = palette.tokens();
// → { light: { 'primary-surface': 'okhsl(...)', 'surface': 'okhsl(...)', ... },
// dark: { 'primary-surface': 'okhsl(...)', 'surface': 'okhsl(...)', ... } }- Theme = one hue/saturation seed. Status themes are siblings created via
extend()— they inherit every color definition and only swap the seed. - Every color is explicit. A color is either a root (absolute
lightness) or dependent (base+ relative offset and/orcontrast). No implicit roles. - WCAG
contrastis a floor, not a target. The solver only widens a color's lightness when the requested position fails the requested ratio. - Light, dark, and high-contrast come from one definition.
mode(auto/fixed/static) picks how each color adapts;lightness/contrast/intensity/valueaccept an optional[normal, hc]pair for explicit high-contrast tuning.
docs/api.md— full API reference (every method, every option).docs/methodology.md— palette design methodology for building from scratch.docs/migration.md— wiring tokens into your app and migrating off a legacy color system.AGENTS.md— source-tree orientation for contributors.