Apply one hue offset to every color instead of rebuilding each token separately:
use PhpColor\Color\Palette\ColorPalette;
$source = ColorPalette::parse([
'primary' => '#7c3aed',
'secondary' => '#0ea5e9',
'accent' => '#f59e0b',
]);
$shifted = $source->rotateHue(24);
assert([
'primary' => '#a51dca',
'secondary' => '#6498f4',
'accent' => '#d6b000',
] === $shifted->toHex());
use PhpColor\Color\Palette\ColorPalette;
$source = ColorPalette::parse([
'primary' => '#7c3aed',
'secondary' => '#0ea5e9',
'accent' => '#f59e0b',
]);
$shifted = $source->rotateHue(24);
assert([
'primary' => '#a51dca',
'secondary' => '#6498f4',
'accent' => '#d6b000',
] === $shifted->toHex());
rotateHue() returns a new palette and leaves $source unchanged. It preserves the relative hue offsets, not the semantic suitability or contrast of each token.