Nine separately built products, one design language, 150 screens in eight months.
Context
BDB.ai runs the whole data lifecycle in one product: connect a source, clean it, move it through pipelines, build and publish models, visualise the result. Nine areas, nine teams, nine separate timelines.
That history was visible in the interface. Three different navigation patterns. Row actions in a different order in every area. Modals confirming with Save and Cancel in one place and Push and No in another. Numbers left-aligned in tables made entirely of numbers. And a single light theme, in a product analysts sit inside for six to eight hours a day.
Navigation confusion and missing empty states were the platform’s two highest-volume support ticket categories.
I tested with five analysts who used the product daily, which is where most of what I know about the old build came from, and reviewed Snowflake, Databricks, Tableau and Power BI to see how mature analytics tools handle density and status.
The constraint
Six engineers on a live codebase with paying customers. No pause in delivery, no rewrite, one designer, 150 screens.
That maths only works one way: stop designing screens and start designing the thing that makes screens cheap.
Four decisions
01 One shell instead of three
The problem. Every area had invented its own navigation. Data Center used an unlabeled icon rail plus a second text list. Data Science Lab used a different icon rail. Designer used a desktop file menu.
What I did. One labelled rail, one global bar carrying search, workspace and account, breadcrumbs on every screen. The same argument runs down to component level: row actions became Open, Edit, Share, Delete, with the irreversible one last where you have to reach for it. Modal footers got one order and one vocabulary. Numerics got right alignment and tabular figures.
Sharing a project, before and after. The old modal floated over the list it belonged to and confirmed with Save on the left. The new one is a full-height panel with a fixed footer order, an empty state that explains itself, and permissions that read as a set.
The result. Nobody notices this work, and it is the reason the platform stopped feeling like nine separate tools.
02 Change the vocabulary, not the furniture
The problem. Analysts had the old layouts memorised. Moving things to help newcomers would have taxed every experienced user, and there were too many screens to migrate at once anyway.
What I did. Kept the layout, the flow and the position of every control on existing screens, and replaced only what sat underneath: components, type, spacing, tokens, alignment, states. Someone who knew the old build could open the new one and finish the task without relearning anything. Full redesigns went only where there was no familiarity to protect.
One of the migrated screens. The rail, the two-column split and the row actions sit exactly where they were. Type, spacing, components, alignment and states are all new.
The result. Because migrated screens kept their structure, old and new sat side by side in production for months without the product feeling like two different things. That is what made an incremental rollout survivable.
Worth saying plainly, since keeping a layout can read as the easy option. Fitting a new system into geometry you didn’t choose means inheriting decisions you disagree with and making consistent components work inside inconsistent containers. You give up the enjoyable part of the job so that people don’t have to learn the product twice.
03 Designing for how an executive reads
The problem. Two banks, two unrelated briefs, one about credit risk and the other about regulatory compliance. No layout given, and I had to compose from chart widgets the platform already had.
What I did. Decided the reading order instead of the components. An alert strip across the top, which was my call and the piece I’d defend hardest, because a CXO doesn’t open a dashboard to browse. They open it to find out whether anything is wrong. Then a KPI grid where every card carries a value, a status and a direction. Then detail tables below the fold, for the person who has already found the problem.
The result. The same three layers held for both banks despite the subject matter having nothing in common, which is how I know it was about reading behaviour rather than content. Developers built both directly from my designs.
04 The conversation beside the data
The problem. The agentic screens arrived as defined requirements, and the obvious pattern for a copilot is an overlay. Overlays cover the thing being discussed.
What I did. Split the view. Conversation on one side, live visuals on the other. Starter prompts in the empty state rather than a blank box, and answers rendered in the product’s own visual language.
The result. The reason you ask an analytics question is to verify the answer. Covering the data defeats that.
The system underneath
Fifteen components, documented with usage rules, every state, and behaviour across breakpoints. Priority went to components that appeared most often and had diverged most badly between areas; the rest were documented and deferred.
Underneath them a tokenised colour system, a spacing scale, and a type scale that stops at 16px because a dense analytics screen has no room for a display size.
No component references a hex value. That is what made dark mode possible at all. Retrofitting a second theme across 150 screens would have been months of work; reading from tokens turned it into a single swap, and it was the change users asked for most.
It had to hold across a pipeline canvas, a notebook with live resource meters, form-heavy configuration, a browsable catalogue, executive dashboards and a telecom support screen. A component library proves itself on the surface nobody anticipated.
Tokens and type
Five named greys carrying text, borders and containers. A brand ramp mapped to button, hover, selected and background states. Every value in a table with its variable name, so an engineer never has to guess which purple.
Components
Every component drawn in each state, in both themes, on the same sheet. Engineers built from these directly.
Icons
One set, one grid, one stroke weight, replacing icons collected from three different sources.
Working with six engineers and a CTO
Handoff was Figma inspect plus sitting with whoever was building the screen.
An engineer told me the chart widgets were fixed. Whatever I designed had to use what already existed. That constraint is the reason the dashboard work is about reading order rather than new components, and it made the result buildable. I’d rather design inside a real limit than hand over something that quietly becomes someone else’s problem.
The CTO and I disagreed about connector creation. Reaching a dataset takes three sequential choices on one page, and I wanted it broken into visible steps so a new user could tell where they were. He wanted it kept as one page, because daily users repeat that flow constantly and a stepped version taxes people who already know the sequence.
It shipped as one page. I still think the hierarchy is too flat, but he was weighing the right thing: who uses it most, not who finds it hardest.
Impact
Testing, five daily users. They hesitated at area boundaries, restarted tasks because nothing confirmed whether the last one had worked, and none of them could read the job list’s status row without help. Every one of them wanted a dark theme.
Percentages circulated internally afterwards, roughly a third faster on navigation and forty percent fewer mis-clicks. Five people is the right sample for finding problems and the wrong one for producing statistics, so treat those as directional.
What is verifiable is the design.
| Before | After | |
|---|---|---|
| Navigation | Three patterns | One labelled shell |
| Row actions | Order varied by area | One order, irreversible last |
| Modals | Button order and wording varied | One order, one vocabulary |
| Numeric data | Left-aligned | Right-aligned, tabular |
| Feedback | No empty, error or loading states | Skeletons, toasts, empty states |
| Theme | Light only | Light and dark from one token layer |
| Handoff | No shared vocabulary | Fifteen documented components |
Everything built afterwards, including the agentic screens, came out of existing components. New patterns now have to justify themselves against what already exists.
Reflections
I got the dashboard structure right and the colour wrong. The three layers hold up, but I let colour decorate the cards and signal severity at the same time, so by the time something was critical there was nowhere for it to land. I’d keep the interface neutral now and spend colour only where something needs attention.
Testing found the problems but couldn’t size them. Five sessions tell you what is broken. Without instrumentation in the product I can describe what changed in a room, not what changed in production.
The Designer area still bothers me. Its rail kept a file-menu vocabulary matching nothing else. Right for the people who lived there, wrong for the product, and I’d revisit it now with a migration path.
Nine teams had each solved the same problems separately, and none of them were wrong. What was missing was somebody deciding once which answer the whole product would use.