The tokens rollout with a Harness Design layer

I closed Milestone 1 and Milestone 2 of the Harness Design System in the previous articles. The token foundation was ready, the governance was defined, and the harness schema was applied in Figma. What was missing was the part no technical article tends to tell properly: taking this out of the controlled environment and putting it in front of the code our customers use every day.
That happened. React web is live with the new tokens. And what I learned in this process matters more than the confirmation that it worked.

The rollout happened, with technical debt bought knowingly
We rolled React out to production. The decision to do it on a Saturday was no accident. Changing color and typography across a large number of screens at once, in production, requires a window in which as few people as possible are working in the system.
Before that came the review. And here a practical problem showed up that we had not properly sized: how do you review a change that affects the color and typography of practically every screen in the system, without opening each one manually? The answer that the developers came up with (here it was exceptional work by React front-end developer Rodolfo Ferreira) was to build, on top of an existing base called Argos CI, a system that shows the current screen side by side with the screen after the new tokens are applied. Without it, reviewing would have meant browsing screen by screen, environment by environment, hoping not to miss anything.

Even with Argos, the review was not perfect. And that was expected. We did the rollout knowing that technical debt would be left over: places with hardcoded colors that the automatic process did not catch, a component that is not in the main flow and was therefore left out of scope, typography that did not migrate in some specific spot. Buying that risk was a conscious decision, not an unexpected problem that showed up later. The alternative would have been not rolling out until everything was perfect, which would mean postponing indefinitely the moment the foundation starts to matter in production.

The divergence the foundation had already anticipated
In "Before AI-first, human-first" I wrote about the risk of publishing new tokens in Figma while the code still runs on the old ones. That was confirmed in practice, but in a more specific way than I expected.
React migrated first. Flutter has not yet. That created a concrete situation: the designers who work on app screens still need to prototype from the old version of Glorp, our design system in Figma, while those working on web screens already use the new version. We had to keep both versions of the library available at the same time: one active for those who migrated, and one as a backup for those who have not yet.

Publishing the entire library at once also exposed a structural problem that had been hidden: not every component had a clear distinction between the variant used on mobile and the one used on web. The same component name, two different contexts, with no explicit separation in the file. This did not show up as a rollout bug. It showed up because the rollout forced everyone to look at the file in a way nobody had looked before.
There was also the most tedious side effect: screens that were already finished with the old tokens had to be redone by hand to follow the change, because otherwise Figma would show one thing and the code another. That is real work, done after the fact, and it was not in the original plan.
For the customer, almost nothing changes. For now
This is the point most worth naming honestly. Internally, this was a big change: two weeks of almost full dedication, an entire infrastructure layer built from scratch to make token updates semi-automatic, a bind plugin built and adjusted over several iterations, and review tests covering dozens of components.

For the people who use the product, the visible impact is small. Some people will notice that a text became a bit more readable, or that a warning color is a bit different. Most will not notice anything.

This is not an execution failure. It is the nature of this layer of the project. The real gain the customer will perceive does not live in the tokens. It lives in the components the next phase of the project will produce faster and more consistently because of this foundation. Tokens are what make that gain possible, not what delivers it directly. I have explained this to internal stakeholders several times over the project, and I still find it strange to have to defend team time for something that, from the outside, looks like just a color palette change.
What actually changed
It is worth breaking down what this foundation carries, because as a whole it is more than it seems.
On accessibility, the numbers confirm the gain, with an important caveat: not everything improved equally. The contrast of tertiary text, the most used tone across the entire system, went from about 4.3:1 to 8.0:1. The secondary neutral icon went from 2.70:1, which failed, to 10.00:1.
The error red family is the case that needs the most context. When we planned the new tokens, we noticed that the old red looked too similar to the yellow and orange tones in some variations, which made it hard to tell the three colors apart in certain parts of the interface. The decision was to shift the red toward magenta, a pinker tone, to create a clear distance between the three families. That solved the differentiation problem, but it had a cost that only showed up later, in the contrast measurement: the red became lighter in this new position, and the most critical pair in this family started to fail by a small margin. We have already identified the point, and it is in the queue to be refined, without losing the distance we gained from yellow and orange.
The orange used for links and actions also still fails, both before and after: 3.31 to 3.24. This case is different from the red. The tone did not change because it is the brand's identity color, and changing it was not a decision that fit within the scope of the tokens. But we understand the path: for use in interfaces, in buttons and links, we will need to apply a tone one step darker within the same orange scale, keeping the brand color recognizable while solving the contrast. It is not done yet.
And the focus indicator is still practically invisible against a white background, around 1.18:1, when the recommended minimum is 3:1. We gained real ground in text and icons. Error, link, and focus are still open items, not wins I am inflating.
On typography, we replaced the font used in the body paragraphs with Figtree. That change had been decided months earlier, in an earlier review of the brand's visual identity, but it had never reached the design system. In other words, the system was out of date with the brand itself, not just with accessibility best practices. Figtree is about 5.6% narrower than Prompt at the same size, and the body text weight went from 300 to 400, which helps people with low vision read text that used to be too thin. In many cases this saves a full line of height in a paragraph, which matters on small screens. The trade-off is that the larger headings, which still use the old font, became proportionally taller after the change in leading. The space gain is not uniform across the whole screen.
Beyond color and typography, we expanded the token set in several areas that had no coverage before: borders, stroke width, shadow, spacing. Each of these families gained variants that simply did not exist, which reduces the amount of loose value typed by hand that was still left in the system.
What this foundation left ready
There is a gain that does not show up on any screen, and it may be the most important of the three: there is now a way to manage and update tokens that did not exist before. Before, changing a token meant someone going manually to every place that value was used. Now, the flow goes through Figma, through an export and bind plugin, and through an infrastructure layer that distributes the update to React and Flutter. That makes testing, adjusting, and improving the process much cheaper than it was two months ago.

The React rollout happened. The Flutter one is still in progress, without a closed date. The divergence between Figma and code, which we knew would show up, did show up, and it is being resolved little by little. It is not a perfect migration. It is the migration we could do, with the risk we decided to buy, and with the foundation the next step of the project will need.



Comments