SaaS Color System Generator - Build an Accessible Palette in Minutes
A tool concept that takes one primary brand color and expands it into a SaaS-ready, WCAG-aware system including semantic colors and export options.
Built for practical use
Brand-to-system mapping
A tool concept that takes one primary brand color and expands it into a SaaS-ready, WCAG-aware system including semantic colors and export options.
Semantic color planning
A tool concept that takes one primary brand color and expands it into a SaaS-ready, WCAG-aware system including semantic colors and export options.
Export guidance
A tool concept that takes one primary brand color and expands it into a SaaS-ready, WCAG-aware system including semantic colors and export options.
Accessibility checks
A tool concept that takes one primary brand color and expands it into a SaaS-ready, WCAG-aware system including semantic colors and export options.
Build Your Palette
Choose your core brand colors and instantly generate a planning snapshot for semantic roles and implementation.
Pick Core Colors
Preview Shade Scale
About This Resource
This document is the framework and methodology behind our SaaS Color System Generator. The interactive web tool lives at desisle.com/tools/color-system (when deployed).
This markdown guide teaches you:
- How to build an accessible color system from scratch
- How to generate WCAG-compliant palettes
- How to structure color tokens for SaaS products
- How to export to CSS variables, Figma tokens, and Tailwind config
Who this is for: Designers, developers, and founders building a new SaaS product who need a color system that looks professional AND passes accessibility standards.
Part 1: Color System Fundamentals
What makes a good SaaS color system
A professional SaaS color system has:
- One primary brand color (the "hero" of your brand)
- One secondary/accent color (optional, used sparingly)
- Four semantic colors (success green, warning yellow/amber, error red, info blue)
- One comprehensive neutral scale (10+ grays — used 70-80% of the time)
- All colors with 9-11 shades (50, 100, 200, ..., 900 or similar)
- WCAG AA contrast validation between all color combinations used
The 10-step color scale pattern
Industry convention (used by Material Design, Tailwind CSS, Radix Colors, IBM Carbon):
| Shade | Use Case |
|---|---|
| 50 | Lightest background tint |
| 100 | Subtle backgrounds (hover states, selected rows) |
| 200 | Muted backgrounds, light borders |
| 300 | Disabled elements, subtle borders |
| 400 | Secondary text on light backgrounds, inactive icons |
| 500 | Base/primary color (most used) |
| 600 | Hover states for 500 |
| 700 | Active/pressed states, primary text |
| 800 | High-contrast text, emphasis |
| 900 | Darkest text, maximum contrast |
Some systems add 950 (darkest, near-black version) for modern aesthetics.
Part 2: Generating an Accessible Palette
Method 1: Start with your brand color
Step 1: Pick your brand color (the "500" value). This should be:
- Distinctive from competitors
- Appropriate for your product's tone (warm/cool, playful/serious)
- Legible at small sizes
- Works in both light and dark modes
Step 2: Generate 10 shades using HSL adjustments or a tool:
- Lighter shades (50-400): Increase lightness, slightly decrease saturation
- Base (500): Your starting color
- Darker shades (600-900): Decrease lightness, slightly increase saturation
Tools to generate palettes:
- Tailwind CSS Color Generator (uicolors.app)
- Radix Colors (radix-ui.com/colors)
- Coolors (coolors.co)
- Leonardo by Adobe (leonardocolor.io)
Method 2: Use perceptually uniform scales
Human perception of color isn't linear. HSL-based palettes can have uneven visual steps (some shades feel closer together than others).
Solution: Use perceptually uniform color spaces:
- OKLCH (newest, best results)
- LCH (similar, more widely supported)
- HSLuv (alternative)
Tools like Leonardo and Radix Colors use perceptually uniform scales by default.
Accessibility validation
Every color pair used for text + background must meet WCAG AA:
| Use Case | Minimum Contrast Ratio |
|---|---|
| Normal text (under 18px or 14px bold) | 4.5:1 |
| Large text (18px+ or 14px+ bold) | 3:1 |
| UI components (buttons, form borders) | 3:1 |
| Graphical objects (icons, chart elements) | 3:1 |
AAA (enhanced) requires:
| Use Case | AAA Contrast Ratio |
|---|---|
| Normal text | 7:1 |
| Large text | 4.5:1 |
Typical safe combinations:
- gray-900 text on white background: ~21:1 (excellent)
- primary-700 text on gray-50 background: ~9-12:1 (AAA)
- gray-500 text on white: ~4.6:1 (AA passing)
- primary-500 on white: usually 3.5-5:1 (depends on hue — test always)
Unsafe combinations (usually fail):
- gray-400 text on white: ~3:1 (fails AA for normal text)
- primary-300 on white background: rarely passes
- Yellow/amber text on white: almost always fails
Part 3: Complete SaaS Color System Template
Here's a complete color system template you can adapt. Each primitive color token has 10 shades; semantic tokens reference primitives.
Primitive Tokens
Neutrals (critical — most used):
gray-50: #F9FAFB
gray-100: #F3F4F6
gray-200: #E5E7EB
gray-300: #D1D5DB
gray-400: #9CA3AF
gray-500: #6B7280
gray-600: #4B5563
gray-700: #374151
gray-800: #1F2937
gray-900: #111827
gray-950: #030712
Primary (example: blue):
primary-50: #EFF6FF
primary-100: #DBEAFE
primary-200: #BFDBFE
primary-300: #93C5FD
primary-400: #60A5FA
primary-500: #3B82F6
primary-600: #2563EB
primary-700: #1D4ED8
primary-800: #1E40AF
primary-900: #1E3A8A
Success (green):
success-50: #F0FDF4
success-100: #DCFCE7
success-500: #22C55E
success-600: #16A34A
success-700: #15803D
Warning (amber):
warning-50: #FFFBEB
warning-100: #FEF3C7
warning-500: #F59E0B
warning-600: #D97706
warning-700: #B45309
Error (red):
error-50: #FEF2F2
error-100: #FEE2E2
error-500: #EF4444
error-600: #DC2626
error-700: #B91C1C
Info (cyan/sky):
info-50: #F0F9FF
info-100: #E0F2FE
info-500: #0EA5E9
info-600: #0284C7
info-700: #0369A1
Semantic Tokens
// Backgrounds
color-bg-primary: gray-0 (white)
color-bg-secondary: gray-50
color-bg-tertiary: gray-100
color-bg-inverse: gray-900
// Surfaces
color-surface-raised: gray-0 (white) + shadow
color-surface-sunken: gray-50
// Text
color-text-primary: gray-900
color-text-secondary: gray-700
color-text-tertiary: gray-500
color-text-disabled: gray-400
color-text-inverse: gray-0
color-text-link: primary-600
color-text-link-hover: primary-700
// Borders
color-border-default: gray-200
color-border-subtle: gray-100
color-border-strong: gray-300
color-border-focus: primary-500
// Action (interactive)
color-action-primary: primary-600
color-action-primary-hover: primary-700
color-action-primary-active: primary-800
color-action-primary-disabled: gray-300
// Feedback
color-feedback-success: success-500
color-feedback-warning: warning-500
color-feedback-error: error-500
color-feedback-info: info-500
Dark Mode Semantic Tokens
In dark mode, only semantic tokens change. Primitive scales stay the same — they're just mapped differently:
// Dark mode backgrounds
color-bg-primary: gray-950
color-bg-secondary: gray-900
color-bg-tertiary: gray-800
// Dark mode text
color-text-primary: gray-50
color-text-secondary: gray-200
color-text-tertiary: gray-400
// Dark mode borders
color-border-default: gray-700
color-border-subtle: gray-800
color-border-strong: gray-600 Part 4: Implementation
Export to CSS Custom Properties
:root {
/* Primitive tokens */
--gray-50: #F9FAFB;
--gray-100: #F3F4F6;
--gray-900: #111827;
--primary-500: #3B82F6;
--primary-600: #2563EB;
/* ... all other primitives */
/* Semantic tokens */
--color-bg-primary: var(--gray-0);
--color-text-primary: var(--gray-900);
--color-action-primary: var(--primary-600);
/* ... */
}
/* Dark mode */
[data-theme="dark"] {
--color-bg-primary: var(--gray-950);
--color-text-primary: var(--gray-50);
/* semantic tokens remap; primitives stay the same */
}
Export to Tailwind Config
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
gray: {
50: '#F9FAFB',
100: '#F3F4F6',
// ... all shades
950: '#030712',
},
primary: {
50: '#EFF6FF',
// ... all shades
900: '#1E3A8A',
},
success: { /* ... */ },
warning: { /* ... */ },
error: { /* ... */ },
info: { /* ... */ },
},
},
},
};
Export to Figma Variables
In Figma:
- Create a variable collection called "Color System"
- Create modes: "Light" and "Dark"
- Add primitives first (gray-50, gray-100, etc.) — same in both modes
- Add semantics (color-bg-primary, etc.) — reference primitives, different values per mode
- Use variables in component fills/strokes/text
Part 5: Color Palette Audit Checklist
Before finalizing your color system:
Fundamentals:
- Primary brand color is distinctive from direct competitors
- Neutral scale has 9-11 shades for sufficient hierarchy
- At least 4 semantic colors (success, warning, error, info)
- All scales use consistent shade numbering (50, 100, 200, ... 900)
Accessibility:
- All text/background combinations meet WCAG AA (4.5:1 normal, 3:1 large)
- Primary buttons pass 4.5:1 contrast with white text
- Error states use red that distinguishes from warning amber
- No color used as sole indicator of meaning (icon/label always present)
- Tested for common types of color blindness (deuteranopia, protanopia, tritanopia)
Tools to test:
- WebAIM Contrast Checker (webaim.org/resources/contrastchecker)
- Stark plugin for Figma/Sketch
- Colorable (colorable.jxnblk.com)
- Who Can Use (whocanuse.com) — simulates color blindness
Dark mode (if applicable):
- Every semantic token has a dark mode value
- Dark mode uses proper surface elevation (not drop shadows)
- Text contrast in dark mode passes WCAG AA
- Primary color is appropriately desaturated for dark mode if needed
Consistency:
- Colors are named semantically (not "blueish-gray")
- Color tokens match between Figma and code
- All designers/developers reference tokens, not raw hex codes
Part 6: Common Color System Mistakes
1. Too many primary colors
One brand color is enough. Having "primary blue" AND "primary purple" AND "primary green" dilutes your brand identity.
2. Insufficient neutral shades
Many systems have 4-5 neutral shades and feel flat. You need 9-11 to build interface depth.
3. Wrong contrast in error messages
Light red (error-300) on white doesn't pass contrast. Error text should use error-600 or error-700.
4. Gray that's too cool or too warm
Pure neutral gray is boring but safe. Slight warmth (#F9F8F6) or coolness (#F9FAFB) is fine — but extreme warmth or coolness limits flexibility.
5. Not testing in dark mode
Light mode colors rarely translate directly to dark mode. Test every semantic combination in both modes.
6. Inconsistent saturation across shades
If primary-500 is vivid but primary-200 is dusty, the scale feels broken. Maintain consistent saturation (or predictable variation) across the scale.
7. Using color as the only signal
Color-blind users miss color-coded meaning. Always pair color with icon, label, or pattern.
8. Too-similar semantic colors
Success green and info blue should be visually distinct. Warning amber and error red should be clearly different (common failure: yellow-orange looks like red-orange).
Part 7: Inspiration: Excellent SaaS Color Systems
Study these for reference:
- Stripe — Classic purple primary with neutral grays. Timeless, trustworthy.
- Linear — Minimal, monochromatic with subtle color accents. Dark mode masterclass.
- Notion — Warm neutrals with friendly accent colors. Approachable.
- Figma — Bold purple primary with neutral gray scale. Playful but professional.
- Vercel — Extreme minimalism with black/white + accent colors as needed.
- Radix Colors — Best-in-class perceptually uniform color scales (open source).
Sources and References
- Web Content Accessibility Guidelines (WCAG) 2.1, W3C
- Material Design Color System (Google)
- Tailwind CSS Color Palette Documentation
- Radix Colors (workos.com/radix-colors)
- Refactoring UI book by Adam Wathan & Steve Schoger
- Understanding Color by Leatrice Eiseman
- Viktor Mukhachev, "HSL vs. OKLCH for Color Systems"
Created by Desisle — SaaS UI/UX Design Agency desisle.com | hello@desisle.com Free to use and share with attribution.
For a custom color system tailored to your brand, contact us at hello@desisle.com.
Keep Building With These Next
The UI Design Checklist - 80 Points for Pixel-Perfect Screens
A UI review checklist for typography, color systems, spacing, consistency, responsiveness, states, accessibility, and handoff readiness.
Open UI ChecklistDesign System Starter Kit - Token Architecture + Component Foundation
A starter Figma system with token architecture, core components, naming conventions, and auto-layout structure so teams can build on a real foundation instead of a loose UI kit.
Open System Starter KitUser Journey Mapping Template - From First Touch to Renewal
A visual template for mapping discovery, signup, onboarding, support, renewal, and referral moments with emotion tracking and friction spotting.
Open Journey MapNeed This Applied to Your Product? We'll Turn It Into Execution.
These resource pages are meant to be used hands-on. If you want the audit, plan, or framework translated into live product work, we can do that with your team.