root mode · red is measurements, green is judgment · press R
01 · Design system · Architecture · N5 Now

MOB: from design system to source of truth

How I turned a request to "modernize the aesthetics" into a layer of rules separated from the technology. It is the one the engineering team consumes today to rebuild the platform.

Drawing: a person sets a piece into a wall made of stacked interface modules; the right half of the wall is already finished and painted a single color.

I built MOB without anyone asking for it, together with a frontend developer, and spent months evangelizing teams that did not believe it was needed. Five years later it was the company's official standard.

And then came the request that makes this case interesting. Leadership wanted to completely modernize the platform's visual language. In parallel, engineering was rebuilding the entire product on a component library, work that could not and should not stop.

Two legitimate requests that, over time, contradicted each other: every sprint built without anticipating the visual change added future rework cost.

Campaigns module in the previous CRM: a dense table of rows, a saturated blue header and a column of indicators down the side. Before MOB
The same module rebuilt with MOB: a light header, four donut charts on top and the table with more air between rows. After
That system — the one that already worked and was the standard — was the one that now had to be modernized without breaking it.

And the system had three representations that had evolved separately: the design documentation, the actual implementation and the prototyping tool each said something different.

The library canvas in Figma: the pages panel on the left and a grid of button variants with all their states.
One of the three representations: the Figma library. Maintained by hand, and therefore always one step behind the code.

Redesigning the aesthetics on that base would have produced a fourth one.


Before drawing the new aesthetics I made a structural bet: encode the system that already existed — the old one, the one about to be replaced — into a prototyping tool. Behavior rules, design philosophy, layouts, composition patterns, component-to-component mapping.

Not an inventory of parts: the judgment behind the parts, written so a machine could apply it.

Plate 4 of the system: the title 'Less is more' and its rule, over a black and white photo of a man in a suit smoking in front of a glass, a gun and a rosary.
The commandments of the system: rules with a reason, not aesthetic preferences.

Starting from the old system was deliberate. If the rules were captured apart from the components, the visual layer became swappable.

I validated it by using it. I prototyped with the tool for weeks and kept correcting it with whatever using it surfaced: every time a real screen revealed a badly written rule, the rule got fixed at the source, not on the screen.

Only once the tool was consistent, and with the visual direction already defined, did I swap the components for those of the new library. The layouts and the patterns were left untouched.


That order is what resolved the contradiction in the brief. Because the layouts and the patterns were independent of the library, the prototypes the team already had were still valid specifications: the same screens, the same behaviors, changing only the components.

Agenda and CTA screen in the previous language: blue headers, a profile photo on every row and accent color on every line of text. Previous language
The same screen with MOB components: a plain-text greeting, initials instead of photos and color reserved for state. New language
The same screen, the same layout, the same data and the same behaviors. The only thing that changed were the components.

The audit up front confirmed the size of the bet. The real coupling with the old library was concentrated in three places. The 990 lines of behavior specification had only two references to the palette, and seven organisms carried over one to one with nothing touched. The layer that is expensive to rebuild came out intact.


With the visual language separated from its implementation, a decision appeared that was not technical but about role.

The temptation was to ask for the migration to the new library: I had the argument ready and the visual exploration worked. Instead I delivered the language in a format any stack can implement, and handed the decision back to the frontend team with a mechanism to make it with data. A scoped spike where a developer rebuilds one or two screens with the generated theme and we measure how much of the aesthetic comes out with theming alone.

The criterion was written down in advance, with a numeric threshold and three possible paths depending on the result. In all three, the tokens and the specification are the same investment: nothing gets thrown away. The only thing I asked for in the short term were two hygiene rules at near-zero cost: every style comes out of the theme, and the team consumes a layer of its own instead of the library directly.

The path ended up being decided by the facts. Today there is a library of 62 components in the new aesthetic, living in the engineering repository with its own Storybook and 196 documented use cases. It grows with every build that moves forward, and the tokens are aligned byte for byte with that repository.

The Button component page in Storybook: the rendered examples on top, the props table below and the system index in the sidebar.
The engineering team's Storybook. In the left column, next to the components: Foundations, Philosophy, Conventions and Motion.

The modules already in clients' hands were left alone: the transition happens where things are being built, not where they already work.


The new library brings eleven color roles and nothing else: it covers no semantic states, no chart series, no per-module accents. Instead of designing three separate subsystems I unified them into one, with ten series where the states are aliases, not new colors. The consequence: the red of an error tag and the red of a chart series are the same token and cannot diverge over time.

The entire neutral scale derives from the hue of the brand color at low chroma: changing the brand means changing one line, and the greys recompute themselves.

Component viewer: buttons, fields, cards and states shown together on a single screen, with the default palette. Default brand
The same viewer with the color picker open and every component already redrawn over the chosen color. Another primary, live
One value changes and the whole system rearranges itself: surfaces, hovers, borders and states recompute as a tint of the new color, without touching a single component.

The rules came out of testing, not out of a manual. Lightness is never touched when warming the greys, so contrast stays intact. And the ceiling is seven percent, because at ten the grey collided with the active state.

Two findings that only show up on a real screen. The background, the hover and the container fell within 0.004 of lightness: the hover on ghost buttons melted into the background, and it was fixed by pushing the background above the hover. And form labels in monospace felt heavy, so mono ended up reserved for overline, caption and micro-text.


The task category accents were the only color subsystem that did not close right away. There are four (commercial, operational, risk and services) and they have to be told apart from each other and, on top of that, not step on the semantic states, which live on the same wheel.

I turned it into a measurable problem instead of an argument about taste: two criteria, the hue distance between categories and the distance against the states. With that, the original mapping ruled itself out. It had commercial nineteen degrees away from "warning", so a routine task read as an alert.

Hue wheel with dots of two sizes spread around the circumference, and labels giving how many degrees separate each pair; one of those labels is highlighted.
The large circles are the categories; the small, faint ones are the states that must not be stepped on. In red, the only collision left to resolve.

Five variants later the threshold appeared: below fifty degrees of hue, two categories stop being distinguishable.

Four chips in a row; each shows a color applied to background and text, its hue number and an oklch() expression underneath.
Each category with its hue and the formula that derives it from the series palette. Background and text come out of the same token: there are no loose values.

Between the two finalists there is an open trade-off, and the underlying question is not aesthetic but about the product: does the risk category own the alert hue, or does no "positive" category touch yellow? Both answers are defensible and the decision is not mine alone to make.

It stays documented with the full path. When it closes, the change is four lines of token, not a screen by screen review.


6 weeks to redefine the system
62 components in engineering
3 builds on the same system
4 formats from a single JSON

The most reusable asset was not the screens: it was the layer. The system stopped being documentation someone looks up and became the source the engineering team consumes — including the AI agents they are rebuilding the platform with — and it updates with every decision that gets made.

And it was not only the components that travelled. In that Storybook, next to the 62 components, there are pages on philosophy, conventions, foundations and motion.

Design judgment stopped living in a file someone checks when they remember to: it sits in the same place the code gets written, and both people and machines read it.

The product team uses it without me: my direct report, the Product Director, builds artifacts for commercial demos on top of the tool, without going through design. And everything the company builds today comes out of the same library and the same tokens: the CRM rebuild and the two new products moving in parallel.

It also changed the timescale of prototyping. On one of the new products I adapted the desktop prototype to iOS and Android in a couple of hours, with an audit of twenty-four findings against the platform guidelines — prioritized, resolved and closed — and then to a webapp in fifteen minutes.

Desktop app: a sidebar with Home, Interactions, Contacts and Settings; in the center, the week's agenda and a conversation field at the bottom.
The starting point: the desktop version.
The product on iPhone: a circle of dots fills the screen with the instruction to tap to record, and below it a floating tab bar, icons only. iOS dialect
The product on Android: the same recording screen, with the navigation bar anchored to the bottom edge and every icon carrying its label. Android dialect
It is not the same screen shrunk down: each platform has its own navigation grammar and its own patterns. What stays constant is the system underneath.

And it maintains itself: every correction that comes up while designing goes into an inbox and is applied to the source with a versioned history. Ten documented consolidations so far. Nothing gets lost in a conversation.

What I take from it. Separating the rules from the parts before touching the aesthetics turned the redesign from a bet into the replacement of a layer. And handing the technical decision back to the frontend team turned an argument about taste into a measurable experiment.


correction The brief said "modernize the aesthetics" and I said yes. It took me three weeks to see that accepting it as written would produce exactly the problem I would have to solve later. The argument that had to happen was not about design: it was about scope.
Starting from the old system was not nostalgia. It was the only way to capture the rules before touching the aesthetics. If I redrew first, the rules got lost inside the new components and there was no layer left to separate.
This is the whole argument of the case. Engineering did not have to wait for me because what I handed them was not screens: it was a specification they could implement with whatever library they chose. A system that forces you to wait for the designer is not a system, it is a bottleneck with documentation.
correction I did the first five palette variants by eye. They looked fine and they were useless: I had no way to defend why those four colors and not four others. The fifty degree threshold only appeared once I stopped picking and started measuring. That is when the conversation with the team moved from taste to criteria.
This case almost ended at chapter 04. A case that only tells the part that went well cannot be verified: anyone can write that. What still has not closed is the part that proves the system is real and that I am still inside it.
← Back to home Singular →