Teardowns

Doppler's team settings page, measured to the pixel

We rebuilt Doppler's team settings screen until 97.69% of pixels matched the original, and wrote down everything we had to understand to get there — an eleven-value grey ramp, a radius ladder tied to element size, and an accent color used exactly four times.

9 min read
Doppler's team settings page, measured to the pixel
Harro KrogHarro KrogPublished

Most design writing is impression dressed up as analysis. Someone screenshots a product they admire, says the spacing feels "generous" and the palette "restrained," and moves on. Nobody checks.

This one was checked. We captured Doppler's team settings page, rebuilt it from scratch, rendered the rebuild back into a headless browser at the same size and pixel density, and diffed it against the original screenshot until the numbers stopped moving. Final score: 97.69% of pixels identical to the original, with a mean per-pixel error of 1.27 out of 255.

Every value below is a measured value. Not a guess about what looks right — the number that had to be there for the diff to pass.

Key Takeaways

  • The entire interface runs on eleven greys, and one of them (#383a42) does three unrelated jobs.
  • Corner radius scales with element size — 4px on a keyboard chip, 10px on the panel — rather than being one global token.
  • The purple accent appears exactly four times on a 1920×937 screen, and the primary button's text color is the page background.
  • Icons sit one to two steps darker than the text they label, deliberately.

The grey ramp is eleven values, and it's doing all the work

There is no color in this interface in any meaningful sense. There is a neutral ramp, and there is one purple. Here is the entire neutral palette, at the values that made the diff pass:

#16171a
page
#1c1d21
raised surface
#25272c
soft divider
#383a42
border · chip · fill
#444850
idle nav icon
#4a4e5a
affordance icon
#6b7280
placeholder
#8e95a2
secondary text
#a8adb7
topbar icon
#d2d5da
body text
#ffffff
headings

Eleven values for an entire application screen. The interesting one is #383a42, which does three unrelated jobs: it is the sidebar's right border, it is the fill of the ⌘+K keyboard chip in the search field, and it is the placeholder block standing in for a user avatar.

That is not laziness. A border and a small filled chip want to sit at the same optical weight — both are "structure you notice but don't read" — and giving them separate tokens is how palettes quietly grow to forty values that nobody can tell apart. One value, three jobs, and the screen stays coherent.

Icons are darker than the words they label

This is the finding that took longest to accept, because it looks like a mistake until you measure it.

The navigation label sits at #d2d5da. The icon immediately to its left sits at #444850. That is not a subtle difference — it's most of the ramp. The magnifier in the search field is #4a4e5a against placeholder text at #6b7280. In the topbar, where there is no accompanying text at all, icons jump to #a8adb7.

ElementIconLabelGap
Sidebar nav row#444850#d2d5daIcon far darker
Search field#4a4e5a#6b7280Icon slightly darker
Topbar (no label)#a8adb7Icon carries alone
Active nav row#9f6afe#9f6afeMatched

The rule underneath: an icon is only as bright as the work it is doing. When a word is there to be read, the icon is a locator, not information, so it recedes. When the icon is alone in the topbar it becomes the information and brightens by four steps. And when a row is selected, icon and label snap to the identical accent — the one moment they are equal partners.

Most dashboards get this backwards, setting icons and labels to the same value and producing a sidebar that reads as visual noise at a glance.

The type scale is four sizes doing everything

26 / 600 Team
19 / 600 Users
16 / 400 Invite your team and control their access.
14 / 400 Projects · Change Requests · Activity
12 / 400 Developer Plan

Five steps: 26, 19, 16, 14, 12. No 20, no 18, no 24. The ratios are irregular — 26→19 is a big drop, 16→14→12 are small ones — because the scale isn't generated from a formula. It's three separate jobs with a gap between them: one page title, one card title, and then a tight cluster of body sizes where all the actual reading happens.

14px carries almost the entire interface: navigation, tabs, table headers, table cells, form labels. Weight does the differentiating, not size — 400 for a resting nav item, 500 for the workspace name and table headers, 600 for the active tab. A single size with three weights reads as more disciplined than three sizes at one weight, and it survives translation into languages with longer words.

The one oddity worth naming: the ⌘+K chip is set at 12.5px. Half-pixel type sizes are usually a bug, but this one is deliberate enough to have survived into production — at 12px the chip's glyphs sat a touch small inside its 21px box, and 13px pushed the label wider than the 48px chip.

Radius is a function of size, not a global token

⌘+K
4px
Invite Users
6px
Search…
8px
10px
50%

4px on the keyboard chip, 6px on the button, 8px on inputs and the workspace card, 10px on the users panel, and full circles on avatars. The radius climbs with the element's shortest side, holding the visual curvature roughly constant instead of the numeric value.

This is why a single --radius: 8px token applied everywhere always looks slightly wrong: at 21px tall it reads as a pill, and at 225px tall it reads as a square with the corners filed off. Doppler's ladder keeps the perceived roundness identical across a tenfold size range.

The accent appears four times

On a 1920×937 screen, #9f6afe occurs in exactly four places:

  1. The active navigation row — icon and label together.
  2. The 64px underline beneath the active tab.
  3. The Invite Users button.
  4. The notification dot, and only at #b085fe, a lighter tint.

That's it. One hyperlink uses a completely separate blue (#06acf9) and is the only other chromatic element on the page.

The restraint is the mechanism. Because purple is scarce, each instance is unambiguous: where you are, what section you're in, and the one action the page wants. Spend the accent on six more things and it stops being a signal and becomes decoration.

The detail worth stealing is the button's foreground. Invite Users is #16171a text on a #9f6afe fill — the page background color, used as the type color. Not white, not black. Pure white on that purple is glary and slightly cheap; black is a hole. Using the page's own background makes the button read as a lit panel cut out of the surface behind it, and it ties the brightest object on screen back to the darkest.

What the remaining 2.31% is

Honesty about the failure is the point of measuring in the first place. The pixels that never matched are concentrated in three places:

  • The logo. Deliberately not reproduced. Brand marks are dropped from every rebuild and replaced with a neutral placeholder, so this region is guaranteed to fail and is excluded from any claim of fidelity.
  • The avatar. A photograph, replaced by a flat #383a42 circle for the same reason.
  • Glyph antialiasing. At 14px, subpixel rendering means two technically identical text runs differ by one or two levels per channel along every stroke edge. This is why the "within 8/255" figure (98.05%) is the more useful number for text-dense screens than exact match.

Nothing structural is in that 2.31%. Every box in the layout passed its floor, which is the condition the pipeline actually enforces — a per-region score, not a global average that a big correct background can hide a broken sidebar inside of.

What this is for

We didn't rebuild this page to have a copy of it. A clone is a worthless deliverable — it has no data, no responsive behaviour, and no reason to exist.

What survives the exercise is the layer above: an eleven-value neutral ramp with a rule for when to use each step, a radius ladder tied to element size, a five-step type scale that leans on weight rather than size, and an accent budget of four. Those are portable. They're also the part of interface design that takes a team years to converge on and that a generative tool, left to its own judgement, will approximate badly and confidently.

That's the argument for measuring instead of eyeballing. You can't extract a rule you never noticed, and you don't notice a 3px difference until something refuses to accept it.


Doppler is used here purely as a technical subject for design analysis. This work is not affiliated with, endorsed by, or sponsored by Doppler; all trademarks and brand marks belong to their respective owners. The rebuild drops brand marks, replaces photographic content with neutral placeholders, and is not published or served as a live site. The measuring pipeline is open source — see how it works.

Get new posts in your inbox.

Notes on paywalls, retention, and release QA — sent when there's something worth reading, not on a schedule.

More from the blog

Let's talk —

Your audience is already there. The app that earns from it isn't.