About

About ToolQuilt: how our color tools work

ToolQuilt is a set of free online color tools and a color theory blog, run as an independent project. No accounts, no sign up, nothing about you stored. This page explains the math behind each tool so you can decide whether to trust the numbers.

The color math

Everything is calculated on the server from first principles, not by a third party library, so the working can be inspected and corrected.

Contrast

The WCAG 2.2 ratio is (L1 + 0.05) / (L2 + 0.05), where L is relative luminance computed from linearized sRGB channels with the standard 0.2126 / 0.7152 / 0.0722 weights. Black on white gives exactly 21:1, which is the sanity check every implementation should pass.

The APCA score uses the published 0.1.9 constants: a 2.4 exponent transfer curve, separate coefficients for the two polarities, a soft black clamp at 0.022, and the low contrast clip at 0.1. Black text on white returns roughly Lc 106; white text on black returns roughly Lc −108. APCA is a candidate for WCAG 3 and is not yet a legal standard, so conform to WCAG 2.2 and use APCA as the second opinion that catches pairs which pass the ratio but still read badly.

Worked example: the same three pairs, scored

WCAG 2.2 · APCA 0.1.9
The quick brown fox
13.55:1 Lc 95.7 Passes AA · Body text
The quick brown fox
4.19:1 Lc 65.8 AA large only · Large text only
The quick brown fox
1.95:1 Lc 35.8 Fails AA · Decoration only
All three sit on the same background. The middle one is the trap: it looks deliberate, and it fails body text by a third of a point.

Color spaces

Conversions go through CIE XYZ under a D65 white point with the 2 degree standard observer. CIELAB and LCH follow the CIE definitions, including the linear segment below the 0.008856 threshold. OKLab and OKLCH use Björn Ottosson's published matrices. Round tripping any color through LAB or OKLCH and back returns the original hex.

CMYK is the simple arithmetic conversion with no color profile attached. It will get you into the right neighborhood and no further. Real print work needs an ICC profile for the specific press, paper and ink set.

Worked example: out to LAB and OKLCH, and back

Computed on this request
#C05746 → lab(50.06% 40.89 30.21) → #C05746 identical
#2F6F68 → lab(42.72% -22.26 -2.29) → #2F6F68 identical
#F2B134 → lab(76.42% 13.09 68.45) → #F2B134 identical
Every value returns the hex it started from. A conversion that cannot make this trip has dropped a coefficient somewhere.

Palettes and scales

Harmony rules set the hue relationships. Lightness and chroma are then spaced again in OKLCH, because HSL lightness does not match perceived lightness: yellow at 50% in HSL looks far brighter than blue at 50%. The 50 to 950 tonal scale holds hue, walks a fixed lightness ladder, and shapes chroma with a curve that peaks in the middle, which is what stops the lightest and darkest steps looking artificial.

Worked example: why HSL lightness is not lightness

Numbers are measured relative luminance

HSL, every swatch at 50% lightness spread 42 points

26% 52% 48% 24% 10% 18%

OKLCH, every swatch at the same perceptual lightness spread 4 points

22% 24% 25% 26% 23% 22%
The top row asks for one lightness and delivers 42 points of variation, and the yellow green is several times brighter than the violet. The bottom row asks the same question in OKLCH and lands within 4. That is the whole reason palettes here are spaced in OKLCH.

Color vision simulation

The protanopia, deuteranopia and tritanopia previews use the Machado, Oliveira and Fernandes (2009) matrices at full severity, applied in linear RGB. They are a reasonable model, not a medical instrument. Treat them as a prompt to add a second signal, such as a label, an icon or a pattern, wherever two swatches converge.

Worked example: one palette, four kinds of vision

Machado et al. (2009), full severity

As drawn: Standard color vision

Protanopia: No working red cones. Around 1 in 100 men.

Deuteranopia: No working green cones. Around 1 in 100 men.

Tritanopia: No working blue cones. Around 1 in 10,000 people.

→ #5AC1BA and #F4B7FF are ΔE₀₀ 39.5 apart normally and 13.0 apart under deuteranopia. That is the pair to give a second signal.

Privacy, in short

The full detail is in the privacy policy and the cookie policy. The summary:

  • No account system, so there is nothing to sign up for and no profile to leak.
  • Colors you enter travel in the URL query string so results are shareable. They are processed to build the page and are not written to any database.
  • A single browser localStorage entry records whether you chose the light or dark theme. It never leaves your device.
  • No analytics script, no session recording, no fingerprinting.
  • No advertising network, and so no advertising cookies.
  • No third party fonts, embeds or social widgets. Every asset is served from this domain.
  • Standard web server request logs may exist at the hosting layer, as they do for every website.

Standards this follows

  • WCAG 2.2, Success Criteria 1.4.3, 1.4.6 and 1.4.11.
  • APCA 0.1.9, as drafted for WCAG 3.
  • CSS Color Module Level 4 for parsing and output syntax.
  • CIE 15:2004 for XYZ, LAB and LCH.

Corrections

If a number here disagrees with a reference implementation, the number here is the one to doubt. Color math has a lot of places to drop a coefficient, and every tool on this site shows its inputs so a disagreement can be traced.