Skip to main content
All projects

A verifiable design system for a luxury maison

From approved HTML/CSS prototypes to a Figma library developers could use without reinterpreting every choice, with tokens, components and automated checks.

Role
Design Engineer, Design Systems
Team
Solo design engineer, with agency team & client developers
Duration
2026 · ongoing
Client
Florence-based luxury fashion maison (via agency, under NDA)

The project in one minute

The Challenge

Approved screens needed to become a consistent, implementable library without losing their behaviour.

My contribution

I translated 13 approved screens into the token architecture, component library and automated verification scripts.

Results and scope

A file-wide audit caught raw colours in 35 icon masters: a defect invisible by eye that propagated to their instances.

From observation to design decision
  1. 01Observation

    A raw colour can look identical to a token-bound colour.

  2. 02Interpretation

    Visual sameness does not prove structural consistency.

  3. 03Design decision

    Audit every component’s fills and strokes against the Variables system.

Reading of the project reconstructed from the case study, not an original research artifact.

What remains to be established: These are delivery checks, not measured reductions in development cost or operator error.

The Challenge

What I was responsible for

  • Extracted and rationalized the design system from 13 approved HTML/CSS prototype screens
  • Designed the token architecture: DTCG source compiled to Figma Variables, primitives aliased by semantic roles
  • Built the component library programmatically via the Figma Plugin API, orchestrating an AI agent
  • Defined the completeness standard (IBM Carbon benchmark) and the naming and structure conventions
  • Wrote file-wide audit scripts that verify the contractual requirements as assertions
  • Maintained the component registry, guidelines and handover documentation

The approved screens described the product, but not yet the rules needed to build it consistently. The design system had to make tokens, variants, Auto Layout and naming explicit, in a form development could use directly.

The starting point was thirteen approved HTML/CSS screens for a PIM, the software operators use to prepare a fashion catalog for its different sales channels. My job was to turn them into a Figma library precise enough to become the reference for development in Vue.

So the file had two users: the people who would use the PIM and the people who would build it. For developers, what mattered most were explicit states, consistent tokens, predictable properties and components that didn't need extra interpretation.

That precision also carried contractual weight. The contract set specific requirements for the delivery file; if they weren't met, development time and cost could be renegotiated.

"Operators work for hours in a dense interface, while developers have to translate that same interface into Vue components. For both, ambiguity and missing states turn into errors, or into questions to settle during implementation."

Impact

The biggest risk was components that looked right while following different rules underneath: hardcoded values, bypassed tokens, or states built inconsistently.

Symptoms

In the prototypes, values were often repeated inline, interactive states were incomplete and naming had grown screen by screen. Rebuilding everything by hand in Figma risked carrying the same inconsistencies into the library.

Research

Prototype inventory

·Inventory of real components, states, labels and contents, separating reusable components from one-off compositions and dead code

~40 reusable components

Identified from the prototypes and separated from one-off screen compositions and dead code: what the system actually had to cover

190 design tokens

Derived and structured as a DTCG source: color primitives and semantic roles, spacing, radii, typography

Labels and content taken from the approved screens

Every component starts from real cases: labels, states and content come from the approved screens rather than from examples invented for the library

Focus and active states missing everywhere

The prototypes covered default, hover and disabled at best. The missing ones were exactly the states accessibility depends on.

Completeness benchmarking

·What a finished component actually includes: state sets, data-entry anatomy, property conventions

Five states for every interactive control

I adopted Carbon's standard: default, hover, focus, active and disabled for every interactive control, plus error, warning and read-only anatomy for data entry

The same rules on every component

From Astryx I took one idea: if every component follows the same naming, property and composition rules, developers and AI agents can use the system without someone having to explain it

Key Insights

File quality had a price

The contract put a cost on hardcoded values and missing states. File quality therefore had to be verified like any other requirement.

The hard part was verifying the file's consistency

Checking dozens of components, states and properties by hand easily leads to mistakes. Drawing the components was the simpler part; the difficulty was verifying that they were all built with the same rules.

Every component starts from an approved screen

For each component I took labels, states and content from the approved screens, checking the page as well as the spec.

I designed the library with the people implementing it in mind

Dev Mode has its own user experience: predictable variants, semantic tokens and clear names cut down questions and guesswork during development.

Halfway through, the Figma system became the reference

Halfway through the project we inverted the hierarchy: the consolidated Figma system became the reference, and from then on differences in the prototype CSS were corrected to match the system.

Goals & Principles

Every variant maps to a prop

Component properties (variant, size, state, disabled) are designed to translate 1:1 into Vue props, with no reinterpretation.

Zero hardcoded values

Every color, space, radius and type style applied by reference to a Variable, and verified by script.

Complete state coverage

Carbon-level state sets on every interactive component, including focus and active, which the prototypes were missing.

Automated checks on the delivery file

The contractual requirements are translated into checks a script can run on the file.

Guiding Principles

Color, spacing and type always go through tokens

Two tiers, primitives and semantic roles; components use roles only. When a surface has its own logic it gets a dedicated role family instead of reusing one meant for something else.

Flat structure, private parts

No atomic design tiers. One flat registry; sub-components used only inside others carry a dot prefix (.Table Row, .Tab), which Figma treats as private.

The same rules on every component

Naming, properties and composition follow the same rules on every component. When an exception is needed, it is made explicit.

Brand rules inside the library

A palette drawn from Renaissance pigments, no pure white, and one brand rule applied everywhere: gold identifies the brand and is never used for interactive elements.

Solution Design

Interactive diagram

From a token to component states

Select a node to highlight its connections and read the design decision behind it.

Base value

A primitive holds a reusable value. Its appearance alone does not explain its purpose.

Connected to: Semantic token

Conceptual reconstruction of the token-to-component relationship, not a live Figma inspector.

Two-tier token architecture in Figma Variables

The contract required reference-only styling, but a flat list of variables makes it easy to reuse a role just because it looks close enough, even when it means something else.

Alternatives considered

  • Figma styles only (no numeric tokens, weak Dev Mode story)
  • Single flat Variables collection (simple, but roles end up used for different purposes)
  • Two-tier architecture: primitives aliased by semantic roles
Decision

A DTCG token source compiled into two Variables collections: primitives (the palette) and semantic roles that alias them. Components use roles only; primitives never appear in a component.

Rationale

With semantic roles, intent can be checked: a text role used as a background shows up as an anomaly. When a surface needed its own logic (sidebar, inverse, avatar), it got a small dedicated role family pointing at the same primitives: nothing changes on screen and the role stays recognizable.

Trade-off: More naming work up front, and when a role is missing you have to create one instead of borrowing it. It's an extra step, but it keeps the semantic layer from losing its meaning over time.

Programmatic construction with an AI agent

Forty components with complete state sets, sizes and properties means thousands of micro-decisions that must be applied identically. Built by hand, differences pile up one component at a time without anyone noticing.

Alternatives considered

  • Manual build with a checklist (differences pile up at this scale)
  • One-off scripts per component (better, but unverified)
  • An AI agent driving the Figma Plugin API from explicit state recipes, with a visual verification loop
Decision

Every component set is generated from an explicit recipe (variant by state by size, each mapped to token roles) executed by an AI agent through the Plugin API. After each build: screenshot, visual check, fix, re-verify.

Rationale

With recipes, consistency no longer depends on the memory of whoever builds the component. Labels become Text properties automatically, focus rings exist because the recipe includes them, and the twentieth variant is built exactly like the first. The agent also collected the Plugin API's traps (operation order, slot quirks, nested-instance overrides) into a set of reusable patterns.

Trade-off: The Plugin API often fails without reporting an error: order-dependent layout properties, slots born with opaque fills, overrides that don't reset inside nested instances. Each one cost a debugging session, once, and became a documented pattern.

File-wide automated audits

At this scale you can't verify by eye that everything is tokenized. A raw value identical to the token can't be told apart in the canvas.

Alternatives considered

  • Visual review (can't see raw values identical to tokens)
  • Spot checks on key components (samples miss systemic bugs)
  • Scripted sweeps of every node in the file
Decision

Audit scripts traverse the entire file, checking every fill and stroke of every node inside every component for paints not bound to a Variable, excluding instances (they mirror their master and generate hundreds of false positives) and filtering by ancestor to skip documentation frames.

Rationale

The audits paid off immediately: they found a 35-icon library whose master fills were raw near-black, identical to the token by eye and inherited silently by every instance in the file. A visual review could not have caught it. A second pass extended the sweep to container nodes and strokes and found another class of leftovers.

Trade-off: Audit scripts are code: they need maintenance, and we had to learn to recognize their false positives. In return, anyone can rerun them and check the contractual requirements.

Flat registry with private sub-components

In practice, atomic design tiers hold up poorly: an atom ends up inside another atom, and the hierarchy stops describing how the components are actually built.

Alternatives considered

  • Atomic design (atoms, molecules, organisms)
  • Ad hoc organization per page
  • Flat registry with dot-prefixed private sub-components
Decision

One flat list of components, tagged by function (action, form, data, nav, overlay, layout). Sub-components that only live inside others carry a dot prefix: private in Figma, hidden from the assets panel.

Rationale

The library's public surface is exactly what a developer should instantiate; internals stay internal. The registry doubles as a machine-readable component inventory, with descriptions on every component.

Trade-off: Function tags are less structured than atomic tiers, and that's deliberate: the taxonomy describes what each component is for.

Outcomes & Impact

The final delivery can be checked against the same criteria it was built with. The audits verify the file's tokens, naming and structure, and they have already caught inconsistencies that looked correct to the eye, such as raw colors inside some icon masters.

~40 reusable components in a flat registry, each with complete interactive states (default, hover, focus, active, disabled)

190 design tokens as Figma Variables: primitives aliased by semantic roles, components use roles only

13 approved prototype screens systematized

100% of fills and strokes inside components bound to Variables after audits, zero raw values

A 35-icon systemic bug caught by script, invisible to eye-level review

Every visible label exposed as a Text property

Contractual requirements verified by script instead of stated in a handoff note

No state left ambiguous, a kind of error that has concrete costs for operators

In Dev Mode the file reads without explanation: predictable variants, semantic tokens, consistent names

Guidelines, component standard and registry live in the repo and stay available after handoff

Recipes, audit scripts and Plugin API patterns can be reused on other client systems

What I delivered

  • Figma library: Variables collections and component sets with complete states
  • DTCG token source (versioned with the project)
  • File-wide audit scripts (raw colors, structure, naming)
  • Figma guidelines and component standard documentation
  • Machine-readable component registry
  • State recipes documenting every variant's token mapping

Reflections

The audits were most useful on rules that are hard to see by eye; where they duplicated a visual review they added little.

Building components through the API only sped things up because tokens, naming and states had been defined first.

What I would change

  • Run the audits from day one: the 35-icon bug was found late, after instances had already spread through the file
  • Define dedicated role families for special surfaces (sidebar, inverse) earlier, instead of discovering borrowed-role smells in review
  • Instrument the component registry from the start rather than reconstructing coverage mid-project
What worked and what was difficult

What Worked

Starting from the approved prototypes

I never invented a label or a state: every component could point at the screen it came from, which kept client conversations short.

The audits changed the conversation about requirements

Instead of arguing that the file met the requirements, I could run a script and show the result.

Building the library with software methods

I used recipes, assertions and reproducible builds, the same practices that make code reliable, and applied them directly to the Figma library.

Challenges

The Plugin API often fails without reporting an error

Layout properties that must be set in a precise order, slots born with opaque white fills, overrides that don't reset inside nested instances, stale screenshots in long sessions. Each trap cost one debugging session and became a documented, reusable pattern.

The audits needed checking too

The first audit pass checked only vectors and text, and missed raw fills on container nodes and strokes. Fixing the audits themselves (extending node types, checking strokes, excluding instances) took separate work.