We don't start with moodboards. We start with roles. Every color in a Kodari palette has a job title before it has a hex code — and that single rule is why our color systems survive client revisions, developer handoff, and production without falling apart.

Most color palette problems aren't aesthetic problems. They're structural problems. A team picks colors they like, assigns them to components by feel, and then spends three weeks in production discovering that the "primary" blue and the "accent" blue look identical on a phone screen at noon. The fix isn't picking better colors. It's building the palette on a system instead of on taste.

This is the exact process we run on every project, from a two-week landing page to a full SaaS product. Five colors. Five roles. One test that tells us whether the palette is ready to ship before we hand it off to anyone.

The rules before we open a color picker

  • Every color gets a role name before a hex value. The name describes what the color does, not what it looks like. "Action" not "blue." "Signal" not "red."
  • Five colors maximum for the core palette. Supporting tints and shades are derived from those five — they are never added independently.
  • Every pair that will appear together on screen has to pass WCAG AA contrast before the palette is locked. No exceptions for hero sections or "it's only decorative."
  • The palette gets tested in grayscale before it gets tested in color. If the hierarchy collapses in grayscale, the structure is wrong and we fix the structure first.

The five roles every palette needs

These are not categories — they are jobs. Each role has specific responsibilities in the UI and specific failure modes if it is doubled up or left undefined.

Primary
Role 01

The action color — used for what you want clicked.

Primary lives on buttons, links, and interactive states. It is the color the eye goes to when it is looking for something to do. This means it should appear nowhere else in the UI. If it shows up on a decorative illustration and also on the submit button, the button loses its signal strength.

The most common mistake: making Primary too similar to the brand's hero color. The brand wants to "own" a color. The UI needs to function. Those are sometimes different requirements and the palette has to serve the UI first.

CTA buttons · active states · links
Surface
Role 02

The background color — sets the stage, never steals it.

Surface is what everything else sits on. It can be warm, cool, or neutral, but it has one job: make every other color in the palette look intentional when placed on top of it. A surface color that competes with Primary or Ink is a palette that is fighting itself.

We test Surface by placing all four other palette colors on top of it and checking that every combination reads clearly. If one pair fails, we adjust Surface — not the failing color — because Surface is the foundation, and you fix foundations, not the walls.

Page backgrounds · card fills · section dividers
Ink
Role 03

The text color — has to work at every size without adjustment.

Ink is the color of words. It needs to pass AA contrast against Surface at 14px regular weight — not just at large heading sizes. This is the role most palettes get lazy about. "It's dark enough" is not a measurement. The contrast ratio is. We run every Ink/Surface pair through a contrast checker before the palette moves forward.

Ink almost always lives in the very dark range — near-black with a warm, cool, or neutral undertone that matches the Surface. A warm cream surface with a cool-grey Ink creates a subtle tension most people cannot name but everyone can feel.

Body text · headings · labels · UI copy
Accent
Role 04

The supporting role — adds energy without taking over.

Accent is the color that makes the palette feel like it has personality. It appears in illustrations, highlights, badges, tags, and hover states — anywhere you want visual warmth or playfulness without directing the user to take an action. The key constraint: Accent should never appear on an interactive element that also uses Primary. If it does, they compete for attention and neither wins.

Accent is also where the brand's personality comes through most clearly. Primary has to function. Accent has more freedom to express. We give the client more input on Accent than on any other role, because this is the color that makes the product feel like theirs.

Illustrations · badges · tags · hover highlights
Signal
Role 05

The error/warning color — reserved exclusively for system states.

Signal is the color of problems. Error messages, destructive action warnings, validation failures, overdue states. If Signal appears anywhere other than a system communication, it loses its meaning. A red decorative element on the homepage trains the eye to ignore red — which is exactly the wrong thing to happen when a form submission fails.

Signal is almost always a red or an amber. Not because of convention, but because decades of UI have built an expectation that these hues mean caution. Breaking that convention is possible, but the UX cost of retraining the user is almost never worth it.

Errors · warnings · destructive actions · overdue

If you can't describe what a color is for in one word, you don't have a palette yet. You have a mood board with hex codes.

The "Does It Ship?" test

Before any palette leaves our hands, we run it through four contexts. A color system that only works in one context is not a color system — it is a Figma presentation.

Color Pair
Light Screen
Dark Mode
Small Text
Print
Ink on Surface
✓ Pass
↻ Invert
✓ Pass
✓ Pass
Primary on Surface
✓ Pass
↻ Adjust
⚠ Check
✓ Pass
Ink on Primary
✓ Pass
✓ Pass
✓ Pass
✓ Pass
Accent on Surface
✓ Pass
↻ Adjust
✗ Decorative only
⚠ Check
Signal on Surface
✓ Pass
↻ Adjust
✓ Pass
⚠ Check

The "Invert" entries for dark mode are not failures — they are reminders that a light-mode palette needs a parallel set of dark-mode values derived from the same five roles. We build the dark mode token map at the same time as the light palette, not as an afterthought in week four.

Real palettes we ship

Here are three actual palette archetypes we return to. Not because we lack imagination, but because these combinations have survived every context we have thrown at them.

Loud & Warm
Brand sites · Marketing pages · Neo-brutalist products
Used in this site
Clean SaaS
Dashboards · Admin panels · B2B products
High contrast
Established Authority
Professional services · Finance · Consulting firms
Trust-forward

What we never do

🌈

Gradients as a primary color

Gradients can't be tokenised. The moment a developer asks "what's the hover state of this gradient button?", you're two hours from an argument. Gradients live in illustrations and backgrounds. Never on interactive elements.

🎨

More than five core colors

Every color added beyond five is a color that competes with an existing role. "We just need one more shade of blue" is the beginning of a palette that nobody can maintain by month three.

👁️

Skipping the grayscale test

Color should reinforce hierarchy, not create it. If the layout only makes sense in color, it will break when someone prints it, views it in poor lighting, or has a color vision deficiency.

🔴

Decorative use of Signal

Red icons in the hero, orange accents in the nav, amber illustrations in the footer — all of these erode the meaning of your error state before a user has even submitted a form.

Color systems break in production when they're built on taste. They hold up when they're built on roles.

Does this actually save time

The answer is yes, but not in the place most people expect. The system does not save time in the initial palette selection — it might even add an hour to that phase. The time it saves is in every round of revisions that comes after.

When a client asks to change the primary color, a role-based palette means one token changes and everything that uses it updates consistently. Without roles, "change the primary color" means hunting through every screen for every place the old blue was used — which is never fully documented — and hoping nothing was missed.

5+
Named color roles in every palette we ship
4×
Contexts tested before a palette is considered done
0x
Times we've shipped a gradient on a primary button

The other thing the role system does is make client conversations about color less personal and more structural. When a client says they want to change the Accent, we are not defending a creative choice — we are explaining a functional constraint. That is a different kind of conversation, and it tends to resolve faster and with less friction on both sides.

If you are building a product or a brand and you want a palette that will still make sense a year into production, start with roles. The hex codes come after.


Kodari Team

We build role-based color systems on every project we take on. If your current palette is causing friction in production or revision, we can audit it and restructure it in a single working session.