What the design system is doing
Monochrome chrome, six agent tones, eight type steps. Why constraint over expression is the right call when the work is supposed to be the agents.
Monochrome chrome, six agent tones, eight type steps. Why constraint over expression is the right call when the work is supposed to be the agents.
The design system is codified, not aspirational. Every screen is verifiable against a table in the design doc — if a text node, an empty state, or a list row doesn't map to a row in that table, we wrote a bug.
The thesis: the agents are the product
Most design systems are an exercise in expression — a chance for the brand to say something about itself in the chrome of the product. We deliberately did the opposite. The brand says everything we want it to say in the agents themselves: their voices, their identities, the work they do. The chrome around them stays out of the way.
This is a load-bearing decision. If we put a brand color anywhere in the chrome, that color competes with the agent identities for attention. If we ship illustrations, those illustrations occupy the visual real estate that should be carrying agent identity and status. If we add gradients to buttons, those gradients say something we did not need the buttons to say.
Constraint over expression is the rule. The constraint is what gives the product its texture.
Monochrome chrome with semantic exceptions
The shell is monochrome with a faint cool tint. Backgrounds, borders, text, buttons — all of it is near-black on near-white in light mode, near-white on near-black in dark mode. There is no brand color anywhere in the chrome.
The only exceptions are semantic. Status uses three colors and only three: success (green), warning (amber), destructive (red). Each one carries a specific runtime meaning — a task completed, a task waiting on approval, a task that failed or is about to do something irreversible. Anywhere you see one of those colors, it is because the runtime has a reason to draw your attention to a specific kind of state.
Everything else is greyscale. That includes hover states, focus rings, active rows, and selected items. The chrome has a single dial — saturation off — and we resist every temptation to turn it back on.
Six agent tones, all the color
The product's color comes from agent identity. Each employee renders inside a tinted badge in one of six tones: violet, blue, emerald, amber, rose, slate. Six is the entire palette — not a starting set, not the most common ones, the whole thing.
Why six? Enough variety that no two adjacent agents look the same, few enough that the eye learns to recognize them. The tones are calibrated to share the same perceptual lightness and chroma, so a row of six agents reads as one family rather than six random colors. Each tone has three values — a paper-thin fill, a saturated accent for icons and rules, and a hairline ring — and all three flip together in dark mode.
Agent identity is the single primitive that earns color. If something on screen needs a color, the only honest reason is that it belongs to a specific agent. Anything else is decoration, and decoration is exactly what we did not want.
Eight type steps, no improvisation
The type scale is a Major Third (1.250 ratio) anchored at 14px in the desktop app and 16px on the marketing site. Eight steps: overline, meta, body, lead, title, headline, display, display-lg. Every text node in the product picks one.
The rule that breaks the most often is the easy one: never use raw text sizes. `text-sm`, `text-lg`, `text-[15px]` — all bugs. Headings without an explicit class fall through to the scale automatically. Shadcn primitives carry internal `text-sm` / `text-xs` and we leave those alone, because those sizes are calibrated for the primitive's UX, not for our reading scale.
The second rule is harder: don't add a step. If you need something between two steps, pick the closer one and adjust weight or spacing instead. The point of a scale is the constraint; the moment we add a ninth step, the discipline that makes the other eight legible falls apart.
What we chose not to do
No illustrations. No mascots, no spot illustrations, no decorative SVGs in empty states. The icon set is Lucide, full stop, and it is used at a single stroke width across the app.
No bouncy animations. Transitions are 150ms colour fades for hover states; spinners use the standard animation; the only ambient motion in the app is a soft hover halo on the org pipeline. Marketing pages may use approved registry blocks for scroll-linked beams and marquees, but the product UI stays calm.
No icon-tile dashboards. Empty states almost never need a card. If there's a catalog you could render with a one-line muted hint above it, we do that. The full Empty primitive is reserved for genuinely empty surfaces, and we override its defaults to keep it on the scale.
No gradients in chrome. The only gradient anywhere in the product is the hero-highlight on one phrase in the marketing H1, calibrated to the agent-violet / agent-blue tones we already ship. Buttons, cards, surfaces — all flat.
No agent on a one-off hex. Ever. If a new role doesn't fit any of the six tones, we either reuse the closest tone or rethink whether the role is really a new role.
Why constraint compounds
Each constraint individually is small. Six tones is not a hardship. Eight type steps is not a hardship. Monochrome chrome is not a hardship. The compound effect is the part that matters: when every screen in the app obeys the same small set of rules, the whole app feels like one app instead of six teams' worth of patches.
That compound legibility is the only chrome-level brand asset we have, and it is the asset that lasts. Brand colors come and go; brand illustrations age; brand mascots embarrass their owners eventually. The discipline of “the chrome doesn't compete with the work” is the one design choice we expect to look right in five years.
The whole system is calibrated around two goals. The agents are the product, and the chrome should never compete with what the agents are doing or saying. Constraint over expression, because a small palette plus a small scale plus a small icon set plus a small primitive set means every screen feels like one app. If we ever break either of those, we are inventing a new convention — and we owe ourselves a real reason before we do.
FAQ
Common questions.
Why no brand color anywhere in the chrome?
Because the agents are the product. Any brand color in the chrome competes with the agent identities for attention. The product's color comes from the six agent tones, period.
Why only six agent tones?
Enough variety that no two adjacent agents look the same; few enough that the eye learns to recognize them. The tones share the same perceptual lightness and chroma, so a row of six agents reads as one family rather than six random colors.
Why a Major Third type scale?
A 1.25 ratio gives you a clean rhythm at small sizes (the bottom four steps where dense product UI lives) and tightens to about 1.12-1.24 at the top so section headers don't shout on long pages. Eight steps is enough hierarchy for the whole app without inventing new sizes.
Do you fork shadcn primitives?
Almost never. We use shadcn out of the box and override at the className layer. The two known forks today are dropped-menu (TypeScript workaround) and sonner (wired to our own theme store).
Can I add a new agent tone for a new role?
No, by rule. If a new role doesn't fit any of the six tones, we either reuse the closest tone or rethink whether the role is really a new role. The palette stays at six.
What about marketing — does the design system relax there?
Slightly. Marketing pages use approved registry blocks for motion (scroll beams, marquees, the hero highlight) but the type scale, color rules, and icon set are identical. Anything Aceternity-shipped gets restyled to the system before it ships.
Continue reading
