Orkhan Mammadov

Nous Design System

Turning one designer’s concepts into a system that holds a terminal, a cloud console, a desktop app and a phone

Client
Nous Research
Role
Senior Product Designer
Design system owner
Year
2025 – 2026
Discipline
Design Systems
Product Design
AI / ML Interfaces
Diagram — component and state coverage matrix, with the deliberate n/a cells
[ THE PROBLEM ]

Nous Research shipped across a terminal, a cloud console, a desktop app and mobile, and each one had drifted into its own dialect of the same visual language. The language itself was not the problem — a visual designer had already established it, and it was good. The problem was that it existed as concepts: a set of compositions showing how things should look at one moment, in one place. Nothing said what a disabled button was, what happened to the palette when there was no background to control, or which of two plausible readings of a concept was the correct one. Four teams answered those questions independently, and four different answers is what drift is.

What a concept cannot tell you

A concept is a picture of one moment. It shows a button, and the button is right. It does not show the button disabled, or mid-request, or focused via keyboard, or holding a label long enough to wrap, or sitting on a background the concept never anticipated. Those are not edge cases; collectively they are most of the time a component is on screen.

So the first job was not to design anything. It was to enumerate — every component, crossed with every state, and to decide each cell rather than let it be inferred. The interesting output of that exercise is not the cells that got filled in. It is the ones deliberately marked as not applicable: a pill never loads, a tab never errors. An unfilled cell is a question, and every implementer who reaches it answers it differently. A cell marked n/a is an answer.

This is the part of design-system work that does not photograph well and is most of the value. The concepts were the input. The grid was the deliverable.

Diagram — component and state coverage matrix, with the deliberate n/a cells
Diagram — component and state coverage matrix, with the deliberate n/a cells

Naming tokens for role, not value

I extracted the language into tokens named for the role they play rather than the value they hold — BG/Primary-Background/Main, Text/White-Background/Secondary — which is what let it survive a terminal, where a background colour cannot be guaranteed.

The distinction sounds pedantic until a surface forces it. A token called blue-500 is a note about what a colour is, and it is useless in a shell where the background belongs to the user and the palette is sixteen colours the user chose. A token called BG/Primary-Background/Main is a contract about what a colour does, and a terminal can honour a contract — by inheriting, by picking the nearest available, by deciding the role does not apply here. Naming for role is what turned four ports of a visual language into one language with four resolutions.

The second half of that naming scheme does the accessibility work before anyone opens a contrast checker. Text/White-Background/Secondary states the ground it expects to sit on, so a pairing that has never been audited is visible as a pairing that has never been audited — you can see the mismatch in the name.

Diagram — tokens named for the role they play rather than the value they hold
Diagram — tokens named for the role they play rather than the value they hold

Auditing the palette

I computed the contrast matrix and wrote down the failures as carefully as the passes. #0000f2 on #f5f5f5 is 8.4:1 and clears AAA. Dark text on that blue is 2.1:1 and is never allowed. The blue on near-black is 2.2:1, so a dark theme needs a lighter blue entirely. Saturated red beside it shimmers, and a blue focus ring on a blue active pill is invisible until you swap it for currentColor.

Recording the failures is the part people skip, and it is the part that makes a system enforceable. A palette documented only by its passes tells you what you may do; it is silent at exactly the moment someone is about to do the wrong thing. Writing down that the brand blue cannot carry dark text is what stops that pairing from reappearing every quarter with a new justification.

It also settles the dark theme honestly. The finding was not that the dark theme needed tuning — it was that the brand blue does not function on near-black at all, and pretending otherwise would have shipped a theme that failed for anyone who needed the contrast most. A lighter blue for dark grounds is a real concession, and it is the correct one.

Auditing an inherited palette — every pairing computed, failures recorded alongside passes
Auditing an inherited palette — every pairing computed, failures recorded alongside passes

The type scale, written down

Sigurd Variable for display, DM Sans for body, DM Mono for captions and buttons. Three faces, each with a job specific enough that choosing between them is not a matter of taste at the point of use.

The documentation matters more than the selection. A type scale that lives in a designer’s head is a scale that gets approximated; written down with its roles attached, it is a scale that gets used. The same applies to the accessibility and interaction guidance layered on top — keyboard model, focus order, target sizes, motion. None of it is novel work. All of it is work that has to exist in writing or it does not exist.

Nous UI kit — the type scale extracted into a documented system
Nous UI kit — the type scale extracted into a documented system

Shipped as code, not as a handoff

It ships as a real codebase rather than a Figma file with a handoff ritual attached. That is the difference between a system and a style guide: a style guide describes the intended result and relies on everyone reproducing it faithfully, and a system is the thing they build with, so faithfulness is the default rather than an act of discipline.

What that bought, concretely: one source of truth across four platforms, and a token layer with enough semantic information that a surface nobody anticipated — a terminal, in this case — could be added by resolving the existing contracts rather than by re-deriving the language.

The credit line matters here and I want it stated plainly. Leigh Taylor set the visual language and the initial Portal concept; the taste in this system is substantially his. What I did was the part that turns taste into infrastructure — enumeration, naming, auditing, documentation. Both halves are necessary and they are not the same skill.

[ OUTCOME ]
4
surfaces held by one system: terminal, cloud, desktop, mobile
WCAG 2.2 AA
inherited palette audited, keyboard model verified