Cube

Role: Expert UX/UI Designer · Organisation: Geopost · Period: 2024 to present · Owned: System strategy, architecture, components, documentation, governance · Team: Two designers, one on business products and one on consumer, with agency designers as backup. Development teams in Poland, Hungary and France.

Context

Cube serves B2B, B2C and C2X products across more than 50 countries. The same component has to hold up in a browser, on a phone, and on a handheld used by delivery drivers, in markets with different languages, different regulations, and different front end teams who joined the platform at different times.

The system has more than one kind of consumer and more than one place it renders. Almost every decision below comes from that.

The same Modal at two widths. Note the buttons: side by side on desktop, stacked and full width on mobile.

Three versions

Each version of Cube was right for the people using it at the time. What changed was not my thinking about design systems. It was who was on the other end of the library.

Cube 1.0

Deprecated

Cube 1.0 was not mine. It existed when I arrived, and it did not hold to the standards a design system needs to be relied on.

I did not argue about it. I built Cube 2.0 alongside it, component by component, and retired Cube 1.0 once there was enough of the new system for teams to move across.

Cube 2.0

Guardrails

The first people building interfaces with the system were not all designers. Some had no UI training at all. Constraint was the point: fewer choices, safer defaults, less rope. Flexibility then would not have produced freedom, it would have produced inconsistency faster.

There was a second constraint that had nothing to do with design. Management would not approve a design system that started empty, so I opened the new file with the legacy components the teams were already using and replaced them gradually. That was an instruction, not a design decision. I am still clearing parts of it.

Cost: senior designers found the system restrictive, and they were right.

Cube 2.0, evolved

Composability

The people using the system changed. Senior UX/UI designers became the primary consumers, and the guardrails that had protected version one were now friction.

I introduced slots: the same components, with defined openings where a designer supplies their own content, and rules for what the system does when they supply the wrong thing. Then I taught the UI designers to build their own small libraries to drop into those slots. That is what actually made the design work fast, more than the slots by themselves.

Cost: more surface to document, and more ways to misuse it.

Ten slots on one card, each switched on or off independently.

Cube Next

Built for the code

Several development teams, different frameworks, each consuming the system differently. Cube Next rebuilds the components with the developer side solved first: headless components, Tailwind CSS v4, Chakra UI v3, React 19. Designers are still in scope, but the decisions are led by code. Semantics, architecture, how a component is actually assembled.

A change of leadership made it possible to start clean, which was the one thing I could not do the first time.

Status: in progress.

Tokens

Two layers. Primitives hold raw values and are hidden from publishing. Themes hold UI roles and may only alias primitives, with one exception for the focus ring. Four brands run as themes on one set of primitives, so only the brand colours change between them.

Cube Next has fewer tokens than Cube 2.0, and that was the point. The earlier set had to be legible to UX designers and concepters, so it carried names and variants that explained themselves to people who were not working in code. Cube Next is consumed by UI designers and front end developers, who do not need that scaffolding. Fewer tokens, stricter naming, and the architecture doing the explaining instead of the labels.

Cube 2.0
Cube Next
The same token, traced through each system.
Fewer steps, stricter names.
Ten slots on one card component. Each one takes a different component, and the card rebuilds itself around whatever is put in.
The same component's own properties. A designer turns on what the case needs and the layout adjusts, without detaching from the library.

One component, all the way down

Modal, from the Figma definition to two rendered front ends.

Every property exists because a real use case needed it, not because the component could support it.
The anatomy as the documentation presents it.
One way back, not three. Documentation like this is what stops the same decision being argued in every team.
Chakra UI v3
Tailwind CSS v4
The same Modal, defined once, rendered by two different front end stacks. This is what the token rebuild was for.

Design to engineering

What I hand over is the Figma file, the documentation, and the JSON token files. The developers build from that, and I take their feedback on how a component behaves in code and adapt it. Components are converted with Cursor connected to Figma. The output is Tailwind CSS v4, and the developers built a translation layer into Chakra UI v3.

The documentation is the contract. If a developer has to ask me what a component is supposed to do, the documentation was not finished.

The specification for the announcement bar. Current state, the problem, and what has to be true before it is done.

Governance and adoption

The designers who own the business products and the consumer products write the requirements. They bring the components and patterns their products need. We are a small team, so the process is light: Jira tickets, and every week I present what I have built and take feedback from the room.

Adoption came from different places at each stage. In the first stage it came from documentation. Giving designers a way to build quickly at a known standard, and giving developers one source of truth, was welcomed faster than I expected. In the current stage it comes from flexibility, using the new slot features in Figma.

Every component carries a status, and contributions arrive through branches. Four states: under construction, rework needed, ready for review, finished. Anyone opening the file can see what is safe to use without asking.

The part that was not about design

Governance in a large company does not get solved by convincing developers one at a time. I ran workshops for the heads of marketing and IT in France, Hungary and Germany, because those were the people whose decisions actually moved teams.

Budget was a separate problem. I gave the VP of Marketing a live demonstration of the system: what it could do, how flexible it was, and rough velocity comparisons against how the same work had been done before. He approved the design system budget for the following year.

Working inside the constraints

Copilot was the only AI tool approved in the company, for security and contract reasons. It is not the tool you want for building a design system.

The development teams later had Cursor approved as a trial, to measure whether AI actually improved their output. I asked to be added to that pool and I was. Inside it there were few limits, so I had room to work with MCP connected to Figma.

Where it stands

  • 42Components
  • ~30Patterns built from them
  • 50+Markets
  • 4Brand themes on one primitive set
  • 105Primitives, Cube Next
  • 197Semantic tokens per theme

All four theme files carry an identical set of token paths. Only the values behind them change, which is what makes a fifth brand a configuration job instead of a rebuild.

  • 6Products fully designed on Cube
  • 6Products partially on Cube
  • 8Products planned to migrate

What I would do differently

I would have asked for a second file. One clean file holding only new components, while the inherited file stayed visible so management could watch it improve. Instead I did both jobs in the same place, which slowed the clearing out and left legacy parts in the system longer than they needed to be there.

My view on design systems did not change. I adapted to the situation and to the people who had to use it.