Context
A growing product, one set of parts
Select is a Media.net web app where people called curators put together advertising deals: ready-made packages of ad space and target audiences that advertisers can buy. It was growing quickly, and moving from an older internal look to a brand of its own.
I built the Select Design System: one shared set of design rules (called tokens) and building blocks (called components) that every screen is made from, so a problem fixed once is fixed everywhere.
The basic rules: colours, spacing, rounded corners, borders, icon and element sizes, 42 text styles and 3 shadows.
24 documented building blocks, from buttons and text fields to date pickers and audience builders.
How each one looks at rest, on hover, when selected, switched off, showing an error or loading.
A shared sheet that lists every rule and its value, so designers and engineers use the same numbers.
The challenges
The problems lived in the components
Before changing anything, we watched people use the product. In February and March 2025 we ran three sessions on the main deal-creation flow: two curators doing the task while we timed them, plus feedback from the sales team. Names stay private.
What surprised us was where the problems sat. They were rarely about the steps of the task. Most were about how a single building block behaved, like a date field or a dropdown, and every screen that used it had the same problem.
Dates fought back. Only the calendar icon opened the picker, and a typed date like 2/2/2025 was rejected.
Dropdowns for one click. Even a single choice meant opening a long dropdown list, and it did not close when clicking outside.
Selected, or not? A faint tick was the only sign of a selection, and there was no clear way to undo it.
Meaning was hidden. Help for a field sat behind a small pop-up you had to hover over, and options were bare labels.
Choices disappeared. Closed sections hid what had been picked, so people reopened each one to check.
Busywork. IDs were typed by hand, and a setting in one place silently disabled a field in another.
Fix each problem once, in the building block, so every screen that uses it gets the fix?
Foundations
Tokens first
Everything starts from two layers of named values. Primitives are the raw ingredients: 26 colours and 21 spacing steps. Semantic tokens say what a value is for, such as "less important text", "the border of a field with an error" or "the background of a warning": 59 colour roles, plus 39 for spacing, corners, borders and sizes.
Components only use the purpose-based names. A field asks for "error border", not a particular shade of red, so a colour can change in one place instead of on every screen.

Type, and one source of truth
Text uses 42 styles in the Inter font, from small body text up to large display headings, each in four weights. A shared sheet lists all 187 tokens with their values and where they come from, so designers and engineers read from the same list.


Before and after
Fixing it where it breaks
Each challenge pointed at a building block. For each one I rebuilt it with every state documented, so the fix travels with it into every screen. Switch between Before and After on each example.
Dates
Before, only the icon opened the calendar, a typed date was rejected, and a setting elsewhere switched off the end date without saying why. Now the whole field opens the Date Picker, presets cover the common dates, time and timezone are built in, and "Always On" sits right under the date it affects.


Multi-select
Before, every choice meant opening a long list with faint ticks, and it stayed open. Now common options sit under the field as one-click tags, items are added with a clear + and check, and a Selected panel shows the count with Clear All.


Options and help
Before, the meaning of a field hid behind a small hover pop-up and options were bare labels. Now help sits under the label with a Learn More link, and each option is a card that explains itself in one line.


Segments
Segments are ready-made groups of people an ad can be aimed at, such as "frequent travellers". Before, a three-level tree made every segment look the same, and a faint tick was the only sign of a selection. Now each segment is a row with its price and the company that supplies it, include and exclude are separate actions, excluded segments turn red, and groups say All of or Any of.


Fields and sections
Before, IDs were typed by hand and closed sections hid what had been chosen. Now a Generate action sits in the label row, and chosen values stay visible as tags under each field.


The system
Built in layers, documented in every state
Components are built from the smallest pieces up. The Date Picker, for example, starts with single day cells and preset buttons, combines them into a field, a calendar and a time input, and ends as a full picker documented in every state. The whole library works this way.


- Button
- Badge
- Card
- Checkbox
- Radio
- Switch
- Toggle
- Toggle Group
- Input
- Input Group
- Combo Box
- Dropdown
- Date Picker
- Dialog
- Tooltip
- Hover Card
- Toast
- Table
- Progress Stepper
- Progress Step
- Header & Navigation
- Widget
- Icons
- Deal Library
What I learned
Research is a component audit
People describe problems with the task, but most fixes were in the building blocks. Fixing a dropdown once fixed it on every screen.
Purpose-based names made changes safe: you change what "error border" means, not every red on every page.
Documenting loading, error, selected and disabled up front is what lets new screens start from solid ground.
