Compare palettes across color vision profiles

Reveal where semantic colors converge before hue becomes the only cue for a status, chart, or control.

Original semantic colors and their PHPColor simulation results
Profile Danger Warning Success Info
Original
Danger #dc2626
Warning #d97706
Success #16a34a
Info #2563eb
Deuteranopia
Danger #98a526
Warning #b4bc28
Success #4b4065
Info #3c38c2
Protanopia
Danger #8d8c26
Warning #afae21
Success #535460
Info #4040ca
Tritanopia
Danger #d32626
Warning #d4373c
Success #1d7174
Info #28b0aa
Monochromacy
Danger #5c5c5c
Warning #878787
Success #6f6f6f
Info #606060

The same semantic palette, five views

PHPColor transforms the four source colors for each profile. Labels and markers stay in place so the meaning survives when hues move closer together.

Simulate every color in the palette

simulateAll() applies one profile to the complete array and returns sRGB color objects in the same order. The matrix above uses the exact hexadecimal results from this example.

<?php

use PhpColor\Color\Color;
use PhpColor\Color\Vision\ColorVisionSimulator;
use PhpColor\Color\Vision\VisionProfile;

$palette = array_map(
    Color::parse(...),
    ['#dc2626', '#d97706', '#16a34a', '#2563eb'],
);

foreach ([
    VisionProfile::Deuteranopia,
    VisionProfile::Protanopia,
    VisionProfile::Tritanopia,
    VisionProfile::Monochromacy,
] as $profile) {
    $colors = ColorVisionSimulator::create($profile)
        ->simulateAll($palette);

    printf(
        "%s: %s\n",
        $profile->value,
        implode(' ', array_map(
            fn ($color) => $color->toHex(),
            $colors,
        )),
    );
}
use PhpColor\Color\Color; use PhpColor\Color\Vision\ColorVisionSimulator; use PhpColor\Color\Vision\VisionProfile; $palette = array_map( Color::parse(...), ['#dc2626', '#d97706', '#16a34a', '#2563eb'], ); foreach ([ VisionProfile::Deuteranopia, VisionProfile::Protanopia, VisionProfile::Tritanopia, VisionProfile::Monochromacy, ] as $profile) { $colors = ColorVisionSimulator::create($profile) ->simulateAll($palette); printf( "%s: %s\n", $profile->value, implode(' ', array_map( fn ($color) => $color->toHex(), $colors, )), ); }

Keep meaning outside the hue

Simulation is an early warning for palette relationships. Status text, icons, shapes, patterns, and sufficient contrast must still carry the distinction in the finished interface.

Treat simulation as an approximation

  • The profiles use transformation matrices on sRGB values, clamp the resulting channels, and return sRGB colors.
  • Anomalous profiles use a fixed severity of 0.6.
  • The distinguishability helper uses Euclidean sRGB distance. Its threshold is not Delta E, WCAG, or a clinical measure.
  • A simulated palette cannot reproduce an individual person's vision or replace testing the complete interface.

Compare the complete palette

Run the simulation, then inspect the relationships