Skip to content

tenphi/glaze

Repository files navigation

Glaze logo

Glaze

OKHSL-based color theme generator with WCAG contrast solving

npm version CI license


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.

Features

  • 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 outputokhsl, rgb, hsl, oklch with 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

Installation

pnpm add @tenphi/glaze
npm install @tenphi/glaze
yarn add @tenphi/glaze

Quick Start

import { 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(...)', ... } }

Concepts at a glance

  1. Theme = one hue/saturation seed. Status themes are siblings created via extend() — they inherit every color definition and only swap the seed.
  2. Every color is explicit. A color is either a root (absolute lightness) or dependent (base + relative offset and/or contrast). No implicit roles.
  3. WCAG contrast is a floor, not a target. The solver only widens a color's lightness when the requested position fails the requested ratio.
  4. Light, dark, and high-contrast come from one definition. mode (auto / fixed / static) picks how each color adapts; lightness / contrast / intensity / value accept an optional [normal, hc] pair for explicit high-contrast tuning.

Documentation

  • 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.

License

MIT

About

OKHSL-based accessible color palette generator with support for dark and high-contrast themes.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors