
color-palette
Generate complete, accessible colour palettes from a single brand hex. Produces 11-shade scale (50-950), semantic tokens, dark mode variants, Tailwind v4 CSS output, WCAG contrast checks. Use whenever the user supplies a brand hex and asks for a palette, mentions setting up a design system, wants Tailwind theme colours from a brand colour, or asks to check colour accessibility / contrast.
- Installs
- 3.2K
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/jezweb/claude-skills --skill color-palette- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads color-palette automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Colour Palette Generator
Generate a complete, accessible colour system from a single brand hex. Produces Tailwind v4 CSS ready to paste into your project.
Workflow
Step 1: Get the Brand Hex
Ask for the primary brand colour. A single hex like #0D9488 is enough.
Step 2: Generate 11-Shade Scale
Convert hex to HSL, then generate shades by varying lightness while keeping hue constant.
Hex to HSL Conversion
function hexToHSL(hex) {
hex = hex.replace(/^#/, '');
const r = parseInt(hex.substring(0, 2), 16) / 255;
const g = parseInt(hex.substring(2, 4), 16) / 255;
const b = parseInt(hex.substring(4, 6), 16) / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const diff = max - min;
let l = (max + min) / 2;
let s = 0;
if (diff !== 0) {
s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min);
}
let h = 0;
if (diff !== 0) {
if (max === r) h = ((g - b) / diff + (g < b ? 6 : 0)) / 6;
else if (max === g) h = ((b - r) / diff + 2) / 6;
else h = ((r - g) / diff + 4) / 6;
}
return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) };
}
Lightness and Saturation Values
| Shade | Lightness | Saturation Mult | Use Case |
|---|---|---|---|
| 50 | 97% | 0.80 | Subtle backgrounds |
| 100 | 94% | 0.80 | Hover states |
| 200 | 87% | 0.85 | Borders, dividers |
| 300 | 75% | 0.90 | Disabled states |
| 400 | 62% | 0.95 | Placeholder text |
| 500 | 48% | 1.00 | Brand colour baseline |
| 600 | 40% | 1.00 | Primary actions (often the brand colour) |
| 700 | 33% | 1.00 | Hover on primary |
| 800 | 27% | 1.00 | Active states |
| 900 | 20% | 1.00 | Text on light bg |
| 950 | 10% | 1.00 | Darkest accents |
Reduce saturation for lighter shades (50-200 by 15-20%, 300-400 by 5-10%) to prevent overly vibrant pastels. Keep full saturation for 500-950.
Complete Scale Generator
function generateShadeScale(brandHex) {
const { h, s } = hexToHSL(brandHex);
const shades = {
50: { l: 97, sMul: 0.8 }, 100: { l: 94, sMul: 0.8 },
200: { l: 87, sMul: 0.85 }, 300: { l: 75, sMul: 0.9 },
400: { l: 62, sMul: 0.95 }, 500: { l: 48, sMul: 1.0 },
600: { l: 40, sMul: 1.0 }, 700: { l: 33, sMul: 1.0 },
800: { l: 27, sMul: 1.0 }, 900: { l: 20, sMul: 1.0 },
950: { l: 10, sMul: 1.0 }
};
const result = {};
for (const [shade, { l, sMul }] of Object.entries(shades)) {
result[shade] = `hsl(${h}, ${Math.round(s * sMul)}%, ${l}%)`;
}
return result;
}
HSL to Hex Conversion
function hslToHex(h, s, l) {
s = s / 100; l = l / 100;
const c = (1 - Math.abs(2 * l - 1)) * s;
const x = c * (1 - Math.abs((h / 60) % 2 - 1));
const m = l - c / 2;
let r = 0, g = 0, b = 0;
if (h < 60) { r = c; g = x; }
else if (h < 120) { r = x; g = c; }
else if (h < 180) { g = c; b = x; }
else if (h < 240) { g = x; b = c; }
else if (h < 300) { r = x; b = c; }
else { r = c; b = x; }
r = Math.round((r + m) * 255);
g = Math.round((g + m) * 255);
b = Math.round((b + m) * 255);
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`.toUpperCase();
}
Verification
Generated shades should look like the same colour family with smooth progression. Light shades (50-300) usable for backgrounds, dark shades (700-950) usable for text. Brand colour recognisable in 500-700.
Step 3: Map Semantic Tokens
Every background token MUST have a paired foreground token. Never use a background without its pair or dark mode will break.
Light Mode Tokens
| Token | Shade | Use Case |
|---|---|---|
background | white | Page backgrounds |
foreground | 950 | Body text |
card | white | Card backgrounds |
card-foreground | 900 | Card text |
popover | white | Dropdown/tooltip backgrounds |
popover-foreground | 950 | Dropdown text |
primary | 600 | Primary buttons, links |
primary-foreground | white | Text on primary buttons |
secondary | 100 | Secondary buttons |
secondary-foreground | 900 | Text on secondary buttons |
muted | 50 | Disabled backgrounds, subtle sections |
muted-foreground | 600 | Muted text, captions |
accent | 100 | Hover states, subtle highlights |
accent-foreground | 900 | Text on accent backgrounds |
destructive | red-600 | Delete buttons, errors |
destructive-foreground | white | Text on destructive buttons |
border | 200 | Input borders, dividers |
input | 200 | Input field borders |
ring | 600 | Focus rings |
Dark Mode Tokens
| Token | Shade | Use Case |
|---|---|---|
background | 950 | Page backgrounds |
foreground | 50 | Body text |
card | 900 | Card backgrounds |
card-foreground | 50 | Card text |
popover | 900 | Dropdown backgrounds |
popover-foreground | 50 | Dropdown text |
primary | 500 | Primary buttons (brighter in dark) |
primary-foreground | white | Text on primary buttons |
secondary | 800 | Secondary buttons |
secondary-foreground | 50 | Text on secondary buttons |
muted | 800 | Disabled backgrounds |
muted-foreground | 400 | Muted text |
accent | 800 | Hover states |
accent-foreground | 50 | Text on accent backgrounds |
destructive | red-500 | Delete buttons (brighter) |
destructive-foreground | white | Text on destructive |
border | 800 | Borders |
input | 800 | Input borders |
ring | 500 | Focus rings |
Dark Mode Inversion Pattern
Dark mode inverts lightness while preserving hue and saturation. Swap extremes (50 becomes 950, 950 becomes 50), preserve middle (500 stays near 500).
| Light Shade | Dark Equivalent | Role |
|---|---|---|
| 50 | 950 | Backgrounds |
| 100 | 900 | Subtle backgrounds |
| 200 | 800 | Borders |
| 500 | 500 (slightly brighter) | Brand baseline |
| 600 | 400 | Primary actions |
| 950 | 50 | Text colour |
Key dark mode principles:
- Use shade 500 (not 600) for primary -- brighter for visibility on dark backgrounds
- Use shade 50 (off-white) for text instead of pure
#FFFFFF-- easier on eyes - Borders need ~10-15% lighter than background (e.g. 800 border on 950 background)
- Higher elevation = lighter colour (opposite of light mode shadows)
- Always update foreground when changing background
Step 4: Check Contrast
WCAG Minimum Ratios
| Content Type | AA | AAA |
|---|---|---|
| Normal text (<18px or <14px bold) | 4.5:1 | 7:1 |
| Large text (>=18px or >=14px bold) | 3:1 | 4.5:1 |
| UI components (buttons, borders) | 3:1 | Not defined |
| Graphical objects (icons, charts) | 3:1 | Not defined |
Target AA for most projects, AAA for high-accessibility needs (government, healthcare).
Luminance and Contrast Formulas
function getLuminance(hex) {
hex = hex.replace(/^#/, '');
const r = parseInt(hex.substring(0, 2), 16) / 255;
const g = parseInt(hex.substring(2, 4), 16) / 255;
const b = parseInt(hex.substring(4, 6), 16) / 255;
const rsRGB = r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4);
const gsRGB = g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4);
const bsRGB = b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4);
return 0.2126 * rsRGB + 0.7152 * gsRGB + 0.0722 * bsRGB;
}
function getContrastRatio(hex1, hex2) {
const lum1 = getLuminance(hex1);
const lum2 = getLuminance(hex2);
const lighter = Math.max(lum1, lum2);
const darker = Math.min(lum1, lum2);
return (lighter + 0.05) / (darker + 0.05);
}
Quick Check Table -- Light Mode
| Foreground | Background | Ratio | Pass? | Use Case |
|---|---|---|---|---|
| 950 | white | 18.5:1 | AAA | Body text |
| 900 | white | 14.2:1 | AAA | Card text |
| 700 | white | 8.1:1 | AAA | Text |
| 600 | white | 5.7:1 | AA | Text, buttons |
| 500 | white | 3.9:1 | Fail | Too light for text |
| white | 600 | 5.7:1 | AA | Button text |
| white | 700 | 8.1:1 | AAA | Button text |
| 600 | 50 | 5.4:1 | AA | Muted section text |
Quick Check Table -- Dark Mode
| Foreground | Background | Ratio | Pass? | Use Case |
|---|---|---|---|---|
| 50 | 950 | 18.5:1 | AAA | Body text |
| 50 | 900 | 14.2:1 | AAA | Card text |
| 400 | 950 | 8.2:1 | AAA | Muted text |
| 400 | 900 | 6.3:1 | AA | Muted text |
| white | 600 | 5.7:1 | AA | Button text |
Rule of thumb: For text, aim for 50%+ lightness difference between foreground and background.
Essential Pairs to Verify
- Body text: foreground on background (light: 950 on white = 18.5:1, dark: 50 on 950 = 18.5:1)
- Primary button: primary-foreground on primary (light: white on 600 = 5.7:1, dark: white on 500 = 3.9:1 -- borderline)
- Muted text: muted-foreground on muted (light: 600 on 50 = 5.4:1, dark: 400 on 800 = 4.1:1 -- may fail)
- Card text: card-foreground on card (light: 900 on white = 14.2:1, dark: 50 on 900 = 14.2:1)
Fixing Common Contrast Failures
White on primary-500 fails (3.9:1): Use primary-600 instead (5.7:1), or use dark text on the button.
Muted text in dark mode fails (400 on 800 = 4.1:1): Use 300 on 900 = 6.8:1.
Links hard to see (500 on white = 3.9:1): Use primary-700 (8.1:1), or add underline decoration.
Step 5: Output Tailwind v4 CSS
@import "tailwindcss";
@theme {
/* Shade scale */
--color-primary-50: #F0FDFA;
--color-primary-100: #CCFBF1;
--color-primary-200: #99F6E4;
--color-primary-300: #5EEAD4;
--color-primary-400: #2DD4BF;
--color-primary-500: #14B8A6;
--color-primary-600: #0D9488;
--color-primary-700: #0F766E;
--color-primary-800: #115E59;
--color-primary-900: #134E4A;
--color-primary-950: #042F2E;
/* Light mode semantic tokens */
--color-background: #FFFFFF;
--color-foreground: var(--color-primary-950);
--color-card: #FFFFFF;
--color-card-foreground: var(--color-primary-900);
--color-popover: #FFFFFF;
--color-popover-foreground: var(--color-primary-950);
--color-primary: var(--color-primary-600);
--color-primary-foreground: #FFFFFF;
--color-secondary: var(--color-primary-100);
--color-secondary-foreground: var(--color-primary-900);
--color-muted: var(--color-primary-50);
--color-muted-foreground: var(--color-primary-600);
--color-accent: var(--color-primary-100);
--color-accent-foreground: var(--color-primary-900);
--color-destructive: #DC2626;
--color-destructive-foreground: #FFFFFF;
--color-border: var(--color-primary-200);
--color-input: var(--color-primary-200);
--color-ring: var(--color-primary-600);
--radius: 0.5rem;
}
/* Dark mode overrides */
.dark {
--color-background: var(--color-primary-950);
--color-foreground: var(--color-primary-50);
--color-card: var(--color-primary-900);
--color-card-foreground: var(--color-primary-50);
--color-popover: var(--color-primary-900);
--color-popover-foreground: var(--color-primary-50);
--color-primary: var(--color-primary-500);
--color-primary-foreground: #FFFFFF;
--color-secondary: var(--color-primary-800);
--color-secondary-foreground: var(--color-primary-50);
--color-muted: var(--color-primary-800);
--color-muted-foreground: var(--color-primary-400);
--color-accent: var(--color-primary-800);
--color-accent-foreground: var(--color-primary-50);
--color-destructive: #EF4444;
--color-destructive-foreground: #FFFFFF;
--color-border: var(--color-primary-800);
--color-input: var(--color-primary-800);
--color-ring: var(--color-primary-500);
}
Copy assets/tailwind-colors.css as a starting template.
Component Usage Examples
// Primary button
<button className="bg-primary text-primary-foreground hover:bg-primary/90">Click me</button>
// Secondary button
<button className="bg-secondary text-secondary-foreground hover:bg-secondary/80">Cancel</button>
// Card
<div className="bg-card text-card-foreground border-border rounded-lg">
<h2>Title</h2>
<p className="text-muted-foreground">Description</p>
</div>
// Input
<input className="bg-background text-foreground border-input focus:ring-ring" />
Common Adjustments
- Too vibrant at light shades: Reduce saturation by 10-20%
- Poor contrast on primary: Use shade 700+ for text
- Dark mode too dark: Use shade 900 instead of 950 for backgrounds
- Brand colour too light/dark: Adjust to shade 500-600 range
- Dark mode looks washed out: Use shade 500 for primary (brighter than light mode's 600)
- Pure white text too harsh in dark mode: Use shade 50 (off-white) instead
- Dark mode muted text fails contrast: Use more extreme shades (300 on 900 instead of 400 on 800)
Brand Identity Adjustments
- Conservative brands (finance, law): Use primary-700 for buttons, reduce saturation in light shades
- Vibrant brands (creative, tech): Use primary-500-600, keep full saturation
- Minimal brands (design, architecture): Use primary sparingly, emphasise muted tones, subtle borders (primary-100)
Verification Checklist
- Body text: >=4.5:1 (normal) or >=3:1 (large)
- Primary button text: >=4.5:1
- Secondary button text: >=4.5:1
- Muted text: >=4.5:1
- Links: >=4.5:1 (or underlined)
- UI elements (borders): >=3:1
- Focus indicators: >=3:1
- Error text: >=4.5:1
- Dark mode: All above checks pass
- Every background has a foreground pair
- Brand colour recognisable in both modes
- Borders visible but not harsh
- Cards/sections have clear boundaries
Test both modes before shipping.
Optional References
- Online contrast checkers: WebAIM (webaim.org/resources/contrastchecker), Coolors (coolors.co/contrast-checker), Accessible Colors (accessible-colors.com)
- CI/CD contrast tests: Use
getContrastRatio()in test suites to assert minimum ratios for all token pairs - Transparent/gradient edge cases: For colours with opacity, calculate against final rendered colour. For gradients, check both endpoints.
- OLED dark mode: Use
@media (prefers-contrast: high)with#000000background for battery savings on AMOLED screens - Multi-colour palettes: Generate separate shade scales for each brand colour, map to different semantic roles (primary, accent)
- Palette visualisation tools: coolors.co, paletton.com, Figma swatches
assets/tailwind-colors.css— Complete CSS output template
FAQ
What does the color-palette skill do?
Generate complete, accessible colour palettes from a single brand hex. Produces 11-shade scale (50-950), semantic tokens, dark mode variants, Tailwind v4 CSS output, WCAG contrast checks. Use whenever the user supplies a brand hex and asks for a palette, mentions setting up a design system, wants Tailwind theme colours from a brand colour, or asks to check colour accessibility / contrast.
How do I install color-palette?
Run npx skills add https://github.com/jezweb/claude-skills --skill color-palette in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/color-palette/ (personal) or .claude/skills/color-palette/ (project).
Which AI agents can use color-palette?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is color-palette safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains color-palette?
It is published by jezweb in jezweb/claude-skills. It has 3,249 recorded installs.
More from jezweb/claude-skills
shadcn-ui
jezweb/claude-skills
Install and configure shadcn/ui components for React projects. Guides component selection, installation order, dependency management, customisation with semantic tokens, and common UI recipes (forms, data tables, navigation, modals). Use after tailwind-theme-builder has set up the theme infrastructure, when adding components, building forms, creating data tables, or setting up navigation.
tailwind-theme-builder
jezweb/claude-skills
Set up Tailwind v4 + shadcn/ui themed UI with dark mode. Install deps, configure CSS variables via @theme inline, wire dark mode toggle, verify. Use whenever the user mentions Tailwind v4, setting up Tailwind theming, shadcn/ui colours, dark mode, or troubleshooting colours not working, tw-animate-css errors, @theme inline conflicts, @apply breaking after upgrade, or v3 → v4 migration issues.
wordpress-elementor
jezweb/claude-skills
Edit Elementor pages and manage templates on WordPress sites via browser automation (for visual / structural changes) or WP-CLI (for safe text replacements). Use whenever the user wants to edit an Elementor page, update text in Elementor widgets, apply or manage Elementor templates, or make content changes to pages built with the Elementor page builder.
ux-audit
jezweb/claude-skills
Walk through a live web app AS a real user to find usability + behavioural bugs that static reviews miss. REQUIRES proof of interaction (typing, clicking, sending, observing) before any verdict — a sweep that didn't interact terminates with verdict 'Incomplete'. Walks threads, exercises every element, runs the multi-pane stress matrix, visual polish sweep, component perfection checklist, automated a11y (axe-core), pragmatic performance budget (LCP/CLS/INP), scenario battery (11 scenarios), and stress recipes including the real-flavour data battery. Hard gates: console errors/warnings = 0, network 5xx = 0, layout collapse = 0, axe Critical/Serious = 0, perf budget green. Audit-the-audit meta-check rejects rushed reports. Each finding has reproduction steps, evidence path, and suspected code location. Trigger with 'ux audit', 'walkthrough', 'qa sweep', 'audit the app', 'dogfood this', 'check all pages', 'find what's broken', 'stress the UI'.
tailwind-v4-shadcn
jezweb/claude-skills
Set up Tailwind v4 with shadcn/ui using @theme inline pattern and CSS variable architecture. Four-step pattern: CSS variables, Tailwind mapping, base styles, automatic dark mode. Prevents 8 documented errors. Use when initializing React projects with Tailwind v4, or fixing colors not working, tw-animate-css errors, @theme inline dark mode conflicts, @apply breaking, v3 migration issues.
tanstack-query
jezweb/claude-skills
Manage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
Popular frontend & design skills
setup-matt-pocock-skills
mattpocock/skills
Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.
frontend-design
anthropics/skills
Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
hyperframes-animation
heygen-com/hyperframes
All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.
prototype
mattpocock/skills
Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.
hyperframes-core
heygen-com/hyperframes
The HyperFrames composition contract — build one renderable project. Use for composition structure, the data- timing attributes, class="clip", tracks, sub-compositions, variables, framework-owned media playback, deterministic-render rules, and validation. Read before writing composition HTML.
vercel-react-best-practices
vercel-labs/agent-skills
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.