# charts.interpolate-color The colour a fraction `t` of the way along a ramp: `interpolateColor(["#000000", "#ffffff"], 0.5)` is `"#636363"`. Use it for heatmaps, choropleths and any sequential (light to dark) or diverging (colour, neutral, colour) scale. The stops are evenly spaced: with three stops, t = 0.5 is exactly the middle one. **Why OKLab.** Mixing the stored sRGB numbers, which is what a naive lerp of hex digits does, gives a grey `#808080` halfway from blue to yellow and bunches the visible change at one end of a ramp. Mixing in linear RGB is better for light but still not perceptually even. OKLab (Björn Ottosson, 2020) is built so that equal distances look like equal differences, so each stop is converted to OKLab (sRGB → linear → LMS → cube root → Lab), the three coordinates are interpolated linearly, and the result is converted back, clipped to the sRGB gamut channel by channel, and rounded to 8 bits. Clipping matters in the middle of red to green, which OKLab places slightly outside sRGB. Hex parsing, the sRGB transfer function and the 8-bit rounding come from `charts.color`; cube roots from `math.pow`. No platform `pow` or `cbrt` is used, so TypeScript, Python and Rust return the same hex. The matrices are the published ones, to Ottosson's ten decimal places; the endpoints come back exactly (t = 0 gives the first stop). `t` must be in 0..1 and the ramp needs at least two stops; anything else is an error. Hex in either `#rgb` or `#rrggbb` form, either case; out is lowercase `#rrggbb`. Sources: B. Ottosson, "A perceptual color space for image processing" (2020), https://bottosson.github.io/posts/oklab/ (the M1 and M2 matrices and their inverses, for linear sRGB); IEC 61966-2-1 (sRGB transfer function).