Building a shared language for a fast-growing crypto casino

FortuneJack is the world's first crypto casino and one of the top 10 globally. This project was a complete design system, built from scratch — a shared language that unified a growing team and transformed how design and development worked together.

Design System

Design System

A complete foundation: color, type, spacing, shadows, and every component the product needs — built from scratch and shared by six designers and five developers.

Design System

A complete foundation: color, type, spacing, shadows, and every component the product needs — built from scratch and shared by six designers and five developers.

Business goals

  1. Eliminate visual inconsistency across the entire platform.

  2. Speed up the design-to-development handoff process

  3. Create a shared language between designers and developers.

The starting point

Before this project, FortuneJack had almost no design foundation. I started by mapping exactly what existed — and the gaps were significant.

Only three components existed — a primary button, a secondary button, navigation, and a dropdown. Everything else was rebuilt from scratch every time.

No tokens of any kind — no color variables, no spacing scale, no typography styles. Every value was hardcoded and undocumented.

Handoff stretched across two to three days per feature — most of it back-and-forth clarification of ambiguous specs, not actual building.

From scattered decisions to a single system

A deliberate process, built with the people who would actually use it — designer to designer, then designer to dev team.

Audit

Token architecture

Naming system

Components

Handoff

how might we make a system rigorous enough to scale, yet simple enough to actually adopt?

how might we make a system rigorous enough to scale, yet simple enough to actually adopt?

A naming system everyone could read

Simplicity starts with language. A system only gets adopted if everyone can read it without a manual — so the naming had to work for designers and developers equally. Token naming looks like a detail. It isn't.

After several sessions with both designers and all developers, we landed on a four-part structure that reads like a sentence.

Element

What it styles

Background

text

stroke

icon

fill

Tone

What it communicates

neutral

brand

success

warning

danger

Emphasis

How prominent it is

strong

weak

weaker

State

When it applies

hover

pressed

focused

disabled

selected

Element

Tone

Emphasis

State

The structure reads like a sentence: 

what it styles → what it communicates → how prominent → when it applies.

A developer adding a hover state to a danger border never has to ask which token to use — the name already tells them.

In use

In use

Primary surface

Background

Neutral

Strong

Light success fill

Background

success

weak

Primary brand text

text

brand

strong

A library that covers every screen

A system only gets used if it has everything the team needs. With the foundation locked, we built out every interactive and structural element the product required — each with full states, variants, and Figma properties, so a designer assembles screens instead of inventing them.

Where it got hard

Where it got hard

Where it got hard

Getting the team to actually adopt the system came down to two judgment calls — not technical problems, but decisions with real consequences either way.

Choosing the right token architecture

Choosing the right token architecture

Choosing the right token architecture

A three-tier approach (brand → alias → mapped) is the standard recommendation for scalable systems — more granular control, more future flexibility. But applied to a single-brand product with one color mode, it would have added a layer of abstraction that served no purpose and made the system harder to learn. Choosing the simpler two-tier structure of primitives and semantics meant deliberately resisting "best practice" in favor of what was actually right here. That's a harder call than it sounds — it's easy to over-engineer when the more complex option is the one that looks safe.

Getting developers off Tailwind

Getting developers off Tailwind

Getting developers off Tailwind

The dev team was already productive with Tailwind and reluctant to switch. The risk was real: if they didn't adopt the system, every design decision would quietly get worked around until the system was ignored entirely. The solution came from empathy rather than authority — keep Tailwind's raw value scale as the foundation so migration felt familiar, while making the design identity fully custom. Neither side got exactly what they wanted. Both got something that worked, and adoption was painless.

The system in practice

The system in practice

The system in practice

Two collections, 439 variables. Primitives hold the raw scale; Theme holds every semantic token that components actually reference. Each one aliases a primitive and resolves per mode — fill/brand/weak is slate/800 in dark and slate/100 in light. One name, correct value everywhere.

The library

Color, typography, and every component the product runs on — built once, with every state accounted for.

3× faster handoff

Developer handoff dropped from two to three days down to a single day.

What actually changed

Designer - developer

Constant back-and-forth

Zero misunderstandings after launch

How the team works

Everyone working differently

One shared source of truth

The product itself

Inconsistent across screens

Consistent at scale