Color palette generator
Shuffle harmonious palettes, lock what you like, or describe your project and let AI mix it. Every palette is checked for WCAG contrast and exports straight to CSS, Tailwind or JSON.
See it on a page
Lightest color becomes the background, darkest the text, the most saturated one the button.
Ship the release notes your users actually read.
Body text in your darkest color on your lightest: 15.03:1 AA pass
Export
CSS custom properties, Tailwind v4 @theme (in OKLCH), Tailwind v3 config, JSON or SCSS.
:root {
--color-midnight-blue: #1B1B3A;
--color-rebecca-purple: #693668;
--color-chocolate: #E4572E;
--color-khaki: #F3C969;
--color-whitesmoke: #F7F3EE;
}Contrast between every pair
WCAG 2.2: 4.5:1 for body text (AA), 3:1 for large text and UI parts, 7:1 for AAA.
| Text / background | #1B1B3A | #693668 | #E4572E | #F3C969 | #F7F3EE |
|---|---|---|---|---|---|
| #1B1B3A | Aa1.84:1Fail | Aa4.50:1AA | Aa10.57:1AAA | Aa15.03:1AAA | |
| #693668 | Aa1.84:1Fail | Aa2.44:1Fail | Aa5.74:1AA | Aa8.16:1AAA | |
| #E4572E | Aa4.50:1AA | Aa2.44:1Fail | Aa2.34:1Fail | Aa3.33:1Large | |
| #F3C969 | Aa10.57:1AAA | Aa5.74:1AA | Aa2.34:1Fail | Aa1.42:1Fail | |
| #F7F3EE | Aa15.03:1AAA | Aa8.16:1AAA | Aa3.33:1Large | Aa1.42:1Fail |
Get an AI critique of this palette
The contrast numbers are calculated exactly in your browser and passed to the AI, so its advice starts from real ratios.
How a good palette is put together
Most usable palettes follow a simple structure: one or two dark colors for text, one or two light colors for backgrounds and surfaces, and one saturated color for buttons and links. The generator keeps that shape by stepping lightness from dark to light, then picks hues with a harmony rule from the color wheel.
It works in OKLCH, a perceptual color space, so two colors with the same lightness really do look equally bright. In HSL a yellow and a blue at “50% lightness” differ enormously in how light they look — and in contrast.
Harmony rules in one line each
- Complementary Colors (180°) — two opposite hues; the strongest contrast, best for one accent.
- Analogous Colors (±30°) — neighbouring hues; calm and cohesive, needs a contrasting accent.
- Triadic Colors (120°) — three evenly spaced hues; lively, let one dominate.
- Split-Complementary Colors (150° / 210°) — a hue plus the two neighbours of its opposite; punchy but forgiving.
- Tetradic Colors (90°) — two complementary pairs; the richest and hardest to balance.
- Monochromatic Color Scheme (0°) — one hue at many lightness levels; instantly cohesive.
Balance the amounts
A palette is also about proportions. The 60-30-10 rule — 60% dominant, 30% secondary, 10% accent — is the quickest way to stop five good colors from fighting each other.
Frequently asked questions
How does the color palette generator work?
Press Generate (or the space bar) to get a new palette. Each palette is built in the OKLCH color space from a harmony rule (complementary, analogous, triadic, split-complementary, tetradic or monochromatic) with a spread of lightness, so there is always a dark color for text and a light one for backgrounds. Lock colors you like and they stay put on the next shuffle.
What does the AI palette feature do?
Type a sentence about your project, such as “calm fintech app for retirees”, and the AI proposes a named palette with a role for each color. Everything else on the page — contrast checks, exports, the UI preview — is calculated instantly in your browser without AI.
Can I export a palette to Tailwind CSS?
Yes. The export box produces a Tailwind v4 @theme block (in oklch()), a Tailwind v3 tailwind.config.js colors object, plain CSS custom properties, SCSS variables and JSON. For a full 50–950 shade scale from one color use the Tailwind color generator.
Is the palette accessible?
The contrast grid shows the WCAG 2.2 ratio of every color on every other color and marks AA, AAA and large-text passes. Body text needs 4.5:1; large text and UI components need 3:1.
Is PaletteForge free? Do I need an account?
It is free and there is no account. Saved palettes are stored only in your browser’s localStorage.