Behind the Scenes: How We Pick Semantic Color Tokens for Client Projects
Every client project starts the same way: someone hands us a brand guide with three or four approved colors, and we have to turn that into a working design system with dozens of contrast-safe pairs. Here's the actual process we walk through, not the polished version, the one we use when the deadline is real.
We're sharing this partly because we get asked about it a lot, and partly because most of what's written about design tokens online skips straight to the tooling without explaining the actual decisions that determine whether the tooling produces something usable. The tooling is the easy part. The decisions below are where projects actually go sideways.
This is also, honestly, the part of a project our engineers and designers argue about most, in a productive way. Design wants more expressive color, engineering wants fewer variables to maintain, and the process below is basically the compromise we've landed on after a lot of those arguments across a lot of projects.
Step 1: We Separate Brand From Function
The first thing we do is stop treating brand colors as the whole palette. A brand blue is a decorative and identity color, not automatically a text color, a border color, and a background color all at once. We build a separate functional layer, neutrals for text and surfaces, semantic colors for state, that references the brand palette but isn't limited to it.
We usually start this whole process with a short intake conversation, asking the client what their current site actually struggles with rather than assuming. Sometimes it's "our forms look inconsistent," sometimes it's "we got an accessibility complaint," sometimes it's just "everything feels flat and boring." The answer shapes how conservative or expressive we're willing to be with the palette from step one, since a client recovering from an accessibility complaint needs a different conversation than one who's mostly unhappy with how their site looks.
Step 2: We Name Tokens by Job, Not by Hue
text-primary survives a rebrand. blue-600 doesn't. We name every token after what it does, not what color it currently is, because clients update brand colors more often than most design systems account for. When a rebrand happens, we swap the values behind the names instead of hunting down every hardcoded hex reference across a codebase.
This naming convention pays off in ways clients don't always anticipate up front. We've had more than one client come back a year later with a refreshed brand guide, new hex values, same visual concept, and been able to swap the whole system over in an afternoon because nothing in the codebase referenced a raw color directly. Contrast that with a project we inherited from another shop where colors were hardcoded everywhere, and a similar rebrand turned into a multi-week search-and-replace exercise with a real risk of missing instances.
Step 3: We Verify Every Pair Before It Ships, Not After
Every token gets checked against its intended surface with an actual contrast calculator, following the WCAG thresholds, 4.5:1 for text, 3:1 for large text and UI components, before it goes into the token file. Not eyeballed, not "it looks fine on my monitor." This step alone catches most of the problems that would otherwise surface during a client's own QA pass.
We keep a running spreadsheet during this step, every token, its intended surface, its verified ratio, and the date it was last checked. It's not glamorous, but it means we can answer "has this actually been verified" instantly instead of re-testing everything every time a question comes up, which matters a lot when a project spans several months and multiple people touch the color system along the way.
Step 4: We Build the Dark Set Separately
We learned this one the hard way on an earlier project: dark mode is not an inverted light mode. We build the dark token set as its own pass, checking every pair against its dark surface independently, because a border or disabled state that passed comfortably in light mode can quietly fail once the background flips.
We've also started building a small deviation section into the dark-mode pass specifically, a short list of any color that had to move meaningfully further from its light-mode counterpart than expected, along with why. This has turned into a useful early warning system, since a token needing a large adjustment in dark mode is often a sign the original light-mode choice was already sitting closer to the edge of its threshold than it should have been.
Step 5: We Document the Reasoning, Not Just the Values
A token file with no context gets misused within a month. We attach a short note to each token explaining what it's for and what it should never be used for, since "don't use text-danger as a decorative accent" saves a future developer, often on the client's own team, from breaking something we spent real time getting right.
We also note which tokens are safe to extend versus which ones are effectively locked. A neutral gray ramp usually has room to add an intermediate step if a future project needs it. A semantic token like danger or success usually shouldn't get new siblings casually, since adding a second "success-ish" green without real justification just recreates the naming confusion the whole system was built to avoid in the first place.
This documentation step is the one clients most often want to skip, since it doesn't produce anything visible on screen. We push back on that instinct every time, because it's consistently the part that determines whether the system we build survives contact with a team that wasn't in the room when we designed it.
We keep it lightweight on purpose. Nobody reads a fifty-page design system manual, but almost everyone will glance at a one-line note attached directly to the token they're about to use, which is why we favor inline comments over a separate reference document that inevitably goes stale.
Step 6: We Hand Off With a Short Walkthrough, Not Just a File
A token file alone, no matter how well documented, tends to get half-understood by whoever inherits it later. We schedule a short handoff call with every client's internal team once the system ships, walking through the naming logic and the reasoning behind the dark-mode pairs specifically, since that's the part most likely to get misused by someone unfamiliar with why it was built the way it was. This one extra step has saved more than one project from a well-intentioned but contrast-breaking edit six months down the line.
Why We Do It This Way
None of this is complicated in isolation. What makes it work is doing every step in order, every time, instead of skipping ahead to "does it look good" before the contrast math is settled. We wrote up the fuller version of this process, including how we think about elevation and governance, in our longer piece on building an accessible web color system. If you're staring down a similar rebuild for your own product, that's the kind of work we do at 137Foundry.

















