Color system with five base palettes and semantic tokens that adapt to light and dark themes.
The Pindoba color system uses custom color ramps stored as W3C Design Tokens (DTCG format) with automatic light and dark mode adaptation. Five base palettes feed into five semantic color groups.
Five base color families, each with 11 shades (50–950). Each family has independent light and dark ramps; semantic tokens pick the right one automatically.
Every group exposes the same shape: solid fills, text steps, borders, and a five-step surface micro-ramp. Reach for these by intent rather than raw shade.
Color ramps are generated in the OKLCH color space using a contrast-based approach:
Text tokens are contrast-solved against the worst-case surface — both the neutral and own-family surface.deep — so text always meets its target ratio regardless of which surface it sits on.
Surfaces are a 5-step micro-ramp interpolated between shade 50 and shade 100, providing fine-grained background variation without jumping to the next full shade.
Per-mode palettes: light and dark modes have independent color family inputs. A lightness reference family (default: blue) shares its solved lightness curve with all other families, keeping them visually consistent. Neutral (gray) always uses its own independent lightness curve.
Two fixed contrast values are available for cases where you need guaranteed light or dark:
contrast.darkest; // #181818
contrast.lightest; // #f9fbff
import { css } from "@pindoba/styled-system/css";
// Semantic surface and text
<div className={css({
backgroundColor: "neutral.surface.soft",
color: "neutral.text.bold",
})}>
Card content
</div>
// Solid fill button
<button className={css({
backgroundColor: "primary",
color: "primary.text.contrast",
_hover: { backgroundColor: "primary.hover" },
_active: { backgroundColor: "primary.active" },
})}>
Submit
</button>
// Subtle surface button
<button className={css({
backgroundColor: "primary.surface.soft",
color: "primary.text",
_hover: { backgroundColor: "primary.surface.step.2" },
_active: { backgroundColor: "primary.surface.deep" },
})}>
Secondary action
</button>
// Status feedback
<div className={css({
backgroundColor: "danger.surface.soft",
color: "danger.text.bold",
borderWidth: "1px",
borderColor: "danger.border.muted",
})}>
Error message
</div>
The colorPalette utility lets components switch between semantic groups without duplicating styles:
<div className={css({ colorPalette: "success" })}>
<span className={css({ color: "colorPalette.text.bold" })}>
Status text
</span>
</div>
<div className={css({ colorPalette: "danger" })}>
<span className={css({ color: "colorPalette.text.bold" })}>
Error text
</span>
</div>
primary.surface.soft, neutral.text.bold) rather than raw base colors (blue.light.500).text.contrast for text on solid-colored backgrounds (primary, primary.hover, primary.active).text.muted for helper text and secondary content.border.muted for subtle separators and .border.bold for emphasissurface.soft for light backgrounds and surface.deep for deeper emphasis — they automatically adapt to the active theme mode.border (30%), .border.muted (15%), .border.bold (65%)