Skip to content

VelkinaStudio/hueshift

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🎨 hueshift

Accessible, harmonious color palettes from one seed color — with WCAG contrast guarantees baked in.

Give it one color. Get a full palette — tonal ramps (50→950), harmonious accents, neutral surfaces, and ready-to-use light/dark roles — plus a contrast audit so you know it's actually readable before you ship it. Zero dependencies. CLI + library.

Built by Velkina.

npm i -g @velkina/hueshift
hueshift "#3b82f6"

Why

Most palette generators give you pretty swatches and leave accessibility as your problem. hueshift treats contrast as a first-class output: it tells you which pairings pass WCAG AA/AAA, picks readable text colors for you, and exits non-zero if a key pairing fails — so it works as a CI gate on your design tokens.

The color math is correct, not approximate: proper sRGB↔linear transfer, WCAG 2.x relative luminance and contrast ratio, and tonal ramps scaled in linear light (which keeps hue stable, unlike naive RGB mixing).

Usage

hueshift "#e84d3c"                      # report + swatches + contrast audit
hueshift "#3b82f6" --scheme triadic     # complementary | analogous | triadic | splitcomp | tetradic
hueshift "#3b82f6" --mode dark          # dark-mode roles
hueshift "#3b82f6" --json               # full palette as JSON
hueshift "#3b82f6" --css > tokens.css   # CSS custom properties

Example output:

hueshift  seed #3b82f6  ·  triadic  ·  light

primary   #3b82f6  ▥▥▥▥▥
accent1   #f63b82  ▥▥▥▥▥
accent2   #82f63b  ▥▥▥▥▥

  ✓ foreground / background     8.26:1  AAA
  ✓ foreground / surface        7.57:1  AAA
  ✗ primary / background        3.46:1  AA-large
  ✓ primaryText / primary       5.71:1  AA

Library

import { generatePalette, contrastRatio, wcagLevels, bestTextOn, tonalRamp } from "@velkina/hueshift";

const p = generatePalette("#3b82f6", { scheme: "triadic", mode: "light" });
p.accents;   // [{ name, hex, ramp: {50..950} }, ...]
p.roles;     // { background, foreground, surface, primary, primaryText }
p.audit;     // [{ label, ratio, AA_normal, AAA_normal, ... }]

contrastRatio({r:0,g:0,b:0}, {r:255,g:255,b:255}); // 21
bestTextOn(parseColor("#3b82f6"));                  // { color: "#ffffff", ratio }

API

fn what
generatePalette(seed, {scheme, mode}) full palette + roles + contrast audit
tonalRamp(color) 50→950 ramp (linear-light scaled)
contrastRatio(a, b) WCAG ratio 1..21
wcagLevels(ratio) {AA_normal, AAA_normal, AA_large, AAA_large}
bestTextOn(bg) black or white, whichever is more readable
parseColor / toHex #rgb/#rrggbb/rgb(){r,g,b}

Accessibility reference

WCAG 2.2 1.4.3 Contrast (Minimum): normal text needs 4.5:1, large text 3:1 (AA); AAA raises these to 7:1 and 4.5:1. hueshift reports all four.

Tests

npm test — 12 tests covering the color math (incl. the black/white = 21:1 invariant), ramp monotonicity, and that generated palettes actually pass their contrast guarantees.

License

MIT © Velkina (Ömer Can Nalbant, Baha Taşkın)

About

Accessible color palettes from one seed — WCAG contrast guarantees baked in

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors