color-palette
Skill17 starsChanged 8 months agoMITView on GitHub
Generate accessible color palettes: OKLCH shade scales (50-950), tinted neutrals, semantic colors, WCAG contrast checks, dark-mode color remaps, gradients, and CSS/Tailwind color output. Use when the task is ONLY about color. Trigger phrases: "color palette", "color scheme", "generate colors", "shade scale", "color tokens", "color system", "accessible colors", "contrast ratio", "semantic colors", "palette from hex". For logo + fonts + guidelines use brand-identity; for full token/component systems (spacing, radius, components) use design-system; for complete dark themes use dark-mode.
5 other projects use a version of this.
Adopted by
Most recently taken up by
- ainurdev/mystical-assistanttheir own version, first seen Nov 8, 2026
- thewyattbrocato/design-and-copy-skillstheir own version, first seen Oct 17, 2026
- SkotAlexsander/skillstheir own version, first seen Sep 16, 2026
- ai4brands-design/claude-skillstheir own version, first seen Mar 22, 2026
- xcrrr/claude-skillstheir own version, first seen Mar 19, 2026
Other versions5 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 5
- ainurdev/mystical-assistant★ 7same name
- xcrrr/claude-skills★ 6same name
- ai4brands-design/claude-skills★ 2same name
- thewyattbrocato/design-and-copy-skills★ 2same name
- SkotAlexsander/skills★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository29 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- ad-creative-designSkill
- banner-designSkill
- brand-identitySkill
- card-designSkill
- dark-modeSkill
- dashboard-designSkill
- design-contextSkill
- design-critiqueSkill
- design-systemSkill
- email-designSkill
- graphic-designSkill
- hero-sectionSkill
- icon-designSkill
- image-generationSkill
- image-treatmentSkill
- infographicSkill
- landing-page-designSkill
- layout-compositionSkill
- mobile-ui-designSkill
- motion-designSkill
- poster-designSkill
- presentation-designSkill
- product-mockupSkill
- social-media-graphicSkill
- thumbnail-designSkill
- typographySkill
- ui-designSkill
The file
We split this skill into the rules it gives an agent
10 rules. 0 are common, 7 are distinctive, and 3 are very specific to this project.
0
Common
Most of the 5 edited versions we read keep these.
7
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 20
Before generating colors, check for existing design context:
- Very specific: line 21
Read .agents/design-context.md (see the design-context skill).
- Very specific: line 22
If a design system already exists in the codebase (CSS variables, Tailwind theme, tokens.json), extend it rather than replacing it.
- Distinctive: line 190
Body text on light bg: use 900 or 950 shade (passes AA comfortably with the lightness map above).
- Distinctive: line 191
Body text on dark bg: use 50 or 100 shade.
- Distinctive: line 193
Disabled states: use 400 shade on light bg.
- Distinctive: line 194
Links: must be distinguishable from surrounding text by more than color alone -- underline them, or give them 3:1 contrast against the …
- Distinctive: line 225
Do NOT simply invert the scale.
- Distinctive: line 288
Use 90-180 degrees for vibrant, energetic gradients.
- Very specific: line 425
Read .agents/design-context.md.
“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Color Palette Generation
Generate harmonious, accessible, and production-ready color systems from any starting point.
Prerequisites
Before generating colors, check for existing design context:
- Read
.agents/design-context.md(see thedesign-contextskill). If it has a Color System, treat those hex values as the source of truth and extend them rather than replacing them. - If a design system already exists in the codebase (CSS variables, Tailwind theme,
tokens.json), extend it rather than replacing it.
Naming convention (shared with design-system, layout-composition, etc.): primitive scales are --brand-50 … --brand-950, --gray-50 … --gray-950, --success-*, --warning-*, --error-*, --info-*; semantic tokens are --bg-*, --text-*, --border-*, --interactive-*, plus the brand aliases --color-primary, --color-secondary, --color-accent.
Step 1: Understand Color Theory Fundamentals
Generate palettes in OKLCH. Its lightness channel is perceptually even, so a fixed L step looks like the same visual step at every hue (in HSL, hsl(60 100% 50%) yellow is far lighter than hsl(240 100% 50%) blue at the "same" lightness). Use HSL only when a legacy tool forces it. Note that high-chroma OKLCH values can fall outside sRGB; reduce chroma (keep L and H) when converting to hex.
Color Wheel Relationships
| Harmony | Angle(s) from base | Feel |
| Complementary | 180° | High contrast, energetic |
| Analogous | ±30° | Harmonious, natural |
| Triadic | 120°, 240° | Vibrant, balanced |
| Split-comp. | 150°, 210° | Contrast with less tension |
| Tetradic | 90°, 180°, 270° | Rich, needs careful balance |
Generating Harmonies in OKLCH
:root {
/* Base brand color in oklch */
--brand-hue: 250; /* hue angle */
--brand-chroma: 0.15; /* chroma (not HSL saturation) */
--brand-l: 0.55; /* lightness */
--color-primary: oklch(var(--brand-l) var(--brand-chroma) var(--brand-hue));
--color-complement: oklch(var(--brand-l) var(--brand-chroma) calc(var(--brand-hue) + 180));
--color-analogous-1: oklch(var(--brand-l) var(--brand-chroma) calc(var(--brand-hue) + 30));
--color-analogous-2: oklch(var(--brand-l) var(--brand-chroma) calc(var(--brand-hue) - 30));
--color-triadic-1: oklch(var(--brand-l) var(--brand-chroma) calc(var(--brand-hue) + 120));
--color-triadic-2: oklch(var(--brand-l) var(--brand-chroma) calc(var(--brand-hue) + 240));
--color-split-comp-1: oklch(var(--brand-l) var(--brand-chroma) calc(var(--brand-hue) + 150));
--color-split-comp-2: oklch(var(--brand-l) var(--brand-chroma) calc(var(--brand-hue) + 210));
}Step 2: Generate a Full Shade Scale (50-950)
From a single brand color, generate an 11-step lightness scale (50, 100-900, 950). In OKLCH, vary lightness while keeping hue stable and slightly reducing chroma at extremes.
Lightness Map
| Token | OKLCH Lightness | Usage |
| 50 | 0.97 | Tinted background |
| 100 | 0.93 | Hover background |
| 200 | 0.87 | Active background |
| 300 | 0.78 | Borders |
| 400 | 0.68 | Placeholder text |
| 500 | 0.55 | Base / primary actions |
| 600 | 0.48 | Hover on primary |
| 700 | 0.40 | Active on primary |
| 800 | 0.32 | Headings on light bg |
| 900 | 0.24 | Body text on light bg |
| 950 | 0.16 | High-contrast text |
CSS Implementation
:root {
--brand-hue: 250;
--brand-chroma: 0.15;
--brand-50: oklch(0.97 calc(var(--brand-chroma) * 0.3) var(--brand-hue));
--brand-100: oklch(0.93 calc(var(--brand-chroma) * 0.4) var(--brand-hue));
--brand-200: oklch(0.87 calc(var(--brand-chroma) * 0.5) var(--brand-hue));
--brand-300: oklch(0.78 calc(var(--brand-chroma) * 0.7) var(--brand-hue));
--brand-400: oklch(0.68 calc(var(--brand-chroma) * 0.85) var(--brand-hue));
--brand-500: oklch(0.55 var(--brand-chroma) var(--brand-hue));
--brand-600: oklch(0.48 var(--brand-chroma) var(--brand-hue));
--brand-700: oklch(0.40 var(--brand-chroma) var(--brand-hue));
--brand-800: oklch(0.32 calc(var(--brand-chroma) * 0.9) var(--brand-hue));
--brand-900: oklch(0.24 calc(var(--brand-chroma) * 0.8) var(--brand-hue));
--brand-950: oklch(0.16 calc(var(--brand-chroma) * 0.7) var(--brand-hue));
}Step 3: Define Semantic Colors
Map purpose-driven tokens to your palette or define independent hues.
Recommended Semantic Hues
| Role | Hue (OKLCH) | Rationale |
| Success | 145 | Green, universal "go" |
| Warning | 85 | Amber/yellow, caution |
| Error | 25 | Red, urgency |
| Info | 230 | Blue, neutral info |
:root {
/* Semantic: success */
--success-50: oklch(0.97 0.04 145);
--success-400: oklch(0.68 0.15 145); /* dark-mode foreground */
--success-500: oklch(0.55 0.16 145);
--success-700: oklch(0.40 0.14 145);
/* Semantic: warning */
--warning-50: oklch(0.97 0.04 85);
--warning-400: oklch(0.72 0.15 85);
--warning-500: oklch(0.60 0.16 85); /* ~4:1 on white: use dark text ON it, 700 for warning TEXT */
--warning-700: oklch(0.45 0.14 85);
/* Semantic: error */
--error-50: oklch(0.97 0.04 25);
--error-400: oklch(0.68 0.16 25);
--error-500: oklch(0.55 0.18 25);
--error-700: oklch(0.40 0.16 25);
/* Semantic: info */
--info-50: oklch(0.97 0.04 230);
--info-400: oklch(0.68 0.12 230);
--info-500: oklch(0.55 0.14 230);
--info-700: oklch(0.40 0.12 230);
}Generate the full 50-950 scale for a semantic hue only if the product needs it (alerts, badges, charts); 50/400/500/700 covers most UI.
Step 4: Generate a Neutral Scale
Neutrals are the backbone. Add a slight hue tint from the brand for warmth.
:root {
--neutral-hue: var(--brand-hue);
--neutral-chroma: 0.01; /* barely tinted */
--gray-50: oklch(0.98 var(--neutral-chroma) var(--neutral-hue));
--gray-100: oklch(0.96 var(--neutral-chroma) var(--neutral-hue));
--gray-200: oklch(0.90 var(--neutral-chroma) var(--neutral-hue));
--gray-300: oklch(0.83 var(--neutral-chroma) var(--neutral-hue));
--gray-400: oklch(0.71 var(--neutral-chroma) var(--neutral-hue));
--gray-500: oklch(0.55 var(--neutral-chroma) var(--neutral-hue));
--gray-600: oklch(0.45 var(--neutral-chroma) var(--neutral-hue));
--gray-700: oklch(0.37 var(--neutral-chroma) var(--neutral-hue));
--gray-800: oklch(0.27 var(--neutral-chroma) var(--neutral-hue));
--gray-900: oklch(0.20 var(--neutral-chroma) var(--neutral-hue));
--gray-950: oklch(0.13 var(--neutral-chroma) var(--neutral-hue));
}Step 5: Ensure WCAG Accessibility
Contrast Requirements (WCAG 2.2 -- the current legal/industry standard)
| Level | Normal text | Large text (≥24px, or ≥18.66px / 14pt bold) | Non-text UI (icons, borders, focus rings, chart marks) |
| WCAG AA | 4.5:1 | 3:1 | 3:1 against adjacent colors (SC 1.4.11) |
| WCAG AAA | 7:1 | 4.5:1 | -- |
Contrast ratio = (L1 + 0.05) / (L2 + 0.05), where L1/L2 are the lighter/darker relative luminance (0.2126 R + 0.7152 G + 0.0722 B on linearized sRGB). Ratios are not rounded up: 4.49:1 fails. APCA (Lc values) is a draft candidate for WCAG 3 -- useful as a second opinion, especially for dark mode, but never report it as the compliance standard.
Practical Rules
- Body text on light bg: use 900 or 950 shade (passes AA comfortably with the lightness map above).
- Body text on dark bg: use 50 or 100 shade.
- Primary buttons: white text on 500+ shade usually passes (L 0.55 blue ≈ 4.9:1), but yellows/ambers/cyans at L 0.55-0.65 often fail -- use dark text on those. Always measure.
- Disabled states: use 400 shade on light bg. Disabled elements are exempt from WCAG but should still be distinguishable.
- Links: must be distinguishable from surrounding text by more than color alone -- underline them, or give them 3:1 contrast against the surrounding text plus a non-color cue on hover/focus.
Quick Contrast Check via OKLCH Lightness
For near-neutral colors, relative luminance ≈ L³, so a lightness gap of about 0.42-0.45+ is needed for 4.5:1 at the extremes (and more in the mid-range). Use it only to pick candidates, then measure.
text L 0.20 | bg L 0.97 | diff 0.77 -> ~16.6:1, passes AAA
text L 0.55 | bg L 0.97 | diff 0.42 -> ~4.5:1, borderline AA -- measure; safe for large text
text L 0.57 | bg L 0.97 | diff 0.40 -> ~4.1:1, FAILS AA for normal textMeasure, Don't Guess
Browsers render OKLCH directly, but design-context stores hex and contrast must be computed on sRGB. Use the bundled scripts (<color-palette> and <design-context> are those skills' directories):
python <color-palette>/scripts/palette.py --from "#2563eb" # scale around a brand color
python <color-palette>/scripts/palette.py 250 0.15 --name brand --css # hue + chroma -> CSS vars
python <color-palette>/scripts/palette.py 250 0.02 --name gray --json # neutrals as JSON
python <design-context>/scripts/contrast.py "#ffffff" "#2563eb" # any real pairingpalette.py prints each step's hex and contrast on white/black, marked AA (4.5:1), large/UI (3:1) or -. Out-of-gamut steps lose chroma, never lightness or hue. contrast.py exits 1 on a failure and suggests the nearest passing shade.
Also check every real text/background pairing you ship (text on --bg-*, button label on --interactive-*, dark-mode pairs), not just against pure white/black.
Step 6: Dark Mode Adaptation
Do NOT simply invert the scale. Instead, remap semantic usage.
Dark Mode Strategy
[data-theme="dark"] {
/* Backgrounds: use 900/950 instead of 50/white */
--bg-primary: var(--gray-950);
--bg-secondary: var(--gray-900);
--bg-tertiary: var(--gray-800);
/* Text: use 50/100 instead of 900/950 */
--text-primary: var(--gray-50);
--text-secondary: var(--gray-300);
--text-tertiary: var(--gray-400);
/* Surfaces: slightly lighter than bg */
--surface: var(--gray-900);
--surface-hover: var(--gray-800);
/* Borders: use 700 instead of 200 */
--border-default: var(--gray-700);
/* Brand colors: increase lightness for dark bg */
--interactive-primary: var(--brand-400); /* lighter than 500 */
/* Semantic: bump to lighter shades */
--color-success: var(--success-400);
--color-warning: var(--warning-400);
--color-error: var(--error-400);
}These names must match the light-mode Layer 2 tokens in Step 10 -- dark mode only remaps them. For a full dark theme (elevation surfaces, images, toggles) hand off to the dark-mode skill.
Key Principles
- Reduce contrast slightly -- pure white on pure black is harsh. Use gray-50 on gray-950.
- Reduce chroma slightly in dark mode -- saturated colors glow on dark backgrounds.
- Elevations in dark mode use lighter surfaces (opposite of light mode shadows).
Step 7: Color Psychology by Industry
| Industry | Primary colors | Why |
| Finance | Navy, dark blue, green | Trust, stability, growth |
| Health | Blue, teal, white | Calm, cleanliness, trust |
| Food | Red, orange, yellow | Appetite, energy, warmth |
| Tech/SaaS | Blue, violet, cyan | Innovation, reliability |
| Luxury | Black, gold, deep purple | Elegance, exclusivity |
| Eco/Green | Green, earth tones | Nature, sustainability |
| Education | Blue, orange, green | Trust, enthusiasm, growth |
| Creative | Bold primaries, neons | Energy, expression, fun |
Step 8: Gradient Combinations
Rules for Effective Gradients
- Stay within 60 degrees of hue rotation for subtle gradients.
- Use 90-180 degrees for vibrant, energetic gradients.
- Writing stops in
oklch()does NOT make the gradient interpolate in OKLCH. Without an interpolation hint, browsers use Oklab for modern colors and sRGB for hex/rgb/hsl stops -- both go straight through the color space and can pass through gray between distant hues. Addin oklchto interpolate around the hue wheel (addlonger huefor rainbow sweeps). - Or add a mid stop with a slight chroma boost to avoid the "gray dead zone."
/* Subtle brand gradient */
.gradient-subtle {
background: linear-gradient(
135deg in oklch,
oklch(0.55 0.15 250),
oklch(0.55 0.15 280)
);
}
/* Vibrant hero gradient */
.gradient-vibrant {
background: linear-gradient(
135deg in oklch,
oklch(0.65 0.20 280),
oklch(0.60 0.22 330),
oklch(0.65 0.20 20)
);
}
/* Mesh gradient (modern trend) */
.gradient-mesh {
background:
radial-gradient(at 0% 0%, oklch(0.70 0.15 280) 0%, transparent 50%),
radial-gradient(at 100% 0%, oklch(0.70 0.15 200) 0%, transparent 50%),
radial-gradient(at 100% 100%, oklch(0.70 0.15 330) 0%, transparent 50%),
oklch(0.97 0.01 250);
}Step 9: Tailwind Config Generation
Tailwind v4 (CSS-first) -- put the scale in @theme, which generates bg-brand-500, text-brand-900, etc.:
@import "tailwindcss";
@theme {
--color-brand-50: oklch(0.97 0.045 250);
--color-brand-500: oklch(0.55 0.15 250);
--color-brand-900: oklch(0.24 0.12 250);
/* ...every step 50-950, plus success/warning/error/info */
}Tailwind v3 (tailwind.config.js):
// tailwind.config.js
const brand = {
50: 'oklch(0.97 0.045 250)',
100: 'oklch(0.93 0.06 250)',
200: 'oklch(0.87 0.075 250)',
300: 'oklch(0.78 0.105 250)',
400: 'oklch(0.68 0.1275 250)',
500: 'oklch(0.55 0.15 250)',
600: 'oklch(0.48 0.15 250)',
700: 'oklch(0.40 0.15 250)',
800: 'oklch(0.32 0.135 250)',
900: 'oklch(0.24 0.12 250)',
950: 'oklch(0.16 0.105 250)',
};
module.exports = {
theme: {
extend: {
colors: {
brand,
success: { /* ... same pattern, hue 145 */ },
warning: { /* ... same pattern, hue 85 */ },
error: { /* ... same pattern, hue 25 */ },
info: { /* ... same pattern, hue 230 */ },
},
},
},
};Step 10: CSS Custom Properties Architecture
Structure tokens in three layers:
/* Layer 1: Primitive (raw values) */
:root {
--brand-500: oklch(0.55 0.15 250);
--error-500: oklch(0.55 0.18 25);
/* ...full --brand-*, --gray-*, semantic scales from Steps 2-4 */
}
/* Layer 2: Semantic (purpose) -- same names design-system uses */
:root {
--color-primary: var(--brand-500);
--interactive-primary: var(--brand-500);
--color-error: var(--error-500);
--bg-primary: var(--gray-50);
--text-primary: var(--gray-900);
--border-default: var(--gray-200);
}
/* Layer 3: Component (scoped) */
.btn-primary {
background: var(--interactive-primary);
color: white; /* verified >= 4.5:1 against brand-500 */
}This three-layer approach makes theming and dark mode trivial -- you only remap Layer 2.
Step 11: Verify Visually and Save to Design Context
- Render a swatch sheet: write a small HTML file (scratchpad) showing each scale as a row of swatches labeled with token, hex, and contrast vs white/black, plus sample text/button pairings in light AND dark mode. Screenshot it (e.g.
npx playwright screenshot --full-page "file://$PWD/swatches.html" swatches.png; add--color-scheme=darkfor the dark pass) and look at the image with Read. Check that steps look evenly spaced, no step is muddy or neon, and neutrals read as neutral. - Offer to write back to
.agents/design-context.md(thedesign-contextskill's file). Update only the Color System rows that changed; never rewrite the whole file. Map the scale to the design-context roles as hex:
| design-context role | Take from |
| Primary | --brand-500 (or 600 if 500 fails 4.5:1 with white text) |
| Primary Light / Primary Dark | --brand-400 / --brand-700 |
| Secondary / Accent | 500 step of the secondary / accent hue |
| Neutral 50 / 100 / 200 / 500 / 800 / 900 | matching --gray-* steps |
| Success / Warning / Error | --success-500 / --warning-500 / --error-500 |
Show the user a before/after diff of the changed rows and ask before saving.
Quick Reference: Palette from a Single Hex
- Read
.agents/design-context.md; convert the brand hex to OKLCH. - Extract hue. This is your brand hue.
- Generate 50-950 scale using the lightness map in Step 2.
- Generate neutrals tinted with brand hue (Step 4).
- Pick semantic hues (Step 3).
- Measure contrast with
palette.py/contrast.py(Step 5) -- fix failures before continuing. - Build dark mode remap (Step 6).
- Export as CSS custom properties or Tailwind config.
- Render and inspect a swatch sheet; offer to save hex values to design-context (Step 11).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

