Map application token names to positions between 0 and 1:
use PhpColor\Color\Palette\ColorPalette;
$scale = ColorPalette::parse(['#111827', '#7c3aed', '#f8fafc']);
$positions = ['900' => 0.0, '700' => 0.2, '500' => 0.5, '300' => 0.8, '50' => 1.0];
$tokens = [];
foreach ($positions as $name => $position) {
$tokens[$name] = $scale->at($position)->toHex();
}
assert([
'900' => '#111827', '700' => '#392a70', '500' => '#7c3aed',
'300' => '#c1b4fc', '50' => '#f8fafc',
] === $tokens);
use PhpColor\Color\Palette\ColorPalette;
$scale = ColorPalette::parse(['#111827', '#7c3aed', '#f8fafc']);
$positions = ['900' => 0.0, '700' => 0.2, '500' => 0.5, '300' => 0.8, '50' => 1.0];
$tokens = [];
foreach ($positions as $name => $position) {
$tokens[$name] = $scale->at($position)->toHex();
}
assert([
'900' => '#111827', '700' => '#392a70', '500' => '#7c3aed',
'300' => '#c1b4fc', '50' => '#f8fafc',
] === $tokens);
at() works on ordered scales and mixes adjacent stops in Oklab. Positions outside the range are clamped.