Ahmed.Idris
All projects
Internal · across two enterprise clientsUNDER NDA

Struct, a shared design system

The shared set of components, rules and colour tokens behind two enterprise products built by different teams, so the two look and behave like one thing. It was not designed up front. A re-skin turned into a rebuild. Other internal platforms are built from it now.

Role
Lead designer & maintainer
Team
Me, plus whoever was on the product
Timeline
From late 2024, ongoing
Status
In use while still unfinished
FIG 01A slice of the current library, at full size. The input box is 320 by 40 with 8 pixels of padding, the label sits 4 pixels above it and the message 4 pixels below. Every other figure here is a screen scaled down to fit; this one is not.Recreated for this portfolio, with fictional content and no client branding.
Outcome
2products on itBoth products use it now.A dealership operations system and a licensing platform, built by different teams, now drawing from one set of components instead of copying each other.
9component groupswas two diverging setsNine groups, picked from what the two products needed.From inputs and navigation to notes, logs, announcements and admin: the parts enterprise tools keep re-inventing.
The group count is from the current library. Everything else here describes work in progress, not a result.
The problem behind the brief

There was no brief. The client asked for a different look. A re-skin turned into a rebuild, and the rebuild turned into a system.

The first build used Material Design, because the client asked for it. After the first module shipped they said it felt dated and wanted something modern. That is a taste argument, which is hard to act on. Underneath it was a real mismatch. We had to build the second attempt instead of downloading one.

My part

The evaluation and the choice of what to build on, the component set itself, most of it drawn from scratch rather than adapted, the tokens, the specialised components that had no equivalent anywhere, and the ongoing work of pulling two products’ worth of drift back into one library.

The team

For long stretches this was one person’s job, and later mine plus designers early in their careers. A system does some of the mentoring. It answers questions a junior designer would otherwise have to ask. It also makes a disagreement about a control visible.

Confidentiality

Everything on this page is a recreation. The client is not named; their branding, real identifiers, customer data and internal documents are replaced with fictional equivalents built for this portfolio. Figures appear only where they describe my own process, and anything commercially sensitive is left out.

The system spans two clients under separate agreements, so the components here are shown with fictional content and neither client’s branding.

Origin

Where it came from

Two enterprise products, started about eight months apart and overlapping for most of their lives: a dealership operations system and a licensing platform for a cloud reseller. Neither project had a design-system line item. Both needed the same forty or so components, and the second one was being drawn by copying the first.

Copying is what causes the trouble. A copied component drifts. Someone fixes a padding bug in one product and not the other. Someone adds a variant the original never had. In time there are two libraries that look related and behave differently.

The first system

Why the first one went

The dealership system was built on Material Design at the client’s request. After the first module shipped, the client said it felt dated and asked for something more modern. I did not argue. They were right, but not for the reason they gave.

The mismatch was not age. Material is built for consumer apps. This is a tool people sit in for eight hours. It puts heavy shadow on every surface. Its touch padding halves the number of rows you can see in a register. Its floating action button competes with the primary action already on the page. It animates things that happen hundreds of times a shift. All of that is right on a phone. In a dense table at work it gets in the way.

First build · Material Design
☰ Get Ready
Service request
VehicleA-0418
StageReady for cleanup
PriorityAssigned
CancelSave
+
Now · the current system
Get Ready / Request
Open
Service request
ReadyWaiting
VehicleA-0418
StageReady for cleanupLocks the record once set.
CancelSave changes
The replacement

What we built on

We evaluated several directions and landed on a variation of shadcn/ui: plain, accessible building blocks with the styling left to you. We took the structure and left the look alone. It meant we stopped inventing a control from scratch every time one was needed, and still made the visual decisions ourselves.

In practice most components were drawn from scratch anyway. What we inherited was structure and behaviour: what states a combobox has, how a date range is expressed, where helper text and error text sit relative to a field. The look, the density and the vocabulary are ours.

The components you cannot get anywhere else are the reason to have a system. A record-level notes panel with pinning and tagging. A management-history log with an action filter. An entity dropdown for users who work across dozens of sites. Announcement records. Plugin connection cards. These come up in every enterprise tool I have worked on, and general-purpose libraries do not ship them.

Generalisation

One component, two products

The notes panel is the clearest case. It was built for a vehicle record and then needed on a client account, which is a different object with different metadata and a different audience. The three questions were the same: who said what, when, and whether it is still relevant.

Generalising it meant deciding what was essential and what was local. Authorship, timestamp, role, pinning and tags are essential. What the tags say is local. The component takes those as configuration, which is what keeps it one component.

In the dealership system
Mona R.12/8/2026VEH-A0418STK-25118NEW
Service, Branch 02Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam viverra mauris sed egestas.
In the licensing platform
Sami A.12/8/2026SUB-03859ACC-10442NEW
Licensing TeamLorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam viverra mauris sed egestas.
The same card, selected
You12/8/2026SUB-03859ACC-10442
Licensing TeamLast edited on 14/8/2026Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam viverra mauris sed egestas.
Foundations

Tokens, and their naming problem

Colour, type, spacing and radius are tokenised and applied, which is what made the compliance-style re-skins on other projects survivable. The families are numbered scales: four backgrounds, three borders, three text levels, five blues, plus two gradients.

Numbers are quick to write and hard to read later. “Border 2” tells you where it sits in a ramp and nothing about when to use it, so every new person guesses, and the guesses drift. Renaming them to roles, such as surface, control and emphasis, is the single largest piece of unfinished work in the system, and it is unfinished because renaming tokens in two products people are using costs time nobody has yet.

FamilyStepsScaleWhat the steps are for
Background1 – 4
Page, card, subtle fill, sunken area.
Border1 – 3
Divider, control, emphasis.
Text1 – 3
Primary, secondary, placeholder.
Blue1 – 5
Tint through primary to pressed.
Scope

What is in it

The nine groups are what the two products needed. We did not work from a list of parts a system is meant to have.

InputsText fields, comboboxes with removable badges, date and date-range pickers, file pickers, textareas with helper and error text.
NavigationThe page frame, sidebars, breadcrumbs, content switchers, tabs, and the dropdown for people who work across many sites.
StatusesThe badge set, and the rules for which colour carries which meaning across products.
NotesThe record-level notes and comments panel, pinning, tagging and authorship.
LogsManagement history, action filters, audit rows.
AnnouncementsSystem-wide notices and the record-level announcement card.
PluginsIntegration cards and connection states for third-party services.
AdminPermission, role and entity management screens.
AnalyticsMetric tiles, comparison rows and the frame around a report.
FIG 02The button carries five types, five styles, three sizes and eight states, and every combination is drawn in the library rather than left to the developer. Shown at real size.Recreated for this portfolio, with no client branding.
FIG 03There is no table component. What there is instead is a row of five slots, built on Figma’s slot feature, plus a grey variant for banding. A product drops whatever cell it needs into each slot, so one record covers every table in both products without a variant per column. The complex cell is its own component, and the hover cell carries the row’s actions. Shown at real size.Recreated for this portfolio, with no client branding.
Status

Where it stands

People are using it, and it is not finished. The board below shows where it stands.

Done
Colour, type and spacing tokens named and applied
Inputs, navigation, statuses, notes and logs drawn
Two products migrated onto the set
In progress
Renaming numbered tokens to semantic roles
Reconciling variants that drifted between products
Usage rules written next to each component
Not started
Code parity with the React implementation
An accessibility audit against the full set
A contribution route for other teams
Retrospect

What I’d do differently

Two things I would do differently.

Start the library at the second product, not the third

By the time we decided to make this a real system, two products had already diverged and the reconciliation work was larger than building it deliberately would have been. The moment to extract a system is the first time you copy a component between products, not the first time the drift becomes painful.

Nobody has measured whether it helps

The case for a design system is usually made in speed and consistency, and I have neither figure. No build time before and after, no count of components reused versus redrawn, no audit of how far the two products agree today. Until that happens, nothing proves it works outside these two products.

Next projectVehicle Operations Platform