Skip to main content

sprezzature-colors

Color accessibility and palette tooling for the sprezzature stack.

What problem this solves

Take a button with light-gray text on a white background. To most people it reads fine. To someone with low vision, or in bright sunlight on a phone screen, the same button can be unreadable: the text and the background are too close in brightness for the eye to separate them. The same gap shows up when a chart uses red for "down" and green for "up": about 1 man in 12 has a form of color vision deficiency (CVD, the inability to tell certain hues apart, most often red from green) and sees both bars as the same color.

This package gives three deterministic, stdlib-only tools that catch these gaps before a design ships, rather than relying on someone happening to notice:

  • Contrast auditing. Checks every (text, background) color pair in a palette against the accessibility thresholds published by the Web Content Accessibility Guidelines (WCAG, the standard body of rules for making web content usable by people with disabilities), and suggests a fix that stays visually close to the original color.
  • Color-blindness simulation. Renders an image the way a person with protanopia, deuteranopia, or tritanopia (the three common forms of red/green/blue color blindness) would actually see it, so a design can be checked before it ships rather than after a complaint.
  • Tailwind palette export. Writes the project's approved brand colors as a ready-to-use Tailwind CSS configuration block, so every project in the stack draws from the same source instead of each one hand-copying hex codes.

All three run on pure stdlib (the color-blindness simulation additionally needs Pillow, a Python imaging library, to read and write image files). Nothing here calls out to the network or an AI model.


Install

pip install sprezzature-colors

For color-blindness image simulation:

pip install sprezzature-colors[cvd]

pip install also puts four console commands on the PATH: sprezzature-colors-contrast, sprezzature-colors-cvd, sprezzature-colors-palette-to-tailwind, and sprezzature-colors-levels. The examples below use python scripts/….py, which is the form for a source checkout (git clone + pip install -e ".[dev,cvd]"); after a plain pip install, run the matching console command instead — for example sprezzature-colors-contrast --fix in place of python scripts/audit_contrast.py --fix.


Quick start

Contrast audit

python scripts/audit_contrast.py
# Target ratio: 4.5
#
#   ✓      brand-blue  on  surface-primary   ratio 4.55
#   ✗      brand-red   on  surface-secondary  ratio 2.83
#       -> suggest #D4000A  (ratio 4.51)

"Ratio" here is the WCAG contrast ratio: a number from 1 (identical brightness, unreadable) to 21 (pure black on pure white). 4.5 is the WCAG threshold for normal body text.

With a custom palette JSON:

python scripts/audit_contrast.py --palette my-palette.json --target 7 --fix
python scripts/audit_contrast.py --palette my-palette.json --format json

Color-blindness simulation

# Three sibling PNG files
python scripts/simulate_cvd.py hero.png

# 2x2 mosaic for design review
python scripts/simulate_cvd.py hero.png --grid --out hero-cvd-grid.png

# Only deuteranopia + grayscale
python scripts/simulate_cvd.py hero.png --types deut --grayscale

Palette to Tailwind

# Copy-paste block for an existing config
python scripts/palette_to_tailwind.py

# Full tailwind.config.js with derived dark variants
python scripts/palette_to_tailwind.py --emit config --with-dark --out tailwind.config.js

Accessibility levels

# Preview the canonical palette at AAA high-contrast
python scripts/accessibility_levels.py --level high-contrast

# Available levels: universal (default), high-contrast, monochrome,
#                   deuteranopia, protanopia, tritanopia

Library usage

from scripts._colors import contrast_ratio_hex, meets_wcag, lighten, darken, simulate_pixel, CVD_MATRICES

# WCAG contrast ratio
ratio = contrast_ratio_hex("#007AFF", "#FFFFFF")   # -> 4.55

# WCAG AA test
ok = meets_wcag("#007AFF", "#FFFFFF", level="AA", size="normal")   # -> True

# Perceptual lighten/darken (OKLCH axis, hue preserved): OKLCH is a color
# model built so that a fixed numeric step in lightness matches what a human
# eye perceives as an equal step in brightness, unlike raw RGB where the same
# numeric step can look barely different in one area and drastic in another.
lighter = lighten("#007AFF", 0.15)   # -> "#5FA8FF" (approx.)
darker  = darken("#007AFF", 0.10)    # -> "#005DC2" (approx.)

# CVD pixel simulation
r, g, b = simulate_pixel((255, 0, 0), CVD_MATRICES["protanopia"])

Features

Feature Detail
WCAG contrast audit AA (4.5:1), AA-large (3:1), AAA (7:1)
Alpha-aware compositing Translucent #RRGGBBAA foregrounds composited before the ratio
Fix suggestions Nearest OKLCH neighbour that passes the threshold
CVD simulation Machado et al. 2009 matrices (protanopia, deuteranopia, tritanopia)
Grayscale luminance check Relative-luminance gray to catch hue-only distinctions
Tailwind theme export theme.extend.colors block or full module.exports config
Accessibility levels universal / high-contrast / monochrome / CVD-specific palette remapping
Palette science OKLab / OKLCH conversions, sRGB transfer functions, curated Apple base palette
Dependencies stdlib only (+ Pillow for CVD image rendering)

Color science

Contrast ratios follow WCAG 2.x: relative luminance (how bright a color looks to the eye, not just its raw RGB numbers) uses the 2.4-gamma transfer function that the standard specifies. Perceptual adjustments use OKLab / OKLCH, a color model designed by Björn Ottosson (2020) precisely so that "move the lightness value by X" matches how much brighter the color actually looks, which plain RGB does not guarantee. Color-blindness simulation matrices come from Machado, Oliveira, and Fernandes (2009, IEEE Transactions on Visualization and Computer Graphics), a widely cited paper that measured how each type of color blindness transforms a color and published the transformation as a matrix of numbers, which is exactly what CVD_MATRICES stores.


Part of sprezzature

Repo What it does
sprezzature Nine skill collection + web
sprezzature-colors This repo
sprezzature-figures Data visualization
best-engine-ai-helper Offline LLM/VLM runtime

Author

Warith HARCHAOUI, harchaoui.org/warith

License: BSD-3-Clause

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sprezzature_colors-1.0.0.tar.gz (52.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sprezzature_colors-1.0.0-py3-none-any.whl (47.1 kB view details)

Uploaded Python 3

File details

Details for the file sprezzature_colors-1.0.0.tar.gz.

File metadata

  • Download URL: sprezzature_colors-1.0.0.tar.gz
  • Upload date:
  • Size: 52.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.13

File hashes

Hashes for sprezzature_colors-1.0.0.tar.gz
Algorithm Hash digest
SHA256 ec4e0f8eaedb72aab28f82b5f6f72b77df5110dd3cb5204f4fed2bc19026b26a
MD5 a1dac44981da3f6504965e06a2be83c7
BLAKE2b-256 ef1d9b7fef2b197a376ad5f403ea616742f7aa48b0d60ce34a8123720fa2dcb9

See more details on using hashes here.

File details

Details for the file sprezzature_colors-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for sprezzature_colors-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eb938ee99e98e0f43cb4f94e92dc2229138b29adf17b281ce77fb443828e45f5
MD5 a7045e4327d9a4f9e3adc5b8580aadab
BLAKE2b-256 07e5bd384ebb3c8ae5d094e7972736e3415d80729eca47c0508c2719dff782ce

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page