---
title: "Color palettes"
description: "Generate 11-stop palettes from a brand color with `@systhemaui/core/color` or the CLI."
requested_language: cs
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/cs/next/design/palettes
version: unreleased (main)
docs_index: https://docs.systhema.app/cs/next/llms.txt
---
> This page isn't translated yet. Showing English.


Systhema generates Tailwind-style 11-stop palettes (`50` to `950`) from a seed color, byte-exact with uicolors.app for the same input. The same generator powers the CLI, Systhema Design and your own code.

## From the CLI

`systhema generate-palette` prints a palette as JSON, TypeScript or DTCG tokens. See [systhema generate-palette](https://docs.systhema.app/cs/next/cli/generate-palette.md).

## In Systhema Design

The Colors section of [Systhema Design](https://docs.systhema.app/cs/next/design/systhema-design/editing.md#managing-palettes--color-system-modes) seeds primitive palettes from a color and lets you move each palette's foundation anchor.

## In code

Color math shared by the `systhema generate-palette` CLI command and the Systhema Design app — both import it from here. The palette generator is a **byte-exact reproduction of [uicolors.app](https://uicolors.app)'s** Tailwind generator (it uses the same library, `chroma-js`, confined to this entry); the lower-level hex converters are pure and dependency-free.

```ts
import {
  generatePalette,
  generatePaletteAnchored,
  classifyInputStop,
  hexToRgbaString,
  hexToOklchString,
  parseHex,
  hexToHsl,
  hslToHex,
  hexToOklab,
  type Palette,
  type Stop,
} from '@systhemaui/core/color'
```

### `generatePalette(hex)`

Generate an 11-stop (`50`–`950`) Tailwind-style ramp from a single seed hex, **identical to uicolors.app's output for the same input**. The seed is matched to its closest reference family (22 Tailwind families + 2 extras, by CIEDE2000 ΔE), anchored byte-exact at the family shade closest to it in lightness, and the other ten stops are the family recoloured to the seed's hue and saturation. Throws on invalid hex.

```ts
generatePalette('#8b54ec')['500'] // '#8B54EC' — the seed lands on its anchor stop
generatePalette('#8b54ec')        // { '50': '#F6F4FE', …, '500': '#8B54EC', …, '950': '#341560' }
```

`classifyInputStop(hex)` returns just the stop (`'50'`…`'950'`) a hex anchors to (its matched family's shade closest in lightness).

### `generatePaletteAnchored(hex, anchor)`

Like `generatePalette`, but you choose which stop the seed lands on instead of accepting its automatic classification. The seed is placed byte-exact at `anchor` and the other ten stops are generated around it.

```ts
generatePaletteAnchored('#8b54ec', '700')['700'] // '#8B54EC' — the seed locks to 700
```

`generatePalette(hex)` is exactly `generatePaletteAnchored(hex, classifyInputStop(hex))` — passing the seed's natural classification reproduces the automatic ramp byte-for-byte. Use the anchored form when you want to lock a seed to a specific shade (for example, treating a brand color as the dark `700` rather than the mid-toned `500`). `anchor` is a `Stop` (`'50'`…`'950'`). Throws on invalid hex.

### Color-format converters

`parseHex` accepts `#rgb`, `#rrggbb`, and `#rrggbbaa` and returns `{ r, g, b, a }` (RGB `0–255`, alpha `0–1`). The string converters emit CSS Color 4 syntax; both append a `/ alpha` component only when the input is translucent.

```ts
parseHex('#00000040')              // { r: 0, g: 0, b: 0, a: 0.251 }

hexToRgbaString('#FF0000')         // 'rgb(255 0 0)'
hexToRgbaString('#00000040')       // 'rgb(0 0 0 / 0.251)'

hexToOklchString('#FF0000')        // 'oklch(0.628 0.2577 29.23)'
```

`hexToOklchString` takes an optional second argument to control the rounding precision of each component, which is useful for compact UI readouts:

```ts
hexToOklchString('#FF0000', { lDigits: 3, cDigits: 3, hDigits: 1, aDigits: 2 })
// 'oklch(0.628 0.258 29.2)'
```

Each option is the number of decimal places for one component — `lDigits` (lightness), `cDigits` (chroma), `hDigits` (hue), `aDigits` (alpha). Omitting the argument, or any individual option, keeps the defaults (`lDigits: 4`, `cDigits: 4`, `hDigits: 2`, `aDigits: 3`), so existing calls produce byte-identical output.

`hexToHsl` / `hslToHex` (with the `HSL` type and `roundHsl` helper) and `hexToOklab` / `hexToOklabL` (with the `OKLab` type) round out the lower-level conversions (the latter back the OKLCH formatter).
