Categorical, sequential, semantic, and diverging chart color palettes
The data visualization color palettes are based on Pluma's color palette, and are dark-mode aware. They are designed to be accessible, consistent, and predictable across a variety of chart types and data representations, ensuring that colors convey meaning effectively while maintaining visual harmony.
The palettes are categorized into four main types:
Each palette and color is available as a color token, with data-viz-prefixed names. For convenience, the @customerio/pluma-components/data-viz package exports utilities to retrieve the right palette subset for your needs. The utilities are:
defaultColor(): Returns the default color descriptor for single-series charts.categorical(n): Returns the first n slots of the categorical palette (1 to 10).sequential(variant, n): Returns a subset of the sequential palette for the specified variant (e.g., 'blue', 'teal') and count n (1 to 7).semantic(role, n): Returns a subset of the semantic palette for the specified role (e.g., 'success', 'warning') and count n (1 to 7).diverging(palette): Returns the full diverging palette for the specified palette (e.g., 'temperature', 'neutral', 'cool').Each returns an array of DataVizColor descriptors (a single one for defaultColor), which is an object with the following keys:
type: The palette type ('categorical', 'sequential', 'semantic', or 'diverging').name: A unique name for the color, derived from its token name.
token: The CSS variable reference for the color (e.g., var(--data-viz-categorical-1)).tokenHover: The CSS variable reference for the hover state of the color (e.g., var(--data-viz-categorical-1-hover)).The count argument in each function is optional - if omitted, the full palette is returned. More details on the functions are available below in their respective sections.
defaultColor() (categorical slot 1).categorical in slot order. For longer series, we recommend applying additional encodings (line style, dash, dot, or pattern) to avoid color confusion. Looping the categorical palette is not recommended, as it can lead to misinterpretation of series identity, but is possible as a last resort.semantic role palette with the subset matching the series count.sequential palette -- the full set for smooth fills, or a subset for identifiable bins.diverging palette.These are best used for unrelated series, or when you want to distinguish between different categories without implying order, magnitude, or relation. The palette should be used in the provided order, as the colors are designed to be visually distinct and harmonious when used together.
color-data-viz-categorical-{n}categorical(n) returns the first n slots of the categorical palette, where n can be any integer from 1 to 10. If n is omitted, the full palette is returned.
Sequential palettes are best for ordered data, where color intensity represents magnitude, or for representing related series.
Each sequential palette contains 7 steps. For each palette, smaller subsets with fewer steps are available, which are designed be visually distinct and harmonious at every count. For example, when showing 3 series specifically, the 3-step subset of a palette should be used, rather than trimming from the full set.
Dark mode does not mirror the light palette position for position. Each hue's dark ramp is anchored where that hue still reads as itself against a dark surface: yellow, teal and green only look like themselves when they are light, while red, purple and blue only do when they are dark. Those anchors are set per hue rather than by one formula, so a step does not carry identical contrast in both modes - check a chart in both when its colors matter.
color-data-viz-sequential-blue-{n}color-data-viz-sequential-green-{n}color-data-viz-sequential-grey-{n}color-data-viz-sequential-orange-{n}color-data-viz-sequential-pink-{n}color-data-viz-sequential-purple-{n}color-data-viz-sequential-red-{n}color-data-viz-sequential-teal-{n}color-data-viz-sequential-yellow-{n}Sequential palettes can be accessed using the sequential(variant, n) function, where variant is the name of the palette (e.g., 'blue', 'teal') and n is the number of steps desired (1 to 7). If n is omitted, the full palette is returned.
The semantic palettes are aliases of the sequential ones, but with a role that conveys meaning. Use these instead of sequential palettes when the series' are associated with a specific meaning. The roles are:
neutral (grey): for series that are neutral or non-critical, such as background or reference data.information (blue): for series that convey information or status, such as notifications or updates.success (green): for series that indicate success or positive outcomes.caution (yellow): for series that indicate caution or warning.critical (red): for series that indicate critical or error states.color-data-viz-semantic-neutral-{n}color-data-viz-semantic-information-{n}color-data-viz-semantic-success-{n}color-data-viz-semantic-caution-{n}color-data-viz-semantic-critical-{n}Semantic palettes can be accessed using the semantic(role, n) function, where role is the semantic role (e.g., 'success', 'warning') and n is the number of steps desired (1 to 7). If n is omitted, the full palette is returned.
Diverging palettes also convey meaning, but are designed for data that diverges around a central point, or for highlighting differences between two extremes.
color-data-viz-diverging-cool-{n}color-data-viz-diverging-neutral-{n}color-data-viz-diverging-temperature-{n}Diverging palettes can be accessed using the diverging(palette) function, where palette is the name of the diverging palette (e.g., 'temperature', 'neutral', 'cool'). The full diverging palette is returned.
Every item returned by the utility functions carries a tokenHover, so a series can swap to color.tokenHover on interaction. The hover always moves in the emphasis direction -- darker in light mode, lighter in dark mode -- for every step of every palette, so lines, bars, and binned encodings all hover the same way.
While we recommend using typical legend-style labels for chart series (a colored box with text beside it), we may sometimes reach to Badge components for additional visual representation of items falling into a particular category. The Badge itself doesn't come with color tokens to match to chart series exactly, but they can be customized on a case-by-case basis using CSS and color mixing.
This recipe recommends:
background-color, mix the chart color 20% with surface-base (lightens in light mode, darkens in dark mode)color, mix the chart color 40% with text-base (darkens in light mode, lightens in dark mode)This produces Badges that are visually distinct, but still clearly associated with the chart color. The recommended mix percentages are designed to maintain accessibility (APCA and WCAG) in both light and dark modes.