> Blog post by Lokesh Saini
> Canonical (HTML): https://www.lokeshsaini.com/blog/designing-with-a-restraint-budget

I've been building a desktop app for myself. It's a tool for working with AI coding agents: routing tasks, reviewing outputs, tracking what's running. Nothing shipped publicly, no real users beyond me. The absence of external pressure turned out to be a design problem in disguise, because when no one is watching, every aesthetic decision becomes optional.

The part I found most useful wasn't a layout or a component. It was a rule I wrote for myself on day one: the visual system is greyscale, and color is reserved exclusively for status.

## What the rule actually means

Not "mostly greyscale." Not "restrained palette." The chrome, the typography, the borders, the surfaces are all pulled from an 11-step neutral scale. No blue primary buttons. No teal accent. No warm-toned headers.

Color appears in exactly four places: success (green), warning (amber), error (red), info (blue). These are semantic colors and they live on specific components: status pills, toasts, inline alerts, banners. Nowhere else.

```css
/* semantic colors: status only, never decoration */
--color-success: #16a34a;
--color-warning: #d97706;
--color-error: #dc2626;
--color-info: #2563eb;
```

If I want to visually weight something, I have one move: scale, weight, and spacing. Larger type is more important. Heavier weight is more important. More surrounding space is more important. The hierarchy is structural, not chromatic.

## Why this works better than a palette

The first thing I noticed was that status became legible at a glance. On a screen where everything is neutral, a green pill is immediately significant. A red banner is alarming in the right way. The semantic system has no competition, so it lands with full force.

The second thing was that coherence came for free. With a full palette you're constantly arbitrating: should this header be the accent color? Does this button get the brand blue or is that too heavy? Is this secondary action warm grey or cool grey? A greyscale constraint collapses all of those decisions. There is one answer.

The third thing I didn't expect: the restraint made motion more readable. When a status changes from in-progress to complete, the color shift from neutral to green is the whole signal. I don't need to animate width or background-color to make it perceptible. I can animate opacity and transform only, which is faster and cleaner.

```css
/* what animates: opacity and transform only */
/* color changes snap. They communicate state, not transition */
.status-pill {
  transition: opacity var(--duration-fast) var(--easing-out),
              transform var(--duration-fast) var(--easing-out);
}
```

## The discipline that's actually hard

The greyscale rule is easy to state. It's hard to follow on the twentieth decision in a row, because the temptation is always the same: add a little color here to make this feel more alive.

The default visual language for AI tools right now is gradients, glow, glass. It reads as "powerful" or "futuristic" and it communicates those qualities effectively. The problem is that it communicates personality instead of state. When your surface has a purple gradient, the gradient is saying something all the time, even when nothing is happening. It's always performing.

A neutral surface says nothing until something needs to be said. Then it says it clearly.

The hardest place to hold the rule was the primary action button. My instinct kept wanting to make it blue or green or anything other than the darkest neutral. The argument for color there is real: users expect primary actions to be visually differentiated. But the differentiation in a greyscale system comes from weight, size, and position. A button with the right border weight and the right spacing is unambiguously a button. It doesn't need color to be read as one.

I wrote the rule into the design system document rather than keeping it in my head, because rules that live only in your head erode:

```text
Neutral palette. Pure greyscale, 11 steps.
No chromatic accent: --accent resolves to the strongest text
color. Used for emphasis, focus, and primary CTAs.
This is the central aesthetic constraint and the most common
place a contributor accidentally drifts.
```

Writing it down also forced me to explain why, which made it easier to defend when I was deciding whether to break it.

## The takeaway

A restraint budget is not about minimalism for its own sake. It's about reserving your expressive tools for the moments that actually need them. If color can mean anything, it means nothing. If color means exactly four things, it does its job every time.

The greyscale constraint gave me hierarchy for free, coherence for free, and readable motion for free. What it cost me was the comfort of being able to reach for color when a design felt flat. That's the right tradeoff.
