A five-color brand palette is the seed of a design system, not the system itself. Real design systems need tints and shades — the 50, 100, 200… 950 ramps that let you bind UI states (hover, focus, disabled, dark) to deterministic values.
The math is simple. Convert each base color to HSL. Hold the hue and saturation. Step the lightness across ten anchors: 96, 90, 80, 70, 60, 50 (this is your base), 40, 30, 20, 11, 6. The 50-step is your light shade, the 950-step is your dark shade.
Saturation can drop slightly at the extremes. A base at saturation 70 might step down to 50 at the 50-step (lightest tint) and 50 at the 950-step (darkest shade) to avoid neon tints and muddy shades. Most token libraries (Radix, Tailwind, Open Props) follow this principle.
Bind tokens to brand roles, not UI roles. token.color.primary.500 not token.color.button.background. UI tokens come later, and they reference the brand tokens. This separation is what lets you swap a brand color in one place and have all 47 components update.
Use the generator's Figma Tokens export as the input format. Tokens Studio (free Figma plugin) reads it directly. Style Dictionary, Theo, and other token build tools also accept a similar JSON shape. Run the build once and you get CSS variables, Tailwind config, SCSS, Swift, and Kotlin in one shot.
For dark mode, generate a separate set of role tokens that map to different scale steps. token.color.surface.background = primary.50 in light mode, primary.950 in dark mode. The brand scale stays identical; only the role mapping changes. This is the technique used by Radix Themes and Material Design 3.
Five base colors, ten-step scales, role tokens that reference scales, separate light and dark role mappings. That is the entire architecture. Everything else — utility classes, component variants, theme switchers — is plumbing on top.