Projects Floret Design System
Design System Figma Variables Tokens Component Library Light & Wonder

Five product squads. Three design languages. Zero single source of truth. Floret is the token-driven system that pulled Light & Wonder's interfaces back into one voice — and cut handoff time in half.

Client Light & Wonder
Role Lead Designer — Design System
Scope Tokens · 90+ Components
Stack Figma Variables · Light/Dark Modes
The Business Problem

Every squad was shipping their own buttons, their own spacing, their own blue. The marketing site didn't match the dashboard. The dashboard didn't match the mobile app. Rebuilding trust in the brand meant rebuilding the pixels behind it.

5
Product squads working in silos
across iGaming, Lottery, SciPlay and more
90+
Components consolidated
from six fragmented Figma libraries
Faster design-to-dev handoff
after token export replaced manual specs

A gaming giant, a dozen digital products, no shared UI language

Light & Wonder had grown through acquisition. Each product team — iGaming, Lottery, SciPlay, B2B portals, internal tooling — had inherited its own Figma files, its own colour palette, and its own definition of "button". The brand team had refreshed the wordmark; the product didn't follow.

When I joined, the brief was blunt: build one design system that every squad would actually use. Not a style guide on a Notion page. A living library — tokens, variants, modes, documentation — that would survive a redesign, a rebrand, and a team reshuffle.

🎯

The constraint that shaped everything: this system had to be maintained by one designer, adopted by five teams, and survive being handed to a new owner. If it wasn't self-documenting and token-driven, it wouldn't last six months.

Three failure modes that kept repeating across every audit

01 · Brand

Fragmented visual language

Seven shades of "brand blue" across three products. Heading scales drifted between 18px and 22px for the same role. A user moving between tools felt like they'd changed companies.

02 · Source

No single source of truth

Components lived in six different Figma files. Engineers copied hex codes from screenshots. When brand updated the palette, nothing downstream updated with it — every team patched manually.

03 · Speed

Slow handoff

Designers hand-annotated every spec. Developers re-guessed spacing. A button variant took two review cycles and four Slack threads before it shipped correctly.

The walls we designed inside

Three real constraints shaped every structural decision in the system:

One designer, five teams. There was no dedicated design system team — I maintained Floret alongside product work. Governance rules had to be strict enough that squads couldn't introduce rogue tokens without the graph breaking visibly. Complexity that required manual oversight was complexity we couldn't sustain.

No big-bang migration. Existing product Figma files couldn't be broken mid-sprint. Every component had to be a swap-in replacement — not a forced rewrite. Adoption had to be opt-in and incremental so teams could migrate at their own pace without halting product work.

Engineering approved the naming convention before any component was published. Renaming a token after the first dev sync would have broken the entire token map in the codebase. `color.action.primary` was a joint decision, agreed in writing before component work began — not a design unilateral.

Build the tokens first — components are just references

I stopped treating Floret as "a component library" and started treating it as a token graph. Components are the surface; tokens are the spine.

If the tokens are right, one rebrand updates the entire product suite in minutes — not quarters. The architecture I landed on is three strict tiers: Primitives (raw values), Semantic (intent), Component (binding). Every component consumes component tokens. Component tokens reference semantic. Semantic references primitives. Change the primitive — the whole tree bends.

No shortcuts. No component ever points directly at a hex code. The moment that abstraction leaks, a rebrand breaks everything downstream.

Tier 01

Primitives

Raw values — hex codes, px steps, font sizes. Never referenced directly by components.

blue-100 blue-500 blue-900 indigo-500 teal-500 space-4 · 4px space-16 · 16px radius-md · 8px font-size-b16 · 16px
Tier 02

Semantic

Role-based — describes intent, not appearance. Swappable across Light & Dark modes.

color.action.primary color.text.default color.surface.muted color.status.danger space.inset.md radius.control type.body.md
Tier 03

Component

The binding — each component consumes only component tokens, never reaches past them.

button.primary.bg button.primary.text button.primary.radius input.border.rest input.border.focus card.surface card.shadow

Four calls that made Floret actually stick

Decision 01

Figma Variables over style libraries

What — Rebuilt every colour, spacing, radius and type token as a Figma Variable with Light/Dark modes.

Why — Styles can't reference each other. Variables can. That's the only way a three-tier token graph survives inside Figma. Change a primitive variable and every semantic and component reference updates automatically.

Problem solved — One variable swap now propagates across 90+ components and every product screen that consumes them. A rebrand or a dark-mode toggle is a single operation, not a two-week reskin.

Decision 02

Variants for states — not for shapes

What — Each component has variants for state (rest, hover, focus, disabled, loading) and intent (primary, secondary, danger, ghost). Size and layout are component properties, not separate components.

Why — Exploding the variant matrix — Button_Primary_Large_Hover, Button_Primary_Small_Rest, etc. — kills maintainability. Every state needs an update if the design changes.

Problem solved — A designer picks one Button, flips three properties in the panel — intent, size, state — instead of hunting through 30 Button_XYZ files.

Button · intent × state
primary · rest
secondary · rest
ghost · rest
danger · rest
primary · disabled
primary · loading
Decision 03

Semantic tokens never skip tiers

What — Enforced a strict rule: components reference component tokens only. Component tokens reference semantic. Semantic references primitives. No exceptions.

Why — The moment a component points directly at #2D5BFF, the abstraction leaks. Dark mode fails. A brand colour change misses that component. The graph only holds if every node points to the layer directly above it.

Problem solved — Dark mode, brand palette tweaks, and accessibility contrast fixes all became single-file changes in the variables panel. No hunt for stranded hex codes.

Variable Light mode Dark mode
color.action.primary blue-500 blue-400
color.text.default blue-900 gray-50
color.surface.muted gray-50 blue-850
color.status.danger red-600 red-400
radius.control 6px 6px
Decision 04

Dev handoff is tokens — not annotations

What — Exported the token graph as JSON (Style Dictionary format) so engineering consumed the same source of truth the designers used — not redline annotations.

Why — Re-typing values into a CSS file is where drift begins. Engineers re-interpret rounding and spacing, and the implementation silently diverges from the design.

Problem solved — Spec drift between Figma and production dropped to near-zero. A token rename in Figma showed up in the codebase on the next sync. No annotation layer. No translation loss.

Six weeks of audit before a single component was drawn

No component was designed until the token graph was agreed and locked. That sequencing — audit → naming → primitives → semantic → component — is what made Floret maintainable.

01 — Audit

Component inventory

Catalogued every button, input, card and icon across five product Figma files. Found 14 button variants, 9 input styles, 7 distinct blues.

02 — Token graph

Naming convention

Drafted the three-tier architecture with product leads. Agreed on naming (color.action.primary) before touching Figma — convention drift kills systems faster than missing components.

03 — Variables

Primitives in Figma

Built 180+ primitive variables with Light/Dark modes. Set up semantic layer. Locked naming and a no-shortcuts rule before opening the gate for component work.

04 — Components

Phased rollout

Shipped in waves — foundations first (Button, Input, Card), then composites (Data Grid, Dialog), then patterns. Each wave gated on a dev review before publishing.

Variables, variants and properties — the machinery behind every screen

Floret — Component Variants, Variables, Properties and Styles overview
Component foundations

One component. Every state. No duplication.

Every component in Floret is assembled from three building blocks: a Variable that holds the value, a Variant that defines the state (rest, hover, focus, disabled, loading), and a Property that switches intent (primary, secondary, danger, ghost).

The Figma Variables panel (centre) shows Light/Dark modes mapped to semantic tokens. The Properties panel (right) shows how those tokens bind to a specific component. This is how a button stays consistent across 90+ screens — and stays correct after a rebrand.

A palette with intent. A type scale with rhythm.

Floret — Typography scale, colour ramps, shadow depths
Primitive layer

Five colour families, nine steps each. Type locked to an 8pt baseline.

Every token earns its place — if it's not referenced by a semantic token, it gets cut from the primitives layer. No decorative colour aliases. No floating type sizes that exist in one file only.

The shadow scale (Depth-1 to Depth-6) maps to an elevation system: lowest depth for borders, highest for modals. Components never invent new shadows — they pick from the six.

180+
Primitive variables
5 × 9
Colour family steps
2
Modes — Light & Dark
6
Elevation depths

The spec isn't the point. The product is.

Floret — Spacing tokens applied in a real product dashboard, with full icon library
Spacing + Icons

200+ icons drawn on the same 8pt grid as every layout.

Spacing tokens land in real UI — the dashboard shows space.inset.md as sidebar padding, space.stack.sm as row gap. Tokens are only useful if they're visibly governing real decisions.

The icon set (200+ glyphs) is drawn against the same 8pt grid. Nothing feels off-grid when dropped into a card or toolbar — because it literally isn't.

90+ components. One naming convention. Zero drift.

From Accordion to Toolbar, every component is documented with its variants, properties, tokens consumed and accessibility notes. Squads pull from one library; brand updates ripple automatically.

Accordion
Action Toolbar
Alerts
App Header
Auto Complete
Avatar
Badge
Breadcrumb
Button
Button Group
Calendar
Cards
Checkbox
Chip
Combo Box
Comment
Data Grid
Data Viz
Dialog
Dropdown
File Uploader
Form
Input
List View
Menu Bar
Pagination
Progress Bar
Rich Text Editor
Scheduler
Sidebar
Skeleton
Stepper
Tabs
Tags
Timeline
Toast
Toggle
Toolbar
Floret Design System — full component library cover sheet
Floret v3.2 — component inventory across Notes, Layout guides, and 90+ production components

What changed after Floret shipped

Faster handoff

Spec annotation disappeared. Engineering pulled tokens from the same JSON the designers edited.

90+
Components unified

Replaced 14 button variants, 9 inputs and 7 blues with one Button, one Input, one palette.

1 file
Rebrand surface area

Dark mode, brand tweaks and contrast fixes all become single-file changes in the variables panel.

5→1
Source of truth

Five fragmented Figma libraries collapsed into one published library consumed by every squad.

The exploration that didn't ship

The early version of Floret was built entirely on Figma Styles — not Variables. In a single-mode build, Styles and Variables look identical in the panel and behave identically in components. The difference only surfaces when you need modes.

In week 3 we added a Dark mode requirement. Styles can't reference each other — so every semantic token had to be manually duplicated in a second Style list for dark. One colour change meant two edits, in two separate places, with no link between them. The lists were guaranteed to diverge within a month.

Why we cut it: The three-tier token graph only works because Figma Variables support nested references — a semantic token can point to a primitive, and a component token can point to a semantic. Styles are flat. The whole architecture collapsed the moment we needed real multi-mode support. We migrated entirely to Variables in week 4 and rebuilt the semantic layer from scratch. It cost a week. It saved the system.

What I'd do differently next time

"A design system only survives if engineering owns half of it. The tokens have to be a shared contract — not a design deliverable thrown over the wall."

What worked. Starting with the token graph — not the components — saved months of rework later. Having Light and Dark modes baked into the primitive layer from day one meant dark mode wasn't a "Phase 2"; it shipped with the library.

What I'd change. I would have set up the Style Dictionary export pipeline in parallel with the Figma work, not after. A month of manual sync between design and code could have been avoided. Next system I build, the JSON export is scaffolded on day one — before the first component is published.

Want to see enterprise UX at scale?

Book intro call →