Color Matching
TailTrace uses perceptual color matching based on the CIEDE2000 algorithm to find the closest Tailwind token for any color value.
Why Not Just Compare Hex Values?
Section titled “Why Not Just Compare Hex Values?”Simple hex comparison fails because:
-
Colors that look similar can have very different hex values
#3b82f6and#3b83f6are nearly identical visually but different in hex
-
Colors that look different can be close in hex
- Linear interpolation in RGB doesn’t match human perception
-
Designers often use “close enough” colors
- A designer might pick
#3b83f6when they meant#3b82f6
- A designer might pick
CIEDE2000 (Delta-E)
Section titled “CIEDE2000 (Delta-E)”TailTrace uses the CIEDE2000 color difference formula, which measures perceptual color difference.
How It Works
Section titled “How It Works”- Convert to LAB color space - Designed to be perceptually uniform
- Apply CIEDE2000 formula - Accounts for hue, chroma, and lightness
- Return Delta-E value - A number representing perceptual difference
Delta-E Values
Section titled “Delta-E Values”| ΔE | Meaning | Example |
|---|---|---|
| 0 | Identical | Same color |
| 1.0 | Not noticeable | Imperceptible difference |
| 2.3 | Just noticeable | JND threshold |
| 5.0 | Clearly different | Visible difference |
| 10+ | Very different | Obviously different colors |
Implementation
Section titled “Implementation”TailTrace’s color matching in @tailtrace/core:
import { parseColor, rgbToLab, deltaE2000 } from '@tailtrace/core';
// Parse colors to RGBconst inputRgb = parseColor('#3b83f6');const tokenRgb = parseColor('#3b82f6');
// Convert to LABconst inputLab = rgbToLab(inputRgb);const tokenLab = rgbToLab(tokenRgb);
// Calculate Delta-E 2000const difference = deltaE2000(inputLab, tokenLab);console.log(difference); // ~0.73
// Classify confidenceif (difference === 0) { // Exact match} else if (difference <= 2.3) { // Fuzzy match - close enough but not exact} else { // No match - too different}Color Space Conversions
Section titled “Color Space Conversions”TailTrace supports these color formats:
| Format | Example | Supported |
|---|---|---|
| Hex | #3b82f6 | ✓ |
| RGB | rgb(59, 130, 246) | ✓ |
| RGBA | rgba(59, 130, 246, 0.5) | ✓ |
| HSL | hsl(217, 91%, 60%) | ✓ |
| Named | blue | ✓ |
All colors are converted to sRGB then CIELAB for comparison.
Tuning the Threshold
Section titled “Tuning the Threshold”Adjust deltaEThreshold based on your needs:
| Use Case | Threshold |
|---|---|
| Strict design systems | 1.0 |
| Standard (default) | 2.3 |
| Lenient/legacy codebases | 5.0 |
{ "deltaEThreshold": 2.3}Why CIEDE2000 Over Other Formulas?
Section titled “Why CIEDE2000 Over Other Formulas?”| Formula | Pros | Cons |
|---|---|---|
| Delta-E 76 | Simple | Poor near neutrals |
| Delta-E 94 | Better | Still issues with blue hues |
| CIEDE2000 | Most accurate | Slightly slower |
TailTrace defaults to CIEDE2000 but exposes all three in @tailtrace/core:
import { deltaE76, deltaE94, deltaE2000 } from '@tailtrace/core';