# Technical Deep Dive

*For the color nerds, math geeks, and optimization enthusiasts who want to know HOW the magic actually works*

So you've used CM-Colors and thought "this is pretty neat, but HOW does it actually work?" Welcome to the rabbit hole! We're about to get into some serious color science, perceptual mathematics, and optimization theory. 

## The Big Picture: What We're Actually Optimizing

When you give us two colors that don't meet accessibility standards, we're solving a constrained optimization problem:

**Find the smallest perceptual change to your text color that achieves the required contrast ratio.**

Sounds simple? It's not. Here's why this is mathematically fascinating:

### The Color Space Problem

Your RGB values (like `#FF5733`) are great for computers, terrible for human perception. When you change `(255, 87, 51)` to `(250, 87, 51)`, that looks like a tiny change numerically, but perceptually it might be huge or imperceptible depending on the color.

**Solution**: We convert everything to OKLCH color space, which is designed to match human vision:
- **L** (Lightness): How bright/dark the color appears
- **C** (Chroma): How saturated/vivid the color is  
- **H** (Hue): The actual color (red, blue, etc.)

OKLCH is perceptually uniform, meaning equal numerical changes produce equal visual changes. This is crucial for making "minimal" adjustments that actually look minimal.

### The Perceptual Distance Problem

How do we measure if two colors "look similar"? Enter **Delta E 2000** - the current state-of-the-art formula for color difference that considers:
- How sensitive human eyes are to different hues
- How lighting conditions affect perception
- The fact that we're better at detecting some color changes than others

Delta E < 1.0 = Changes most people can't detect
Delta E < 2.0 = Only noticeable when colors are side-by-side
Delta E > 5.0 = Obviously different colors

We try to keep changes under 2.0 Delta E whenever possible.

> Note: The function's we are mentioning are all from `optimised.py` and is used to create our `tune_colors()` function
## The Algorithm: Multi-Phase Optimization

Our `generate_accessible_color()` function uses a sophisticated multi-phase approach:

### Phase 1: Binary Search on Lightness

```python
def binary_search_lightness(text_rgb, bg_rgb, delta_e_threshold=2.0, target_contrast=7.0):
```

**Why lightness first?** Most accessibility problems are solved by making text darker or lighter. This gives us the biggest contrast improvements with minimal perceptual change.

**The binary search magic:**
- Convert your color to OKLCH
- Determine if we need to go lighter or darker based on background
- Binary search the lightness value (L component) in 20 iterations
- Each iteration cuts the search space in half
- Achieves ~1 million precision levels in just 20 steps

**Mathematical complexity**: O(log n) vs O(n) for brute force

### Phase 2: Gradient Descent on Lightness + Chroma

```python
def gradient_descent_oklch(text_rgb, bg_rgb, delta_e_threshold=2.0, target_contrast=7.0):
```

If adjusting lightness alone isn't enough, we optimize both lightness AND chroma (saturation) simultaneously using gradient descent.

**The cost function we're minimizing:**
```python
cost = contrast_penalty + delta_e_penalty + distance_penalty

# Where:
contrast_penalty = max(0, target_contrast - actual_contrast) * 1000
delta_e_penalty = max(0, delta_e - threshold) * 10000  
distance_penalty = delta_e * 100
```

**Why these specific weights?**
- **10000x** penalty for exceeding Delta E threshold (hard constraint)
- **1000x** penalty for missing contrast target (primary goal)
- **100x** penalty for perceptual distance (minimize brand impact)

**Numerical gradient computation**: We use central difference approximation because the color conversion functions aren't analytically differentiable:

```python
gradient[i] = (f(x + ε) - f(x - ε)) / (2ε)
```

**Adaptive learning rate**: Starts at 0.02, decays by 5% every 10 iterations to ensure convergence.

### Phase 3: Progressive Delta E Relaxation

If neither binary search nor gradient descent finds a solution within our strict Delta E threshold, we progressively relax constraints:

```python
delta_e_sequence = [0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.7, 3.0, 3.5, 4.0, 5.0]
```

We run both optimization phases at each threshold level, keeping the best candidate found so far.

## The Color Science Behind the Scenes

### OKLCH Color Space Conversion

OKLCH is based on the OKLAB color space, which was designed in 2020 to be more perceptually uniform than previous attempts. The conversion from RGB involves:

1. **Linear RGB**: Remove gamma correction
2. **XYZ conversion**: Transform to CIE XYZ color space  
3. **OKLAB transformation**: Apply the OK color appearance model
4. **Cylindrical coordinates**: Convert to lightness-chroma-hue

### Delta E 2000 Calculation

The Delta E 2000 formula considers:
- **Lightness weighting**: How sensitive we are to brightness changes
- **Chroma weighting**: How saturation affects perceived difference  
- **Hue weighting**: Different sensitivity to hue shifts across the color wheel
- **Interaction terms**: How lightness, chroma, and hue changes interact

It's a beast of a formula involving elliptical parameters, rotation terms, and compensation factors. The math is gnarly, but the perceptual accuracy is worth it.

### Contrast Ratio Mathematics

WCAG contrast ratio is defined as:
```
contrast = (L1 + 0.05) / (L2 + 0.05)
```

Where L1 and L2 are the relative luminances of the lighter and darker colors respectively.

**Target ratios:**
- **AAA Large Text**: 4.5:1 minimum
- **AA Normal Text**: 4.5:1 minimum  
- **AAA Normal Text**: 7:1 minimum (our default target)

## Performance Optimizations

### Why Not Brute Force?

A naive brute force approach might test every possible RGB combination:
- 256³ = 16.7 million possible colors
- Plus Delta E calculation for each = computationally expensive
- Plus contrast ratio calculation = even slower

### Our Optimized Approach

1. **Binary search**: 20 iterations vs ~256 for linear search
2. **OKLCH space**: More efficient than RGB for perceptual operations
3. **Gradient descent**: Follows the mathematical gradient toward optimal solution
4. **Early termination**: Stop as soon as we find a valid solution
5. **Progressive relaxation**: Only try harder thresholds if needed

**Result**: ~100x faster than brute force with identical quality.

## Edge Cases and Failure Modes

### When We Can't Help You

Some color combinations are just mathematically impossible to fix within reasonable perceptual bounds:

1. **Neon yellow on white**: Even perfect black text only gives ~17:1 contrast
2. **Very similar colors**: If your text and background are too close, we'd need to change them dramatically
3. **Extreme saturation**: Highly saturated colors have limited lightness range in RGB

### Fallback Behavior

When optimization fails:
- Return the best candidate found (may not meet full contrast requirements)
- Preserve original color if no improvement possible
- Never return invalid RGB values
- Always return something usable

## Implementation Details

### Numerical Stability

Color space conversions can be numerically unstable near the edges of the RGB gamut. We handle this with:

- **Safe conversion functions**: Check for valid RGB output at each step
- **Gamut clamping**: Keep intermediate values within valid ranges
- **Exception handling**: Gracefully fail to fallback methods

### Memory Efficiency

- **No color caching**: Each optimization is stateless
- **Minimal object allocation**: Reuse data structures where possible
- **Stack-based**: No recursive algorithms that could cause stack overflow

## Extending the Algorithm

Want to hack on CM-Colors? Here are some areas for improvement:

### Alternative Optimization Methods

- **Simulated annealing**: For even better global optimization
- **Genetic algorithms**: Population-based search
- **Constrained optimization**: Using scipy.optimize for more sophisticated constraints

### Different Color Spaces

- **LAB**: Older but still widely used perceptual space
- **LUV**: Alternative perceptual uniform space
- **HSV/HSL**: More intuitive for designers but less perceptually uniform

### Multi-Objective Optimization

- **Pareto fronts**: Trade-off between multiple objectives
- **Weighted objectives**: Let users specify preference for contrast vs. brand preservation
- **Color harmony**: Maintain color scheme relationships

## Testing and Validation

Our optimization algorithms are validated against:

1. **Brute force reference**: Identical results with better performance
2. **Perceptual studies**: Human evaluation of "minimal change"
3. **Edge case coverage**: Pathological color combinations
4. **Performance benchmarks**: Speed comparisons across color ranges

## The Math Stuff (For the Really Curious)

### Lagrangian Formulation

Our constrained optimization problem can be expressed as:

```
minimize f(L, C) = ΔE(original, new)
subject to: contrast(new, background) ≥ target
           ΔE(original, new) ≤ threshold
           new ∈ RGB_gamut
```

### Gradient Computation

For the OKLCH gradient descent, we numerically approximate:

```
∇f = [∂f/∂L, ∂f/∂C]
```

Using central differences for stability.

### Convergence Criteria

We stop optimization when:
- Objective function change < 1e-6 (numerical convergence)
- Valid solution found (early termination)
- Maximum iterations reached (50 for gradient descent)

## Conclusion

What looks like "just making colors accessible" is actually a sophisticated optimization problem involving:
- Perceptual color science
- Numerical optimization
- Constrained search algorithms
- Color space mathematics

The magic happens in the intersection of human perception, mathematical optimization, and practical engineering constraints. Pretty cool for something that "just fixes your colors," right?

---

*Still want to go deeper? Check out the research papers on OKLCH color space, Delta E 2000 perceptual difference, and WCAG contrast mathematics. Fair warning: there's a LOT of math involved.* 🤓

*Found this interesting or spotted an optimization we could make better? [Open an issue](https://github.com/comfort-mode-toolkit/cm-colors/issues) - we love talking about color science!*
